/// <summary>
        /// this function will be invoked every time a packet is sent or received. all logics about 
        /// Client' states will be implemented here.
        /// </summary>
        /// <param name="connection">the connection object.</param>
        /// <param name="packet">the sent or received packet in stack transport.</param>
        protected override void UpdateRoleContext(CifsClientPerConnection connection, SmbPacket packet)
        {
            // Do nothing if no connection is found or the packet is not SmbPacket:
            if (connection == null || packet == null)
            {
                return;
            }

            // request packet:
            if (packet.PacketType == SmbPacketType.BatchedRequest
                || packet.PacketType == SmbPacketType.SingleRequest)
            {
                RequestPacketUpdateRoleContext(connection, packet, false);
            }
            // response packet:
            else if (packet.PacketType == SmbPacketType.BatchedResponse
                || packet.PacketType == SmbPacketType.SingleResponse)
            {
                if (!this.SmbUpdateContextWithResponsePacket(connection as SmbClientConnection, packet))
                {
                    SmbPacket request = this.GetOutstandingRequest(connection.ConnectionId, (ulong)packet.SmbHeader.Mid);
                    ResponsePacketUpdateRoleContext(connection, request, packet);
                }
                ResponsePacketUpdateRoleContextRegular(connection, packet);
            }
            else
            {
                // Do nothing if neither request nor response.
                // No exception is thrown here because UpdateRoleContext is not responsible for checking the 
                // invalidation of the packet.
            }
        }
        private bool SmbUpdateContextWithResponsePacket(SmbClientConnection connection, SmbPacket response)
        {
            if (response == null)
            {
                return false;
            }

            int connectionId = connection.ConnectionId;

            SmbHeader smbHeader = response.SmbHeader;

            // only process the response packet.
            if (response.PacketType != SmbPacketType.BatchedResponse
                && response.PacketType != SmbPacketType.SingleResponse)
            {
                return false;
            }

            // packet status
            SmbStatus packetStatus = (SmbStatus)smbHeader.Status;

            // filter error packet
            if (packetStatus != SmbStatus.STATUS_SUCCESS &&
                    packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED &&
                    packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW)
            {
                return false;
            }

            // process each special command
            switch (smbHeader.Command)
            {
                #region Negotiate Response

                case SmbCommand.SMB_COM_NEGOTIATE:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // down cast to negotiate response packet.
                    SmbNegotiateResponsePacket negotiate = response as SmbNegotiateResponsePacket;

                    // set negotiate flag
                    connection.NegotiateSent = true;

                    #region update security mode

                    SecurityModes securityModes = negotiate.SmbParameters.SecurityMode;

                    if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED))
                    {
                        connection.ServerSigningState = SignState.ENABLED;
                    }
                    else if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED))
                    {
                        connection.ServerSigningState = SignState.REQUIRED;
                    }
                    else
                    {
                        connection.ServerSigningState = SignState.DISABLED;
                    }

                    if (SecurityModes.NEGOTIATE_USER_SECURITY
                        == (securityModes & SecurityModes.NEGOTIATE_USER_SECURITY))
                    {
                        connection.UsesSharePasswords = false;
                    }
                    else
                    {
                        connection.UsesSharePasswords = true;
                    }

                    if (SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS
                        == (securityModes & SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS))
                    {
                        connection.IsClientEncryptPasswords = true;
                    }
                    else
                    {
                        connection.IsClientEncryptPasswords = false;
                    }

                    // update IsSignActive using the combination of the client's 
                    // MessageSigningPolicy and the connection's ServerSigningState
                    smbClient.Context.UpdateSigningActive(connection);

                    #endregion

                    #region update server capabilities

                    connection.ServerCapabilities = (Capabilities)negotiate.SmbParameters.Capabilities;

                    if (Capabilities.CAP_INFOLEVEL_PASSTHRU
                        == (connection.ServerCapabilities & Capabilities.CAP_INFOLEVEL_PASSTHRU))
                    {
                        smbClient.Capability.IsUsePassThrough = true;
                    }

                    #endregion

                    #region update maxbuffersize

                    connection.MaxBufferSize = negotiate.SmbParameters.MaxBufferSize;

                    #endregion

                    this.AddOrUpdateConnection(connection);

                    break;

                #endregion

                #region Session Setup Response

                case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // the session to operation on.
                    SmbClientSession session = null;

                    // down-case the packet
                    SmbSessionSetupAndxResponsePacket packet = response as SmbSessionSetupAndxResponsePacket;

                    // if session exists, use it.
                    if (this.GetSession(connectionId, smbHeader.Uid) != null)
                    {
                        session = new SmbClientSession(this.GetSession(connectionId, smbHeader.Uid));
                    }
                    else
                    {
                        session = new SmbClientSession();
                    }

                    // if success, update context and session key.
                    if (packetStatus == SmbStatus.STATUS_SUCCESS)
                    {
                        // if spng, the SessionKey is null and the SecurityBlob from server contains data
                        // in this situation, need to initialize the SecurityBlob of server to generate the SessionKey
                        if (connection.GssApi.SessionKey == null
                            && packet.SecurityBlob != null && packet.SecurityBlob.Length > 0)
                        {
                            connection.GssApi.Initialize(packet.SecurityBlob);
                        }

                        // get session key and store in the context
                        session.SessionKey = connection.GssApi.SessionKey;

                        // reset the gss api of connection
                        connection.GssApi = null;

                        // reset the securityblob when success
                        packet.SecurityBlob = null;
                    }

                    // update the security blob from server
                    connection.SecurityBlob = packet.SecurityBlob;
                    this.AddOrUpdateConnection(connection);

                    // update session
                    session.SessionUid = smbHeader.Uid;
                    session.ConnectionId = connectionId;

                    this.AddOrUpdateSession(session);

                    break;

                #endregion

                default:
                    return false;
            }

            return true;
        }
        private SmbPacket CreateTransaction2ResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0)
            {
                return(smbPacket);
            }

            SmbTransaction2RequestPacket transaction2Request = request as SmbTransaction2RequestPacket;

            if (transaction2Request == null)
            {
                return(smbPacket);
            }

            // if no setup command. break
            if (transaction2Request.SmbParameters.SetupCount == 0)
            {
                return(smbPacket);
            }

            // decode packet using the setup command
            switch ((Trans2SubCommand)transaction2Request.SmbParameters.Setup[0])
            {
            case Trans2SubCommand.TRANS2_QUERY_FILE_INFORMATION:
                SmbTrans2QueryFileInformationRequestPacket queryFileRequest =
                    transaction2Request as SmbTrans2QueryFileInformationRequestPacket;
                if (queryFileRequest != null)
                {
                    smbPacket = new SmbTrans2QueryFileInformationResponsePacket(
                        queryFileRequest.Trans2Parameters.InformationLevel);
                }
                break;

            case Trans2SubCommand.TRANS2_QUERY_PATH_INFORMATION:
                SmbTrans2QueryPathInformationRequestPacket queryPathRequest =
                    transaction2Request as SmbTrans2QueryPathInformationRequestPacket;
                if (queryPathRequest != null)
                {
                    smbPacket = new SmbTrans2QueryPathInformationResponsePacket(
                        queryPathRequest.Trans2Parameters.InformationLevel);
                }
                break;

            case Trans2SubCommand.TRANS2_SET_FILE_INFORMATION:
                smbPacket = new SmbTrans2SetFileInformationResponsePacket();
                break;

            case Trans2SubCommand.TRANS2_SET_PATH_INFORMATION:
                smbPacket = new SmbTrans2SetPathInformationResponsePacket();
                break;

            case Trans2SubCommand.TRANS2_QUERY_FS_INFORMATION:
                SmbTrans2QueryFsInformationRequestPacket queryFsRequest =
                    transaction2Request as SmbTrans2QueryFsInformationRequestPacket;
                if (queryFsRequest != null)
                {
                    smbPacket = new SmbTrans2QueryFsInformationResponsePacket(
                        queryFsRequest.Trans2Parameters.InformationLevel);
                }
                break;

            case Trans2SubCommand.TRANS2_SET_FS_INFORMATION:
                smbPacket = new SmbTrans2SetFsInformationResponsePacket();
                break;

            case Trans2SubCommand.TRANS2_FIND_FIRST2:
                SmbTrans2FindFirst2RequestPacket first2Request =
                    transaction2Request as SmbTrans2FindFirst2RequestPacket;
                if (first2Request != null)
                {
                    smbPacket = new SmbTrans2FindFirst2ResponsePacket(first2Request.Trans2Parameters.InformationLevel,
                                                                      (first2Request.Trans2Parameters.Flags & Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS)
                                                                      == Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS);
                }
                break;

            case Trans2SubCommand.TRANS2_FIND_NEXT2:
                SmbTrans2FindNext2RequestPacket next2Request =
                    transaction2Request as SmbTrans2FindNext2RequestPacket;
                if (next2Request != null)
                {
                    smbPacket = new SmbTrans2FindNext2ResponsePacket(next2Request.Trans2Parameters.InformationLevel,
                                                                     (next2Request.Trans2Parameters.Flags & Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS)
                                                                     == Trans2FindFlags.SMB_FIND_RETURN_RESUME_KEYS);
                }
                break;

            case Trans2SubCommand.TRANS2_GET_DFS_REFERRAL:
                smbPacket = new SmbTrans2GetDfsReferralResponsePacket();
                break;

            default:
                break;
            }

            return(smbPacket);
        }
        /// <summary>
        /// create the nt transaction packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateNtTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0)
            {
                return(smbPacket);
            }

            SmbNtTransactRequestPacket ntTransactRequest = request as SmbNtTransactRequestPacket;

            if (ntTransactRequest == null)
            {
                return(smbPacket);
            }

            // find regular packet
            switch ((uint)ntTransactRequest.SmbParameters.Function)
            {
            case (uint)NtTransSubCommand.NT_TRANSACT_RENAME:
                smbPacket = new SmbNtTransRenameResponsePacket();
                break;

            case (uint)NtTransSubCommand.NT_TRANSACT_CREATE:
                smbPacket = new SmbNtTransactCreateResponsePacket();
                break;

            case (uint)NtTransSubCommand.NT_TRANSACT_IOCTL:

                NT_TRANSACT_IOCTL_SETUP setup =
                    CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>(
                        CifsMessageUtils.ToBytesArray <ushort>(ntTransactRequest.SmbParameters.Setup));

                switch ((NtTransFunctionCode)setup.FunctionCode)
                {
                case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                    smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsResponsePacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY:
                    smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyResponsePacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK:
                    smbPacket = new SmbNtTransFsctlSrvCopyChunkResponsePacket();
                    break;

                default:
                    smbPacket = new SmbNtTransactIoctlResponsePacket();
                    break;
                }

                break;

            case (uint)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                smbPacket = new SmbNtTransQueryQuotaResponsePacket();
                break;

            case (uint)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                smbPacket = new SmbNtTransSetQuotaResponsePacket();
                break;

            default:
                break;
            }

            return(smbPacket);
        }
        protected override SmbPacket CreateSmbResponsePacket(
            SmbPacket request,
            SmbHeader smbHeader,
            Channel channel)
        {
            SmbPacket smbPacket = null;

            // error packet
            SmbStatus packetStatus = (SmbStatus)smbHeader.Status;

            // error packet
            if (packetStatus != SmbStatus.STATUS_SUCCESS &&
                packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED &&
                packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW)
            {
                smbPacket           = new SmbErrorResponsePacket();
                smbPacket.SmbHeader = smbHeader;

                return(smbPacket);
            }

            // success packet
            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_NEGOTIATE:
                if (smbClient.Capability.IsSupportsExtendedSecurity)
                {
                    smbPacket = new SmbNegotiateResponsePacket();
                }
                else
                {
                    smbPacket = new SmbNegotiateImplicitNtlmResponsePacket();
                }
                break;

            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                if (smbClient.Capability.IsSupportsExtendedSecurity)
                {
                    smbPacket = new SmbSessionSetupAndxResponsePacket();
                }
                else
                {
                    smbPacket = new SmbSessionSetupImplicitNtlmAndxResponsePacket();
                }
                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
                smbPacket = new SmbTreeConnectAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                smbPacket = new SmbTreeDisconnectResponsePacket();
                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                smbPacket = new SmbLogoffAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
                smbPacket = new SmbNtCreateAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_CLOSE:
                smbPacket = new SmbCloseResponsePacket();
                break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
                smbPacket = new SmbOpenAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_WRITE_ANDX:
                smbPacket = new SmbWriteAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_READ_ANDX:
                smbPacket = new SmbReadAndxResponsePacket();
                break;

            case SmbCommand.SMB_COM_TRANSACTION:
                smbPacket = this.CreateTransactionResponsePacket(request, smbHeader, channel);

                break;

            case SmbCommand.SMB_COM_TRANSACTION2:
                smbPacket = this.CreateTransaction2ResponsePacket(request, smbHeader, channel);

                break;

            case SmbCommand.SMB_COM_NT_TRANSACT:
                smbPacket = this.CreateNtTransactionResponsePacket(request, smbHeader, channel);

                break;

            default:
                break;
            }
            if (smbPacket != null)
            {
                smbPacket.SmbHeader = smbHeader;
                return(smbPacket);
            }

            return(base.CreateSmbResponsePacket(request, smbHeader, channel));
        }
        /// <summary>
        /// createt the transactions packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0)
            {
                return(smbPacket);
            }

            SmbTransactionRequestPacket transactionRequest = request as SmbTransactionRequestPacket;

            if (transactionRequest == null)
            {
                return(smbPacket);
            }
            switch (smbClient.Capability.TransactionSubCommand)
            {
            case TransSubCommandExtended.TRANS_EXT_MAILSLOT_WRITE:
                smbPacket = new SmbTransMailslotWriteResponsePacket();
                break;

            case TransSubCommandExtended.TRANS_EXT_RAP:
                smbPacket = new SmbTransRapResponsePacket();
                break;

            default:
                break;
            }

            // the packet is find
            if (smbPacket != null)
            {
                return(smbPacket);
            }

            // if no setup command. break
            if (transactionRequest.SmbParameters.SetupCount == 0)
            {
                return(smbPacket);
            }

            // decode packet using the setup command
            switch ((TransSubCommand)transactionRequest.SmbParameters.Setup[0])
            {
            case TransSubCommand.TRANS_SET_NMPIPE_STATE:
                smbPacket = new SmbTransSetNmpipeStateResponsePacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_STATE:
                smbPacket = new SmbTransQueryNmpipeStateResponsePacket();
                break;

            case TransSubCommand.TRANS_RAW_READ_NMPIPE:
                smbPacket = new SmbTransRawReadNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_INFO:
                smbPacket = new SmbTransQueryNmpipeInfoResponsePacket();
                break;

            case TransSubCommand.TRANS_PEEK_NMPIPE:
                smbPacket = new SmbTransPeekNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_TRANSACT_NMPIPE:
                smbPacket = new SmbTransTransactNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_READ_NMPIPE:
                smbPacket = new SmbTransReadNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_WRITE_NMPIPE:
                smbPacket = new SmbTransWriteNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_WAIT_NMPIPE:
                smbPacket = new SmbTransWaitNmpipeResponsePacket();
                break;

            case TransSubCommand.TRANS_CALL_NMPIPE:
                smbPacket = new SmbTransCallNmpipeResponsePacket();
                break;

            default:
                break;
            }

            return(smbPacket);
        }
 /// <summary>
 /// the transport
 /// </summary>
 /// <param name = "packet">the packet to send through TCP </param>
 public SmbDirectTcpPacket(SmbPacket packet)
 {
     this.packet = packet;
 }
