SessionSetupHelper.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. response.PrimaryDomain = request.PrimaryDomain;
  39. header.UID = state.AddConnectedUser(user.AccountName);
  40. }
  41. else if (users.EnableGuestLogin)
  42. {
  43. response.Action = SessionSetupAction.SetupGuest;
  44. response.PrimaryDomain = request.PrimaryDomain;
  45. header.UID = state.AddConnectedUser("Guest");
  46. }
  47. else
  48. {
  49. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  50. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  51. }
  52. if ((request.Capabilities & ServerCapabilities.LargeRead) > 0)
  53. {
  54. state.LargeRead = true;
  55. }
  56. if ((request.Capabilities & ServerCapabilities.LargeWrite) > 0)
  57. {
  58. state.LargeWrite = true;
  59. }
  60. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  61. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  62. return response;
  63. }
  64. internal static SMB1Command GetSessionSetupResponseExtended(SMB1Header header, SessionSetupAndXRequestExtended request, INTLMAuthenticationProvider users, SMB1ConnectionState state)
  65. {
  66. SessionSetupAndXResponseExtended response = new SessionSetupAndXResponseExtended();
  67. // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob
  68. byte[] messageBytes = request.SecurityBlob;
  69. bool isRawMessage = true;
  70. if (!AuthenticationMessageUtils.IsSignatureValid(messageBytes))
  71. {
  72. messageBytes = GSSAPIHelper.GetNTLMSSPMessage(request.SecurityBlob);
  73. isRawMessage = false;
  74. }
  75. if (!AuthenticationMessageUtils.IsSignatureValid(messageBytes))
  76. {
  77. header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
  78. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  79. }
  80. MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(messageBytes);
  81. if (messageType == MessageTypeName.Negotiate)
  82. {
  83. byte[] challengeMessageBytes = users.GetChallengeMessageBytes(messageBytes);
  84. if (isRawMessage)
  85. {
  86. response.SecurityBlob = challengeMessageBytes;
  87. }
  88. else
  89. {
  90. response.SecurityBlob = GSSAPIHelper.GetGSSTokenResponseBytesFromNTLMSSPMessage(challengeMessageBytes);
  91. }
  92. header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED;
  93. }
  94. else // MessageTypeName.Authenticate
  95. {
  96. User user;
  97. try
  98. {
  99. user = users.Authenticate(messageBytes);
  100. }
  101. catch (EmptyPasswordNotAllowedException)
  102. {
  103. header.Status = NTStatus.STATUS_ACCOUNT_RESTRICTION;
  104. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  105. }
  106. if (user != null)
  107. {
  108. header.UID = state.AddConnectedUser(user.AccountName);
  109. }
  110. else if (users.EnableGuestLogin)
  111. {
  112. response.Action = SessionSetupAction.SetupGuest;
  113. header.UID = state.AddConnectedUser("Guest");
  114. }
  115. else
  116. {
  117. header.Status = NTStatus.STATUS_LOGON_FAILURE;
  118. return new ErrorResponse(CommandName.SMB_COM_SESSION_SETUP_ANDX);
  119. }
  120. }
  121. response.NativeOS = String.Empty; // "Windows Server 2003 3790 Service Pack 2"
  122. response.NativeLanMan = String.Empty; // "Windows Server 2003 5.2"
  123. return response;
  124. }
  125. }
  126. }