/// <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; }
/// <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); }
/// <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); }
/// <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; }
/// <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); }