diff --git a/SMBLibrary/Client/SMB1Client.cs b/SMBLibrary/Client/SMB1Client.cs index 12ceffd..90fbba1 100644 --- a/SMBLibrary/Client/SMB1Client.cs +++ b/SMBLibrary/Client/SMB1Client.cs @@ -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 m_incomingQueue = new List(); @@ -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();