Beispiel #8
0
        /// <summary>
        /// find the transaction packet.
        /// </summary>
        /// <param name="setupCount">the count of setup</param>
        /// <param name="command">the command of transaction packet</param>
        /// <returns>the target transaction packet</returns>
        private static SmbPacket FindTheTransactionPacket(byte setupCount, TransSubCommand command)
        {
            if (setupCount == 0)
            {
                return(new SmbTransRapRequestPacket());
            }
            else if (setupCount == 3)
            {
                return(new SmbTransMailslotWriteRequestPacket());
            }

            SmbPacket smbPacket = null;

            switch ((TransSubCommand)command)
            {
            case TransSubCommand.TRANS_SET_NMPIPE_STATE:
                smbPacket = new SmbTransSetNmpipeStateRequestPacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_STATE:
                smbPacket = new SmbTransQueryNmpipeStateRequestPacket();
                break;

            case TransSubCommand.TRANS_QUERY_NMPIPE_INFO:
                smbPacket = new SmbTransQueryNmpipeInfoRequestPacket();
                break;

            case TransSubCommand.TRANS_PEEK_NMPIPE:
                smbPacket = new SmbTransPeekNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_TRANSACT_NMPIPE:
                smbPacket = new SmbTransTransactNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_RAW_READ_NMPIPE:
                smbPacket = new SmbTransRawReadNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_READ_NMPIPE:
                smbPacket = new SmbTransReadNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_WRITE_NMPIPE:
                smbPacket = new SmbTransWriteNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_WAIT_NMPIPE:
                smbPacket = new SmbTransWaitNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_CALL_NMPIPE:
                smbPacket = new SmbTransCallNmpipeRequestPacket();
                break;

            case TransSubCommand.TRANS_RAW_WRITE_NMPIPE:
                smbPacket = new SmbTransRawWriteNmpipeRequestPacket();
                break;

            default:
                break;
            }
            return(smbPacket);
        }
