Ver código fonte

Added SMBServer.OnLogEntry event

Implementers can now subscribe to the OnLogEntry event and receive log
entries.
Tal Aloni 8 anos atrás
pai
commit
74e92f2e2b

+ 1 - 0
SMBLibrary/SMBLibrary.csproj

@@ -396,6 +396,7 @@
     <Compile Include="Tests\AuthenticationTests.cs" />
     <Compile Include="Tests\NetBiosTests.cs" />
     <Compile Include="Tests\RPCTests.cs" />
+    <Compile Include="Utilities\LogEntry.cs" />
     <Compile Include="Utilities\PrefetchedStream.cs" />
     <Compile Include="Utilities\SocketUtils.cs" />
     <Compile Include="Win32\Authentication\LoginAPI.cs" />

+ 35 - 1
SMBLibrary/Server/ConnectionState/ConnectionState.cs

@@ -6,26 +6,60 @@
  */
 using System;
 using System.Collections.Generic;
+using System.Net;
 using System.Net.Sockets;
 using SMBLibrary.NetBios;
 using Utilities;
 
 namespace SMBLibrary.Server
 {
+    public delegate void LogDelegate(Severity severity, string message);
+
     public class ConnectionState
     {
         public Socket ClientSocket;
+        public IPEndPoint ClientEndPoint;
         public NBTConnectionReceiveBuffer ReceiveBuffer;
+        protected LogDelegate LogToServerHandler;
 
-        public ConnectionState()
+        public ConnectionState(LogDelegate logToServerHandler)
         {
             ReceiveBuffer = new NBTConnectionReceiveBuffer();
+            LogToServerHandler = logToServerHandler;
         }
 
         public ConnectionState(ConnectionState state)
         {
             ClientSocket = state.ClientSocket;
+            ClientEndPoint = state.ClientEndPoint;
             ReceiveBuffer = state.ReceiveBuffer;
+            LogToServerHandler = state.LogToServerHandler;
+        }
+
+        public void LogToServer(Severity severity, string message)
+        {
+            message = String.Format("[{0}] {1}", ConnectionIdentifier, message);
+            if (LogToServerHandler != null)
+            {
+                LogToServerHandler(severity, message);
+            }
+        }
+
+        public void LogToServer(Severity severity, string message, params object[] args)
+        {
+            LogToServer(severity, String.Format(message, args));
+        }
+
+        public string ConnectionIdentifier
+        {
+            get
+            {
+                if (ClientEndPoint != null)
+                {
+                    return ClientEndPoint.Address + ":" + ClientEndPoint.Port;
+                }
+                return String.Empty;
+            }
         }
     }
 }

+ 1 - 1
SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs

@@ -232,7 +232,7 @@ namespace SMBLibrary.Server
             Stream stream = m_openedFiles[fileID].Stream;
             if (stream != null)
             {
-                System.Diagnostics.Debug.Print("[{0}] Closing file '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), m_openedFiles[fileID].Path);
+                LogToServer(Severity.Verbose, "Closing file '{0}'", m_openedFiles[fileID].Path);
                 stream.Close();
             }
             m_openedFiles.Remove(fileID);

+ 9 - 9
SMBLibrary/Server/SMB1/FileSystemResponseHelper.cs

@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. 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,
@@ -31,13 +31,13 @@ namespace SMBLibrary.Server.SMB1
             }
             catch (IOException)
             {
-                System.Diagnostics.Debug.Print("[{0}] CreateDirectory: Cannot create '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), request.DirectoryName);
+                state.LogToServer(Severity.Debug, "CreateDirectory: Cannot create '{0}'", request.DirectoryName);
                 header.Status = NTStatus.STATUS_OBJECT_NAME_INVALID;
                 return new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY);
             }
             catch (UnauthorizedAccessException)
             {
-                System.Diagnostics.Debug.Print("[{0}] CreateDirectory: Cannot create '{1}', Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), request.DirectoryName);
+                state.LogToServer(Severity.Debug, "CreateDirectory: Cannot create '{0}', Access Denied", request.DirectoryName);
                 header.Status = NTStatus.STATUS_ACCESS_DENIED;
                 return new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY);
             }
