// Special case - SMB2 client initially connecting using SMB1 internal static SMB2Command GetNegotiateResponse(List <string> smb2Dialects, GSSProvider securityProvider, ConnectionState state, Guid serverGuid, DateTime serverStartTime) { NegotiateResponse response = new NegotiateResponse(); response.Header.Credits = 1; if (smb2Dialects.Contains(SMB2xxxDialect)) { response.DialectRevision = SMB2Dialect.SMB2xx; } else if (smb2Dialects.Contains(SMB2002Dialect)) { state.Dialect = SMBDialect.SMB202; response.DialectRevision = SMB2Dialect.SMB202; } else { throw new ArgumentException("SMB2 dialect is not present"); } 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); }
public void Start() { IPAddress serverAddress = IPAddress.Parse(IpAddress); SMBTransportType transportType = SMBTransportType.DirectTCPTransport; UserCollection users = new UserCollection(); users.Add(UserName, UserPassword); NTLMAuthenticationProviderBase authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); SMBShareCollection shares = new SMBShareCollection(); FileSystemShare share = new FileSystemShare("documents", new NTDirectoryFileSystem("/storage/emulated/0/Documents")); share.AccessRequested += delegate(object sender, AccessRequestArgs args) { // allow read and write on share args.Allow = true; }; shares.Add(share); GSSProvider securityProvider = new GSSProvider(authenticationMechanism); server = new SmbServer2(shares, securityProvider); try { server.Start(serverAddress, transportType, true, true); } catch (Exception ex) { } }
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); }
public SMBServer(SMBShareCollection shares, GSSProvider securityProvider) { m_shares = shares; m_securityProvider = securityProvider; m_services = new NamedPipeShare(shares.ListShares()); m_serverGuid = Guid.NewGuid(); m_connectionManager = new ConnectionManager(); }
private void StartService() { IPAddress serverAddress = IPAddress.Any; SMBTransportType transportType = SMBTransportType.DirectTCPTransport; UserCollection users = null; List <ShareSettings> sharesSettings = null; int port = SettingsHelper.DefaultPort; try { users = SettingsHelper.ReadUserSettings(); sharesSettings = SettingsHelper.ReadSharesSettings(); port = SettingsHelper.ReadServerPort(); } catch { m_logWriter.WriteLine("Fail to load Settings.xml"); return; } NTLMAuthenticationProviderBase authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); SMBShareCollection shares = new SMBShareCollection(); foreach (ShareSettings shareSettings in sharesSettings) { FileSystemShare share = shareSettings.InitializeShare(); shares.Add(share); } GSSProvider securityProvider = new GSSProvider(authenticationMechanism); m_server = new SMBLibrary.Server.SMBServer(shares, securityProvider); // The provided logging mechanism will synchronously write to the disk during server activity. // To maximize server performance, you can disable logging by commenting out the following line. m_server.LogEntryAdded += new EventHandler <LogEntry>(m_logWriter.OnLogEntryAdded); try { SMBServer.DirectTCPPort = port; m_server.Start(serverAddress, transportType); if (transportType == SMBTransportType.NetBiosOverTCP) { if (serverAddress.AddressFamily == AddressFamily.InterNetwork && !IPAddress.Equals(serverAddress, IPAddress.Any)) { IPAddress subnetMask = NetworkInterfaceHelper.GetSubnetMask(serverAddress); m_nameServer = new NameServer(serverAddress, subnetMask); m_nameServer.Start(); } } } catch (Exception ex) { m_logWriter.WriteLine(ex.Message); } }
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); }
// Special case - SMB2 client initially connecting using SMB1 internal static SMB2Command GetNegotiateResponse(List <string> smb2Dialects, GSSProvider securityProvider, ConnectionState state, SMBTransportType transportType, Guid serverGuid, DateTime serverStartTime) { NegotiateResponse response = new NegotiateResponse(); response.Header.Credits = 1; if (smb2Dialects.Contains(SMB2xxxDialect)) { response.DialectRevision = SMB2Dialect.SMB2xx; } else if (smb2Dialects.Contains(SMB2002Dialect)) { state.Dialect = SMBDialect.SMB202; response.DialectRevision = SMB2Dialect.SMB202; } else { throw new ArgumentException("SMB2 dialect is not present"); } 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); }
public Form1() { InitializeComponent(); if (!Directory.Exists(AppPath + "PS2")) { Directory.CreateDirectory(AppPath + "PS2"); } users.Add("Guest", ""); users.Add("Guest", "Guest"); authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); List <ShareSettings> sharesSettings = new List <ShareSettings>(); ShareSettings itemtoshare = new ShareSettings("PS2", AppPath + "PS2", new List <string>() { "Guest" }, new List <string>() { "Guest" }); sharesSettings.Add(itemtoshare); SMBShareCollection shares = new SMBShareCollection(); foreach (ShareSettings shareSettings in sharesSettings) { FileSystemShare share = InitializeShare(shareSettings); shares.Add(share); } GSSProvider securityProvider = new GSSProvider(authenticationMechanism); m_server = new SMBLibrary.Server.SMBServer(shares, securityProvider); loadSettings(); m_logWriter = new LogWriter(); if (tsbEnableLog.Checked) { m_server.LogEntryAdded += m_server_LogEntryAdded; } }
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); }
static void RunOptions(Options opts) { logger.Info("Options: {0}", opts); List <ShareSettings> sharesSettings; try { sharesSettings = SettingsHelper.ReadSharesSettings(); } catch (Exception) { logger.Error("Cannot read " + SettingsHelper.SettingsFileName); return; } List <AggregatedShareSettings> aggregatedSharesSettings; try { aggregatedSharesSettings = SettingsHelper.ReadAggregatedSharesSettings(); } catch (Exception) { logger.Error("Cannot read " + SettingsHelper.SettingsFileName); return; } SMBShareCollection shares = new SMBShareCollection(); foreach (ShareSettings shareSettings in sharesSettings) { FileSystemShare share = InitializeShare(shareSettings); shares.Add(share); } foreach (AggregatedShareSettings settings in aggregatedSharesSettings) { FileSystemShare share = InitializeAggFSShare(settings); shares.Add(share); } NTLMAuthenticationProviderBase authenticationMechanism = new IntegratedNTLMAuthenticationProvider(); GSSProvider securityProvider = new GSSProvider(authenticationMechanism); theServer = new SMBLibrary.Server.SMBServer(shares, securityProvider); if (opts.Verbose) { theServer.LogEntryAdded += TheServer_LogEntryAdded; } bool enableSMB1 = (opts.SMBProtocol & SMBProtocol.SMB1) == SMBProtocol.SMB1; bool enableSMB2 = (opts.SMBProtocol & SMBProtocol.SMB2) == SMBProtocol.SMB2; bool enableSMB3 = (opts.SMBProtocol & SMBProtocol.SMB3) == SMBProtocol.SMB3; IPAddress listenAddr; if (!IPAddress.TryParse(opts.ListenIPAddress, out listenAddr)) { logger.Error(opts.ListenIPAddress + " is not a valid IP Address."); Environment.Exit(-1); return; } try { theServer.Start(listenAddr, opts.TransportType, enableSMB1, enableSMB2, enableSMB3); if (opts.TransportType == SMBTransportType.NetBiosOverTCP) { if (listenAddr.AddressFamily == AddressFamily.InterNetwork && !IPAddress.Equals(listenAddr, IPAddress.Any)) { IPAddress subnetMask = NetworkInterfaceHelper.GetSubnetMask(listenAddr); theNameServer = new NameServer(listenAddr, subnetMask); theNameServer.Start(); } } Console.Read(); } catch (Exception ex) { logger.Error(ex.Message); Environment.Exit(-1); return; } }
internal static SMB1Command GetSessionSetupResponseExtended(SMB1Header header, SessionSetupAndXRequestExtended request, GSSProvider securityProvider, SMB1ConnectionState state) { SessionSetupAndXResponseExtended response = new SessionSetupAndXResponseExtended(); // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob byte[] outputToken; NTStatus status = securityProvider.AcceptSecurityContext(ref state.AuthenticationContext, request.SecurityBlob, out outputToken); if (status != NTStatus.STATUS_SUCCESS && status != NTStatus.SEC_I_CONTINUE_NEEDED) { string userName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string; string domainName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string; string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string; string osVersion = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string; state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), NTStatus: {4}", userName, domainName, machineName, osVersion, status); header.Status = status; return(new ErrorResponse(request.CommandName)); } if (outputToken != null) { response.SecurityBlob = outputToken; } // According to [MS-SMB] 3.3.5.3, a UID MUST be allocated if the server returns STATUS_MORE_PROCESSING_REQUIRED if (header.UID == 0) { ushort?userID = state.AllocateUserID(); if (!userID.HasValue) { header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS; return(new ErrorResponse(request.CommandName)); } header.UID = userID.Value; } if (status == NTStatus.SEC_I_CONTINUE_NEEDED) { header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED; } else // header.Status == NTStatus.STATUS_SUCCESS { string userName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string; string domainName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string; string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string; string osVersion = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string; byte[] sessionKey = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.SessionKey) as byte[]; object accessToken = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.AccessToken); bool? isGuest = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.IsGuest) as bool?; if (!isGuest.HasValue || !isGuest.Value) { state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", userName, domainName, machineName, osVersion); state.CreateSession(header.UID, userName, machineName, sessionKey, accessToken); } else { state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", userName, domainName, machineName, osVersion); state.CreateSession(header.UID, "Guest", machineName, sessionKey, accessToken); response.Action = SessionSetupAction.SetupGuest; } } response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2" response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2" return(response); }
public SmbServer2(SMBShareCollection shares, GSSProvider securityProvider) : base(shares, securityProvider) { }
public Form1() { InitializeComponent(); makeDirectory(); users.Add("Guest", ""); users.Add("Guest", "Guest"); authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); List <ShareSettings> sharesSettings = new List <ShareSettings>(); foreach (string Directory in shareDirName) { ShareSettings itemtoshare = new ShareSettings(Directory, AppPath + Directory, new List <string>() { "Guest" }, new List <string>() { "Guest" }); sharesSettings.Add(itemtoshare); } SMBShareCollection shares = new SMBShareCollection(); foreach (ShareSettings shareSettings in sharesSettings) { FileSystemShare share = InitializeShare(shareSettings); shares.Add(share); } GSSProvider securityProvider = new GSSProvider(authenticationMechanism); m_server = new SMBLibrary.Server.SMBServer(shares, securityProvider); loadSettings(); m_logWriter = new LogWriter(); if (tsbEnableLog.Checked) { m_server.LogEntryAdded += m_server_LogEntryAdded; } string[] args = Environment.GetCommandLineArgs(); foreach (string arg in args) { if (arg.ToUpper() == "/NOLOG") { addLogList(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Information", "Commandline", "/NOLOG"); tsbEnableLog.Checked = false; } if (arg.ToUpper() == "/START") { addLogList(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Information", "Commandline", "/START"); tsbServerState.Checked = true; //tsbServerState_CheckedChanged(null, null); } } }
private void StartButton_Click(object sender, RoutedEventArgs e) { string accountName = this.username_textbox.Text; string password = this.password_box.Password; if (CommonUtils.IsEmptyString(accountName)) { MessageBox.Show("User Name or Password cannot be empty!", "Error"); return; } List <ShareSettings> sharesSettings = this.GetShareSettings(); if (sharesSettings == null || sharesSettings.Count == 0) { MessageBox.Show("Please add directories for sharing!", "Error"); return; } int port = SettingsHelper.DefaultPort; try { port = int.Parse(this.port_textbox.Text); SettingsHelper.WriteServerPort(port); } catch { MessageBox.Show("Invalid port number!", "Error"); return; } UserCollection users = new UserCollection(); users.Add(new User(accountName, password)); // Save account if necessary if (this.NeedUpdateUserCollection()) { SettingsHelper.WriteUserSettings(users); } bool runAsService = this.service_checkbox.IsChecked ?? false; if (runAsService) { if (!this.IsInAdminRole()) { MessageBox.Show("To start the service, please run application as administrator.", "Info"); return; } try { ServiceController serviceController = new ServiceController("RedfishService"); serviceController.Start(); this.start_button.IsEnabled = false; this.stop_button.IsEnabled = true; } catch (Exception ex) { MessageBox.Show(ex.Message, "Error"); } } else { KeyValuePair <string, IPAddress> selectedValue = (KeyValuePair <string, IPAddress>) this.address_combobox.SelectedValue; IPAddress serverAddress = selectedValue.Value; SMBTransportType transportType = SMBTransportType.DirectTCPTransport; NTLMAuthenticationProviderBase authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); SMBShareCollection shares = new SMBShareCollection(); foreach (ShareSettings shareSettings in sharesSettings) { FileSystemShare share = shareSettings.InitializeShare(); shares.Add(share); } GSSProvider securityProvider = new GSSProvider(authenticationMechanism); m_server = new SMBLibrary.Server.SMBServer(shares, securityProvider); m_logWriter = new LogWriter(); // The provided logging mechanism will synchronously write to the disk during server activity. // To maximize server performance, you can disable logging by commenting out the following line. m_server.LogEntryAdded += new EventHandler <LogEntry>(m_logWriter.OnLogEntryAdded); try { SMBServer.DirectTCPPort = port; m_server.Start(serverAddress, transportType); if (transportType == SMBTransportType.NetBiosOverTCP) { if (serverAddress.AddressFamily == AddressFamily.InterNetwork && !IPAddress.Equals(serverAddress, IPAddress.Any)) { IPAddress subnetMask = NetworkInterfaceHelper.GetSubnetMask(serverAddress); m_nameServer = new NameServer(serverAddress, subnetMask); m_nameServer.Start(); } } this.start_button.IsEnabled = false; this.stop_button.IsEnabled = true; } catch (Exception ex) { MessageBox.Show(ex.Message, "Error"); } } }
private void btnStart_Click(object sender, EventArgs e) { IPAddress serverAddress = (IPAddress)comboIPAddress.SelectedValue; SMBTransportType transportType; if (rbtNetBiosOverTCP.Checked) { transportType = SMBTransportType.NetBiosOverTCP; } else { transportType = SMBTransportType.DirectTCPTransport; } NTLMAuthenticationProviderBase authenticationMechanism; if (chkIntegratedWindowsAuthentication.Checked) { authenticationMechanism = new IntegratedNTLMAuthenticationProvider(); } else { UserCollection users; try { users = ReadUserSettings(); } catch { MessageBox.Show("Cannot read " + SettingsFileName, "Error"); return; } authenticationMechanism = new IndependentNTLMAuthenticationProvider(users.GetUserPassword); } SMBShareCollection shares; try { shares = ReadShareSettings(); } catch (Exception) { MessageBox.Show("Cannot read " + SettingsFileName, "Error"); return; } GSSProvider securityProvider = new GSSProvider(authenticationMechanism); m_server = new SmbLibraryStd.Server.SMBServer(shares, securityProvider); m_logWriter = new LogWriter(); // The provided logging mechanism will synchronously write to the disk during server activity. // To maximize server performance, you can disable logging by commenting out the following line. m_server.LogEntryAdded += new EventHandler <LogEntry>(m_logWriter.OnLogEntryAdded); try { m_server.Start(serverAddress, transportType, chkSMB1.Checked, chkSMB2.Checked); if (transportType == SMBTransportType.NetBiosOverTCP) { if (serverAddress.AddressFamily == AddressFamily.InterNetwork && !IPAddress.Equals(serverAddress, IPAddress.Any)) { IPAddress subnetMask = NetworkInterfaceHelper.GetSubnetMask(serverAddress); m_nameServer = new NameServer(serverAddress, subnetMask); m_nameServer.Start(); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error"); return; } btnStart.Enabled = false; btnStop.Enabled = true; comboIPAddress.Enabled = false; rbtDirectTCPTransport.Enabled = false; rbtNetBiosOverTCP.Enabled = false; chkSMB1.Enabled = false; chkSMB2.Enabled = false; chkIntegratedWindowsAuthentication.Enabled = false; }
internal static SMB2Command GetSessionSetupResponse(SessionSetupRequest request, GSSProvider securityProvider, SMB2ConnectionState state) { // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication. SessionSetupResponse response = new SessionSetupResponse(); byte[] outputToken; NTStatus status = securityProvider.AcceptSecurityContext(ref state.AuthenticationContext, request.SecurityBuffer, out outputToken); if (status != NTStatus.STATUS_SUCCESS && status != NTStatus.SEC_I_CONTINUE_NEEDED) { string userName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string; string domainName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string; string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string; string osVersion = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string; state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), NTStatus: {4}", userName, domainName, machineName, osVersion, status); return(new ErrorResponse(request.CommandName, status)); } if (outputToken != null) { response.SecurityBuffer = outputToken; } // According to [MS-SMB2] 3.3.5.5.3, response.Header.SessionID must be allocated if the server returns STATUS_MORE_PROCESSING_REQUIRED if (request.Header.SessionID == 0) { ulong?sessionID = state.AllocateSessionID(); if (!sessionID.HasValue) { return(new ErrorResponse(request.CommandName, NTStatus.STATUS_TOO_MANY_SESSIONS)); } response.Header.SessionID = sessionID.Value; } if (status == NTStatus.SEC_I_CONTINUE_NEEDED) { response.Header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED; } else // status == STATUS_SUCCESS { string userName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string; string domainName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string; string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string; string osVersion = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string; byte[] sessionKey = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.SessionKey) as byte[]; object accessToken = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.AccessToken); bool? isGuest = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.IsGuest) as bool?; if (!isGuest.HasValue || !isGuest.Value) { state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", userName, domainName, machineName, osVersion); bool signingRequired = (request.SecurityMode & SecurityMode.SigningRequired) > 0; SMB2Dialect smb2Dialect = SMBServer.ToSMB2Dialect(state.Dialect); byte[] signingKey = SMB2Cryptography.GenerateSigningKey(sessionKey, smb2Dialect, null); state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken, signingRequired, signingKey); } else { state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", userName, domainName, machineName, osVersion); state.CreateSession(request.Header.SessionID, "Guest", machineName, sessionKey, accessToken, false, null); response.SessionFlags = SessionFlags.IsGuest; } } return(response); }
internal static SMB1Command GetSessionSetupResponse(SMB1Header header, SessionSetupAndXRequest request, GSSProvider securityProvider, SMB1ConnectionState state) { SessionSetupAndXResponse response = new SessionSetupAndXResponse(); // The PrimaryDomain field in the request is used to determine with domain controller should authenticate the user credentials, // However, the domain controller itself does not use this field. // See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749%28v=vs.85%29.aspx AuthenticateMessage message = CreateAuthenticateMessage(request.AccountName, request.OEMPassword, request.UnicodePassword); header.Status = securityProvider.NTLMAuthenticate(state.AuthenticationContext, message); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', OS: '{2}'), NTStatus: {3}", request.AccountName, request.PrimaryDomain, request.NativeOS, header.Status); return(new ErrorResponse(request.CommandName)); } string osVersion = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string; byte[] sessionKey = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.SessionKey) as byte[]; object accessToken = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.AccessToken); bool? isGuest = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.IsGuest) as bool?; SMB1Session session; if (!isGuest.HasValue || !isGuest.Value) { state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", message.UserName, message.DomainName, message.WorkStation, osVersion); session = state.CreateSession(message.UserName, message.WorkStation, sessionKey, accessToken); } else { state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", message.UserName, message.DomainName, message.WorkStation, osVersion); session = state.CreateSession("Guest", message.WorkStation, sessionKey, accessToken); response.Action = SessionSetupAction.SetupGuest; } if (session == null) { header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS; return(new ErrorResponse(request.CommandName)); } header.UID = session.UserID; response.PrimaryDomain = request.PrimaryDomain; if ((request.Capabilities & ServerCapabilities.LargeRead) > 0) { state.LargeRead = true; } if ((request.Capabilities & ServerCapabilities.LargeWrite) > 0) { state.LargeWrite = true; } response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2" response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2" return(response); }