SMB1Session.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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.Now;
  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">Should include the path relative to the share</param>
  81. /// <returns>FileID</returns>
  82. public ushort? AddOpenFile(ushort treeID, string shareName, string relativePath)
  83. {
  84. return AddOpenFile(treeID, shareName, relativePath, null);
  85. }
  86. public ushort? AddOpenFile(ushort treeID, string shareName, string relativePath, object handle)
  87. {
  88. lock (m_connection)
  89. {
  90. ushort? fileID = m_connection.AllocateFileID();
  91. if (fileID.HasValue)
  92. {
  93. m_openFiles.Add(fileID.Value, new OpenFileObject(treeID, shareName, relativePath, handle));
  94. }
  95. return fileID;
  96. }
  97. }
  98. public OpenFileObject GetOpenFileObject(ushort fileID)
  99. {
  100. OpenFileObject openFile;
  101. m_openFiles.TryGetValue(fileID, out openFile);
  102. return openFile;
  103. }
  104. public void RemoveOpenFile(ushort fileID)
  105. {
  106. lock (m_connection)
  107. {
  108. m_openFiles.Remove(fileID);
  109. }
  110. }
  111. public List<string> ListOpenFiles()
  112. {
  113. List<string> result = new List<string>();
  114. lock (m_connection)
  115. {
  116. foreach (OpenFileObject openFile in m_openFiles.Values)
  117. {
  118. result.Add(@"\" + openFile.ShareName + openFile.Path);
  119. }
  120. }
  121. return result;
  122. }
  123. private ushort? AllocateSearchHandle()
  124. {
  125. for (ushort offset = 0; offset < UInt16.MaxValue; offset++)
  126. {
  127. ushort searchHandle = (ushort)(m_nextSearchHandle + offset);
  128. if (searchHandle == 0 || searchHandle == 0xFFFF)
  129. {
  130. continue;
  131. }
  132. if (!m_openSearches.ContainsKey(searchHandle))
  133. {
  134. m_nextSearchHandle = (ushort)(searchHandle + 1);
  135. return searchHandle;
  136. }
  137. }
  138. return null;
  139. }
  140. public ushort? AddOpenSearch(List<QueryDirectoryFileInformation> entries, int enumerationLocation)
  141. {
  142. ushort? searchHandle = AllocateSearchHandle();
  143. if (searchHandle.HasValue)
  144. {
  145. OpenSearch openSearch = new OpenSearch(entries, enumerationLocation);
  146. m_openSearches.Add(searchHandle.Value, openSearch);
  147. }
  148. return searchHandle;
  149. }
  150. public OpenSearch GetOpenSearch(ushort searchHandle)
  151. {
  152. OpenSearch openSearch;
  153. m_openSearches.TryGetValue(searchHandle, out openSearch);
  154. return openSearch;
  155. }
  156. public void RemoveOpenSearch(ushort searchHandle)
  157. {
  158. m_openSearches.Remove(searchHandle);
  159. }
  160. /// <summary>
  161. /// Free all resources used by this session
  162. /// </summary>
  163. public void Close()
  164. {
  165. List<ushort> treeIDList = new List<ushort>(m_connectedTrees.Keys);
  166. foreach (ushort treeID in treeIDList)
  167. {
  168. DisconnectTree(treeID);
  169. }
  170. }
  171. public ushort UserID
  172. {
  173. get
  174. {
  175. return m_userID;
  176. }
  177. }
  178. public SecurityContext SecurityContext
  179. {
  180. get
  181. {
  182. return m_securityContext;
  183. }
  184. }
  185. public string UserName
  186. {
  187. get
  188. {
  189. return m_securityContext.UserName;
  190. }
  191. }
  192. public string MachineName
  193. {
  194. get
  195. {
  196. return m_securityContext.MachineName;
  197. }
  198. }
  199. public DateTime CreationDT
  200. {
  201. get
  202. {
  203. return m_creationDT;
  204. }
  205. }
  206. }
  207. }