@@ -75,13 +75,13 @@ namespace SMBLibrary.Server.SMB1
             }
             catch (IOException)
             {
-                System.Diagnostics.Debug.Print("[{0}] DeleteDirectory: Cannot delete '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), request.DirectoryName);
+                state.LogToServer(Severity.Debug, "DeleteDirectory: Cannot delete '{0}'", request.DirectoryName);
                 header.Status = NTStatus.STATUS_CANNOT_DELETE;
                 return new ErrorResponse(CommandName.SMB_COM_DELETE_DIRECTORY);
             }
             catch (UnauthorizedAccessException)
             {
-                System.Diagnostics.Debug.Print("[{0}] DeleteDirectory: Cannot delete '{1}', Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), request.DirectoryName);
+                state.LogToServer(Severity.Debug, "DeleteDirectory: Cannot delete '{0}', Access Denied", request.DirectoryName);
                 header.Status = NTStatus.STATUS_ACCESS_DENIED;
                 return new ErrorResponse(CommandName.SMB_COM_DELETE_DIRECTORY);
             }
@@ -131,13 +131,13 @@ namespace SMBLibrary.Server.SMB1
             }
             catch (IOException)
             {
-                System.Diagnostics.Debug.Print("[{0}] Delete: Cannot delete '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), request.FileName);
+                state.LogToServer(Severity.Debug, "Delete: Cannot delete '{0}'", request.FileName);
                 header.Status = NTStatus.STATUS_CANNOT_DELETE;
                 return new ErrorResponse(CommandName.SMB_COM_DELETE);
             }
             catch (UnauthorizedAccessException)
             {
-                System.Diagnostics.Debug.Print("[{0}] DeleteDirectory: Cannot delete '{1}', Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), request.FileName);
+                state.LogToServer(Severity.Debug, "DeleteDirectory: Cannot delete '{0}', Access Denied", request.FileName);
                 header.Status = NTStatus.STATUS_ACCESS_DENIED;
                 return new ErrorResponse(CommandName.SMB_COM_DELETE);
             }
@@ -177,13 +177,13 @@ namespace SMBLibrary.Server.SMB1
             }
             catch (IOException)
             {
-                System.Diagnostics.Debug.Print("[{0}] Rename: Sharing violation renaming '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), request.OldFileName);
+                state.LogToServer(Severity.Debug, "Rename: Sharing violation renaming '{0}'", request.OldFileName);
                 header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                 return new ErrorResponse(CommandName.SMB_COM_RENAME);
             }
             catch (UnauthorizedAccessException)
             {
-                System.Diagnostics.Debug.Print("[{0}] Rename: Cannot rename '{1}', Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), request.OldFileName);
+                state.LogToServer(Severity.Debug, "Rename: Cannot rename '{0}', Access Denied", request.OldFileName);
                 header.Status = NTStatus.STATUS_ACCESS_DENIED;
                 return new ErrorResponse(CommandName.SMB_COM_RENAME);
             }

+ 12 - 10
SMBLibrary/Server/SMB1/NTCreateHelper.cs

@@ -92,7 +92,7 @@ namespace SMBLibrary.Server.SMB1
                     if (entry != null)
                     {
                         // File already exists, fail the request
-                        System.Diagnostics.Debug.Print("[{0}] NTCreate: File '{1}' already exist", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                        state.LogToServer(Severity.Debug, "NTCreate: File '{0}' already exist", path);
                         header.Status = NTStatus.STATUS_OBJECT_NAME_COLLISION;
                         return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                     }
@@ -107,12 +107,12 @@ namespace SMBLibrary.Server.SMB1
                     {
                         if (forceDirectory)
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Creating directory '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                            state.LogToServer(Severity.Information, "NTCreate: Creating directory '{0}'", path);
                             entry = fileSystem.CreateDirectory(path);
                         }
                         else
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Creating file '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                            state.LogToServer(Severity.Information, "NTCreate: Creating file '{0}'", path);
                             entry = fileSystem.CreateFile(path);
                         }
                     }
@@ -121,20 +121,20 @@ namespace SMBLibrary.Server.SMB1
                         ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
                         if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Sharing violation creating '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                            state.LogToServer(Severity.Debug, "NTCreate: Sharing violation creating '{0}'", path);
                             header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                             return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                         }
                         else
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Error creating '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                            state.LogToServer(Severity.Debug, "NTCreate: Error creating '{0}'", path);
                             header.Status = NTStatus.STATUS_DATA_ERROR;
                             return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                         }
                     }
                     catch (UnauthorizedAccessException)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] NTCreate: Error creating '{1}', Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                        state.LogToServer(Severity.Debug, "NTCreate: Error creating '{0}', Access Denied", path);
                         header.Status = NTStatus.STATUS_ACCESS_DENIED;
                         return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                     }