Beispiel #9
0
        /// <summary>
        /// find the target packet.
        /// </summary>
        /// <param name="smbHeader">the header of smb packet</param>
        /// <param name="channel">the channel to access bytes</param>
        /// <returns>the target packet</returns>
        private static SmbPacket FindTheTargetPacket(SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_NEGOTIATE:
                smbPacket = new SmbNegotiateRequestPacket();
                break;

            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                SmbHeader_Flags2_Values flags2 = (SmbHeader_Flags2_Values)smbHeader.Flags2;
                if ((flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY)
                    == SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY)
                {
                    smbPacket = new Smb.SmbSessionSetupAndxRequestPacket();
                }
                else
                {
                    smbPacket = new Cifs.SmbSessionSetupAndxRequestPacket();
                }
                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
                smbPacket = new SmbTreeConnectAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
                smbPacket = new SmbNtCreateAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
                smbPacket = new SmbOpenAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_WRITE_ANDX:
                smbPacket = new SmbWriteAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_READ_ANDX:
                smbPacket = new SmbReadAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_CLOSE:
                smbPacket = new SmbCloseRequestPacket();
                break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                smbPacket = new SmbTreeDisconnectRequestPacket();
                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                smbPacket = new SmbLogoffAndxRequestPacket();
                break;

            case SmbCommand.SMB_COM_TRANSACTION:
                SMB_COM_TRANSACTION_Request_SMB_Parameters transaction =
                    channel.Read <SMB_COM_TRANSACTION_Request_SMB_Parameters>();
                if (transaction.SetupCount == 0)
                {
                    smbPacket = new SmbTransRapRequestPacket();
                }
                else
                {
                    smbPacket = FindTheTransactionPacket(
                        transaction.SetupCount, (TransSubCommand)transaction.Setup[0]);
                }
                break;

            case SmbCommand.SMB_COM_TRANSACTION2:
                SMB_COM_TRANSACTION2_Request_SMB_Parameters transaction2 =
                    channel.Read <SMB_COM_TRANSACTION2_Request_SMB_Parameters>();
                smbPacket = FindTheTrans2Packet((Trans2SubCommand)transaction2.Subcommand);
                break;

            case SmbCommand.SMB_COM_NT_TRANSACT:
                SMB_COM_NT_TRANSACT_Request_SMB_Parameters ntTransactoin =
                    channel.Read <SMB_COM_NT_TRANSACT_Request_SMB_Parameters>();
                smbPacket = FindTheNtTransPacket(ntTransactoin.Function, CifsMessageUtils.ToBytesArray <ushort>(ntTransactoin.Setup));
                break;

            default:
                break;
            }

            return(smbPacket);
        }
