SMB1Client: Store and expose server capabilities

This commit is contained in:
Tal Aloni 2017-10-01 00:25:17 +03:00
parent b3af07e5e4
commit e1c5cf8b54

View file

@ -33,6 +33,11 @@ namespace SMBLibrary.Client
private Socket m_clientSocket;
private IAsyncResult m_currentAsyncResult;
private bool m_forceExtendedSecurity;
private bool m_unicode;
private bool m_largeFiles;
private bool m_infoLevelPassthrough;
private bool m_largeRead;
private bool m_largeWrite;
private object m_incomingQueueLock = new object();
private List<SMB1Message> m_incomingQueue = new List<SMB1Message>();
@ -125,14 +130,30 @@ namespace SMBLibrary.Client
if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity)
{
NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0);
m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0);
bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0);
m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0);
m_serverChallenge = response.Challenge;
return true;
return ntSMB && rpc && ntStatusCode;
}
else if (reply.Commands[0] is NegotiateResponseExtended)
{
NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
m_unicode = ((response.Capabilities & Capabilities.Unicode) > 0);
m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
bool ntSMB = ((response.Capabilities & Capabilities.NTSMB) > 0);
bool rpc = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
m_largeRead = ((response.Capabilities & Capabilities.LargeRead) > 0);
m_largeWrite = ((response.Capabilities & Capabilities.LargeWrite) > 0);
m_securityBlob = response.SecurityBlob;
return true;
return ntSMB && rpc && ntStatusCode;
}
else
{
@ -152,12 +173,26 @@ namespace SMBLibrary.Client
throw new InvalidOperationException("A connection must be successfully established before attempting login");
}
Capabilities clientCapabilities = Capabilities.NTSMB | Capabilities.RpcRemoteApi | Capabilities.NTStatusCode | Capabilities.NTFind;
if (m_unicode)
{
clientCapabilities |= Capabilities.Unicode;
}
if (m_largeFiles)
{
clientCapabilities |= Capabilities.LargeFiles;
}
if (m_largeRead)
{
clientCapabilities |= Capabilities.LargeRead;
}
if (m_serverChallenge != null)
{
SessionSetupAndXRequest request = new SessionSetupAndXRequest();
request.MaxBufferSize = MaxBufferSize;
request.MaxMpxCount = MaxMpxCount;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode;
request.Capabilities = clientCapabilities;
request.AccountName = userName;
request.PrimaryDomain = domainName;
byte[] clientChallenge = new byte[8];
@ -199,7 +234,7 @@ namespace SMBLibrary.Client
SessionSetupAndXRequestExtended request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = MaxBufferSize;
request.MaxMpxCount = MaxMpxCount;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode | Capabilities.LargeRead | Capabilities.LargeWrite;
request.Capabilities = clientCapabilities;
request.SecurityBlob = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, authenticationMethod);
TrySendMessage(request);
@ -213,7 +248,7 @@ namespace SMBLibrary.Client
request = new SessionSetupAndXRequestExtended();
request.MaxBufferSize = MaxBufferSize;
request.MaxMpxCount = MaxMpxCount;
request.Capabilities = Capabilities.Unicode | Capabilities.NTStatusCode | Capabilities.LargeRead | Capabilities.LargeWrite | Capabilities.ExtendedSecurity;
request.Capabilities = clientCapabilities;
request.SecurityBlob = NTLMAuthenticationHelper.GetAuthenticateMessage(response.SecurityBlob, domainName, userName, password, authenticationMethod, out m_sessionKey);
TrySendMessage(request);
@ -461,7 +496,7 @@ namespace SMBLibrary.Client
internal void TrySendMessage(SMB1Command request, ushort treeID)
{
SMB1Message message = new SMB1Message();
message.Header.UnicodeFlag = true;
message.Header.UnicodeFlag = m_unicode;
message.Header.ExtendedSecurityFlag = m_forceExtendedSecurity;
message.Header.Flags2 |= HeaderFlags2.LongNamesAllowed | HeaderFlags2.LongNameUsed | HeaderFlags2.NTStatusCode;
message.Header.UID = m_userID;
@ -470,6 +505,46 @@ namespace SMBLibrary.Client
TrySendMessage(m_clientSocket, message);
}
public bool Unicode
{
get
{
return m_unicode;
}
}
public bool LargeFiles
{
get
{
return m_largeFiles;
}
}
public bool InfoLevelPassthrough
{
get
{
return m_infoLevelPassthrough;
}
}
public bool LargeRead
{
get
{
return m_largeRead;
}
}
public bool LargeWrite
{
get
{
return m_largeWrite;
}
}
public static void TrySendMessage(Socket socket, SMB1Message message)
{
SessionMessagePacket packet = new SessionMessagePacket();