SessionSetupHelper.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* Copyright (C) 2014-2017 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.SMB1
  14. {
  15. /// <summary>
  16. /// Session Setup helper
  17. /// </summary>
  18. public class SessionSetupHelper
  19. {
  20. internal static SMB1Command GetSessionSetupResponse(SMB1Header header, SessionSetupAndXRequest request, INTLMAuthenticationProvider users, SMB1ConnectionState state)
  21. {
  22. SessionSetupAndXResponse response = new SessionSetupAndXResponse();
  23. // The PrimaryDomain field in the request is used to determine with domain controller should authenticate the user credentials,
  24. // However, the domain controller itself does not use this field.
  25. // See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378749%28v=vs.85%29.aspx
  26. User user;
  27. try
  28. {
  29. user = users.Authenticate(request.AccountName, request.OEMPassword, request.UnicodePassword);
  30. }
  31. catch (EmptyPasswordNotAllowedException)
  32. {
  33. header.Status = NTStatus.STATUS_ACCOUNT_RESTRICTION;
  34. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  35. }
  36. if (user != null)
  37. {
  38. ushort? userID = state.AddConnectedUser(user.AccountName);
  39. if (!userID.HasValue)
  40. {
  41. header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
  42. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  43. }
  44. header.UID = userID.Value;
  45. response.PrimaryDomain = request.PrimaryDomain;
  46. }
  47. else if (users.EnableGuestLogin)
  48. {
  49. ushort? userID = state.AddConnectedUser("Guest");
  50. if (!userID.HasValue)
  51. {
  52. header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
  53. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  54. }
  55. header.UID = userID.Value;
  56. response.Action = SessionSetupAction.SetupGuest;
  57. response.PrimaryDomain = request.PrimaryDomain;
  58. }
  59. else
  60. {
  61. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  62. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  63. }
  64. if ((request.Capabilities & ServerCapabilities.LargeRead) > 0)
  65. {
  66. state.LargeRead = true;
  67. }
  68. if ((request.Capabilities & ServerCapabilities.LargeWrite) > 0)
  69. {
  70. state.LargeWrite = true;
  71. }
  72. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  73. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  74. return response;
  75. }
  76. internal static SMB1Command GetSessionSetupResponseExtended(SMB1Header header, SessionSetupAndXRequestExtended request, INTLMAuthenticationProvider users, SMB1ConnectionState state)
  77. {
  78. SessionSetupAndXResponseExtended response = new SessionSetupAndXResponseExtended();
  79. // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob
  80. byte[] messageBytes = request.SecurityBlob;
  81. bool isRawMessage = true;
  82. if (!AuthenticationMessageUtils.IsSignatureValid(messageBytes))
  83. {
  84. messageBytes = GSSAPIHelper.GetNTLMSSPMessage(request.SecurityBlob);
  85. isRawMessage = false;
  86. }
  87. if (!AuthenticationMessageUtils.IsSignatureValid(messageBytes))
  88. {
  89. header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
  90. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  91. }
  92. MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(messageBytes);
  93. if (messageType == MessageTypeName.Negotiate)
  94. {
  95. byte[] challengeMessageBytes = users.GetChallengeMessageBytes(messageBytes);
  96. if (isRawMessage)
  97. {
  98. response.SecurityBlob = challengeMessageBytes;
  99. }
  100. else
  101. {
  102. response.SecurityBlob = GSSAPIHelper.GetGSSTokenResponseBytesFromNTLMSSPMessage(challengeMessageBytes);
  103. }
  104. header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED;
  105. }
  106. else // MessageTypeName.Authenticate
  107. {
  108. User user;
  109. try
  110. {
  111. user = users.Authenticate(messageBytes);
  112. }
  113. catch (EmptyPasswordNotAllowedException)
  114. {
  115. header.Status = NTStatus.STATUS_ACCOUNT_RESTRICTION;
  116. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  117. }
  118. if (user != null)
  119. {
  120. ushort? userID = state.AddConnectedUser(user.AccountName);
  121. if (!userID.HasValue)
  122. {
  123. header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
  124. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  125. }
  126. header.UID = userID.Value;
  127. }
  128. else if (users.EnableGuestLogin)
  129. {
  130. ushort? userID = state.AddConnectedUser("Guest");
  131. if (!userID.HasValue)
  132. {
  133. header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
  134. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  135. }
  136. header.UID = userID.Value;
  137. response.Action = SessionSetupAction.SetupGuest;
  138. }
  139. else
  140. {
  141. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  142. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  143. }
  144. }
  145. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  146. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  147. return response;
  148. }
  149. }
  150. }