Beispiel #10
0
        /// <summary>
        /// update the context with request packet
        /// </summary>
        /// <param name="connection">the connection of endpoint</param>
        /// <param name="packet">the packet to update the context</param>
        private void RequestPacketUpdateRoleContext(SmbServerConnection connection, SmbPacket packet)
        {
            connection.AddRequestPacket(packet);

            // update the message id
            connection.MessageId = packet.SmbHeader.Mid;

            // update the process id
            connection.ProcessId  = (uint)(packet.SmbHeader.PidHigh << 16);
            connection.ProcessId += packet.SmbHeader.PidLow;

            // update the message sign sequence number
            if (packet.SmbHeader.SecurityFeatures != 0 &&
                connection.GssApi != null && connection.GssApi.SessionKey != null)
            {
                if (packet.SmbHeader.Command == SmbCommand.SMB_COM_NT_CANCEL)
                {
                    connection.ServerNextReceiveSequenceNumber++;
                }
                else
                {
                    ServerSendSequenceNumberKey key = new ServerSendSequenceNumberKey();

                    key.PidHigh = packet.SmbHeader.PidHigh;
                    key.PidLow  = packet.SmbHeader.PidLow;
                    key.Mid     = packet.SmbHeader.Mid;

                    connection.ServerSendSequenceNumber[key]    = connection.ServerNextReceiveSequenceNumber + 1;
                    connection.ServerNextReceiveSequenceNumber += 2;
                }
            }

            // process each special command
            switch (packet.SmbHeader.Command)
            {
            case SmbCommand.SMB_COM_NEGOTIATE:
                SmbNegotiateRequestPacket request = packet as SmbNegotiateRequestPacket;
                byte[] dialects = request.SmbData.Dialects;

                List <string> negotiateDialects = new List <string>();

                for (int i = 0; i < dialects.Length; i++)
                {
                    if (dialects[i] == 0x02)
                    {
                        continue;
                    }

                    string dialect = "";

                    for (; i < dialects.Length && dialects[i] != 0x00; i++)
                    {
                        dialect += (char)dialects[i];
                    }

                    negotiateDialects.Add(dialect);
                }

                connection.NegotiatedDialects = negotiateDialects.ToArray();

                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:

                // down-case the packet
                Cifs.SmbTreeConnectAndxRequestPacket treeconnect = packet as Cifs.SmbTreeConnectAndxRequestPacket;

                // get the specified session.
                SmbServerSession treeconnectSession = connection.GetSession((ushort)treeconnect.SmbHeader.Uid);
                if (treeconnectSession == null)
                {
                    return;
                }

                // Calculate the one-way hash
                byte[] sessionKey = FileServiceUtils.ProtectSessionKey(treeconnectSession.SessionKey);

                // update the session key state.
                treeconnectSession.SessionKeyState = SessionKeyStateValue.Available;

                // if server does not support SMB_EXTENDED_SIGNATURES, return.
                if (SmbClientTreeConnect.TreeConnectAndxExtendedSignatures !=
                    (treeconnect.SmbParameters.Flags & SmbClientTreeConnect.TreeConnectAndxExtendedSignatures))
                {
                    return;
                }

                treeconnectSession.SessionKey = sessionKey;

                break;

            default:
                return;
            }

            return;
        }
