From 6507d88bf58fa290703a0d85cfe9252f5f6b0cb0 Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Tue, 25 Jul 2017 16:53:42 +0300 Subject: [PATCH] Minor code refactoring, do not try to process async commands other than CANCEL --- SMBLibrary/SMBLibrary.csproj | 4 +++ SMBLibrary/Server/SMB1/CancelHelper.cs | 20 +++++++++++++ SMBLibrary/Server/SMB1/NTTransactHelper.cs | 8 ++++-- SMBLibrary/Server/SMB1/NotifyChangeHelper.cs | 23 +++++++++++++++ SMBLibrary/Server/SMB2/CancelHelper.cs | 30 ++++++++++++++++++++ SMBLibrary/Server/SMB2/ChangeNotifyHelper.cs | 26 +++++++++++++++++ SMBLibrary/Server/SMBServer.SMB1.cs | 7 +++++ SMBLibrary/Server/SMBServer.SMB2.cs | 29 +++++++------------ 8 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 SMBLibrary/Server/SMB1/CancelHelper.cs create mode 100644 SMBLibrary/Server/SMB1/NotifyChangeHelper.cs create mode 100644 SMBLibrary/Server/SMB2/CancelHelper.cs create mode 100644 SMBLibrary/Server/SMB2/ChangeNotifyHelper.cs diff --git a/SMBLibrary/SMBLibrary.csproj b/SMBLibrary/SMBLibrary.csproj index 8a22625..9fbf9cd 100644 --- a/SMBLibrary/SMBLibrary.csproj +++ b/SMBLibrary/SMBLibrary.csproj @@ -200,8 +200,10 @@ + + @@ -217,6 +219,8 @@ + + diff --git a/SMBLibrary/Server/SMB1/CancelHelper.cs b/SMBLibrary/Server/SMB1/CancelHelper.cs new file mode 100644 index 0000000..5bab2df --- /dev/null +++ b/SMBLibrary/Server/SMB1/CancelHelper.cs @@ -0,0 +1,20 @@ +/* Copyright (C) 2017 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, + * either version 3 of the License, or (at your option) any later version. + */ +using System; +using System.Collections.Generic; +using SMBLibrary.SMB1; +using Utilities; + +namespace SMBLibrary.Server.SMB1 +{ + internal class CancelHelper + { + internal static void ProcessNTCancelRequest(SMB1Header header, NTCancelRequest request, ISMBShare share, SMB1ConnectionState state) + { + } + } +} diff --git a/SMBLibrary/Server/SMB1/NTTransactHelper.cs b/SMBLibrary/Server/SMB1/NTTransactHelper.cs index 06bccd5..428a967 100644 --- a/SMBLibrary/Server/SMB1/NTTransactHelper.cs +++ b/SMBLibrary/Server/SMB1/NTTransactHelper.cs @@ -102,9 +102,11 @@ namespace SMBLibrary.Server.SMB1 } else if (subcommand is NTTransactNotifyChangeRequest) { - // [MS-CIFS] If the server does not support the NT_TRANSACT_NOTIFY_CHANGE subcommand, it can return an - // error response with STATUS_NOT_IMPLEMENTED [..] in response to an NT_TRANSACT_NOTIFY_CHANGE Request. - header.Status = NTStatus.STATUS_NOT_IMPLEMENTED; + NotifyChangeHelper.ProcessNTTransactNotifyChangeRequest(header, maxParameterCount, (NTTransactNotifyChangeRequest)subcommand, share, state); + if (header.Status == NTStatus.STATUS_PENDING) + { + return new List(); + } } else if (subcommand is NTTransactQuerySecurityDescriptorRequest) { diff --git a/SMBLibrary/Server/SMB1/NotifyChangeHelper.cs b/SMBLibrary/Server/SMB1/NotifyChangeHelper.cs new file mode 100644 index 0000000..197305b --- /dev/null +++ b/SMBLibrary/Server/SMB1/NotifyChangeHelper.cs @@ -0,0 +1,23 @@ +/* Copyright (C) 2017 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, + * either version 3 of the License, or (at your option) any later version. + */ +using System; +using System.Collections.Generic; +using SMBLibrary.SMB1; +using Utilities; + +namespace SMBLibrary.Server.SMB1 +{ + internal class NotifyChangeHelper + { + internal static void ProcessNTTransactNotifyChangeRequest(SMB1Header header, uint maxParameterCount, NTTransactNotifyChangeRequest subcommand, ISMBShare share, SMB1ConnectionState state) + { + // [MS-CIFS] If the server does not support the NT_TRANSACT_NOTIFY_CHANGE subcommand, it can return an + // error response with STATUS_NOT_IMPLEMENTED [..] in response to an NT_TRANSACT_NOTIFY_CHANGE Request. + header.Status = NTStatus.STATUS_NOT_IMPLEMENTED; + } + } +} diff --git a/SMBLibrary/Server/SMB2/CancelHelper.cs b/SMBLibrary/Server/SMB2/CancelHelper.cs new file mode 100644 index 0000000..5c870c5 --- /dev/null +++ b/SMBLibrary/Server/SMB2/CancelHelper.cs @@ -0,0 +1,30 @@ +/* Copyright (C) 2017 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, + * either version 3 of the License, or (at your option) any later version. + */ +using System; +using System.Collections.Generic; +using SMBLibrary.SMB2; +using Utilities; + +namespace SMBLibrary.Server.SMB2 +{ + internal class CancelHelper + { + internal static SMB2Command GetCancelResponse(CancelRequest request, SMB2ConnectionState state) + { + if (request.Header.IsAsync && request.Header.AsyncID == 0) + { + ErrorResponse response = new ErrorResponse(request.CommandName, NTStatus.STATUS_CANCELLED); + response.Header.IsAsync = true; + return response; + } + + // [MS-SMB2] If a request is not found [..] no response is sent. + // [MS-SMB2] If the target request is not successfully canceled [..] no response is sent. + return null; + } + } +} diff --git a/SMBLibrary/Server/SMB2/ChangeNotifyHelper.cs b/SMBLibrary/Server/SMB2/ChangeNotifyHelper.cs new file mode 100644 index 0000000..909d9ab --- /dev/null +++ b/SMBLibrary/Server/SMB2/ChangeNotifyHelper.cs @@ -0,0 +1,26 @@ +/* Copyright (C) 2017 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, + * either version 3 of the License, or (at your option) any later version. + */ +using System; +using System.Collections.Generic; +using SMBLibrary.SMB2; +using Utilities; + +namespace SMBLibrary.Server.SMB2 +{ + internal class ChangeNotifyHelper + { + internal static SMB2Command GetChangeNotifyInterimResponse(ChangeNotifyRequest request, ISMBShare share, SMB2ConnectionState state) + { + // [MS-SMB2] If the underlying object store does not support change notifications, the server MUST fail this request with STATUS_NOT_SUPPORTED + ErrorResponse response = new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED); + // Windows 7 / 8 / 10 will infinitely retry sending ChangeNotify requests if the response does not have SMB2_FLAGS_ASYNC_COMMAND set. + // Note: NoRemoteChangeNotify can be set in the registry to prevent the client from sending ChangeNotify requests altogether. + response.Header.IsAsync = true; + return response; + } + } +} diff --git a/SMBLibrary/Server/SMBServer.SMB1.cs b/SMBLibrary/Server/SMBServer.SMB1.cs index 035e5f5..45a18d9 100644 --- a/SMBLibrary/Server/SMBServer.SMB1.cs +++ b/SMBLibrary/Server/SMBServer.SMB1.cs @@ -281,6 +281,13 @@ namespace SMBLibrary.Server NTCreateAndXRequest request = (NTCreateAndXRequest)command; return NTCreateHelper.GetNTCreateResponse(header, request, share, state); } + else if (command is NTCancelRequest) + { + NTCancelRequest request = (NTCancelRequest)command; + CancelHelper.ProcessNTCancelRequest(header, request, share, state); + // [MS-CIFS] The SMB_COM_NT_CANCEL command MUST NOT send a response. + return new List(); + } } } diff --git a/SMBLibrary/Server/SMBServer.SMB2.cs b/SMBLibrary/Server/SMBServer.SMB2.cs index 542f8e9..14af160 100644 --- a/SMBLibrary/Server/SMBServer.SMB2.cs +++ b/SMBLibrary/Server/SMBServer.SMB2.cs @@ -113,22 +113,16 @@ namespace SMBLibrary.Server state.RemoveSession(command.Header.SessionID); return new LogoffResponse(); } - else + else if (command.Header.IsAsync) { - // Cancel requests can have an ASYNC header (TreeID will not be present) + // TreeID will not be present in an ASYNC header if (command is CancelRequest) { - if (command.Header.IsAsync && command.Header.AsyncID == 0) - { - ErrorResponse response = new ErrorResponse(command.CommandName, NTStatus.STATUS_CANCELLED); - response.Header.IsAsync = true; - return response; - } - - // [MS-SMB2] If a request is not found, the server MUST stop processing for this cancel request. No response is sent. - return null; + return CancelHelper.GetCancelResponse((CancelRequest)command, state); } - + } + else + { ISMBShare share = session.GetConnectedTree(command.Header.TreeID); if (share == null) { @@ -175,14 +169,13 @@ namespace SMBLibrary.Server { return IOCtlHelper.GetIOCtlResponse((IOCtlRequest)command, share, state); } + else if (command is CancelRequest) + { + return CancelHelper.GetCancelResponse((CancelRequest)command, state); + } else if (command is ChangeNotifyRequest) { - // [MS-SMB2] If the underlying object store does not support change notifications, the server MUST fail this request with STATUS_NOT_SUPPORTED - ErrorResponse response = new ErrorResponse(command.CommandName, NTStatus.STATUS_NOT_SUPPORTED); - // Windows 7 / 8 / 10 will infinitely retry sending ChangeNotify requests if the response does not have SMB2_FLAGS_ASYNC_COMMAND set. - // Note: NoRemoteChangeNotify can be set in the registry to prevent the client from sending ChangeNotify requests altogether. - response.Header.IsAsync = true; - return response; + return ChangeNotifyHelper.GetChangeNotifyInterimResponse((ChangeNotifyRequest)command, share, state); } } }