NegotiateHelper.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using SMBLibrary.Authentication;
  11. using SMBLibrary.SMB1;
  12. using Utilities;
  13. namespace SMBLibrary.Server
  14. {
  15. /// <summary>
  16. /// Negotiate and Session Setup helper
  17. /// </summary>
  18. public class NegotiateHelper
  19. {
  20. internal static NegotiateResponseNTLM GetNegotiateResponse(SMBHeader header, NegotiateRequest request, byte[] serverChallenge)
  21. {
  22. NegotiateResponseNTLM response = new NegotiateResponseNTLM();
  23. response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
  24. response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
  25. response.MaxMpxCount = 50;
  26. response.MaxNumberVcs = 1;
  27. response.MaxBufferSize = 16644;
  28. response.MaxRawSize = 65536;
  29. response.Capabilities = ServerCapabilities.Unicode |
  30. ServerCapabilities.LargeFiles |
  31. ServerCapabilities.NTSMB |
  32. ServerCapabilities.NTStatusCode |
  33. ServerCapabilities.NTFind |
  34. ServerCapabilities.LargeRead |
  35. ServerCapabilities.LargeWrite;
  36. response.SystemTime = DateTime.UtcNow;
  37. response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
  38. response.Challenge = serverChallenge;
  39. response.DomainName = String.Empty;
  40. response.ServerName = String.Empty;
  41. return response;
  42. }
  43. internal static NegotiateResponseNTLMExtended GetNegotiateResponseExtended(NegotiateRequest request, Guid serverGuid)
  44. {
  45. NegotiateResponseNTLMExtended response = new NegotiateResponseNTLMExtended();
  46. response.DialectIndex = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
  47. response.SecurityMode = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
  48. response.MaxMpxCount = 50;
  49. response.MaxNumberVcs = 1;
  50. response.MaxBufferSize = 16644;
  51. response.MaxRawSize = 65536;
  52. response.Capabilities = ServerCapabilities.Unicode |
  53. ServerCapabilities.LargeFiles |
  54. ServerCapabilities.NTSMB |
  55. ServerCapabilities.NTStatusCode |
  56. ServerCapabilities.NTFind |
  57. ServerCapabilities.LargeRead |
  58. ServerCapabilities.LargeWrite |
  59. ServerCapabilities.ExtendedSecurity;
  60. response.SystemTime = DateTime.UtcNow;
  61. response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
  62. response.ServerGuid = serverGuid;
  63. return response;
  64. }
  65. internal static SMBCommand GetSessionSetupResponse(SMBHeader header, SessionSetupAndXRequest request, INTLMAuthenticationProvider users, StateObject state)
  66. {
  67. SessionSetupAndXResponse response = new SessionSetupAndXResponse();
  68. // The PrimaryDomain field in the request is used to determine with domain controller should authenticate the user credentials,
  69. // However, the domain controller itself does not use this field.
  70. // See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749%28v=vs.85%29.aspx
  71. User user;
  72. try
  73. {
  74. user = users.Authenticate(request.AccountName, request.OEMPassword, request.UnicodePassword);
  75. }
  76. catch(EmptyPasswordNotAllowedException)
  77. {
  78. header.Status = NTStatus.STATUS_ACCOUNT_RESTRICTION;
  79. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  80. }
  81. if (user != null)
  82. {
  83. response.PrimaryDomain = request.PrimaryDomain;
  84. header.UID = state.AddConnectedUser(user.AccountName);
  85. }
  86. else if (users.EnableGuestLogin)
  87. {
  88. response.Action = SessionSetupAction.SetupGuest;
  89. response.PrimaryDomain = request.PrimaryDomain;
  90. header.UID = state.AddConnectedUser("Guest");
  91. }
  92. else
  93. {
  94. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  95. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  96. }
  97. if ((request.Capabilities & ServerCapabilities.LargeRead) > 0)
  98. {
  99. state.LargeRead = true;
  100. }
  101. if ((request.Capabilities & ServerCapabilities.LargeWrite) > 0)
  102. {
  103. state.LargeWrite = true;
  104. }
  105. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  106. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  107. return response;
  108. }
  109. internal static SMBCommand GetSessionSetupResponseExtended(SMBHeader header, SessionSetupAndXRequestExtended request, INTLMAuthenticationProvider users, StateObject state)
  110. {
  111. SessionSetupAndXResponseExtended response = new SessionSetupAndXResponseExtended();
  112. bool isValid = AuthenticationMessageUtils.IsSignatureValid(request.SecurityBlob);
  113. if (!isValid)
  114. {
  115. header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
  116. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  117. }
  118. MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(request.SecurityBlob);
  119. if (messageType == MessageTypeName.Negotiate)
  120. {
  121. byte[] challengeMessageBytes = users.GetChallengeMessageBytes(request.SecurityBlob);
  122. response.SecurityBlob = challengeMessageBytes;
  123. header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED;
  124. }
  125. else // MessageTypeName.Authenticate
  126. {
  127. User user;
  128. try
  129. {
  130. user = users.Authenticate(request.SecurityBlob);
  131. }
  132. catch(EmptyPasswordNotAllowedException)
  133. {
  134. header.Status = NTStatus.STATUS_ACCOUNT_RESTRICTION;
  135. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  136. }
  137. if (user != null)
  138. {
  139. header.UID = state.AddConnectedUser(user.AccountName);
  140. }
  141. else if (users.EnableGuestLogin)
  142. {
  143. response.Action = SessionSetupAction.SetupGuest;
  144. header.UID = state.AddConnectedUser("Guest");
  145. }
  146. else
  147. {
  148. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  149. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  150. }
  151. }
  152. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  153. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  154. return response;
  155. }
  156. }
  157. }