internal static NegotiateResponseExtended GetNegotiateResponseExtended(NegotiateRequest request, Guid serverGuid) { NegotiateResponseExtended response = new NegotiateResponseExtended(); response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect); response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords; response.MaxMpxCount = ServerMaxMpxCount; response.MaxNumberVcs = ServerNumberVcs; response.MaxBufferSize = ServerMaxBufferSize; response.MaxRawSize = ServerMaxRawSize; response.Capabilities = Capabilities.Unicode | Capabilities.LargeFiles | Capabilities.NTSMB | Capabilities.RpcRemoteApi | Capabilities.NTStatusCode | Capabilities.NTFind | Capabilities.InfoLevelPassthrough | Capabilities.LargeRead | Capabilities.LargeWrite | Capabilities.ExtendedSecurity; response.SystemTime = DateTime.UtcNow; response.ServerTimeZone = (short)-TimeZoneInfo.Local.GetUtcOffset(DateTime.Now).TotalMinutes; response.ServerGuid = serverGuid; return(response); }
internal static NegotiateResponse GetNegotiateResponse(SMB1Header header, NegotiateRequest request, GSSProvider securityProvider, ConnectionState state) { NegotiateResponse response = new NegotiateResponse(); response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect); response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords; response.MaxMpxCount = 50; response.MaxNumberVcs = 1; response.MaxBufferSize = 16644; response.MaxRawSize = 65536; response.Capabilities = ServerCapabilities.Unicode | ServerCapabilities.LargeFiles | ServerCapabilities.NTSMB | ServerCapabilities.NTStatusCode | ServerCapabilities.NTFind | ServerCapabilities.LargeRead | ServerCapabilities.LargeWrite; response.SystemTime = DateTime.UtcNow; response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes; NegotiateMessage negotiateMessage = CreateNegotiateMessage(); ChallengeMessage challengeMessage; NTStatus status = securityProvider.GetNTLMChallengeMessage(out state.AuthenticationContext, negotiateMessage, out challengeMessage); if (status == NTStatus.SEC_I_CONTINUE_NEEDED) { response.Challenge = challengeMessage.ServerChallenge; } response.DomainName = String.Empty; response.ServerName = String.Empty; return(response); }
private bool NegotiateNTLanManagerDialect() { if (m_transport == SMBTransportType.NetBiosOverTCP) { SessionRequestPacket sessionRequest = new SessionRequestPacket(); sessionRequest.CalledName = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);; sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService); TrySendPacket(m_clientSocket, sessionRequest); } NegotiateRequest request = new NegotiateRequest(); request.Dialects.Add(NTLanManagerDialect); TrySendMessage(m_clientSocket, request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE); if (reply == null) { return(false); } if (reply.Commands[0] is NegotiateResponse) { NegotiateResponse response = (NegotiateResponse)reply.Commands[0]; return(true); } else if (reply.Commands[0] is NegotiateResponseExtended) { NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0]; return(true); } else { return(false); } }
internal static NegotiateResponseNTLM GetNegotiateResponse(SMBHeader header, NegotiateRequest request, byte[] serverChallenge) { NegotiateResponseNTLM response = new NegotiateResponseNTLM(); response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect); response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords; response.MaxMpxCount = 50; response.MaxNumberVcs = 1; response.MaxBufferSize = 16644; response.MaxRawSize = 65536; response.Capabilities = ServerCapabilities.Unicode | ServerCapabilities.LargeFiles | ServerCapabilities.NTSMB | ServerCapabilities.NTStatusCode | ServerCapabilities.NTFind | ServerCapabilities.LargeRead | ServerCapabilities.LargeWrite; response.SystemTime = DateTime.UtcNow; response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes; response.Challenge = serverChallenge; response.DomainName = String.Empty; response.ServerName = String.Empty; return(response); }
internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, Guid serverGuid, DateTime serverStartTime) { NegotiateResponse response = new NegotiateResponse(); if (request.Dialects.Contains(SMB2Dialect.SMB210)) { state.Dialect = SMBDialect.SMB210; response.DialectRevision = SMB2Dialect.SMB210; } else if (request.Dialects.Contains(SMB2Dialect.SMB202)) { state.Dialect = SMBDialect.SMB202; response.DialectRevision = SMB2Dialect.SMB202; } else { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED)); } response.SecurityMode = SecurityMode.SigningEnabled; response.ServerGuid = serverGuid; response.MaxTransactSize = 65536; response.MaxReadSize = 65536; response.MaxWriteSize = 65536; response.SystemTime = DateTime.Now; response.ServerStartTime = serverStartTime; response.SecurityBuffer = securityProvider.GetSPNEGOTokenInitBytes(); return(response); }
private bool NegotiateDialect() { NegotiateRequest request = new NegotiateRequest(); request.SecurityMode = SecurityMode.SigningEnabled; request.ClientGuid = Guid.NewGuid(); request.ClientStartTime = DateTime.Now; request.Dialects.Add(SMB2Dialect.SMB202); request.Dialects.Add(SMB2Dialect.SMB210); TrySendCommand(request); NegotiateResponse response = WaitForCommand(SMB2CommandName.Negotiate) as NegotiateResponse; if (response != null && response.Header.Status == NTStatus.STATUS_SUCCESS) { m_dialect = response.DialectRevision; m_signingRequired = (response.SecurityMode & SecurityMode.SigningRequired) > 0; m_maxTransactSize = Math.Min(response.MaxTransactSize, ClientMaxTransactSize); m_maxReadSize = Math.Min(response.MaxReadSize, ClientMaxReadSize); m_maxWriteSize = Math.Min(response.MaxWriteSize, ClientMaxWriteSize); m_securityBlob = response.SecurityBuffer; return(true); } return(false); }
private bool NegotiateDialect(bool forceExtendedSecurity) { if (m_transport == SMBTransportType.NetBiosOverTCP) { SessionRequestPacket sessionRequest = new SessionRequestPacket(); sessionRequest.CalledName = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);; sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService); TrySendPacket(m_clientSocket, sessionRequest); } NegotiateRequest request = new NegotiateRequest(); request.Dialects.Add(NTLanManagerDialect); TrySendMessage(request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE); if (reply == null) { return(false); } if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity) { NegotiateResponse response = (NegotiateResponse)reply.Commands[0]; m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = response.MaxBufferSize; m_maxMpxCount = Math.Min(response.MaxMpxCount, ClientMaxMpxCount); m_serverChallenge = response.Challenge; return(ntSMB && rpc && ntStatusCode); } else if (reply.Commands[0] is NegotiateResponseExtended) { NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0]; m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = response.MaxBufferSize; m_maxMpxCount = Math.Min(response.MaxMpxCount, ClientMaxMpxCount); m_securityBlob = response.SecurityBlob; return(ntSMB && rpc && ntStatusCode); } else { return(false); } }
/// <summary> /// Update SMB_COM_NEGOTIATE request. /// </summary> /// <param name="connection">It represents the SMB connection.</param> /// <param name="smbRequest">It represents the SMB request.</param> public static void UpdateNegotiateRequest(SmbConnection connection, SmbRequest smbRequest) { NegotiateRequest req = smbRequest as NegotiateRequest; connection.SutSendSequenceNumber.Add(smbRequest.messageId); connection.sentRequest.Add(smbRequest.messageId, smbRequest); connection.clientSignState = req.signState; connection.isNegotiateSent = true; connection.isClientSupportExtSecurity = req.isSupportExtSecurity; }
private bool NegotiateDialect(bool forceExtendedSecurity) { NegotiateRequest request = new NegotiateRequest(); request.Dialects.Add(NTLanManagerDialect); TrySendMessage(request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE); if (reply == null) { return(false); } if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity) { NegotiateResponse response = (NegotiateResponse)reply.Commands[0]; Domainname = response.DomainName; Hostname = response.ServerName; m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = response.MaxBufferSize; m_maxMpxCount = Math.Min(response.MaxMpxCount, ClientMaxMpxCount); m_serverChallenge = response.Challenge; return(ntSMB && rpc && ntStatusCode); } else if (reply.Commands[0] is NegotiateResponseExtended) { NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0]; m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = response.MaxBufferSize; m_maxMpxCount = Math.Min(response.MaxMpxCount, ClientMaxMpxCount); m_securityBlob = response.SecurityBlob; return(ntSMB && rpc && ntStatusCode); } else { return(false); } }
internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, SMBTransportType transportType, Guid serverGuid, DateTime serverStartTime, bool enableSMB3) { NegotiateResponse response = new NegotiateResponse(); if (enableSMB3 && request.Dialects.Contains(SMB2Dialect.SMB300)) { state.Dialect = SMBDialect.SMB300; response.DialectRevision = SMB2Dialect.SMB300; } else if (request.Dialects.Contains(SMB2Dialect.SMB210)) { state.Dialect = SMBDialect.SMB210; response.DialectRevision = SMB2Dialect.SMB210; } else if (request.Dialects.Contains(SMB2Dialect.SMB202)) { state.Dialect = SMBDialect.SMB202; response.DialectRevision = SMB2Dialect.SMB202; } else { state.LogToServer(Severity.Verbose, "Negotiate failure: None of the requested SMB2 dialects is supported"); return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED)); } response.SecurityMode = SecurityMode.SigningEnabled; response.ServerGuid = serverGuid; if (state.Dialect != SMBDialect.SMB202 && transportType == SMBTransportType.DirectTCPTransport) { response.Capabilities = Capabilities.LargeMTU; response.MaxTransactSize = ServerMaxTransactSizeLargeMTU; response.MaxReadSize = ServerMaxReadSizeLargeMTU; response.MaxWriteSize = ServerMaxWriteSizeLargeMTU; // [MS-SMB2] 3.3.5.2 Receiving Any Message - If the length of the message exceeds Connection.MaxTransactSize + 256, the server MUST disconnect the connection. int maxPacketSize = SessionPacket.HeaderLength + (int)ServerMaxTransactSizeLargeMTU + 256; if (maxPacketSize > state.ReceiveBuffer.Buffer.Length) { state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize); } } else { response.MaxTransactSize = ServerMaxTransactSize; response.MaxReadSize = ServerMaxReadSize; response.MaxWriteSize = ServerMaxWriteSize; } response.SystemTime = DateTime.Now; response.ServerStartTime = serverStartTime; response.SecurityBuffer = securityProvider.GetSPNEGOTokenInitBytes(); return(response); }
private bool NegotiateDialect(bool forceExtendedSecurity) { NegotiateRequest request = new NegotiateRequest(); request.Dialects.Add(NTLanManagerDialect); SendMessage(request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE); switch (reply.Commands[0]) { case NegotiateResponse negotiateResponse when !forceExtendedSecurity: { m_unicode = ((negotiateResponse.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((negotiateResponse.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((negotiateResponse.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((negotiateResponse.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((negotiateResponse.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((negotiateResponse.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((negotiateResponse.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((negotiateResponse.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = negotiateResponse.MaxBufferSize; m_maxMpxCount = Math.Min(negotiateResponse.MaxMpxCount, ClientMaxMpxCount); m_serverChallenge = negotiateResponse.Challenge; return(ntSMB && rpc && ntStatusCode); } case NegotiateResponseExtended response: { m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0); m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0); bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0); bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0); bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0); m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0); m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0); m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0); m_serverMaxBufferSize = response.MaxBufferSize; m_maxMpxCount = Math.Min(response.MaxMpxCount, ClientMaxMpxCount); m_securityBlob = response.SecurityBlob; return(ntSMB && rpc && ntStatusCode); } default: return(false); } }
/// <summary> /// May return an empty list /// </summary> private List <SMB1Command> ProcessSMB1Command(SMB1Header header, SMB1Command command, ref ConnectionState state) { if (state.Dialect == SMBDialect.NotSet) { if (command is NegotiateRequest) { NegotiateRequest request = (NegotiateRequest)command; if (request.Dialects.Contains(SMBServer.NTLanManagerDialect)) { state = new SMB1ConnectionState(state); state.Dialect = SMBDialect.NTLM012; m_connectionManager.AddConnection(state); if (EnableExtendedSecurity && header.ExtendedSecurityFlag) { return(NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid)); } else { return(NegotiateHelper.GetNegotiateResponse(header, request, m_securityProvider, state)); } } else { return(new NegotiateResponseNotSupported()); } } else { // [MS-CIFS] An SMB_COM_NEGOTIATE exchange MUST be completed before any other SMB messages are sent to the server header.Status = NTStatus.STATUS_INVALID_SMB; return(new ErrorResponse(command.CommandName)); } } else if (command is NegotiateRequest) { // There MUST be only one SMB_COM_NEGOTIATE exchange per SMB connection. // Subsequent SMB_COM_NEGOTIATE requests received by the server MUST be rejected with error responses. header.Status = NTStatus.STATUS_INVALID_SMB; return(new ErrorResponse(command.CommandName)); } else { return(ProcessSMB1Command(header, command, (SMB1ConnectionState)state)); } }
public SMBClient(IPAddress serverAddress, SMBTransportType transport) { NegotiateRequest request = new NegotiateRequest(); request.Dialects.Add(NTLanManagerDialect); Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (transport == SMBTransportType.DirectTCPTransport) { serverSocket.Connect(serverAddress, DirectTCPPort); } else { serverSocket.Connect(serverAddress, NetBiosOverTCPPort); } TrySendMessage(serverSocket, request); }
/// <summary> /// May return null /// </summary> private SMB2Command ProcessSMB2Command(SMB2Command command, ref ConnectionState state) { if (state.Dialect == SMBDialect.NotSet) { if (command is NegotiateRequest) { NegotiateRequest request = (NegotiateRequest)command; SMB2Command response = NegotiateHelper.GetNegotiateResponse(request, m_securityProvider, state, m_transport, m_serverGuid, m_serverStartTime, m_enableSMB3); if (state.Dialect != SMBDialect.NotSet) { state = new SMB2ConnectionState(state); m_connectionManager.AddConnection(state); } return(response); } else { // [MS-SMB2] If the request being received is not an SMB2 NEGOTIATE Request [..] // and Connection.NegotiateDialect is 0xFFFF or 0x02FF, the server MUST // disconnect the connection. state.LogToServer(Severity.Debug, "Invalid Connection State for command {0}", command.CommandName.ToString()); state.ClientSocket.Close(); return(null); } } else if (command is NegotiateRequest) { // [MS-SMB2] If Connection.NegotiateDialect is 0x0202, 0x0210, 0x0300, 0x0302, or 0x0311, // the server MUST disconnect the connection. state.LogToServer(Severity.Debug, "Rejecting NegotiateRequest. NegotiateDialect is already set"); state.ClientSocket.Close(); return(null); } else { return(ProcessSMB2Command(command, (SMB2ConnectionState)state)); } }
internal static NegotiateResponseExtended GetNegotiateResponseExtended(NegotiateRequest request, Guid serverGuid) { NegotiateResponseExtended response = new NegotiateResponseExtended(); response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect); response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords; response.MaxMpxCount = 50; response.MaxNumberVcs = 1; response.MaxBufferSize = 16644; response.MaxRawSize = 65536; response.Capabilities = ServerCapabilities.Unicode | ServerCapabilities.LargeFiles | ServerCapabilities.NTSMB | ServerCapabilities.NTStatusCode | ServerCapabilities.NTFind | ServerCapabilities.LargeRead | ServerCapabilities.LargeWrite | ServerCapabilities.ExtendedSecurity; response.SystemTime = DateTime.UtcNow; response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes; response.ServerGuid = serverGuid; return(response); }
public void Negotiate() { if (IsConnectd) { throw new Exception("Repeat Negotiate"); } ulong mid = (ulong)Interlocked.Increment(ref MessageId); SMB2Header smb2Header = new SMB2Header(ESMB2Command.NEGOTIATE, SMB2HeaderFlags.None, mid, 0, 0); SMB2Body smb2Body = new NegotiateRequest(ESecurityMode.SMB2_NEGOTIATE_SIGNING_ENABLED, Guid.NewGuid()); SMB2Message smb2Message = new SMB2Message(smb2Header, smb2Body); SMBTransport.SendDatas(smb2Message.DumpBinary()); var sm = GetMessage(mid); if (sm.SMB2Header.Status == 0) { IsConnectd = true; } else { throw new Exception("Negotiate Status error:" + sm.SMB2Header.Status); } }
/// <summary> /// May return null /// </summary> public SMBCommand ProcessCommand(SMBHeader header, SMBCommand command, StateObject state, List <SMBCommand> sendQueue) { if (command is NegotiateRequest) { NegotiateRequest request = (NegotiateRequest)command; if (request.Dialects.Contains(SMBServer.NTLanManagerDialect)) { if (EnableExtendedSecurity && header.ExtendedSecurityFlag) { return(NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid)); } else { return(new NegotiateResponseNotSupported()); } } else { return(new NegotiateResponseNotSupported()); } } else if (command is SessionSetupAndXRequest) { SessionSetupAndXRequest request = (SessionSetupAndXRequest)command; state.MaxBufferSize = request.MaxBufferSize; //this probably won't work return(NegotiateHelper.GetSessionSetupResponse(header, request, state)); } else if (command is SessionSetupAndXRequestExtended) { SessionSetupAndXRequestExtended request = (SessionSetupAndXRequestExtended)command; state.MaxBufferSize = request.MaxBufferSize; return(NegotiateHelper.GetSessionSetupResponseExtended(header, request, state)); } else if (command is EchoRequest) { return(ServerResponseHelper.GetEchoResponse((EchoRequest)command, sendQueue)); } else if (state.IsAuthenticated(header.UID)) { if (command is TreeConnectAndXRequest) { TreeConnectAndXRequest request = (TreeConnectAndXRequest)command; return(TreeConnectHelper.GetTreeConnectResponse(header, request, state, m_shares)); } else if (command is LogoffAndXRequest) { return(new LogoffAndXResponse()); } else if (state.IsTreeConnected(header.TID)) { string rootPath = state.GetConnectedTreePath(header.TID); object share; if (state.IsIPC(header.TID)) { share = m_services; } else { share = m_shares.GetShareFromRelativePath(rootPath); } if (command is CreateDirectoryRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } CreateDirectoryRequest request = (CreateDirectoryRequest)command; return(FileSystemResponseHelper.GetCreateDirectoryResponse(header, request, (FileSystemShare)share, state)); } else if (command is DeleteDirectoryRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } DeleteDirectoryRequest request = (DeleteDirectoryRequest)command; return(FileSystemResponseHelper.GetDeleteDirectoryResponse(header, request, (FileSystemShare)share, state)); } else if (command is CloseRequest) { CloseRequest request = (CloseRequest)command; return(ServerResponseHelper.GetCloseResponse(header, request, state)); } else if (command is FlushRequest) { return(new FlushResponse()); } else if (command is DeleteRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } DeleteRequest request = (DeleteRequest)command; return(FileSystemResponseHelper.GetDeleteResponse(header, request, (FileSystemShare)share, state)); } else if (command is RenameRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } RenameRequest request = (RenameRequest)command; return(FileSystemResponseHelper.GetRenameResponse(header, request, (FileSystemShare)share, state)); } else if (command is QueryInformationRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } QueryInformationRequest request = (QueryInformationRequest)command; return(FileSystemResponseHelper.GetQueryInformationResponse(header, request, (FileSystemShare)share)); } else if (command is SetInformationRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } SetInformationRequest request = (SetInformationRequest)command; return(FileSystemResponseHelper.GetSetInformationResponse(header, request, (FileSystemShare)share, state)); } else if (command is ReadRequest) { ReadRequest request = (ReadRequest)command; return(ReadWriteResponseHelper.GetReadResponse(header, request, share, state)); } else if (command is WriteRequest) { string userName = state.GetConnectedUserName(header.UID); if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName)) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(command.CommandName)); } WriteRequest request = (WriteRequest)command; return(ReadWriteResponseHelper.GetWriteResponse(header, request, share, state)); } else if (command is CheckDirectoryRequest) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } CheckDirectoryRequest request = (CheckDirectoryRequest)command; return(FileSystemResponseHelper.GetCheckDirectoryResponse(header, request, (FileSystemShare)share)); } else if (command is WriteRawRequest) { // [MS-CIFS] 3.3.5.26 - Receiving an SMB_COM_WRITE_RAW Request: // the server MUST verify that the Server.Capabilities include CAP_RAW_MODE, // If an error is detected [..] the Write Raw operation MUST fail and // the server MUST return a Final Server Response [..] with the Count field set to zero. return(new WriteRawFinalResponse()); } else if (command is SetInformation2Request) { if (!(share is FileSystemShare)) { header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); } SetInformation2Request request = (SetInformation2Request)command; return(FileSystemResponseHelper.GetSetInformation2Response(header, request, (FileSystemShare)share, state)); } else if (command is LockingAndXRequest) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(CommandName.SMB_COM_LOCKING_ANDX)); } else if (command is OpenAndXRequest) { OpenAndXRequest request = (OpenAndXRequest)command; return(OpenAndXHelper.GetOpenAndXResponse(header, request, share, state)); } else if (command is ReadAndXRequest) { ReadAndXRequest request = (ReadAndXRequest)command; return(ReadWriteResponseHelper.GetReadResponse(header, request, share, state)); } else if (command is WriteAndXRequest) { string userName = state.GetConnectedUserName(header.UID); if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName)) { header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(command.CommandName)); } WriteAndXRequest request = (WriteAndXRequest)command; return(ReadWriteResponseHelper.GetWriteResponse(header, request, share, state)); } else if (command is FindClose2Request) { return(ServerResponseHelper.GetFindClose2Request(header, (FindClose2Request)command, state)); } else if (command is TreeDisconnectRequest) { TreeDisconnectRequest request = (TreeDisconnectRequest)command; return(TreeConnectHelper.GetTreeDisconnectResponse(header, request, state)); } else if (command is TransactionRequest) // Both TransactionRequest and Transaction2Request { TransactionRequest request = (TransactionRequest)command; try { return(TransactionHelper.GetTransactionResponse(header, request, share, state, sendQueue)); } catch (UnsupportedInformationLevelException) { header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(new ErrorResponse(command.CommandName)); } } else if (command is TransactionSecondaryRequest) // Both TransactionSecondaryRequest and Transaction2SecondaryRequest { TransactionSecondaryRequest request = (TransactionSecondaryRequest)command; try { return(TransactionHelper.GetTransactionResponse(header, request, share, state, sendQueue)); } catch (UnsupportedInformationLevelException) { header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(new ErrorResponse(command.CommandName)); } } else if (command is NTTransactRequest) { NTTransactRequest request = (NTTransactRequest)command; return(NTTransactHelper.GetNTTransactResponse(header, request, share, state, sendQueue)); } else if (command is NTTransactSecondaryRequest) { NTTransactSecondaryRequest request = (NTTransactSecondaryRequest)command; return(NTTransactHelper.GetNTTransactResponse(header, request, share, state, sendQueue)); } else if (command is NTCreateAndXRequest) { NTCreateAndXRequest request = (NTCreateAndXRequest)command; return(NTCreateHelper.GetNTCreateResponse(header, request, share, state)); } } else { header.Status = NTStatus.STATUS_SMB_BAD_TID; return(new ErrorResponse(command.CommandName)); } } header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; return(new ErrorResponse(command.CommandName)); }
public static void NegotiateResponse(ModelSmb2Status status, DialectRevision dialectRevision) { Condition.IsTrue(State == ModelState.Connected); Condition.IsTrue(Request is ModelComNegotiateRequest || Request is NegotiateRequest); // Avoid "Microsoft.SpecExplorer.Runtime.Testing.UnboundVariableException: Variable's value cannot be read before it is bound" Condition.IsTrue(dialectRevision == DialectRevision.Smb2002 || dialectRevision == DialectRevision.Smb21 || dialectRevision == DialectRevision.Smb30 || dialectRevision == DialectRevision.Smb302 || dialectRevision == DialectRevision.Smb2Wildcard || dialectRevision == DialectRevision.Smb2Unknown); if (Request is ModelComNegotiateRequest) { ModelComNegotiateRequest comNegotiateReq = ModelHelper.RetrieveOutstandingRequest <ModelComNegotiateRequest>(ref Request); if (Config.MaxSmbVersionSupported != DialectRevision.Smb21 && !ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported)) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the server does not implement the SMB 2.1 or 3.x dialect family, processing MUST continue as specified in 3.3.5.3.2."); ComNegotiateHandleSmb2002InResponse(dialectRevision); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: Otherwise, the server MUST scan the dialects provided for the dialect string \"SMB 2.???\"."); if (comNegotiateReq.Dialects.Contains(SMBDialects.SMB_2_X)) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is present, the server MUST respond with an SMB2 NEGOTIATE Response as specified in 2.2.4."); ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: DialectRevision MUST be set to 0x02FF"); NegotiateDialect = DialectRevision.Smb2Wildcard; ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: Connection.NegotiateDialect MUST be set to 0x02FF, and the response is sent to the client"); Condition.IsTrue(dialectRevision == DialectRevision.Smb2Wildcard); } else { ModelHelper.Log( LogType.Requirement, "3.3.5.3.1: If the string is not present, continue to section 3.3.5.3.2"); ComNegotiateHandleSmb2002InResponse(dialectRevision); } } } else { NegotiateRequest negotiateReq = ModelHelper.RetrieveOutstandingRequest <NegotiateRequest>(ref Request); if (negotiateReq.Dialects.Count == 0) { ModelHelper.Log( LogType.Requirement, "3.3.5.4: If the DialectCount of the SMB2 NEGOTIATE Request is 0, the server MUST fail the request with STATUS_INVALID_PARAMETER"); ModelHelper.Log( LogType.TestInfo, "DialectCount of the SMB2 NEGOTIATE Request is 0"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER); return; } ModelHelper.Log( LogType.Requirement, "3.3.5.4: The server MUST select the greatest common dialect between the dialects it implements and the Dialects array of the SMB2 NEGOTIATE request"); DialectRevision commonDialect = SelectCommonDialect(negotiateReq.Dialects); ModelHelper.Log( LogType.TestInfo, "Common dialect is {0}", commonDialect); if (commonDialect == DialectRevision.Smb2Unknown) { ModelHelper.Log( LogType.Requirement, "3.3.5.4: If a common dialect is not found, the server MUST fail the request with STATUS_NOT_SUPPORTED"); ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields); Condition.IsTrue(status == ModelSmb2Status.STATUS_NOT_SUPPORTED); return; } ModelHelper.Log( LogType.Requirement, "3.3.5.4: If a common dialect is found, the server MUST set Connection.Dialect to \"2.002\", \"2.100\", \"3.000\", or \"3.002\"," + " and Connection.NegotiateDialect to 0x0202, 0x0210, 0x0300, or 0x0302 accordingly, to reflect the dialect selected"); NegotiateDialect = commonDialect; ModelHelper.Log( LogType.TestInfo, "Connection.Dialect is set to {0}", NegotiateDialect); ModelHelper.Log( LogType.Requirement, "3.3.5.4: The server MUST then construct an SMB2 NEGOTIATE Response, as specified in section 2.2.4, with the following specific values, and return STATUS_SUCCESS to the client."); ModelHelper.Log( LogType.Requirement, "\tDialectRevision MUST be set to the common dialect"); Condition.IsTrue(dialectRevision == commonDialect); } Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS); }