@@ -163,12 +163,12 @@ namespace SMBLibrary.Server.SMB1
                         {
                             if (forceDirectory)
                             {
-                                System.Diagnostics.Debug.Print("[{0}] NTCreate: Creating directory '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                                state.LogToServer(Severity.Information, "NTCreate: Creating directory '{0}'", path);
                                 entry = fileSystem.CreateDirectory(path);
                             }
                             else
                             {
-                                System.Diagnostics.Debug.Print("[{0}] NTCreate: Creating file '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                                state.LogToServer(Severity.Information, "NTCreate: Creating file '{0}'", path);
                                 entry = fileSystem.CreateFile(path);
                             }
                         }
@@ -260,7 +260,7 @@ namespace SMBLibrary.Server.SMB1
                     bool openReparsePoint = (request.CreateOptions & CreateOptions.FILE_OPEN_REPARSE_POINT) > 0;
                     bool disableBuffering = (request.CreateOptions & CreateOptions.FILE_NO_INTERMEDIATE_BUFFERING) > 0;
                     bool buffered = (request.CreateOptions & CreateOptions.FILE_SEQUENTIAL_ONLY) > 0 && !disableBuffering && !openReparsePoint;
-                    System.Diagnostics.Debug.Print("[{0}] NTCreate: Opening '{1}', Access={2}, Share={3}, Buffered={4}", DateTime.Now.ToString("HH:mm:ss:ffff"), path, fileAccess, fileShare, buffered);
+                    state.LogToServer(Severity.Verbose, "NTCreate: Opening '{0}', Access={1}, Share={2}, Buffered={3}", path, fileAccess, fileShare, buffered);
                     try
                     {
                         stream = fileSystem.OpenFile(path, FileMode.Open, fileAccess, fileShare);
@@ -270,18 +270,20 @@ namespace SMBLibrary.Server.SMB1
                         ushort errorCode = IOExceptionHelper.GetWin32ErrorCode(ex);
                         if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Sharing violation opening '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                            state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}'", path);
                             header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                             return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                         }
                         else
                         {
+                            state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Data Error", path);
                             header.Status = NTStatus.STATUS_DATA_ERROR;
                             return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                         }
                     }
                     catch (UnauthorizedAccessException)
                     {
+                        state.LogToServer(Severity.Debug, "NTCreate: Sharing violation opening '{0}', Access Denied", path);
                         header.Status = NTStatus.STATUS_ACCESS_DENIED;
                         return new ErrorResponse(CommandName.SMB_COM_NT_CREATE_ANDX);
                     }

+ 3 - 3
SMBLibrary/Server/SMB1/OpenAndXHelper.cs

@@ -104,12 +104,12 @@ namespace SMBLibrary.Server.SMB1
 
                     if ((request.FileAttrs & SMBFileAttributes.Directory) > 0)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] OpenAndX: Creating directory '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                        state.LogToServer(Severity.Information, "OpenAndX: Creating directory '{0}'", path);
                         entry = fileSystem.CreateDirectory(path);
                     }
                     else
                     {
-                        System.Diagnostics.Debug.Print("[{0}] OpenAndX: Creating file '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                        state.LogToServer(Severity.Information, "OpenAndX: Creating file '{0}'", path);
                         entry = fileSystem.CreateFile(path);
                     }
                     openResult = OpenResult.NotExistedAndWasCreated;
@@ -121,7 +121,7 @@ namespace SMBLibrary.Server.SMB1
                 if (!entry.IsDirectory)
                 {
                     bool buffered = (request.AccessMode.CachedMode == CachedMode.CachingAllowed && request.AccessMode.WriteThroughMode == WriteThroughMode.Disabled);
-                    System.Diagnostics.Debug.Print("[{0}] OpenAndX: Opening '{1}', Access={2}, Share={3}, Buffered={4}", DateTime.Now.ToString("HH:mm:ss:ffff"), path, fileAccess, fileShare, buffered);
+                    state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}', Access={1}, Share={2}, Buffered={3}", path, fileAccess, fileShare, buffered);
                     stream = fileSystem.OpenFile(path, FileMode.Open, fileAccess, fileShare);
                     if (buffered)
                     {

+ 4 - 2
SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs

@@ -103,24 +103,26 @@ namespace SMBLibrary.Server.SMB1
                     if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                     {
                         // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
-                        System.Diagnostics.Debug.Print("[{0}] ReadAndX: Cannot read '{1}'. Sharing Violation.", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                        state.LogToServer(Severity.Debug, "ReadAndX: Cannot read '{0}'. Sharing Violation.", openedFilePath);
                         header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                         return null;
                     }
                     else
                     {
+                        state.LogToServer(Severity.Debug, "ReadAndX: Cannot read '{0}'. Data Error.", openedFilePath);
                         header.Status = NTStatus.STATUS_DATA_ERROR;
                         return null;
                     }
                 }
                 catch (ArgumentOutOfRangeException)
                 {
+                    state.LogToServer(Severity.Debug, "ReadAndX: Cannot read '{0}'. Offset Out Of Range.", openedFilePath);
                     header.Status = NTStatus.STATUS_DATA_ERROR;
                     return null;
                 }
                 catch (UnauthorizedAccessException)
                 {
-                    System.Diagnostics.Debug.Print("[{0}] ReadAndX: Cannot read '{1}', Access Denied.", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                    state.LogToServer(Severity.Debug, "ReadAndX: Cannot read '{0}', Access Denied.", openedFilePath);
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return null;
                 }

+ 1 - 1
SMBLibrary/Server/SMB1/ServerResponseHelper.cs

@@ -33,7 +33,7 @@ namespace SMBLibrary.Server.SMB1
                 }
                 catch
                 {
-                    System.Diagnostics.Debug.Print("[{0}] Close: Cannot delete '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFile.Path);
+                    state.LogToServer(Severity.Debug, "Close: Cannot delete '{0}'", openedFile.Path);
                 }
             }
             CloseResponse response = new CloseResponse();

+ 10 - 9
SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs

@@ -235,7 +235,7 @@ namespace SMBLibrary.Server.SMB1
             return response;
         }
 
-        internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryPathInformationRequest subcommand, FileSystemShare share)
+        internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryPathInformationRequest subcommand, FileSystemShare share, SMB1ConnectionState state)
         {
             IFileSystem fileSystem = share.FileSystem;
             string path = subcommand.FileName;
@@ -244,7 +244,7 @@ namespace SMBLibrary.Server.SMB1
             {
                 // Windows Server 2003 will return STATUS_OBJECT_NAME_NOT_FOUND
                 // Returning STATUS_NO_SUCH_FILE caused an issue when executing ImageX.exe from WinPE 3.0 (32-bit)
-                System.Diagnostics.Debug.Print("[{0}] Transaction2QueryPathInformation: File not found, Path: '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), path);
+                state.LogToServer(Severity.Debug, "Transaction2QueryPathInformation: File not found, Path: '{0}'", path);
                 header.Status = NTStatus.STATUS_OBJECT_NAME_NOT_FOUND;
                 return null;
             }
@@ -349,7 +349,7 @@ namespace SMBLibrary.Server.SMB1
                         if (errorCode == (ushort)Win32Error.ERROR_SHARING_VIOLATION)
                         {
                             // Returning STATUS_SHARING_VIOLATION is undocumented but apparently valid
-                            System.Diagnostics.Debug.Print("[{0}] Transaction2SetFileInformation: Sharing violation setting file dates, Path: '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                            state.LogToServer(Severity.Debug, "Transaction2SetFileInformation: Sharing violation setting file dates, Path: '{0}'", openedFilePath);
                             header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                             return null;
                         }
@@ -384,17 +384,18 @@ namespace SMBLibrary.Server.SMB1
                         }
                         try
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Deleting file '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                            state.LogToServer(Severity.Information, "NTCreate: Deleting file '{0}'", openedFilePath);
                             share.FileSystem.Delete(openedFilePath);
                         }
                         catch (IOException)
                         {
-                            System.Diagnostics.Debug.Print("[{0}] NTCreate: Error deleting '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                            state.LogToServer(Severity.Information, "NTCreate: Error deleting '{0}'", openedFilePath);
                             header.Status = NTStatus.STATUS_SHARING_VIOLATION;
                             return null;
                         }
                         catch (UnauthorizedAccessException)
                         {
+                            state.LogToServer(Severity.Information, "NTCreate: Error deleting '{0}', Access Denied", openedFilePath);
                             header.Status = NTStatus.STATUS_ACCESS_DENIED;
                             return null;
                         }
@@ -412,11 +413,11 @@ namespace SMBLibrary.Server.SMB1
                     }
                     catch (IOException)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] SMB_SET_FILE_ALLOCATION_INFO: Cannot set allocation for '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                        state.LogToServer(Severity.Debug, "SMB_SET_FILE_ALLOCATION_INFO: Cannot set allocation for '{0}'", openedFilePath);
                     }
                     catch (UnauthorizedAccessException)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] SMB_SET_FILE_ALLOCATION_INFO: Cannot set allocation for '{1}'. Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                        state.LogToServer(Severity.Debug, "SMB_SET_FILE_ALLOCATION_INFO: Cannot set allocation for '{0}'. Access Denied", openedFilePath);
                     }
                     return response;
                 }