Beispiel #11
0
        /// <summary>
        /// update the context with response packet
        /// </summary>
        /// <param name="connection">the connection of endpoint</param>
        /// <param name="packet">the packet to update the context</param>
        private void ResponsePacketUpdateRoleContext(SmbServerConnection connection, SmbPacket packet)
        {
            SmbHeader smbHeader = packet.SmbHeader;

            SmbPacket requestPacket = connection.GetRequestPacket(smbHeader.Mid);

            if (requestPacket == null)
            {
                return;
            }

            switch (smbHeader.Command)
            {
            case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:
                if (smbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    SmbServerSession session = new SmbServerSession();
                    session.Uid = smbHeader.Uid;
                    session.AuthenticationState = SessionState.Complete;
                    session.Connection          = connection;
                    session.SessionKey          = connection.GssApi.SessionKey;

                    connection.AddSession(session);
                }

                break;

            case SmbCommand.SMB_COM_LOGOFF_ANDX:
                if (requestPacket.SmbHeader.Uid == 0)
                {
                    break;
                }
                else
                {
                    connection.RemoveSession(connection.GetSession(requestPacket.SmbHeader.Uid));
                }

                break;

            case SmbCommand.SMB_COM_TREE_CONNECT_ANDX:
            {
                SmbTreeConnectAndxRequestPacket request = requestPacket as SmbTreeConnectAndxRequestPacket;

                SmbServerTreeConnect treeconnect = new SmbServerTreeConnect();
                treeconnect.TreeId  = smbHeader.Tid;
                treeconnect.Session = connection.GetSession(smbHeader.Uid);
                if (treeconnect.Session == null)
                {
                    break;
                }
                if ((request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) != 0)
                {
                    treeconnect.Path = Encoding.Unicode.GetString(request.SmbData.Path);
                }
                else
                {
                    treeconnect.Path = Encoding.ASCII.GetString(request.SmbData.Path);
                }
                treeconnect.Path = treeconnect.Path.TrimEnd('\0');
                treeconnect.Session.AddTreeConnect(treeconnect);
            }

            break;

            case SmbCommand.SMB_COM_TREE_DISCONNECT:
                if (requestPacket.SmbHeader.Uid != 0)
                {
                    SmbServerSession session = connection.GetSession(requestPacket.SmbHeader.Uid);
                    if (session == null)
                    {
                        break;
                    }
                    session.RemoveTreeConnect(session.GetTreeConnect(requestPacket.SmbHeader.Tid));
                }

                break;

            case SmbCommand.SMB_COM_NT_CREATE_ANDX:
            {
                SmbNtCreateAndxResponsePacket response = packet as SmbNtCreateAndxResponsePacket;
                SmbNtCreateAndxRequestPacket  request  = requestPacket as SmbNtCreateAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.PathName    = open.PathName.TrimEnd('\0');
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_OPEN_ANDX:
            {
                SmbOpenAndxResponsePacket response = packet as SmbOpenAndxResponsePacket;
                SmbOpenAndxRequestPacket  request  = requestPacket as SmbOpenAndxRequestPacket;

                SmbServerOpen open = new SmbServerOpen();
                open.SmbFid   = response.SmbParameters.FID;
                open.PathName = SmbMessageUtils.GetString(request.SmbData.FileName,
                                                          SmbFlags2.SMB_FLAGS2_UNICODE == (request.SmbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE));
                open.Session     = connection.GetSession(smbHeader.Uid);
                open.TreeConnect = connection.GetTreeConnect(smbHeader.Tid);
                if (open.TreeConnect == null)
                {
                    break;
                }
                open.TreeConnect.AddOpen(open);
            }

            break;

            case SmbCommand.SMB_COM_CLOSE:
            {
                SmbCloseRequestPacket closeRequest = requestPacket as SmbCloseRequestPacket;

                SmbServerTreeConnect treeconnect = connection.GetTreeConnect(requestPacket.SmbHeader.Tid);
                if (treeconnect == null)
                {
                    break;
                }

                treeconnect.RemoveOpen(treeconnect.GetOpen(closeRequest.SmbParameters.FID));
            }

            break;

            default:
                break;
            }

            connection.RemoveRequestPacket(packet);
        }