SMB1Session.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using Utilities;
  11. namespace SMBLibrary.Server
  12. {
  13. internal class SMB1Session
  14. {
  15. private const int MaxSearches = 2048; // Windows servers initialize Server.MaxSearches to 2048.
  16. private SMB1ConnectionState m_connection;
  17. private ushort m_userID;
  18. private byte[] m_sessionKey;
  19. private SecurityContext m_securityContext;
  20. private DateTime m_creationDT;
  21. // Key is TID
  22. private Dictionary<ushort, ISMBShare> m_connectedTrees = new Dictionary<ushort, ISMBShare>();
  23. // Key is FID
  24. private Dictionary<ushort, OpenFileObject> m_openFiles = new Dictionary<ushort, OpenFileObject>();
  25. // Key is search handle a.k.a. Search ID
  26. private Dictionary<ushort, OpenSearch> m_openSearches = new Dictionary<ushort, OpenSearch>();
  27. private ushort m_nextSearchHandle = 1;
  28. public SMB1Session(SMB1ConnectionState connection, ushort userID, string userName, string machineName, byte[] sessionKey, object accessToken)
  29. {
  30. m_connection = connection;
  31. m_userID = userID;
  32. m_sessionKey = sessionKey;
  33. m_securityContext = new SecurityContext(userName, machineName, connection.ClientEndPoint, connection.AuthenticationContext, accessToken);
  34. m_creationDT = DateTime.UtcNow;
  35. }
  36. public ushort? AddConnectedTree(ISMBShare share)
  37. {
  38. lock (m_connection)
  39. {
  40. ushort? treeID = m_connection.AllocateTreeID();
  41. if (treeID.HasValue)
  42. {
  43. m_connectedTrees.Add(treeID.Value, share);
  44. }
  45. return treeID;
  46. }
  47. }
  48. public ISMBShare GetConnectedTree(ushort treeID)
  49. {
  50. ISMBShare share;
  51. m_connectedTrees.TryGetValue(treeID, out share);
  52. return share;
  53. }
  54. public void DisconnectTree(ushort treeID)
  55. {
  56. ISMBShare share;
  57. m_connectedTrees.TryGetValue(treeID, out share);
  58. if (share != null)
  59. {
  60. lock (m_connection)
  61. {
  62. List<ushort> fileIDList = new List<ushort>(m_openFiles.Keys);
  63. foreach (ushort fileID in fileIDList)
  64. {
  65. OpenFileObject openFile = m_openFiles[fileID];
  66. if (openFile.TreeID == treeID)
  67. {
  68. share.FileStore.CloseFile(openFile.Handle);
  69. m_openFiles.Remove(fileID);
  70. }
  71. }
  72. m_connectedTrees.Remove(treeID);
  73. }
  74. }
  75. }
  76. public bool IsTreeConnected(ushort treeID)
  77. {
  78. return m_connectedTrees.ContainsKey(treeID);
  79. }
  80. /// <param name="relativePath">The path relative to the share</param>
  81. /// <returns>FileID</returns>
  82. public ushort? AddOpenFile(ushort treeID, string shareName, string relativePath, object handle, FileAccess fileAccess)
  83. {
  84. lock (m_connection)
  85. {
  86. ushort? fileID = m_connection.AllocateFileID();
  87. if (fileID.HasValue)
  88. {
  89. m_openFiles.Add(fileID.Value, new OpenFileObject(treeID, shareName, relativePath, handle, fileAccess));
  90. }
  91. return fileID;
  92. }
  93. }
  94. public OpenFileObject GetOpenFileObject(ushort fileID)
  95. {
  96. OpenFileObject openFile;
  97. m_openFiles.TryGetValue(fileID, out openFile);
  98. return openFile;
  99. }
  100. public void RemoveOpenFile(ushort fileID)
  101. {
  102. lock (m_connection)
  103. {
  104. m_openFiles.Remove(fileID);
  105. }
  106. }
  107. public List<OpenFileInformation> GetOpenFilesInformation()
  108. {
  109. List<OpenFileInformation> result = new List<OpenFileInformation>();
  110. lock (m_connection)
  111. {
  112. foreach (OpenFileObject openFile in m_openFiles.Values)
  113. {
  114. result.Add(new OpenFileInformation(openFile.ShareName, openFile.Path, openFile.FileAccess, openFile.OpenedDT));
  115. }
  116. }
  117. return result;
  118. }
  119. private ushort? AllocateSearchHandle()
  120. {
  121. for (ushort offset = 0; offset < UInt16.MaxValue; offset++)
  122. {
  123. ushort searchHandle = (ushort)(m_nextSearchHandle + offset);
  124. if (searchHandle == 0 || searchHandle == 0xFFFF)
  125. {
  126. continue;
  127. }
  128. if (!m_openSearches.ContainsKey(searchHandle))
  129. {
  130. m_nextSearchHandle = (ushort)(searchHandle + 1);
  131. return searchHandle;
  132. }
  133. }
  134. return null;
  135. }
  136. public ushort? AddOpenSearch(List<QueryDirectoryFileInformation> entries, int enumerationLocation)
  137. {
  138. ushort? searchHandle = AllocateSearchHandle();
  139. if (searchHandle.HasValue)
  140. {
  141. OpenSearch openSearch = new OpenSearch(entries, enumerationLocation);
  142. m_openSearches.Add(searchHandle.Value, openSearch);
  143. }
  144. return searchHandle;
  145. }
  146. public OpenSearch GetOpenSearch(ushort searchHandle)
  147. {
  148. OpenSearch openSearch;
  149. m_openSearches.TryGetValue(searchHandle, out openSearch);
  150. return openSearch;
  151. }
  152. public void RemoveOpenSearch(ushort searchHandle)
  153. {
  154. m_openSearches.Remove(searchHandle);
  155. }
  156. /// <summary>
  157. /// Free all resources used by this session
  158. /// </summary>
  159. public void Close()
  160. {
  161. List<ushort> treeIDList = new List<ushort>(m_connectedTrees.Keys);
  162. foreach (ushort treeID in treeIDList)
  163. {
  164. DisconnectTree(treeID);
  165. }
  166. }
  167. public ushort UserID
  168. {
  169. get
  170. {
  171. return m_userID;
  172. }
  173. }
  174. public SecurityContext SecurityContext
  175. {
  176. get
  177. {
  178. return m_securityContext;
  179. }
  180. }
  181. public string UserName
  182. {
  183. get
  184. {
  185. return m_securityContext.UserName;
  186. }
  187. }
  188. public string MachineName
  189. {
  190. get
  191. {
  192. return m_securityContext.MachineName;
  193. }
  194. }
  195. public DateTime CreationDT
  196. {
  197. get
  198. {
  199. return m_creationDT;
  200. }
  201. }
  202. }
  203. }