Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

621 lines
21 KiB

  1. /*++ BUILD Version: 0009 // Increment this if a change has global effects
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. 3connect.c
  5. Abstract:
  6. This module implements the tree connect SMB related routines. It also implements the
  7. three flavours of this routine ( user level and share level non NT server tree connect
  8. SMB construction and the tree connect SMB construction for SMB servers)
  9. Author:
  10. Balan Sethu Raman (SethuR) 06-Mar-95 Created
  11. --*/
  12. #include "precomp.h"
  13. #include "ntlsapi.h"
  14. #include <hmac.h>
  15. #include "vcsndrcv.h"
  16. #pragma hdrstop
  17. //
  18. // The order of these names should match the order in which the enumerated type
  19. // NET_ROOT_TYPE is defined. This facilitates easy access of share type names
  20. //
  21. VOID
  22. HashUserSessionKey(
  23. PCHAR SessionKey,
  24. PCHAR NewSessionKey,
  25. PSMBCE_SESSION Session
  26. );
  27. #ifdef ALLOC_PRAGMA
  28. #pragma alloc_text(PAGE, BuildCanonicalNetRootInformation)
  29. #pragma alloc_text(PAGE, CoreBuildTreeConnectSmb)
  30. #pragma alloc_text(PAGE, LmBuildTreeConnectSmb)
  31. #pragma alloc_text(PAGE, NtBuildTreeConnectSmb)
  32. #pragma alloc_text(PAGE, HashUserSessionKey)
  33. #endif
  34. PCHAR s_NetRootTypeName[] = {
  35. SHARE_TYPE_NAME_DISK,
  36. SHARE_TYPE_NAME_PIPE,
  37. SHARE_TYPE_NAME_COMM,
  38. SHARE_TYPE_NAME_PRINT,
  39. SHARE_TYPE_NAME_WILD
  40. };
  41. extern NTSTATUS
  42. BuildTreeConnectSecurityInformation(
  43. PSMB_EXCHANGE pExchange,
  44. PBYTE pBuffer,
  45. PBYTE pPasswordLength,
  46. PULONG pSmbBufferSize);
  47. NTSTATUS
  48. BuildCanonicalNetRootInformation(
  49. PUNICODE_STRING pServerName,
  50. PUNICODE_STRING pNetRootName,
  51. NET_ROOT_TYPE NetRootType,
  52. BOOLEAN fUnicode,
  53. BOOLEAN fPostPendServiceString,
  54. PBYTE *pBufferPointer,
  55. PULONG pBufferSize)
  56. /*++
  57. Routine Description:
  58. This routine builds the desired net root information for a tree connect SMB
  59. Arguments:
  60. pServerName - the server name
  61. pNetRootName - the net root name
  62. NetRootType - the net root type ( print,pipe,disk etc.,)
  63. fUnicode - TRUE if it is to be built in UNICODE
  64. pBufferPointer - the SMB buffer
  65. pBufferSize - the size on input. modified to the remaining size on output
  66. Return Value:
  67. RXSTATUS - The return status for the operation
  68. Notes:
  69. This routine relies upon the names being in certain formats to ensure that a
  70. valid UNC name can be formulated.
  71. 1) The RDBSS netroot names start with a \ and also include the server name as
  72. part of the net root name. This is mandated by the prefix table search requirements
  73. in RDBSS.
  74. --*/
  75. {
  76. NTSTATUS Status;
  77. PAGED_CODE();
  78. if (fUnicode) {
  79. // Align the buffer and adjust the size accordingly.
  80. PBYTE pBuffer = *pBufferPointer;
  81. RxDbgTrace( 0, (DEBUG_TRACE_CREATE),
  82. ("BuildCanonicalNetRootInformation -- tcstring as unicode %wZ\n", pNetRootName));
  83. pBuffer = ALIGN_SMB_WSTR(pBuffer);
  84. *pBufferSize -= (ULONG)(pBuffer - *pBufferPointer);
  85. *pBufferPointer = pBuffer;
  86. *((PWCHAR)*pBufferPointer) = L'\\';
  87. *pBufferPointer = *pBufferPointer + sizeof(WCHAR);
  88. *pBufferSize -= sizeof(WCHAR);
  89. #if ZZZ_MODE
  90. { UNICODE_STRING XlatedNetRootName;
  91. ULONG i,NumWhacksEncountered;
  92. WCHAR NameBuffer[64]; //this is debug stuff.....64 chars is plenty
  93. if (pNetRootName->Length <= sizeof(NameBuffer)) {
  94. XlatedNetRootName.Buffer = &NameBuffer[0];
  95. XlatedNetRootName.Length = pNetRootName->Length;
  96. RtlCopyMemory(XlatedNetRootName.Buffer,pNetRootName->Buffer,XlatedNetRootName.Length);
  97. for (i=NumWhacksEncountered=0;i<(XlatedNetRootName.Length/sizeof(WCHAR));i++) {
  98. WCHAR c = XlatedNetRootName.Buffer[i];
  99. if (c==L'\\') {
  100. NumWhacksEncountered++;
  101. if (NumWhacksEncountered>2) {
  102. XlatedNetRootName.Buffer[i] = L'z';
  103. }
  104. }
  105. }
  106. RxDbgTrace( 0, (DEBUG_TRACE_CREATE),
  107. ("BuildCanonicalNetRootInformationZZZMode -- xltcstring as unicode %wZ\n", &XlatedNetRootName));
  108. Status = SmbPutUnicodeStringAndUpcase(pBufferPointer,&XlatedNetRootName,pBufferSize);
  109. } else {
  110. Status = STATUS_INSUFFICIENT_RESOURCES;
  111. }
  112. }
  113. #else
  114. Status = SmbPutUnicodeStringAndUpcase(pBufferPointer,pNetRootName,pBufferSize);
  115. #endif //#if ZZZ_MODE
  116. } else {
  117. RxDbgTrace( 0, (DEBUG_TRACE_CREATE), ("BuildCanonicalNetRootInformation -- tcstring as ascii\n"));
  118. *((PCHAR)*pBufferPointer) = '\\';
  119. *pBufferPointer += sizeof(CHAR);
  120. *pBufferSize -= sizeof(CHAR);
  121. Status = SmbPutUnicodeStringAsOemStringAndUpcase(pBufferPointer,pNetRootName,pBufferSize);
  122. }
  123. if (NT_SUCCESS(Status) && fPostPendServiceString) {
  124. // Put the desired service name in ASCII ( always )
  125. ULONG Length = strlen(s_NetRootTypeName[NetRootType]) + 1;
  126. if (*pBufferSize >= Length) {
  127. RtlCopyMemory(*pBufferPointer,s_NetRootTypeName[NetRootType],Length);
  128. *pBufferSize -= Length;
  129. *pBufferPointer += Length;
  130. } else {
  131. Status = STATUS_BUFFER_OVERFLOW;
  132. }
  133. }
  134. return Status;
  135. }
  136. NTSTATUS
  137. CoreBuildTreeConnectSmb(
  138. PSMB_EXCHANGE pExchange,
  139. PGENERIC_ANDX pAndXSmb,
  140. PULONG pAndXSmbBufferSize)
  141. /*++
  142. Routine Description:
  143. This routine builds the tree connect SMB for a pre NT server
  144. Arguments:
  145. pExchange - the exchange instance
  146. pAndXSmb - the tree connect to be filled in...it's not really a andX
  147. pAndXSmbBufferSize - the SMB buffer size on input modified to remaining size on
  148. output.
  149. Return Value:
  150. RXSTATUS - The return status for the operation
  151. --*/
  152. {
  153. NTSTATUS Status;
  154. USHORT PasswordLength;
  155. PMRX_NET_ROOT NetRoot;
  156. UNICODE_STRING ServerName;
  157. UNICODE_STRING NetRootName;
  158. PSMBCE_SERVER pServer;
  159. PREQ_TREE_CONNECT pTreeConnect = (PREQ_TREE_CONNECT)pAndXSmb;
  160. ULONG OriginalBufferSize = *pAndXSmbBufferSize;
  161. BOOLEAN AppendServiceString;
  162. PBYTE pBuffer;
  163. PCHAR ServiceName;// = s_NetRootTypeName[NET_ROOT_WILD];
  164. ULONG Length;// = strlen(ServiceName) + 1;
  165. PAGED_CODE();
  166. NetRoot = pExchange->SmbCeContext.pVNetRoot->pNetRoot;
  167. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS),
  168. ("CoreBuildTreeConnectSmb buffer,remptr %08lx %08lx, nrt=%08lx\n",
  169. pAndXSmb,
  170. pAndXSmbBufferSize,
  171. NetRoot->Type));
  172. pServer = SmbCeGetExchangeServer(pExchange);
  173. SmbCeGetServerName(NetRoot->pSrvCall,&ServerName);
  174. SmbCeGetNetRootName(NetRoot,&NetRootName);
  175. ServiceName = s_NetRootTypeName[NetRoot->Type];
  176. Length = strlen(ServiceName) + 1;
  177. pTreeConnect->WordCount = 0;
  178. AppendServiceString = FALSE;
  179. pBuffer = (PBYTE)pTreeConnect + FIELD_OFFSET(REQ_TREE_CONNECT,Buffer);
  180. *pBuffer = 0x04;
  181. pBuffer++;
  182. *pAndXSmbBufferSize -= (FIELD_OFFSET(REQ_TREE_CONNECT,Buffer)+1);
  183. // put in the netname
  184. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb before bcnri buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  185. Status = BuildCanonicalNetRootInformation(
  186. &ServerName,
  187. &NetRootName,
  188. pExchange->SmbCeContext.pVNetRoot->pNetRoot->Type,
  189. (BOOLEAN)(pServer->Dialect >= NTLANMAN_DIALECT),
  190. AppendServiceString,
  191. &pBuffer,
  192. pAndXSmbBufferSize);
  193. if (!NT_SUCCESS(Status))
  194. return Status;
  195. // put in the password
  196. pBuffer = (PBYTE)pTreeConnect + OriginalBufferSize - *pAndXSmbBufferSize;
  197. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb88 buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  198. *pBuffer = 0x04;
  199. pBuffer++;
  200. *pAndXSmbBufferSize -= 1;
  201. if (pServer->SecurityMode == SECURITY_MODE_SHARE_LEVEL) {
  202. // The password information needs to be sent as part of the tree connect
  203. // SMB for share level servers.
  204. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb before btcsi buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  205. Status = BuildTreeConnectSecurityInformation(
  206. pExchange,
  207. pBuffer,
  208. (PBYTE)&PasswordLength,
  209. pAndXSmbBufferSize);
  210. }
  211. // string in the service string based on the netroot type
  212. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb beforesscopy buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  213. pBuffer = (PBYTE)pTreeConnect + OriginalBufferSize - *pAndXSmbBufferSize;
  214. *pBuffer = 0x04;
  215. pBuffer++;
  216. *pAndXSmbBufferSize -= 1;
  217. if (*pAndXSmbBufferSize >= Length) {
  218. RtlCopyMemory(pBuffer,ServiceName,Length);
  219. *pAndXSmbBufferSize -= Length;
  220. pBuffer += Length;
  221. } else {
  222. Status = STATUS_BUFFER_OVERFLOW;
  223. }
  224. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb beforesscopy buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  225. SmbPutUshort(
  226. &pTreeConnect->ByteCount,
  227. (USHORT)(OriginalBufferSize
  228. - *pAndXSmbBufferSize
  229. - FIELD_OFFSET(REQ_TREE_CONNECT,Buffer)
  230. )
  231. );
  232. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("CoreBuildTreeConnectSmb end buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  233. return Status;
  234. }
  235. NTSTATUS
  236. LmBuildTreeConnectSmb(
  237. PSMB_EXCHANGE pExchange,
  238. PGENERIC_ANDX pAndXSmb,
  239. PULONG pAndXSmbBufferSize)
  240. /*++
  241. Routine Description:
  242. This routine builds the tree connect SMB for a pre NT server
  243. Arguments:
  244. pExchange - the exchange instance
  245. pAndXSmb - the tree connect to be filled in...it's not really a andX
  246. pAndXSmbBufferSize - the SMB buffer size on input modified to remaining size on
  247. output.
  248. Return Value:
  249. RXSTATUS - The return status for the operation
  250. --*/
  251. {
  252. NTSTATUS Status;
  253. USHORT PasswordLength;
  254. PMRX_NET_ROOT NetRoot;
  255. UNICODE_STRING ServerName;
  256. UNICODE_STRING NetRootName;
  257. PSMBCE_SERVER pServer;
  258. PREQ_TREE_CONNECT_ANDX pTreeConnectAndX = (PREQ_TREE_CONNECT_ANDX)pAndXSmb;
  259. ULONG OriginalBufferSize = *pAndXSmbBufferSize;
  260. BOOLEAN AppendServiceString;
  261. PBYTE pBuffer;
  262. PCHAR ServiceName;
  263. ULONG Length;
  264. USHORT Flags = 0;
  265. PSMBCE_SESSION Session = &pExchange->SmbCeContext.pVNetRootContext->pSessionEntry->Session;
  266. PAGED_CODE();
  267. NetRoot = pExchange->SmbCeContext.pVNetRoot->pNetRoot;
  268. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS),
  269. ("LmBuildTreeConnectSmb buffer,remptr %08lx %08lx, nrt=%08lx\n",
  270. pAndXSmb,
  271. pAndXSmbBufferSize,
  272. NetRoot->Type));
  273. pServer = SmbCeGetExchangeServer(pExchange);
  274. SmbCeGetServerName(NetRoot->pSrvCall,&ServerName);
  275. SmbCeGetNetRootName(NetRoot,&NetRootName);
  276. ServiceName = s_NetRootTypeName[NetRoot->Type];
  277. Length = strlen(ServiceName) + 1;
  278. AppendServiceString = TRUE;
  279. pTreeConnectAndX->WordCount = 4;
  280. SmbPutUshort(&pTreeConnectAndX->AndXReserved,0);
  281. pBuffer = (PBYTE)pTreeConnectAndX + FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer);
  282. *pAndXSmbBufferSize -= (FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer)+1);
  283. if (pServer->SecurityMode == SECURITY_MODE_SHARE_LEVEL) {
  284. // for Share level security, signatures aren't used
  285. SmbPutUshort(
  286. &pTreeConnectAndX->Flags,Flags);
  287. // The password information needs to be sent as part of the tree connect
  288. // SMB for share level servers.
  289. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("LmBuildTreeConnectSmb before btcsi buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  290. Status = BuildTreeConnectSecurityInformation(
  291. pExchange,
  292. pBuffer,
  293. (PBYTE)&PasswordLength,
  294. pAndXSmbBufferSize);
  295. if (Status == RX_MAP_STATUS(SUCCESS)) {
  296. pBuffer += PasswordLength;
  297. SmbPutUshort(&pTreeConnectAndX->PasswordLength,PasswordLength);
  298. }
  299. } else {
  300. // Ask for a signature upgrade if possible
  301. if( Session->SessionKeyState == SmbSessionKeyAuthenticating )
  302. {
  303. Flags |= TREE_CONNECT_ANDX_EXTENDED_SIGNATURES;
  304. pExchange->SmbCeFlags |= SMBCE_EXCHANGE_EXTENDED_SIGNATURES;
  305. }
  306. SmbPutUshort(
  307. &pTreeConnectAndX->Flags,Flags);
  308. pBuffer = (PBYTE)pTreeConnectAndX + FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer);
  309. *pAndXSmbBufferSize -= FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer);
  310. // No password is required for user level security servers as part of tree
  311. // connect
  312. SmbPutUshort(&pTreeConnectAndX->PasswordLength,0x1);
  313. *((PCHAR)pBuffer) = '\0';
  314. pBuffer += sizeof(CHAR);
  315. *pAndXSmbBufferSize -= sizeof(CHAR);
  316. Status = STATUS_SUCCESS;
  317. }
  318. if (Status == STATUS_SUCCESS) {
  319. Status = BuildCanonicalNetRootInformation(
  320. &ServerName,
  321. &NetRootName,
  322. pExchange->SmbCeContext.pVNetRoot->pNetRoot->Type,
  323. (BOOLEAN)(pServer->Dialect >= NTLANMAN_DIALECT),
  324. AppendServiceString,
  325. &pBuffer,
  326. pAndXSmbBufferSize);
  327. //RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("LmBuildTreeConnectSmb beforesscopy buffer,rem %08lx %08lx\n",pBuffer,*pAndXSmbBufferSize));
  328. if (Status == RX_MAP_STATUS(SUCCESS)) {
  329. if( Flags & TREE_CONNECT_ANDX_EXTENDED_SIGNATURES )
  330. {
  331. HashUserSessionKey( Session->UserSessionKey, Session->UserNewSessionKey, Session );
  332. }
  333. SmbPutUshort(
  334. &pTreeConnectAndX->ByteCount,
  335. (USHORT)(OriginalBufferSize
  336. - *pAndXSmbBufferSize
  337. - FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer)
  338. )
  339. );
  340. }
  341. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS),
  342. ("LmBuildTreeConnectSmb end buffer,rem %08lx %08lx\n",
  343. pBuffer,
  344. *pAndXSmbBufferSize));
  345. }
  346. return Status;
  347. }
  348. NTSTATUS
  349. NtBuildTreeConnectSmb(
  350. PSMB_EXCHANGE pExchange,
  351. PGENERIC_ANDX pAndXSmb,
  352. PULONG pAndXSmbBufferSize)
  353. /*++
  354. Routine Description:
  355. This routine builds the tree connect SMB for a pre NT server
  356. Arguments:
  357. pExchange - the exchange instance
  358. pAndXSmb - the session setup to be filled in
  359. pAndXSmbBufferSize - the SMB buffer size on input modified to remaining size on
  360. output.
  361. Return Value:
  362. RXSTATUS - The return status for the operation
  363. --*/
  364. {
  365. NTSTATUS Status = RX_MAP_STATUS(SUCCESS); //bob: note cool macro syntax..........
  366. UNICODE_STRING ServerName;
  367. UNICODE_STRING NetRootName;
  368. PSMBCE_SERVER pServer;
  369. PREQ_TREE_CONNECT_ANDX pTreeConnect = (PREQ_TREE_CONNECT_ANDX)pAndXSmb;
  370. ULONG OriginalBufferSize = *pAndXSmbBufferSize;
  371. PBYTE pBuffer;
  372. ULONG BufferSize;
  373. USHORT Flags = 0;
  374. PSMBCE_SESSION Session = &pExchange->SmbCeContext.pVNetRootContext->pSessionEntry->Session;
  375. PAGED_CODE();
  376. BufferSize = OriginalBufferSize;
  377. pServer = SmbCeGetExchangeServer(pExchange);
  378. SmbCeGetServerName(pExchange->SmbCeContext.pVNetRoot->pNetRoot->pSrvCall,&ServerName);
  379. SmbCeGetNetRootName(pExchange->SmbCeContext.pVNetRoot->pNetRoot,&NetRootName);
  380. pTreeConnect->AndXCommand = 0xff; // No ANDX
  381. pTreeConnect->AndXReserved = 0x00; // Reserved (MBZ)
  382. SmbPutUshort(&pTreeConnect->AndXOffset, 0x0000); // No AndX as of yet.
  383. pTreeConnect->WordCount = 4;
  384. Flags |= TREE_CONNECT_ANDX_EXTENDED_RESPONSE;
  385. if( Session->SessionKeyState == SmbSessionKeyAuthenticating )
  386. {
  387. Flags |= TREE_CONNECT_ANDX_EXTENDED_SIGNATURES;
  388. pExchange->SmbCeFlags |= SMBCE_EXCHANGE_EXTENDED_SIGNATURES;
  389. }
  390. SmbPutUshort(
  391. &pTreeConnect->Flags,
  392. Flags); //do not specify disconnect
  393. pBuffer = (PBYTE)pTreeConnect + FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer);
  394. BufferSize -= FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer);
  395. if(pServer->SecurityMode == SECURITY_MODE_USER_LEVEL){
  396. // No password information is required as part of tree connect for user level
  397. // security servers. Therefore send a null string as the password.
  398. SmbPutUshort(&pTreeConnect->PasswordLength,0x1);
  399. *((PCHAR)pBuffer) = '\0';
  400. pBuffer += sizeof(CHAR);
  401. BufferSize -= sizeof(CHAR);
  402. } else {
  403. USHORT PasswordLength;
  404. //plug in the password for this server.....qweee
  405. Status = BuildTreeConnectSecurityInformation(
  406. pExchange,
  407. pBuffer,
  408. (PBYTE)&PasswordLength,
  409. &BufferSize);
  410. if (Status == RX_MAP_STATUS(SUCCESS)) {
  411. pBuffer += PasswordLength;
  412. SmbPutUshort(&pTreeConnect->PasswordLength,PasswordLength);
  413. }
  414. }
  415. if (NT_SUCCESS(Status)) {
  416. Status = BuildCanonicalNetRootInformation(
  417. &ServerName,
  418. &NetRootName,
  419. NET_ROOT_WILD, //let the server tell us! pNetRoot->Type,
  420. BooleanFlagOn(pServer->DialectFlags,DF_UNICODE),
  421. TRUE, //postpend the service string
  422. &pBuffer,
  423. &BufferSize);
  424. if( Flags & TREE_CONNECT_ANDX_EXTENDED_SIGNATURES )
  425. {
  426. HashUserSessionKey( Session->UserSessionKey, Session->UserNewSessionKey, Session );
  427. }
  428. }
  429. if (NT_SUCCESS(Status)) {
  430. SmbPutUshort(
  431. &pTreeConnect->ByteCount,
  432. (USHORT)(OriginalBufferSize -
  433. FIELD_OFFSET(REQ_TREE_CONNECT_ANDX,Buffer) -
  434. BufferSize));
  435. }
  436. // update the buffer size to reflect the amount consumed.
  437. *pAndXSmbBufferSize = BufferSize;
  438. return Status;
  439. }
  440. VOID
  441. HashUserSessionKey(
  442. PCHAR SessionKey,
  443. PCHAR NewSessionKey,
  444. PSMBCE_SESSION Session
  445. )
  446. {
  447. ULONG i;
  448. HMACMD5_CTX Ctx;
  449. static BYTE SSKeyHash[256] = {
  450. 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
  451. 0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07,
  452. 0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb, 0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4,
  453. 0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba, 0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e,
  454. 0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53, 0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73,
  455. 0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa, 0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f,
  456. 0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19, 0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18,
  457. 0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3, 0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8,
  458. 0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9, 0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51,
  459. 0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83, 0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91,
  460. 0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91, 0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8,
  461. 0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93, 0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d,
  462. 0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7, 0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a,
  463. 0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda, 0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8,
  464. 0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5, 0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32,
  465. 0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3, 0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1
  466. };
  467. ASSERT( MSV1_0_USER_SESSION_KEY_LENGTH == MD5DIGESTLEN );
  468. if( !FlagOn( Session->Flags, SMBCE_SESSION_FLAGS_SESSION_KEY_HASHED ) )
  469. {
  470. HMACMD5Init( &Ctx, SessionKey, MSV1_0_USER_SESSION_KEY_LENGTH );
  471. HMACMD5Update( &Ctx, SSKeyHash, 256 );
  472. HMACMD5Final( &Ctx, NewSessionKey );
  473. Session->Flags |= SMBCE_SESSION_FLAGS_SESSION_KEY_HASHED;
  474. }
  475. }