@@ -429,11 +430,11 @@ namespace SMBLibrary.Server.SMB1
                     }
                     catch (IOException)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] SMB_SET_FILE_END_OF_FILE_INFO: Cannot set end of file for '{1}'", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                        state.LogToServer(Severity.Debug, "SMB_SET_FILE_END_OF_FILE_INFO: Cannot set end of file for '{0}'", openedFilePath);
                     }
                     catch (UnauthorizedAccessException)
                     {
-                        System.Diagnostics.Debug.Print("[{0}] SMB_SET_FILE_END_OF_FILE_INFO: Cannot set end of file for '{1}'. Access Denied", DateTime.Now.ToString("HH:mm:ss:ffff"), openedFilePath);
+                        state.LogToServer(Severity.Debug, "SMB_SET_FILE_END_OF_FILE_INFO: Cannot set end of file for '{0}'. Access Denied", openedFilePath);
                     }
                     return response;
                 }

+ 1 - 1
SMBLibrary/Server/SMB1/TransactionHelper.cs

@@ -189,7 +189,7 @@ namespace SMBLibrary.Server.SMB1
             }
             else if (subcommand is Transaction2QueryPathInformationRequest)
             {
-                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2QueryPathInformationRequest)subcommand, fileSystemShare);
+                subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2QueryPathInformationRequest)subcommand, fileSystemShare, state);
             }
             else if (subcommand is Transaction2SetPathInformationRequest)
             {

+ 1 - 1
SMBLibrary/Server/SMBServer.SMB1.cs

@@ -319,7 +319,7 @@ namespace SMBLibrary.Server
             SessionMessagePacket packet = new SessionMessagePacket();
             packet.Trailer = response.GetBytes();
             TrySendPacket(state, packet);
-            System.Diagnostics.Debug.Print("[{0}] Response sent: {1} Commands, First Command: {2}, Packet length: {3}", DateTime.Now.ToString("HH:mm:ss:ffff"), response.Commands.Count, response.Commands[0].CommandName.ToString(), packet.Length);
+            state.LogToServer(Severity.Verbose, "Response sent: {0} Commands, First Command: {1}, Packet length: {2}", response.Commands.Count, response.Commands[0].CommandName.ToString(), packet.Length);
         }
 
         private static void PrepareResponseHeader(SMB1Message response, SMB1Message request)

