diff --git a/SMBLibrary/Server/SMB2/NegotiateHelper.cs b/SMBLibrary/Server/SMB2/NegotiateHelper.cs index 6929f2e..47bc3a1 100644 --- a/SMBLibrary/Server/SMB2/NegotiateHelper.cs +++ b/SMBLibrary/Server/SMB2/NegotiateHelper.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Tal Aloni . All rights reserved. +/* Copyright (C) 2017-2020 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, @@ -22,9 +22,12 @@ namespace SMBLibrary.Server.SMB2 public const uint ServerMaxTransactSize = 65536; public const uint ServerMaxReadSize = 65536; public const uint ServerMaxWriteSize = 65536; + public const uint ServerMaxTransactSizeLargeMTU = 8388608; + public const uint ServerMaxReadSizeLargeMTU = 8388608; + public const uint ServerMaxWriteSizeLargeMTU = 8388608; // Special case - SMB2 client initially connecting using SMB1 - internal static SMB2Command GetNegotiateResponse(List smb2Dialects, GSSProvider securityProvider, ConnectionState state, Guid serverGuid, DateTime serverStartTime) + internal static SMB2Command GetNegotiateResponse(List smb2Dialects, GSSProvider securityProvider, ConnectionState state, SMBTransportType transportType, Guid serverGuid, DateTime serverStartTime) { NegotiateResponse response = new NegotiateResponse(); response.Header.Credits = 1; @@ -44,16 +47,26 @@ namespace SMBLibrary.Server.SMB2 } response.SecurityMode = SecurityMode.SigningEnabled; response.ServerGuid = serverGuid; - response.MaxTransactSize = ServerMaxTransactSize; - response.MaxReadSize = ServerMaxReadSize; - response.MaxWriteSize = ServerMaxWriteSize; + if (state.Dialect != SMBDialect.SMB202 && transportType == SMBTransportType.DirectTCPTransport) + { + response.Capabilities = Capabilities.LargeMTU; + response.MaxTransactSize = ServerMaxTransactSizeLargeMTU; + response.MaxReadSize = ServerMaxReadSizeLargeMTU; + response.MaxWriteSize = ServerMaxWriteSizeLargeMTU; + } + else + { + response.MaxTransactSize = ServerMaxTransactSize; + response.MaxReadSize = ServerMaxReadSize; + response.MaxWriteSize = ServerMaxWriteSize; + } response.SystemTime = DateTime.Now; response.ServerStartTime = serverStartTime; response.SecurityBuffer = securityProvider.GetSPNEGOTokenInitBytes(); return response; } - internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, Guid serverGuid, DateTime serverStartTime) + internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, SMBTransportType transportType, Guid serverGuid, DateTime serverStartTime) { NegotiateResponse response = new NegotiateResponse(); if (request.Dialects.Contains(SMB2Dialect.SMB210)) @@ -73,9 +86,19 @@ namespace SMBLibrary.Server.SMB2 } response.SecurityMode = SecurityMode.SigningEnabled; response.ServerGuid = serverGuid; - response.MaxTransactSize = ServerMaxTransactSize; - response.MaxReadSize = ServerMaxReadSize; - response.MaxWriteSize = ServerMaxWriteSize; + if (state.Dialect != SMBDialect.SMB202 && transportType == SMBTransportType.DirectTCPTransport) + { + response.Capabilities = Capabilities.LargeMTU; + response.MaxTransactSize = ServerMaxTransactSizeLargeMTU; + response.MaxReadSize = ServerMaxReadSizeLargeMTU; + response.MaxWriteSize = ServerMaxWriteSizeLargeMTU; + } + else + { + response.MaxTransactSize = ServerMaxTransactSize; + response.MaxReadSize = ServerMaxReadSize; + response.MaxWriteSize = ServerMaxWriteSize; + } response.SystemTime = DateTime.Now; response.ServerStartTime = serverStartTime; response.SecurityBuffer = securityProvider.GetSPNEGOTokenInitBytes(); diff --git a/SMBLibrary/Server/SMBServer.SMB2.cs b/SMBLibrary/Server/SMBServer.SMB2.cs index a966472..d5f513e 100644 --- a/SMBLibrary/Server/SMBServer.SMB2.cs +++ b/SMBLibrary/Server/SMBServer.SMB2.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Tal Aloni . All rights reserved. +/* Copyright (C) 2017-2020 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, @@ -83,7 +83,7 @@ namespace SMBLibrary.Server if (command is NegotiateRequest) { NegotiateRequest request = (NegotiateRequest)command; - SMB2Command response = NegotiateHelper.GetNegotiateResponse(request, m_securityProvider, state, m_serverGuid, m_serverStartTime); + SMB2Command response = NegotiateHelper.GetNegotiateResponse(request, m_securityProvider, state, m_transport, m_serverGuid, m_serverStartTime); if (state.Dialect != SMBDialect.NotSet) { state = new SMB2ConnectionState(state); diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs index b20fbcf..c16f840 100644 --- a/SMBLibrary/Server/SMBServer.cs +++ b/SMBLibrary/Server/SMBServer.cs @@ -319,7 +319,7 @@ namespace SMBLibrary.Server List smb2Dialects = SMB2.NegotiateHelper.FindSMB2Dialects(message); if (smb2Dialects.Count > 0) { - SMB2Command response = SMB2.NegotiateHelper.GetNegotiateResponse(smb2Dialects, m_securityProvider, state, m_serverGuid, m_serverStartTime); + SMB2Command response = SMB2.NegotiateHelper.GetNegotiateResponse(smb2Dialects, m_securityProvider, state, m_transport, m_serverGuid, m_serverStartTime); if (state.Dialect != SMBDialect.NotSet) { state = new SMB2ConnectionState(state);