diff --git a/SMBLibrary/SMBLibrary.csproj b/SMBLibrary/SMBLibrary.csproj index dae5507..96b852f 100644 --- a/SMBLibrary/SMBLibrary.csproj +++ b/SMBLibrary/SMBLibrary.csproj @@ -396,6 +396,7 @@ + diff --git a/SMBLibrary/Server/ConnectionState/ConnectionState.cs b/SMBLibrary/Server/ConnectionState/ConnectionState.cs index 2b791f8..bddbc08 100644 --- a/SMBLibrary/Server/ConnectionState/ConnectionState.cs +++ b/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; + } } } } diff --git a/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs b/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs index 8e08da3..8d1f624 100644 --- a/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs +++ b/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); diff --git a/SMBLibrary/Server/SMB1/FileSystemResponseHelper.cs b/SMBLibrary/Server/SMB1/FileSystemResponseHelper.cs index 761605e..4e3b40e 100644 --- a/SMBLibrary/Server/SMB1/FileSystemResponseHelper.cs +++ b/SMBLibrary/Server/SMB1/FileSystemResponseHelper.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-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, @@ -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); } diff --git a/SMBLibrary/Server/SMB1/NTCreateHelper.cs b/SMBLibrary/Server/SMB1/NTCreateHelper.cs index becff02..e5d1fd4 100644 --- a/SMBLibrary/Server/SMB1/NTCreateHelper.cs +++ b/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); } diff --git a/SMBLibrary/Server/SMB1/OpenAndXHelper.cs b/SMBLibrary/Server/SMB1/OpenAndXHelper.cs index 9bb4d4f..487b0c1 100644 --- a/SMBLibrary/Server/SMB1/OpenAndXHelper.cs +++ b/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) { diff --git a/SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs b/SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs index d4a7565..b7f5915 100644 --- a/SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs +++ b/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; } diff --git a/SMBLibrary/Server/SMB1/ServerResponseHelper.cs b/SMBLibrary/Server/SMB1/ServerResponseHelper.cs index 6951ab7..0bd12b6 100644 --- a/SMBLibrary/Server/SMB1/ServerResponseHelper.cs +++ b/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(); diff --git a/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs b/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs index 47294d9..3151165 100644 --- a/SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs +++ b/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; } diff --git a/SMBLibrary/Server/SMB1/TransactionHelper.cs b/SMBLibrary/Server/SMB1/TransactionHelper.cs index 39345d6..7527649 100644 --- a/SMBLibrary/Server/SMB1/TransactionHelper.cs +++ b/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) { diff --git a/SMBLibrary/Server/SMBServer.SMB1.cs b/SMBLibrary/Server/SMBServer.SMB1.cs index 9dd1749..9eb3add 100644 --- a/SMBLibrary/Server/SMBServer.SMB1.cs +++ b/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) diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs index 25a1372..6e6e630 100644 --- a/SMBLibrary/Server/SMBServer.cs +++ b/SMBLibrary/Server/SMBServer.cs @@ -32,6 +32,8 @@ namespace SMBLibrary.Server private bool m_listening; private Guid m_serverGuid; + public event EventHandler 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 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)); + } } } diff --git a/SMBLibrary/Utilities/LogEntry.cs b/SMBLibrary/Utilities/LogEntry.cs new file mode 100644 index 0000000..02a0716 --- /dev/null +++ b/SMBLibrary/Utilities/LogEntry.cs @@ -0,0 +1,37 @@ +/* Copyright (C) 2012-2016 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; + +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; + } + } +} diff --git a/SMBServer/ServerUI.cs b/SMBServer/ServerUI.cs index f572d2a..ef27037 100644 --- a/SMBServer/ServerUI.cs +++ b/SMBServer/ServerUI.cs @@ -90,6 +90,7 @@ namespace SMBServer } m_server = new SMBLibrary.Server.SMBServer(shares, provider, serverAddress, transportType); + m_server.OnLogEntry += new EventHandler(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); + } } } \ No newline at end of file