diff --git a/SMBLibrary/SMBLibrary.csproj b/SMBLibrary/SMBLibrary.csproj index d7339c9..da5473e 100644 --- a/SMBLibrary/SMBLibrary.csproj +++ b/SMBLibrary/SMBLibrary.csproj @@ -195,6 +195,7 @@ + diff --git a/SMBLibrary/Server/ConnectionManager.cs b/SMBLibrary/Server/ConnectionManager.cs index 4f92dbd..c80f77e 100644 --- a/SMBLibrary/Server/ConnectionManager.cs +++ b/SMBLibrary/Server/ConnectionManager.cs @@ -43,5 +43,19 @@ namespace SMBLibrary.Server connection.CloseSessions(); RemoveConnection(connection); } + + public List GetSessionsInformation() + { + List result = new List(); + lock (m_activeConnections) + { + foreach (ConnectionState connection in m_activeConnections) + { + List sessions = connection.GetSessionsInformation(); + result.AddRange(sessions); + } + } + return result; + } } } diff --git a/SMBLibrary/Server/ConnectionState/ConnectionState.cs b/SMBLibrary/Server/ConnectionState/ConnectionState.cs index 0c129bd..0d47585 100644 --- a/SMBLibrary/Server/ConnectionState/ConnectionState.cs +++ b/SMBLibrary/Server/ConnectionState/ConnectionState.cs @@ -50,6 +50,11 @@ namespace SMBLibrary.Server { } + public virtual List GetSessionsInformation() + { + return new List(); + } + public void LogToServer(Severity severity, string message) { message = String.Format("[{0}] {1}", ConnectionIdentifier, message); diff --git a/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs b/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs index ab1ac05..bfff0de 100644 --- a/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs +++ b/SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs @@ -55,7 +55,10 @@ namespace SMBLibrary.Server public SMB1Session CreateSession(ushort userID, string userName, string machineName, byte[] sessionKey, object accessToken) { SMB1Session session = new SMB1Session(this, userID, userName, machineName, sessionKey, accessToken); - m_sessions.Add(userID, session); + lock (m_sessions) + { + m_sessions.Add(userID, session); + } return session; } @@ -84,20 +87,39 @@ namespace SMBLibrary.Server if (session != null) { session.Close(); - m_sessions.Remove(userID); + lock (m_sessions) + { + m_sessions.Remove(userID); + } } } public override void CloseSessions() { - foreach (SMB1Session session in m_sessions.Values) + lock (m_sessions) { - session.Close(); + foreach (SMB1Session session in m_sessions.Values) + { + session.Close(); + } } m_sessions.Clear(); } + public override List GetSessionsInformation() + { + List result = new List(); + lock (m_sessions) + { + foreach (SMB1Session session in m_sessions.Values) + { + result.Add(new SessionInformation(this.ClientEndPoint, this.Dialect, session.UserName, session.MachineName, session.ListOpenFiles(), session.CreationDT)); + } + } + return result; + } + /// /// An open TID MUST be unique within an SMB connection. /// The value 0xFFFF MUST NOT be used as a valid TID. All other possible values for TID, including zero (0x0000), are valid. diff --git a/SMBLibrary/Server/ConnectionState/SMB1Session.cs b/SMBLibrary/Server/ConnectionState/SMB1Session.cs index 351c3a2..ed5a3d2 100644 --- a/SMBLibrary/Server/ConnectionState/SMB1Session.cs +++ b/SMBLibrary/Server/ConnectionState/SMB1Session.cs @@ -63,14 +63,17 @@ namespace SMBLibrary.Server m_connectedTrees.TryGetValue(treeID, out share); if (share != null) { - List fileIDList = new List(m_openFiles.Keys); - foreach (ushort fileID in fileIDList) + lock (m_openFiles) { - OpenFileObject openFile = m_openFiles[fileID]; - if (openFile.TreeID == treeID) + List fileIDList = new List(m_openFiles.Keys); + foreach (ushort fileID in fileIDList) { - share.FileStore.CloseFile(openFile.Handle); - m_openFiles.Remove(fileID); + OpenFileObject openFile = m_openFiles[fileID]; + if (openFile.TreeID == treeID) + { + share.FileStore.CloseFile(openFile.Handle); + m_openFiles.Remove(fileID); + } } } m_connectedTrees.Remove(treeID); @@ -94,7 +97,10 @@ namespace SMBLibrary.Server ushort? fileID = m_connection.AllocateFileID(); if (fileID.HasValue) { - m_openFiles.Add(fileID.Value, new OpenFileObject(treeID, relativePath, handle)); + lock (m_openFiles) + { + m_openFiles.Add(fileID.Value, new OpenFileObject(treeID, relativePath, handle)); + } } return fileID; } @@ -108,7 +114,23 @@ namespace SMBLibrary.Server public void RemoveOpenFile(ushort fileID) { - m_openFiles.Remove(fileID); + lock (m_openFiles) + { + m_openFiles.Remove(fileID); + } + } + + public List ListOpenFiles() + { + List result = new List(); + lock (m_openFiles) + { + foreach (OpenFileObject openFile in m_openFiles.Values) + { + result.Add(openFile.Path); + } + } + return result; } private ushort? AllocateSearchHandle() diff --git a/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs b/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs index 29d7049..fe56eae 100644 --- a/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs +++ b/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs @@ -47,7 +47,10 @@ namespace SMBLibrary.Server public SMB2Session CreateSession(ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken) { SMB2Session session = new SMB2Session(this, sessionID, userName, machineName, sessionKey, accessToken); - m_sessions.Add(sessionID, session); + lock (m_sessions) + { + m_sessions.Add(sessionID, session); + } return session; } @@ -65,18 +68,37 @@ namespace SMBLibrary.Server if (session != null) { session.Close(); - m_sessions.Remove(sessionID); + lock (m_sessions) + { + m_sessions.Remove(sessionID); + } } } public override void CloseSessions() { - foreach (SMB2Session session in m_sessions.Values) + lock (m_sessions) { - session.Close(); + foreach (SMB2Session session in m_sessions.Values) + { + session.Close(); + } } m_sessions.Clear(); } + + public override List GetSessionsInformation() + { + List result = new List(); + lock (m_sessions) + { + foreach (SMB2Session session in m_sessions.Values) + { + result.Add(new SessionInformation(this.ClientEndPoint, this.Dialect, session.UserName, session.MachineName, session.ListOpenFiles(), session.CreationDT)); + } + } + return result; + } } } diff --git a/SMBLibrary/Server/ConnectionState/SMB2Session.cs b/SMBLibrary/Server/ConnectionState/SMB2Session.cs index 34e8fe7..01d412c 100644 --- a/SMBLibrary/Server/ConnectionState/SMB2Session.cs +++ b/SMBLibrary/Server/ConnectionState/SMB2Session.cs @@ -85,14 +85,17 @@ namespace SMBLibrary.Server m_connectedTrees.TryGetValue(treeID, out share); if (share != null) { - List fileIDList = new List(m_openFiles.Keys); - foreach (ushort fileID in fileIDList) + lock (m_openFiles) { - OpenFileObject openFile = m_openFiles[fileID]; - if (openFile.TreeID == treeID) + List fileIDList = new List(m_openFiles.Keys); + foreach (ushort fileID in fileIDList) { - share.FileStore.CloseFile(openFile.Handle); - m_openFiles.Remove(fileID); + OpenFileObject openFile = m_openFiles[fileID]; + if (openFile.TreeID == treeID) + { + share.FileStore.CloseFile(openFile.Handle); + m_openFiles.Remove(fileID); + } } } m_connectedTrees.Remove(treeID); @@ -110,7 +113,10 @@ namespace SMBLibrary.Server ulong? persistentID = m_connection.AllocatePersistentFileID(); if (persistentID.HasValue) { - m_openFiles.Add(persistentID.Value, new OpenFileObject(treeID, relativePath, handle)); + lock (m_openFiles) + { + m_openFiles.Add(persistentID.Value, new OpenFileObject(treeID, relativePath, handle)); + } } return persistentID; } @@ -129,10 +135,26 @@ namespace SMBLibrary.Server public void RemoveOpenFile(ulong fileID) { - m_openFiles.Remove(fileID); + lock (m_openFiles) + { + m_openFiles.Remove(fileID); + } m_openSearches.Remove(fileID); } + public List ListOpenFiles() + { + List result = new List(); + lock (m_openFiles) + { + foreach (OpenFileObject openFile in m_openFiles.Values) + { + result.Add(openFile.Path); + } + } + return result; + } + public OpenSearch AddOpenSearch(ulong fileID, List entries, int enumerationLocation) { OpenSearch openSearch = new OpenSearch(entries, enumerationLocation); diff --git a/SMBLibrary/Server/SMBServer.cs b/SMBLibrary/Server/SMBServer.cs index 56b152b..ba4673f 100644 --- a/SMBLibrary/Server/SMBServer.cs +++ b/SMBLibrary/Server/SMBServer.cs @@ -360,6 +360,11 @@ namespace SMBLibrary.Server } } + public List GetSessionsInformation() + { + return m_connectionManager.GetSessionsInformation(); + } + private void Log(Severity severity, string message) { // To be thread-safe we must capture the delegate reference first diff --git a/SMBLibrary/Server/SessionInformation.cs b/SMBLibrary/Server/SessionInformation.cs new file mode 100644 index 0000000..1d40619 --- /dev/null +++ b/SMBLibrary/Server/SessionInformation.cs @@ -0,0 +1,32 @@ +/* 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 System.Net; + +namespace SMBLibrary.Server +{ + public class SessionInformation + { + public IPEndPoint ClientEndPoint; + public SMBDialect Dialect; + public string UserName; + public string MachineName; + public List OpenFiles; + public DateTime CreationDT; + + public SessionInformation(IPEndPoint clientEndPoint, SMBDialect dialect, string userName, string machineName, List openFiles, DateTime creationDT) + { + ClientEndPoint = clientEndPoint; + Dialect = dialect; + UserName = userName; + MachineName = machineName; + OpenFiles = openFiles; + CreationDT = creationDT; + } + } +}