+ 24 - 6
SMBLibrary/Server/SMBServer.cs

@@ -32,6 +32,8 @@ namespace SMBLibrary.Server
         private bool m_listening;
         private Guid m_serverGuid;
 
+        public event EventHandler<LogEntry> OnLogEntry;
+
         public SMBServer(ShareCollection shares, INTLMAuthenticationProvider users, IPAddress serverAddress, SMBTransportType transport)
         {
             m_shares = shares;
@@ -66,7 +68,6 @@ namespace SMBLibrary.Server
         // This method Accepts new connections
         private void ConnectRequestCallback(IAsyncResult ar)
         {
-            System.Diagnostics.Debug.Print("[{0}] New connection request", DateTime.Now.ToString("HH:mm:ss:ffff"));
             Socket listenerSocket = (Socket)ar.AsyncState;
 
             Socket clientSocket;
@@ -88,14 +89,16 @@ namespace SMBLibrary.Server
                 {
                     m_listenerSocket.BeginAccept(ConnectRequestCallback, m_listenerSocket);
                 }
-                System.Diagnostics.Debug.Print("[{0}] Connection request error {1}", DateTime.Now.ToString("HH:mm:ss:ffff"), ex.ErrorCode);
+                Log(Severity.Debug, "Connection request error {0}", ex.ErrorCode);
                 return;
             }
 
-            SMB1ConnectionState state = new SMB1ConnectionState(new ConnectionState());
+            SMB1ConnectionState state = new SMB1ConnectionState(new ConnectionState(Log));
             // Disable the Nagle Algorithm for this tcp socket:
             clientSocket.NoDelay = true;
             state.ClientSocket = clientSocket;
+            state.ClientEndPoint = clientSocket.RemoteEndPoint as IPEndPoint;
+            state.LogToServer(Severity.Verbose, "New connection request");
             try
             {
                 // Direct TCP transport packet is actually an NBT Session Message Packet,
@@ -139,7 +142,7 @@ namespace SMBLibrary.Server
             if (numberOfBytesReceived == 0)
             {
                 // The other side has closed the connection
-                System.Diagnostics.Debug.Print("[{0}] The other side closed the connection", DateTime.Now.ToString("HH:mm:ss:ffff"));
+                state.LogToServer(Severity.Debug, "The other side closed the connection");
                 clientSocket.Close();
                 return;
             }
@@ -203,7 +206,7 @@ namespace SMBLibrary.Server
                 SMB1Message message = null;
 #if DEBUG
                 message = SMB1Message.GetSMB1Message(packet.Trailer);
-                System.Diagnostics.Debug.Print("[{0}] Message Received: {1} Commands, First Command: {2}, Packet length: {3}", DateTime.Now.ToString("HH:mm:ss:ffff"), message.Commands.Count, message.Commands[0].CommandName.ToString(), packet.Length);
+                state.LogToServer(Severity.Verbose, "Message Received: {0} Commands, First Command: {1}, Packet length: {2}", message.Commands.Count, message.Commands[0].CommandName.ToString(), packet.Length);
 #else
                 try
                 {
@@ -219,7 +222,7 @@ namespace SMBLibrary.Server
             }
             else
             {
-                System.Diagnostics.Debug.Print("[{0}] Invalid NetBIOS packet", DateTime.Now.ToString("HH:mm:ss:ffff"));
+                state.LogToServer(Severity.Warning, "Invalid NetBIOS packet");
                 state.ClientSocket.Close();
                 return;
             }
@@ -239,5 +242,20 @@ namespace SMBLibrary.Server
             {
             }
         }
+
+        public void Log(Severity severity, string message)
+        {
+            // To be thread-safe we must capture the delegate reference first
+            EventHandler<LogEntry> handler = OnLogEntry;
+            if (handler != null)
+            {
+                handler(this, new LogEntry(DateTime.Now, severity, "SMB Server", message));
+            }
+        }
+
+        public void Log(Severity severity, string message, params object[] args)
+        {
+            Log(severity, String.Format(message, args));
+        }
     }
 }

