Client: Added support for single-stage and triple-stage session setup

Applicable when working with custom IAuthenticationClient
This commit is contained in:
Tal Aloni 2024-09-25 06:39:50 +03:00
parent 8b795d5233
commit ab876da50f
2 changed files with 72 additions and 75 deletions

View file

@ -316,39 +316,39 @@ namespace SMBLibrary.Client
TrySendMessage(request); TrySendMessage(request);
SMB1Message reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX);
if (reply != null) while (reply != null && reply.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && reply.Commands[0] is SessionSetupAndXResponseExtended)
{ {
if (reply.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && reply.Commands[0] is SessionSetupAndXResponseExtended) SessionSetupAndXResponseExtended response = (SessionSetupAndXResponseExtended)reply.Commands[0];
byte[] authenticateMessage = authenticationClient.InitializeSecurityContext(response.SecurityBlob);
if (authenticateMessage == null)
{ {
SessionSetupAndXResponseExtended response = (SessionSetupAndXResponseExtended)reply.Commands[0]; return NTStatus.SEC_E_INVALID_TOKEN;
byte[] authenticateMessage = authenticationClient.InitializeSecurityContext(response.SecurityBlob);
if (authenticateMessage == null)
{
return NTStatus.SEC_E_INVALID_TOKEN;
}
m_sessionKey = authenticationClient.GetSessionKey();
m_userID = reply.Header.UID;
request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = ClientMaxBufferSize;
request.MaxMpxCount = m_maxMpxCount;
request.Capabilities = clientCapabilities;
request.SecurityBlob = authenticateMessage;
TrySendMessage(request);
reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX);
if (reply != null)
{
m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS);
return reply.Header.Status;
}
}
else
{
return reply.Header.Status;
} }
m_userID = reply.Header.UID;
request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = ClientMaxBufferSize;
request.MaxMpxCount = m_maxMpxCount;
request.Capabilities = clientCapabilities;
request.SecurityBlob = authenticateMessage;
TrySendMessage(request);
reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX);
}
if (reply != null && reply.Commands[0] is SessionSetupAndXResponseExtended)
{
m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS);
if (m_isLoggedIn)
{
m_sessionKey = authenticationClient.GetSessionKey();
}
return reply.Header.Status;
}
else
{
return NTStatus.STATUS_INVALID_SMB;
} }
return NTStatus.STATUS_INVALID_SMB;
} }
} }

View file

@ -257,56 +257,53 @@ namespace SMBLibrary.Client
request.SecurityBuffer = negotiateMessage; request.SecurityBuffer = negotiateMessage;
TrySendCommand(request); TrySendCommand(request);
SMB2Command response = WaitForCommand(request.MessageID); SMB2Command response = WaitForCommand(request.MessageID);
if (response != null) while (response is SessionSetupResponse && response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED)
{ {
if (response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && response is SessionSetupResponse) byte[] authenticateMessage = authenticationClient.InitializeSecurityContext(((SessionSetupResponse)response).SecurityBuffer);
if (authenticateMessage == null)
{ {
byte[] authenticateMessage = authenticationClient.InitializeSecurityContext(((SessionSetupResponse)response).SecurityBuffer); return NTStatus.SEC_E_INVALID_TOKEN;
if (authenticateMessage == null)
{
return NTStatus.SEC_E_INVALID_TOKEN;
}
m_sessionKey = authenticationClient.GetSessionKey();
m_sessionID = response.Header.SessionID;
request = new SessionSetupRequest();
request.SecurityMode = SecurityMode.SigningEnabled;
request.SecurityBuffer = authenticateMessage;
TrySendCommand(request);
response = WaitForCommand(request.MessageID);
if (response != null)
{
m_isLoggedIn = (response.Header.Status == NTStatus.STATUS_SUCCESS);
if (m_isLoggedIn)
{
SessionFlags sessionFlags = ((SessionSetupResponse)response).SessionFlags;
if ((sessionFlags & SessionFlags.IsGuest) > 0)
{
// [MS-SMB2] 3.2.5.3.1 If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the SMB2
// SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired MUST be set to FALSE.
m_signingRequired = false;
}
else
{
m_signingKey = SMB2Cryptography.GenerateSigningKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
}
if (m_dialect >= SMB2Dialect.SMB300)
{
m_encryptSessionData = (sessionFlags & SessionFlags.EncryptData) > 0;
m_encryptionKey = SMB2Cryptography.GenerateClientEncryptionKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
m_decryptionKey = SMB2Cryptography.GenerateClientDecryptionKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
}
}
return response.Header.Status;
}
}
else
{
return response.Header.Status;
} }
m_sessionID = response.Header.SessionID;
request = new SessionSetupRequest();
request.SecurityMode = SecurityMode.SigningEnabled;
request.SecurityBuffer = authenticateMessage;
TrySendCommand(request);
response = WaitForCommand(request.MessageID);
}
if (response is SessionSetupResponse)
{
m_isLoggedIn = (response.Header.Status == NTStatus.STATUS_SUCCESS);
if (m_isLoggedIn)
{
m_sessionKey = authenticationClient.GetSessionKey();
SessionFlags sessionFlags = ((SessionSetupResponse)response).SessionFlags;
if ((sessionFlags & SessionFlags.IsGuest) > 0)
{
// [MS-SMB2] 3.2.5.3.1 If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the SMB2
// SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired MUST be set to FALSE.
m_signingRequired = false;
}
else
{
m_signingKey = SMB2Cryptography.GenerateSigningKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
}
if (m_dialect >= SMB2Dialect.SMB300)
{
m_encryptSessionData = (sessionFlags & SessionFlags.EncryptData) > 0;
m_encryptionKey = SMB2Cryptography.GenerateClientEncryptionKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
m_decryptionKey = SMB2Cryptography.GenerateClientDecryptionKey(m_sessionKey, m_dialect, m_preauthIntegrityHashValue);
}
}
return response.Header.Status;
}
else
{
return NTStatus.STATUS_INVALID_SMB;
} }
return NTStatus.STATUS_INVALID_SMB;
} }
public NTStatus Logoff() public NTStatus Logoff()