+ 37 - 0
SMBLibrary/Utilities/LogEntry.cs

@@ -0,0 +1,37 @@
+/* Copyright (C) 2012-2016 Tal Aloni <tal.aloni.il@gmail.com>. 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;
+
+namespace Utilities
+{
+    public enum Severity
+    {
+        Critical = 1,
+        Error = 2,
+        Warning = 3,
+        Information = 4,
+        Verbose = 5,
+        Debug = 6,
+        Trace = 7,
+    }
+
+    public class LogEntry : EventArgs
+    {
+        public DateTime Time;
+        public Severity Severity;
+        public string Source;
+        public string Message;
+
+        public LogEntry(DateTime time, Severity severity, string source, string message)
+        {
+            Time = time;
+            Severity = severity;
+            Source = source;
+            Message = message;
+        }
+    }
+}

+ 8 - 0
SMBServer/ServerUI.cs

@@ -90,6 +90,7 @@ namespace SMBServer
             }
 
             m_server = new SMBLibrary.Server.SMBServer(shares, provider, serverAddress, transportType);
+            m_server.OnLogEntry += new EventHandler<LogEntry>(Server_OnLogEntry);
 
             try
             {
@@ -214,5 +215,12 @@ namespace SMBServer
             }
             return result;
         }
+
+        private void Server_OnLogEntry(object sender, LogEntry entry)
+        {
+            string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ");
+            string message = String.Format("{0} {1} {2}", entry.Severity.ToString().PadRight(12), timestamp, entry.Message);
+            System.Diagnostics.Debug.Print(message);
+        }
     }
 }