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.

1857 lines
50 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: ctxtapi.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10-02-96 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "sslp.h"
  18. #include <ssl2msg.h>
  19. #include <ssl3msg.h>
  20. #include <ssl2prot.h>
  21. #include <sslcache.h>
  22. #include <lsasecpk.h>
  23. NTSTATUS NTAPI
  24. SslPurgeSessionCache(
  25. IN PLSA_CLIENT_REQUEST ClientRequest,
  26. IN PVOID ProtocolSubmitBuffer,
  27. IN PVOID ClientBufferBase,
  28. IN ULONG SubmitBufferSize,
  29. OUT PVOID *ProtocolReturnBuffer,
  30. OUT PULONG ReturnBufferLength,
  31. OUT PNTSTATUS ProtocolStatus);
  32. NTSTATUS NTAPI
  33. SslSessionCacheInfo(
  34. IN PLSA_CLIENT_REQUEST ClientRequest,
  35. IN PVOID ProtocolSubmitBuffer,
  36. IN PVOID ClientBufferBase,
  37. IN ULONG SubmitBufferSize,
  38. OUT PVOID *ProtocolReturnBuffer,
  39. OUT PULONG ReturnBufferLength,
  40. OUT PNTSTATUS ProtocolStatus);
  41. NTSTATUS NTAPI
  42. SslGetPerfmonInfo(
  43. IN PLSA_CLIENT_REQUEST ClientRequest,
  44. IN PVOID ProtocolSubmitBuffer,
  45. IN PVOID ClientBufferBase,
  46. IN ULONG SubmitBufferSize,
  47. OUT PVOID *ProtocolReturnBuffer,
  48. OUT PULONG ReturnBufferLength,
  49. OUT PNTSTATUS ProtocolStatus);
  50. SECURITY_STATUS SEC_ENTRY
  51. SpInitLsaModeContext(
  52. LSA_SEC_HANDLE dwCredHandle,
  53. LSA_SEC_HANDLE dwCtxtHandle,
  54. PSECURITY_STRING pszTargetName,
  55. ULONG fContextReq,
  56. ULONG TargetDataRep,
  57. PSecBufferDesc pInput,
  58. PLSA_SEC_HANDLE pdwNewContext,
  59. PSecBufferDesc pOutput,
  60. PULONG pfContextAttr,
  61. PTimeStamp ptsExpiry,
  62. PBYTE pfMapContext,
  63. PSecBuffer pContextData)
  64. {
  65. PSPContext pContext = NULL;
  66. PSPCredentialGroup pCred = NULL;
  67. SPBuffer CommOut;
  68. SPBuffer CommIn;
  69. PSecBuffer pInToken = NULL;
  70. PSecBuffer pOutToken = NULL;
  71. PSecBuffer pExtra = NULL;
  72. DWORD fAttr = ISC_RET_REPLAY_DETECT |
  73. ISC_RET_SEQUENCE_DETECT |
  74. ISC_RET_CONFIDENTIALITY |
  75. ISC_RET_STREAM;
  76. DWORD fSchContext = CONTEXT_FLAG_CLIENT;
  77. int i;
  78. SP_STATUS pctRet = PCT_ERR_OK;
  79. UNREFERENCED_PARAMETER(TargetDataRep);
  80. #if DBG
  81. DebugLog((DEB_TRACE, "SpInitLsaModeContext(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
  82. dwCredHandle, dwCtxtHandle, pszTargetName, fContextReq,
  83. pInput, pdwNewContext, pOutput, pfContextAttr, ptsExpiry, pfMapContext,
  84. pContextData));
  85. if(pszTargetName)
  86. {
  87. DebugLog((DEB_TRACE, "pszTargetName:<%ls>\n",pszTargetName->Buffer));
  88. }
  89. #endif
  90. /* These flags are never allowed */
  91. if (fContextReq & (ISC_REQ_DELEGATE | ISC_REQ_PROMPT_FOR_CREDS ))
  92. {
  93. TRACE_EXIT( SpInitLsaModeContext, SEC_E_UNSUPPORTED_FUNCTION );
  94. return SP_LOG_RESULT( SEC_E_UNSUPPORTED_FUNCTION );
  95. }
  96. /* Initialize output buffer locations */
  97. for (i = 0; i < (int)pOutput->cBuffers; i++ )
  98. {
  99. switch( ( pOutput->pBuffers[i].BufferType ) & (~(SECBUFFER_ATTRMASK)))
  100. {
  101. case SECBUFFER_EMPTY:
  102. if(!pOutToken && (fContextReq & ISC_REQ_ALLOCATE_MEMORY))
  103. pOutToken = &pOutput->pBuffers[i];
  104. break;
  105. case SECBUFFER_TOKEN:
  106. pOutToken = &pOutput->pBuffers[i];
  107. break;
  108. case SECBUFFER_DATA:
  109. case SECBUFFER_STREAM_HEADER:
  110. case SECBUFFER_STREAM_TRAILER:
  111. default:
  112. break;
  113. }
  114. }
  115. if ( pOutToken == NULL )
  116. {
  117. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INVALID_TOKEN );
  118. return SP_LOG_RESULT( SEC_E_INVALID_TOKEN );
  119. }
  120. pOutToken->BufferType = SECBUFFER_TOKEN;
  121. if ( fContextReq & ISC_REQ_ALLOCATE_MEMORY )
  122. {
  123. CommOut.pvBuffer = NULL;
  124. CommOut.cbBuffer = 0;
  125. CommOut.cbData = 0;
  126. fAttr |= ISC_RET_ALLOCATED_MEMORY;
  127. pOutToken->pvBuffer = NULL;
  128. pOutToken->cbBuffer = 0;
  129. }
  130. else
  131. {
  132. if ( pOutToken->pvBuffer == NULL )
  133. {
  134. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  135. return SP_LOG_RESULT( SEC_E_INSUFFICIENT_MEMORY );
  136. }
  137. }
  138. CommOut.pvBuffer = pOutToken->pvBuffer;
  139. CommOut.cbBuffer = pOutToken->cbBuffer;
  140. CommOut.cbData = 0;
  141. if ( fContextReq & (ISC_REQ_EXTENDED_ERROR) )
  142. {
  143. fAttr |= ISC_RET_EXTENDED_ERROR;
  144. fSchContext |= CONTEXT_FLAG_EXT_ERR;
  145. }
  146. if ( fContextReq & (ISC_REQ_CONNECTION) )
  147. {
  148. fAttr |= ISC_REQ_CONNECTION;
  149. fSchContext |= CONTEXT_FLAG_CONNECTION_MODE;
  150. }
  151. if ( fContextReq & (ISC_REQ_MUTUAL_AUTH) )
  152. {
  153. // Validate the server certificate.
  154. fAttr |= ISC_RET_MUTUAL_AUTH;
  155. fSchContext |= CONTEXT_FLAG_MUTUAL_AUTH;
  156. fSchContext &= ~CONTEXT_FLAG_MANUAL_CRED_VALIDATION;
  157. if ( fContextReq & (ISC_REQ_MANUAL_CRED_VALIDATION))
  158. {
  159. // These flags are mutually exclusive
  160. return SP_LOG_RESULT( SEC_E_UNSUPPORTED_FUNCTION );
  161. }
  162. }
  163. else
  164. {
  165. if ( fContextReq & (ISC_REQ_MANUAL_CRED_VALIDATION))
  166. {
  167. fAttr |= ISC_RET_MANUAL_CRED_VALIDATION;
  168. fSchContext |= CONTEXT_FLAG_MANUAL_CRED_VALIDATION;
  169. }
  170. // Turn off automatic credential validation if so specified in registry.
  171. if(g_fManualCredValidation)
  172. {
  173. fSchContext |= CONTEXT_FLAG_MANUAL_CRED_VALIDATION;
  174. }
  175. }
  176. if ( fContextReq & (ISC_REQ_USE_SUPPLIED_CREDS))
  177. {
  178. fAttr |= ISC_REQ_USE_SUPPLIED_CREDS;
  179. fSchContext |= CONTEXT_FLAG_NO_INCOMPLETE_CRED_MSG;
  180. }
  181. if( pfContextAttr )
  182. {
  183. *pfContextAttr = fAttr;
  184. }
  185. if ( dwCtxtHandle == 0 )
  186. {
  187. pContext = SPContextCreate( pszTargetName->Buffer );
  188. if(pContext == NULL)
  189. {
  190. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  191. return SP_LOG_RESULT( SEC_E_INSUFFICIENT_MEMORY );
  192. }
  193. pContext->Flags |= fSchContext;
  194. pCred = (PSPCredentialGroup) dwCredHandle ;
  195. if(pctRet == PCT_ERR_OK)
  196. {
  197. pctRet = SPContextSetCredentials(pContext, pCred);
  198. }
  199. if(pctRet != PCT_ERR_OK)
  200. {
  201. SPContextDelete(pContext);
  202. *pdwNewContext = 0;
  203. TRACE_EXIT( SpInitLsaModeContext, PctTranslateError( pctRet ));
  204. return SP_LOG_RESULT( PctTranslateError(pctRet) );
  205. }
  206. pctRet = pContext->InitiateHello( pContext, &CommOut, TRUE);
  207. if ( (CommOut.cbBuffer == 0) &&
  208. (pctRet == PCT_INT_BUFF_TOO_SMALL) )
  209. {
  210. SPContextDelete(pContext);
  211. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  212. return SP_LOG_RESULT( SEC_E_INSUFFICIENT_MEMORY );
  213. }
  214. if ( pctRet != PCT_ERR_OK )
  215. {
  216. SPContextDelete(pContext);
  217. *pdwNewContext = 0;
  218. TRACE_EXIT( SpInitLsaModeContext, PctTranslateError( pctRet) );
  219. return SP_LOG_RESULT( PctTranslateError(pctRet) );
  220. }
  221. if ( fContextReq & ISC_REQ_ALLOCATE_MEMORY )
  222. {
  223. //
  224. // Easy: The caller asked for us to allocate memory for them, so
  225. // let the LSA do it.
  226. //
  227. pOutToken->pvBuffer = CommOut.pvBuffer ;
  228. }
  229. else
  230. {
  231. //
  232. // The caller has a buffer that we're supposed to use. Make sure we
  233. // can fit.
  234. //
  235. if ( (ULONG) CommOut.cbBuffer <= pOutToken->cbBuffer )
  236. {
  237. RtlCopyMemory( pOutToken->pvBuffer,
  238. CommOut.pvBuffer,
  239. CommOut.cbBuffer );
  240. }
  241. else
  242. {
  243. DebugLog(( DEB_TRACE, "Supplied buffer is too small\n" ));
  244. SPContextDelete( pContext );
  245. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  246. return SP_LOG_RESULT( SEC_E_INSUFFICIENT_MEMORY );
  247. }
  248. }
  249. *pdwNewContext = (LSA_SEC_HANDLE) pContext ;
  250. pOutToken->pvBuffer = CommOut.pvBuffer;
  251. pOutToken->cbBuffer = CommOut.cbData;
  252. #if DBG
  253. DebugLog((
  254. DEB_TRACE,
  255. "Output: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  256. pOutToken->BufferType,
  257. pOutToken->pvBuffer,
  258. pOutToken->cbBuffer));
  259. if(pOutToken->pvBuffer)
  260. {
  261. DBG_HEX_STRING(DEB_BUFFERS, pOutToken->pvBuffer, pOutToken->cbBuffer);
  262. }
  263. #endif
  264. }
  265. else
  266. {
  267. /* Initialize input buffer locations */
  268. for (i = 0; i < (int)pInput->cBuffers; i++ )
  269. {
  270. switch( (pInput->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) )
  271. {
  272. case SECBUFFER_TOKEN:
  273. case SECBUFFER_TOKEN | SECBUFFER_READONLY:
  274. pInToken = &pInput->pBuffers[i];
  275. break;
  276. case SECBUFFER_EMPTY:
  277. if(!pInToken)
  278. {
  279. pInToken = &pInput->pBuffers[i];
  280. }
  281. else if(!pExtra)
  282. {
  283. pExtra = &pInput->pBuffers[i];
  284. }
  285. break;
  286. case SECBUFFER_DATA:
  287. case SECBUFFER_STREAM_HEADER:
  288. case SECBUFFER_STREAM_TRAILER:
  289. default:
  290. break;
  291. }
  292. }
  293. #if DBG
  294. if(pInToken)
  295. {
  296. DebugLog((
  297. DEB_TRACE,
  298. "Input: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  299. pInToken->BufferType,
  300. pInToken->pvBuffer,
  301. pInToken->cbBuffer));
  302. if(pInToken->pvBuffer)
  303. {
  304. DBG_HEX_STRING(DEB_BUFFERS, pInToken->pvBuffer, pInToken->cbBuffer);
  305. }
  306. }
  307. if(pExtra)
  308. {
  309. DebugLog((
  310. DEB_TRACE,
  311. "Extra: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  312. pExtra->BufferType,
  313. pExtra->pvBuffer,
  314. pExtra->cbBuffer));
  315. }
  316. #endif
  317. if(pInToken == NULL)
  318. {
  319. CommIn.pvBuffer = NULL;
  320. CommIn.cbBuffer = 0;
  321. CommIn.cbData = 0;
  322. }
  323. else
  324. {
  325. CommIn.pvBuffer = pInToken->pvBuffer;
  326. CommIn.cbBuffer = pInToken->cbBuffer;
  327. CommIn.cbData = pInToken->cbBuffer;
  328. }
  329. pContext = (PSPContext) dwCtxtHandle ;
  330. if ( dwCredHandle )
  331. {
  332. pCred = (PSPCredentialGroup) dwCredHandle ;
  333. }
  334. if( pContext == NULL || pCred == NULL )
  335. {
  336. TRACE_EXIT( SpInitLsaModeContext, SEC_E_INVALID_HANDLE );
  337. return SP_LOG_RESULT( SEC_E_INVALID_HANDLE );
  338. }
  339. pContext->Flags |= fSchContext;
  340. pctRet = SPContextSetCredentials(pContext, pCred);
  341. if(pctRet == PCT_ERR_OK)
  342. {
  343. pctRet = pContext->ProtocolHandler( pContext,
  344. &CommIn,
  345. &CommOut);
  346. }
  347. if(pctRet == PCT_INT_INCOMPLETE_MSG)
  348. {
  349. if(pExtra)
  350. {
  351. pExtra->BufferType = SECBUFFER_MISSING | SECBUFFER_UNMAPPED ;
  352. pExtra->cbBuffer = CommIn.cbData - pInToken->cbBuffer;
  353. pExtra->pvBuffer = NULL ;
  354. }
  355. }
  356. else
  357. {
  358. pOutToken->pvBuffer = CommOut.pvBuffer;
  359. pOutToken->cbBuffer = CommOut.cbData;
  360. }
  361. if(pctRet == PCT_INT_BUFF_TOO_SMALL)
  362. {
  363. pOutToken->BufferType |= SECBUFFER_UNMAPPED;
  364. }
  365. #if DBG
  366. if(pOutToken)
  367. {
  368. DebugLog((
  369. DEB_TRACE,
  370. "Output: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  371. pOutToken->BufferType,
  372. pOutToken->pvBuffer,
  373. pOutToken->cbBuffer));
  374. if(pOutToken->pvBuffer)
  375. {
  376. DBG_HEX_STRING(DEB_BUFFERS, pOutToken->pvBuffer, pOutToken->cbBuffer);
  377. }
  378. }
  379. if(pExtra)
  380. {
  381. DebugLog((
  382. DEB_TRACE,
  383. "Extra: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  384. pExtra->BufferType,
  385. pExtra->pvBuffer,
  386. pExtra->cbBuffer));
  387. }
  388. #endif
  389. if(!SP_FATAL(pctRet))
  390. {
  391. *pdwNewContext = dwCtxtHandle ;
  392. }
  393. if(PCT_ERR_OK != pctRet)
  394. {
  395. TRACE_EXIT( SpInitLsaModeContext, PctTranslateError( pctRet ));
  396. return SP_LOG_RESULT( PctTranslateError(pctRet) );
  397. }
  398. if(pInToken)
  399. {
  400. if(CommIn.cbData < pInToken->cbBuffer && pExtra)
  401. {
  402. pExtra->BufferType = SECBUFFER_EXTRA | SECBUFFER_UNMAPPED ;
  403. pExtra->cbBuffer = pInToken->cbBuffer - CommIn.cbData;
  404. pExtra->pvBuffer = NULL ;
  405. }
  406. }
  407. }
  408. if ( (pContext->State == SP_STATE_CONNECTED) &&
  409. ( (pContext->Flags & CONTEXT_FLAG_MAPPED) == 0 ) )
  410. {
  411. //
  412. // Need to map the context back down to the user process. It
  413. // doesn't get any scarier than this:
  414. //
  415. *pfMapContext = TRUE ;
  416. DebugOut(( DEB_TRACE, "Mapping context to usermode\n" ));
  417. pctRet = SPContextSerialize(pContext,
  418. SslRelocateToken,
  419. (PUCHAR *) &pContextData->pvBuffer,
  420. &pContextData->cbBuffer,
  421. TRUE);
  422. if(PCT_ERR_OK != pctRet)
  423. {
  424. return SP_LOG_RESULT( PctTranslateError(pctRet) );
  425. }
  426. pContext->Flags |= CONTEXT_FLAG_MAPPED ;
  427. LogHandshakeInfoEvent(pContext->RipeZombie->fProtocol,
  428. pContext->pCipherInfo,
  429. pContext->pHashInfo,
  430. pContext->pKeyExchInfo,
  431. pContext->RipeZombie->dwExchStrength);
  432. }
  433. if(ptsExpiry != NULL)
  434. {
  435. if(pContext->RipeZombie->pRemoteCert != NULL)
  436. {
  437. ptsExpiry->QuadPart = *((LONGLONG *)&pContext->RipeZombie->pRemoteCert->pCertInfo->NotAfter);
  438. }
  439. else
  440. {
  441. ptsExpiry->QuadPart = MAXTIMEQUADPART;
  442. }
  443. }
  444. if(pContext->State == SP_STATE_CONNECTED ||
  445. pContext->State == SP_STATE_SHUTDOWN)
  446. {
  447. return SEC_E_OK;
  448. }
  449. else
  450. {
  451. return SEC_I_CONTINUE_NEEDED;
  452. }
  453. }
  454. SECURITY_STATUS SEC_ENTRY
  455. SpMoveContextToUser( ULONG dwCtxtHandle,
  456. PSecBuffer pContextBuffer)
  457. {
  458. UNREFERENCED_PARAMETER(dwCtxtHandle);
  459. UNREFERENCED_PARAMETER(pContextBuffer);
  460. return(SEC_E_UNSUPPORTED_FUNCTION);
  461. }
  462. SECURITY_STATUS
  463. SEC_ENTRY
  464. SpDeleteContext(
  465. LSA_SEC_HANDLE dwCtxtHandle)
  466. {
  467. PSPContext pContext ;
  468. DebugLog((DEB_TRACE, "SpDeleteContext(0x%x)\n", dwCtxtHandle));
  469. pContext = (PSPContext) dwCtxtHandle ;
  470. SPContextDelete( pContext );
  471. return( SEC_E_OK );
  472. }
  473. SECURITY_STATUS
  474. SEC_ENTRY
  475. SpApplyControlToken(
  476. LSA_SEC_HANDLE dwCtxtHandle,
  477. PSecBufferDesc pInput)
  478. {
  479. PSPContext pContext;
  480. PSecBuffer Buffer ;
  481. DebugLog((DEB_TRACE, "SpApplyControlToken(0x%x, 0x%x)\n", dwCtxtHandle, pInput));
  482. pContext = (PSPContext) dwCtxtHandle ;
  483. if ( pInput->cBuffers != 1 )
  484. {
  485. return SP_LOG_RESULT(SEC_E_INVALID_TOKEN);
  486. }
  487. Buffer = pInput->pBuffers ;
  488. if(Buffer->cbBuffer < sizeof(DWORD))
  489. {
  490. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  491. }
  492. switch(*(DWORD *)Buffer->pvBuffer)
  493. {
  494. case SCHANNEL_RENEGOTIATE:
  495. {
  496. PDWORD RedoData;
  497. DebugLog((DEB_TRACE, "SCHANNEL_RENEGOTIATE\n"));
  498. if(Buffer->cbBuffer < sizeof(DWORD) * 2)
  499. {
  500. return SP_LOG_RESULT(SEC_E_INVALID_TOKEN);
  501. }
  502. RedoData = (DWORD *)Buffer->pvBuffer;
  503. pContext->State = RedoData[1];
  504. pContext->Flags &= ~CONTEXT_FLAG_MAPPED;
  505. return SEC_E_OK;
  506. }
  507. case SCHANNEL_SHUTDOWN:
  508. DebugLog((DEB_TRACE, "SCHANNEL_SHUTDOWN\n"));
  509. pContext->State = SP_STATE_SHUTDOWN_PENDING;
  510. return SEC_E_OK;
  511. case SCHANNEL_ALERT:
  512. {
  513. SCHANNEL_ALERT_TOKEN *pAlertToken;
  514. DebugLog((DEB_TRACE, "SCHANNEL_TLS1_ALERT\n"));
  515. if(Buffer->cbBuffer < sizeof(SCHANNEL_ALERT_TOKEN))
  516. {
  517. return SP_LOG_RESULT(SEC_E_INVALID_TOKEN);
  518. }
  519. pAlertToken = (SCHANNEL_ALERT_TOKEN *)Buffer->pvBuffer;
  520. // Alerts are only supported in SSL3 and TLS1
  521. if(!(pContext->RipeZombie->fProtocol & SP_PROT_SSL3TLS1))
  522. {
  523. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  524. }
  525. // Reality check alert values.
  526. if(pAlertToken->dwAlertType >= 0x100 ||
  527. pAlertToken->dwAlertNumber >= 0x100)
  528. {
  529. return SP_LOG_RESULT(SEC_E_INVALID_TOKEN);
  530. }
  531. SetTls1Alert(pContext,
  532. (BYTE)pAlertToken->dwAlertType,
  533. (BYTE)pAlertToken->dwAlertNumber);
  534. #if DBG
  535. DebugLog((DEB_TRACE,
  536. "AlertLevel:0x%x, AlertNumber:0x%x\n",
  537. pAlertToken->dwAlertType,
  538. pAlertToken->dwAlertNumber));
  539. #endif
  540. return SEC_E_OK;
  541. }
  542. case SCHANNEL_SESSION:
  543. {
  544. SCHANNEL_SESSION_TOKEN *pSessionToken;
  545. SECURITY_STATUS Status = SEC_E_UNSUPPORTED_FUNCTION;
  546. DebugLog((DEB_TRACE, "SCHANNEL_SESSION\n"));
  547. if(pContext->RipeZombie == NULL)
  548. {
  549. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  550. }
  551. if(Buffer->cbBuffer < sizeof(SCHANNEL_SESSION_TOKEN))
  552. {
  553. return SP_LOG_RESULT(SEC_E_INVALID_TOKEN);
  554. }
  555. pSessionToken = (SCHANNEL_SESSION_TOKEN *)Buffer->pvBuffer;
  556. if(pSessionToken->dwFlags & SSL_SESSION_DISABLE_RECONNECTS)
  557. {
  558. // Disable reconnects
  559. pContext->RipeZombie->ZombieJuju = FALSE;
  560. Status = SEC_E_OK;
  561. }
  562. if(pSessionToken->dwFlags & SSL_SESSION_ENABLE_RECONNECTS)
  563. {
  564. // Enable reconnects
  565. if(pContext->RipeZombie->DeferredJuju)
  566. {
  567. pContext->RipeZombie->ZombieJuju = TRUE;
  568. pContext->RipeZombie->DeferredJuju = FALSE;
  569. Status = SEC_E_OK;
  570. }
  571. }
  572. return Status;
  573. }
  574. default:
  575. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  576. }
  577. }
  578. VOID
  579. SEC_ENTRY
  580. SpLogonTerminated(PLUID pLogonId)
  581. {
  582. UNREFERENCED_PARAMETER(pLogonId);
  583. return;
  584. }
  585. SECURITY_STATUS SEC_ENTRY
  586. SpAcceptLsaModeContext(
  587. LSA_SEC_HANDLE dwCredHandle,
  588. LSA_SEC_HANDLE dwCtxtHandle,
  589. PSecBufferDesc pInput,
  590. ULONG fContextReq,
  591. ULONG TargetDataRep,
  592. PLSA_SEC_HANDLE pdwNewContext,
  593. PSecBufferDesc pOutput,
  594. PULONG pfContextAttr,
  595. PTimeStamp ptsExpiry,
  596. PBYTE pfMapContext,
  597. PSecBuffer pContextData)
  598. {
  599. PSPContext pContext = NULL;
  600. PSPCredentialGroup pCred = NULL;
  601. SPBuffer CommOut;
  602. SPBuffer CommIn;
  603. PSecBuffer pInToken = NULL;
  604. PSecBuffer pOutToken = NULL;
  605. PSecBuffer pExtra = NULL;
  606. unsigned long fAttr = ASC_RET_REPLAY_DETECT |
  607. ASC_RET_SEQUENCE_DETECT |
  608. ASC_RET_CONFIDENTIALITY |
  609. ASC_RET_STREAM;
  610. DWORD fSchContext = 0;
  611. int i;
  612. SP_STATUS pctRet = PCT_ERR_OK;
  613. UNREFERENCED_PARAMETER(TargetDataRep);
  614. TRACE_ENTER( SpAcceptLsaModeContext );
  615. #if DBG
  616. DebugLog((DEB_TRACE, "SpAcceptLsaModeContext(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
  617. dwCredHandle, dwCtxtHandle, pInput, fContextReq, pdwNewContext,
  618. pOutput, pfContextAttr, ptsExpiry, pfMapContext, pContextData));
  619. #endif
  620. // This flag is never allowed
  621. if(fContextReq & ASC_REQ_DELEGATE)
  622. {
  623. TRACE_EXIT( SpAcceptLsaModeContext, SEC_E_UNSUPPORTED_FUNCTION );
  624. return SEC_E_UNSUPPORTED_FUNCTION;
  625. }
  626. if ( fContextReq & ASC_REQ_MUTUAL_AUTH )
  627. {
  628. fSchContext |= CONTEXT_FLAG_MUTUAL_AUTH;
  629. }
  630. if ( fContextReq & ASC_REQ_NO_TOKEN )
  631. {
  632. fSchContext |= CONTEXT_FLAG_NO_CERT_MAPPING;
  633. fAttr |= ASC_RET_NO_TOKEN;
  634. }
  635. /* Initialize input buffer locations */
  636. for (i = 0; i < (int)pInput->cBuffers; i++ )
  637. {
  638. switch( pInput->pBuffers[i].BufferType & (~(SECBUFFER_ATTRMASK)) )
  639. {
  640. case SECBUFFER_TOKEN:
  641. pInToken = &pInput->pBuffers[i];
  642. break;
  643. case SECBUFFER_EMPTY:
  644. if(!pInToken)
  645. {
  646. pInToken = &pInput->pBuffers[i];
  647. }
  648. else if(!pExtra)
  649. {
  650. pExtra = &pInput->pBuffers[i];
  651. }
  652. break;
  653. case SECBUFFER_DATA:
  654. case SECBUFFER_STREAM_HEADER:
  655. case SECBUFFER_STREAM_TRAILER:
  656. default:
  657. break;
  658. }
  659. }
  660. #if DBG
  661. if(pInToken)
  662. {
  663. DebugLog((
  664. DEB_TRACE,
  665. "Input: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  666. pInToken->BufferType,
  667. pInToken->pvBuffer,
  668. pInToken->cbBuffer));
  669. if(pInToken->pvBuffer)
  670. {
  671. DBG_HEX_STRING(DEB_BUFFERS, pInToken->pvBuffer, pInToken->cbBuffer);
  672. }
  673. }
  674. if(pExtra)
  675. {
  676. DebugLog((
  677. DEB_TRACE,
  678. "Extra: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  679. pExtra->BufferType,
  680. pExtra->pvBuffer,
  681. pExtra->cbBuffer));
  682. }
  683. #endif
  684. /* Initialize output buffer locations */
  685. for (i = 0; i < (int) pOutput->cBuffers; i++ )
  686. {
  687. switch( pOutput->pBuffers[i].BufferType & (~(SECBUFFER_ATTRMASK)) )
  688. {
  689. case SECBUFFER_EMPTY:
  690. if(!pOutToken && (fContextReq & ASC_REQ_ALLOCATE_MEMORY))
  691. pOutToken = &pOutput->pBuffers[i];
  692. break;
  693. case SECBUFFER_TOKEN:
  694. pOutToken = &pOutput->pBuffers[i];
  695. break;
  696. case SECBUFFER_DATA:
  697. case SECBUFFER_STREAM_HEADER:
  698. case SECBUFFER_STREAM_TRAILER:
  699. default:
  700. break;
  701. }
  702. }
  703. if(pOutToken == NULL)
  704. {
  705. TRACE_EXIT( SpAcceptLsaModeContext, SEC_E_INVALID_TOKEN );
  706. return SEC_E_INVALID_TOKEN;
  707. }
  708. if ( !pExtra )
  709. {
  710. DebugOut(( DEB_TRACE, " Warning - no Empty security buffer\n"));
  711. }
  712. pOutToken->BufferType = SECBUFFER_TOKEN;
  713. if(pInToken && pInToken->BufferType == SECBUFFER_TOKEN)
  714. {
  715. CommIn.pvBuffer = pInToken->pvBuffer;
  716. CommIn.cbBuffer = pInToken->cbBuffer;
  717. CommIn.cbData = pInToken->cbBuffer;
  718. }
  719. else
  720. {
  721. CommIn.pvBuffer = NULL;
  722. CommIn.cbBuffer = 0;
  723. CommIn.cbData = 0;
  724. }
  725. if (fContextReq & ASC_REQ_ALLOCATE_MEMORY)
  726. {
  727. fAttr |= ASC_RET_ALLOCATED_MEMORY;
  728. pOutToken->pvBuffer = NULL;
  729. pOutToken->cbBuffer = 0;
  730. }
  731. CommOut.pvBuffer = pOutToken->pvBuffer;
  732. CommOut.cbBuffer = pOutToken->cbBuffer;
  733. CommOut.cbData = 0;
  734. if (fContextReq & (ASC_REQ_EXTENDED_ERROR))
  735. {
  736. fAttr |= ASC_RET_EXTENDED_ERROR;
  737. fSchContext |= CONTEXT_FLAG_EXT_ERR;
  738. }
  739. if ( fContextReq & (ASC_REQ_CONNECTION) )
  740. {
  741. fAttr |= ASC_RET_CONNECTION;
  742. fSchContext |= CONTEXT_FLAG_CONNECTION_MODE;
  743. }
  744. if (pfContextAttr)
  745. {
  746. *pfContextAttr = fAttr;
  747. }
  748. if ( dwCtxtHandle == 0 )
  749. {
  750. pContext = SPContextCreate(NULL);
  751. if (pContext == NULL)
  752. {
  753. TRACE_EXIT( SpAcceptLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  754. return SEC_E_INSUFFICIENT_MEMORY;
  755. }
  756. }
  757. else
  758. {
  759. pContext = (PSPContext) dwCtxtHandle ;
  760. }
  761. if ( dwCredHandle == 0 )
  762. {
  763. pCred = NULL ;
  764. }
  765. else
  766. {
  767. pCred = (PSPCredentialGroup) dwCredHandle ;
  768. }
  769. if ( (pContext == NULL) || (pCred == NULL) )
  770. {
  771. if ( dwCtxtHandle == 0 )
  772. {
  773. SPContextDelete( pContext );
  774. }
  775. TRACE_EXIT( SpAcceptLsaModeContext, SEC_E_INVALID_HANDLE );
  776. return( SEC_E_INVALID_HANDLE );
  777. }
  778. pctRet = SPContextSetCredentials(pContext, pCred);
  779. pContext->Flags |= fSchContext;
  780. if ( pctRet == PCT_ERR_OK )
  781. {
  782. pctRet = pContext->ProtocolHandler( pContext, &CommIn, &CommOut);
  783. }
  784. if ( dwCtxtHandle == 0 )
  785. {
  786. if ( pctRet != PCT_ERR_OK )
  787. {
  788. SPContextDelete( pContext );
  789. }
  790. else
  791. {
  792. *pdwNewContext = (LSA_SEC_HANDLE) pContext ;
  793. }
  794. }
  795. else
  796. {
  797. *pdwNewContext = (LSA_SEC_HANDLE) pContext ;
  798. }
  799. if (CommOut.cbData == 0 && pctRet == PCT_INT_BUFF_TOO_SMALL)
  800. {
  801. TRACE_EXIT( SpAcceptLsaModeContext, SEC_E_INSUFFICIENT_MEMORY );
  802. return SEC_E_INSUFFICIENT_MEMORY;
  803. }
  804. if (pctRet == PCT_INT_INCOMPLETE_MSG)
  805. {
  806. if(pExtra)
  807. {
  808. pExtra->BufferType = SECBUFFER_MISSING | SECBUFFER_UNMAPPED ;
  809. pExtra->cbBuffer = CommIn.cbData - pInToken->cbBuffer;
  810. pExtra->pvBuffer = NULL ;
  811. DebugOut(( DEB_TRACE, "Incomplete message, needs %d more bytes\n",
  812. pExtra->cbBuffer ));
  813. }
  814. else
  815. {
  816. DebugOut(( DEB_TRACE, "No Empty buffer for returning missing info!\n" ));
  817. }
  818. }
  819. else
  820. {
  821. pOutToken->pvBuffer = CommOut.pvBuffer;
  822. pOutToken->cbBuffer = CommOut.cbData;
  823. }
  824. if(pctRet == PCT_INT_BUFF_TOO_SMALL)
  825. {
  826. pOutToken->BufferType |= SECBUFFER_UNMAPPED;
  827. }
  828. if(pOutToken->cbBuffer == 0)
  829. {
  830. // Don't return an output token if the output buffer is
  831. // empty. Also, make sure that the extended error flag is
  832. // turned off.
  833. pOutToken->BufferType = SECBUFFER_EMPTY;
  834. if(pfContextAttr)
  835. {
  836. *pfContextAttr &= ~ASC_RET_EXTENDED_ERROR;
  837. }
  838. }
  839. if (PCT_ERR_OK != pctRet)
  840. {
  841. TRACE_EXIT( SpAcceptLsaModeContext, PctTranslateError( pctRet ) );
  842. return PctTranslateError(pctRet);
  843. }
  844. if(pInToken)
  845. {
  846. if (CommIn.cbData < pInToken->cbBuffer && pExtra)
  847. {
  848. pExtra->BufferType = SECBUFFER_EXTRA | SECBUFFER_UNMAPPED ;
  849. pExtra->cbBuffer = pInToken->cbBuffer - CommIn.cbData;
  850. pExtra->pvBuffer = NULL ;
  851. DebugOut(( DEB_TRACE, "Extra data, needs to be mapped back: %d\n", pExtra->cbBuffer ));
  852. }
  853. }
  854. if ( (pContext->State == SP_STATE_CONNECTED) &&
  855. ( (pContext->Flags & CONTEXT_FLAG_MAPPED) == 0 ) )
  856. {
  857. //
  858. // Need to map the context back down to the user process. It
  859. // doesn't get any scarier than this:
  860. //
  861. *pfMapContext = TRUE ;
  862. DebugOut(( DEB_TRACE, "Mapping context to usermode\n" ));
  863. pctRet = SPContextSerialize(pContext,
  864. SslRelocateToken,
  865. (PUCHAR *) &pContextData->pvBuffer,
  866. &pContextData->cbBuffer,
  867. TRUE);
  868. if (PCT_ERR_OK != pctRet)
  869. {
  870. TRACE_EXIT( SpAcceptLsaModeContext, PctTranslateError( pctRet ) );
  871. return PctTranslateError(pctRet);
  872. }
  873. pContext->Flags |= CONTEXT_FLAG_MAPPED ;
  874. LogHandshakeInfoEvent(pContext->RipeZombie->fProtocol,
  875. pContext->pCipherInfo,
  876. pContext->pHashInfo,
  877. pContext->pKeyExchInfo,
  878. pContext->RipeZombie->dwExchStrength);
  879. }
  880. #if DBG
  881. if(pOutToken)
  882. {
  883. DebugLog((
  884. DEB_TRACE,
  885. "Output: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  886. pOutToken->BufferType,
  887. pOutToken->pvBuffer,
  888. pOutToken->cbBuffer));
  889. if(pOutToken->pvBuffer)
  890. {
  891. DBG_HEX_STRING(DEB_BUFFERS, pOutToken->pvBuffer, pOutToken->cbBuffer);
  892. }
  893. }
  894. if(pExtra)
  895. {
  896. DebugLog((
  897. DEB_TRACE,
  898. "Extra: type:0x%8.8x, pv:0x%8.8x, cb:0x%x\n",
  899. pExtra->BufferType,
  900. pExtra->pvBuffer,
  901. pExtra->cbBuffer));
  902. }
  903. if(pContext->State == SP_STATE_CONNECTED)
  904. {
  905. DebugLog((DEB_TRACE, "Server handshake complete\n"));
  906. }
  907. #endif
  908. if(ptsExpiry != NULL)
  909. {
  910. if(pContext->RipeZombie->pRemoteCert != NULL)
  911. {
  912. ptsExpiry->QuadPart = *((LONGLONG *)&pContext->RipeZombie->pRemoteCert->pCertInfo->NotAfter);
  913. }
  914. else
  915. {
  916. ptsExpiry->QuadPart = MAXTIMEQUADPART;
  917. }
  918. }
  919. if(pContext->State == SP_STATE_CONNECTED &&
  920. pContext->RipeZombie->hLocator)
  921. {
  922. // Certificate mapping was successful.
  923. *pfContextAttr |= ASC_RET_MUTUAL_AUTH;
  924. }
  925. if(pContext->State == SP_STATE_CONNECTED ||
  926. pContext->State == SP_STATE_SHUTDOWN)
  927. {
  928. return SEC_E_OK;
  929. }
  930. else
  931. {
  932. return SEC_I_CONTINUE_NEEDED;
  933. }
  934. }
  935. NTSTATUS
  936. SpCallPackage(
  937. IN PLSA_CLIENT_REQUEST ClientRequest,
  938. IN PVOID ProtocolSubmitBuffer,
  939. IN PVOID ClientBufferBase,
  940. IN ULONG SubmitBufferLength,
  941. OUT PVOID *ProtocolReturnBuffer,
  942. OUT PULONG ReturnBufferLength,
  943. OUT PNTSTATUS ProtocolStatus
  944. )
  945. {
  946. PULONG Request ;
  947. if((ProtocolSubmitBuffer == NULL) || (SubmitBufferLength < sizeof(ULONG)))
  948. {
  949. return STATUS_INVALID_PARAMETER;
  950. }
  951. if(!SchannelInit(FALSE))
  952. {
  953. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  954. }
  955. Request = (PULONG) ProtocolSubmitBuffer ;
  956. if ( *Request == SSL_LOOKUP_CERT_MESSAGE )
  957. {
  958. return SslDoClientRequest(
  959. ClientRequest,
  960. ProtocolSubmitBuffer,
  961. ClientBufferBase,
  962. SubmitBufferLength,
  963. ProtocolReturnBuffer,
  964. ReturnBufferLength,
  965. ProtocolStatus );
  966. }
  967. else if ( *Request == SSL_LOOKUP_EXTERNAL_CERT_MESSAGE &&
  968. ClientBufferBase == ProtocolSubmitBuffer)
  969. {
  970. // This function is only allowed to be called from the
  971. // lsass.exe process.
  972. return SslMapExternalCredential(
  973. ClientRequest,
  974. ProtocolSubmitBuffer,
  975. ClientBufferBase,
  976. SubmitBufferLength,
  977. ProtocolReturnBuffer,
  978. ReturnBufferLength,
  979. ProtocolStatus );
  980. }
  981. else if( *Request == SSL_CACHE_INFO_MESSAGE )
  982. {
  983. return SslSessionCacheInfo(
  984. ClientRequest,
  985. ProtocolSubmitBuffer,
  986. ClientBufferBase,
  987. SubmitBufferLength,
  988. ProtocolReturnBuffer,
  989. ReturnBufferLength,
  990. ProtocolStatus );
  991. }
  992. else if( *Request == SSL_PURGE_CACHE_MESSAGE )
  993. {
  994. return SslPurgeSessionCache(
  995. ClientRequest,
  996. ProtocolSubmitBuffer,
  997. ClientBufferBase,
  998. SubmitBufferLength,
  999. ProtocolReturnBuffer,
  1000. ReturnBufferLength,
  1001. ProtocolStatus );
  1002. }
  1003. return( SEC_E_UNSUPPORTED_FUNCTION );
  1004. }
  1005. NTSTATUS
  1006. SpCallPackageUntrusted(
  1007. IN PLSA_CLIENT_REQUEST ClientRequest,
  1008. IN PVOID ProtocolSubmitBuffer,
  1009. IN PVOID ClientBufferBase,
  1010. IN ULONG SubmitBufferLength,
  1011. OUT PVOID *ProtocolReturnBuffer,
  1012. OUT PULONG ReturnBufferLength,
  1013. OUT PNTSTATUS ProtocolStatus
  1014. )
  1015. {
  1016. ULONG MessageType;
  1017. //
  1018. // Get the messsage type from the protocol submit buffer.
  1019. //
  1020. if((ProtocolSubmitBuffer == NULL) || (SubmitBufferLength < sizeof(ULONG)))
  1021. {
  1022. return STATUS_INVALID_PARAMETER;
  1023. }
  1024. MessageType = *((ULONG *)(ProtocolSubmitBuffer));
  1025. if(!SchannelInit(FALSE))
  1026. {
  1027. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1028. }
  1029. //
  1030. // Allow the dispatch routines to only set the return buffer information
  1031. // on success conditions.
  1032. //
  1033. *ProtocolReturnBuffer = NULL;
  1034. *ReturnBufferLength = 0;
  1035. //
  1036. // Process message as appropriate.
  1037. //
  1038. switch(MessageType)
  1039. {
  1040. case SSL_PURGE_CACHE_MESSAGE:
  1041. return SslPurgeSessionCache(
  1042. ClientRequest,
  1043. ProtocolSubmitBuffer,
  1044. ClientBufferBase,
  1045. SubmitBufferLength,
  1046. ProtocolReturnBuffer,
  1047. ReturnBufferLength,
  1048. ProtocolStatus);
  1049. case SSL_CACHE_INFO_MESSAGE:
  1050. return SslSessionCacheInfo(
  1051. ClientRequest,
  1052. ProtocolSubmitBuffer,
  1053. ClientBufferBase,
  1054. SubmitBufferLength,
  1055. ProtocolReturnBuffer,
  1056. ReturnBufferLength,
  1057. ProtocolStatus);
  1058. case SSL_PERFMON_INFO_MESSAGE:
  1059. return SslGetPerfmonInfo(
  1060. ClientRequest,
  1061. ProtocolSubmitBuffer,
  1062. ClientBufferBase,
  1063. SubmitBufferLength,
  1064. ProtocolReturnBuffer,
  1065. ReturnBufferLength,
  1066. ProtocolStatus);
  1067. default:
  1068. return( SEC_E_UNSUPPORTED_FUNCTION );
  1069. }
  1070. }
  1071. NTSTATUS NTAPI
  1072. SslPurgeSessionCache(
  1073. IN PLSA_CLIENT_REQUEST ClientRequest,
  1074. IN PVOID ProtocolSubmitBuffer,
  1075. IN PVOID ClientBufferBase,
  1076. IN ULONG SubmitBufferSize,
  1077. OUT PVOID *ProtocolReturnBuffer,
  1078. OUT PULONG ReturnBufferLength,
  1079. OUT PNTSTATUS ProtocolStatus)
  1080. {
  1081. NTSTATUS Status;
  1082. SECPKG_CALL_INFO CallInfo;
  1083. SECPKG_CLIENT_INFO ClientInfo;
  1084. PLUID LogonId;
  1085. SSL_PURGE_SESSION_CACHE_REQUEST PurgeRequest;
  1086. PSSL_PURGE_SESSION_CACHE_REQUEST pPurgeRequest;
  1087. UNREFERENCED_PARAMETER(ClientRequest);
  1088. //
  1089. // Verify the request.
  1090. //
  1091. DebugLog((DEB_TRACE, "Purging session cache\n"));
  1092. if(!LsaTable->GetCallInfo(&CallInfo))
  1093. {
  1094. Status = STATUS_INTERNAL_ERROR;
  1095. goto Cleanup;
  1096. }
  1097. if(CallInfo.Attributes & SECPKG_CALL_WOWCLIENT)
  1098. {
  1099. PSSL_PURGE_SESSION_CACHE_REQUEST_WOW64 pRequest;
  1100. if(SubmitBufferSize < sizeof(SSL_PURGE_SESSION_CACHE_REQUEST_WOW64))
  1101. {
  1102. Status = STATUS_INVALID_PARAMETER;
  1103. goto Cleanup;
  1104. }
  1105. pRequest = (PSSL_PURGE_SESSION_CACHE_REQUEST_WOW64)ProtocolSubmitBuffer;
  1106. memset(&PurgeRequest, 0, sizeof(PurgeRequest));
  1107. PurgeRequest.MessageType = pRequest->MessageType;
  1108. PurgeRequest.LogonId = pRequest->LogonId;
  1109. PurgeRequest.Flags = pRequest->Flags;
  1110. PurgeRequest.ServerName.Length = pRequest->ServerName.Length;
  1111. PurgeRequest.ServerName.MaximumLength = pRequest->ServerName.MaximumLength;
  1112. PurgeRequest.ServerName.Buffer = (PVOID) UlongToPtr(pRequest->ServerName.Buffer);
  1113. pPurgeRequest = &PurgeRequest;
  1114. }
  1115. else
  1116. {
  1117. if (SubmitBufferSize < sizeof(SSL_PURGE_SESSION_CACHE_REQUEST))
  1118. {
  1119. Status = STATUS_INVALID_PARAMETER;
  1120. goto Cleanup;
  1121. }
  1122. pPurgeRequest = (PSSL_PURGE_SESSION_CACHE_REQUEST) ProtocolSubmitBuffer;
  1123. }
  1124. //
  1125. // Normalize the strings
  1126. //
  1127. NULL_RELOCATE_ONE(&pPurgeRequest->ServerName);
  1128. //
  1129. // Find the callers logon id & TCB status
  1130. //
  1131. Status = LsaTable->GetClientInfo(&ClientInfo);
  1132. if (!NT_SUCCESS(Status))
  1133. {
  1134. goto Cleanup;
  1135. }
  1136. //
  1137. // Verify the caller has TCB privilege if they want to purge someone
  1138. // else's session cache entries.
  1139. //
  1140. if(!RtlIsZeroLuid(&pPurgeRequest->LogonId) ||
  1141. (pPurgeRequest->Flags & SSL_PURGE_CLIENT_ALL_ENTRIES) ||
  1142. (pPurgeRequest->Flags & SSL_PURGE_SERVER_ALL_ENTRIES))
  1143. {
  1144. if(!ClientInfo.HasTcbPrivilege)
  1145. {
  1146. Status = STATUS_PRIVILEGE_NOT_HELD;
  1147. goto Cleanup;
  1148. }
  1149. }
  1150. //
  1151. // If the caller did not provide a logon id, use the caller's logon id.
  1152. //
  1153. if(RtlIsZeroLuid(&pPurgeRequest->LogonId))
  1154. {
  1155. LogonId = &ClientInfo.LogonId;
  1156. }
  1157. else
  1158. {
  1159. LogonId = &pPurgeRequest->LogonId;
  1160. }
  1161. //
  1162. // Purge the requested cache entries.
  1163. //
  1164. Status = SPCachePurgeEntries(LogonId,
  1165. ClientInfo.ProcessID,
  1166. pPurgeRequest->ServerName.Buffer,
  1167. pPurgeRequest->Flags);
  1168. *ProtocolReturnBuffer = NULL;
  1169. *ReturnBufferLength = 0;
  1170. Cleanup:
  1171. *ProtocolStatus = Status;
  1172. return(STATUS_SUCCESS);
  1173. }
  1174. NTSTATUS NTAPI
  1175. SslSessionCacheInfo(
  1176. IN PLSA_CLIENT_REQUEST ClientRequest,
  1177. IN PVOID ProtocolSubmitBuffer,
  1178. IN PVOID ClientBufferBase,
  1179. IN ULONG SubmitBufferSize,
  1180. OUT PVOID *ProtocolReturnBuffer,
  1181. OUT PULONG ReturnBufferLength,
  1182. OUT PNTSTATUS ProtocolStatus)
  1183. {
  1184. NTSTATUS Status;
  1185. SECPKG_CALL_INFO CallInfo;
  1186. SECPKG_CLIENT_INFO ClientInfo;
  1187. PLUID LogonId;
  1188. SSL_SESSION_CACHE_INFO_REQUEST InfoRequest;
  1189. PSSL_SESSION_CACHE_INFO_REQUEST pInfoRequest;
  1190. PSSL_SESSION_CACHE_INFO_RESPONSE pInfoResponse = NULL;
  1191. DWORD cbInfoResponse;
  1192. PVOID pvClient;
  1193. UNREFERENCED_PARAMETER(ClientRequest);
  1194. *ProtocolReturnBuffer = NULL;
  1195. *ReturnBufferLength = 0;
  1196. //
  1197. // Verify the request.
  1198. //
  1199. if(!LsaTable->GetCallInfo(&CallInfo))
  1200. {
  1201. Status = STATUS_INTERNAL_ERROR;
  1202. goto Cleanup;
  1203. }
  1204. if(CallInfo.Attributes & SECPKG_CALL_WOWCLIENT)
  1205. {
  1206. PSSL_SESSION_CACHE_INFO_REQUEST_WOW64 pRequest;
  1207. if(SubmitBufferSize < sizeof(SSL_SESSION_CACHE_INFO_REQUEST_WOW64))
  1208. {
  1209. Status = STATUS_INVALID_PARAMETER;
  1210. goto Cleanup;
  1211. }
  1212. pRequest = (PSSL_SESSION_CACHE_INFO_REQUEST_WOW64)ProtocolSubmitBuffer;
  1213. memset(&InfoRequest, 0, sizeof(InfoRequest));
  1214. InfoRequest.MessageType = pRequest->MessageType;
  1215. InfoRequest.LogonId = pRequest->LogonId;
  1216. InfoRequest.Flags = pRequest->Flags;
  1217. InfoRequest.ServerName.Length = pRequest->ServerName.Length;
  1218. InfoRequest.ServerName.MaximumLength = pRequest->ServerName.MaximumLength;
  1219. InfoRequest.ServerName.Buffer = (PVOID) UlongToPtr(pRequest->ServerName.Buffer);
  1220. pInfoRequest = &InfoRequest;
  1221. }
  1222. else
  1223. {
  1224. if (SubmitBufferSize < sizeof(SSL_SESSION_CACHE_INFO_REQUEST))
  1225. {
  1226. Status = STATUS_INVALID_PARAMETER;
  1227. goto Cleanup;
  1228. }
  1229. pInfoRequest = (PSSL_SESSION_CACHE_INFO_REQUEST)ProtocolSubmitBuffer;
  1230. }
  1231. //
  1232. // Normalize the strings
  1233. //
  1234. NULL_RELOCATE_ONE(&pInfoRequest->ServerName);
  1235. //
  1236. // Find the callers logon id & TCB status
  1237. //
  1238. Status = LsaTable->GetClientInfo(&ClientInfo);
  1239. if (!NT_SUCCESS(Status))
  1240. {
  1241. goto Cleanup;
  1242. }
  1243. //
  1244. // If the caller did not provide a logon id, use the caller's logon id.
  1245. //
  1246. if ( RtlIsZeroLuid( &pInfoRequest->LogonId ) )
  1247. {
  1248. LogonId = &ClientInfo.LogonId;
  1249. }
  1250. else
  1251. {
  1252. //
  1253. // Verify the caller has TCB privilege if they want access to someone
  1254. // else's session cache.
  1255. //
  1256. if (!ClientInfo.HasTcbPrivilege)
  1257. {
  1258. Status = STATUS_PRIVILEGE_NOT_HELD;
  1259. goto Cleanup;
  1260. }
  1261. LogonId = &pInfoRequest->LogonId;
  1262. }
  1263. pInfoResponse = SPExternalAlloc(sizeof(SSL_SESSION_CACHE_INFO_RESPONSE));
  1264. if(pInfoResponse == NULL)
  1265. {
  1266. Status = STATUS_NO_MEMORY;
  1267. goto Cleanup;
  1268. }
  1269. Status = SPCacheGetInfo(LogonId,
  1270. pInfoRequest->ServerName.Buffer,
  1271. pInfoRequest->Flags,
  1272. pInfoResponse);
  1273. if(!NT_SUCCESS(Status))
  1274. {
  1275. goto Cleanup;
  1276. }
  1277. cbInfoResponse = sizeof(SSL_SESSION_CACHE_INFO_RESPONSE);
  1278. //
  1279. // Copy the response data to the client process.
  1280. //
  1281. Status = LsaTable->AllocateClientBuffer(
  1282. NULL,
  1283. cbInfoResponse,
  1284. &pvClient);
  1285. if(!NT_SUCCESS(Status))
  1286. {
  1287. goto Cleanup;
  1288. }
  1289. Status = LsaTable->CopyToClientBuffer(
  1290. NULL,
  1291. cbInfoResponse,
  1292. pvClient,
  1293. pInfoResponse);
  1294. if(!NT_SUCCESS(Status))
  1295. {
  1296. LsaTable->FreeClientBuffer(NULL, pvClient);
  1297. goto Cleanup;
  1298. }
  1299. *ProtocolReturnBuffer = pvClient;
  1300. *ReturnBufferLength = cbInfoResponse;
  1301. Cleanup:
  1302. if(pInfoResponse)
  1303. {
  1304. SPExternalFree(pInfoResponse);
  1305. }
  1306. *ProtocolStatus = Status;
  1307. return(STATUS_SUCCESS);
  1308. }
  1309. NTSTATUS NTAPI
  1310. SslGetPerfmonInfo(
  1311. IN PLSA_CLIENT_REQUEST ClientRequest,
  1312. IN PVOID ProtocolSubmitBuffer,
  1313. IN PVOID ClientBufferBase,
  1314. IN ULONG SubmitBufferSize,
  1315. OUT PVOID *ProtocolReturnBuffer,
  1316. OUT PULONG ReturnBufferLength,
  1317. OUT PNTSTATUS ProtocolStatus)
  1318. {
  1319. NTSTATUS Status;
  1320. PSSL_PERFMON_INFO_REQUEST pInfoRequest;
  1321. PSSL_PERFMON_INFO_RESPONSE pInfoResponse = NULL;
  1322. DWORD cbInfoResponse;
  1323. PVOID pvClient;
  1324. UNREFERENCED_PARAMETER(ClientRequest);
  1325. UNREFERENCED_PARAMETER(ClientBufferBase);
  1326. *ProtocolReturnBuffer = NULL;
  1327. *ReturnBufferLength = 0;
  1328. //
  1329. // Verify the request.
  1330. //
  1331. if (SubmitBufferSize < sizeof(SSL_PERFMON_INFO_REQUEST))
  1332. {
  1333. Status = STATUS_INVALID_PARAMETER;
  1334. goto Cleanup;
  1335. }
  1336. pInfoRequest = (PSSL_PERFMON_INFO_REQUEST)ProtocolSubmitBuffer;
  1337. pInfoResponse = SPExternalAlloc(sizeof(SSL_PERFMON_INFO_RESPONSE));
  1338. if(pInfoResponse == NULL)
  1339. {
  1340. Status = STATUS_NO_MEMORY;
  1341. goto Cleanup;
  1342. }
  1343. Status = SPCacheGetPerfmonInfo(pInfoRequest->Flags,
  1344. pInfoResponse);
  1345. if(!NT_SUCCESS(Status))
  1346. {
  1347. goto Cleanup;
  1348. }
  1349. cbInfoResponse = sizeof(SSL_PERFMON_INFO_RESPONSE);
  1350. //
  1351. // Copy the response data to the client process.
  1352. //
  1353. Status = LsaTable->AllocateClientBuffer(
  1354. NULL,
  1355. cbInfoResponse,
  1356. &pvClient);
  1357. if(!NT_SUCCESS(Status))
  1358. {
  1359. goto Cleanup;
  1360. }
  1361. Status = LsaTable->CopyToClientBuffer(
  1362. NULL,
  1363. cbInfoResponse,
  1364. pvClient,
  1365. pInfoResponse);
  1366. if(!NT_SUCCESS(Status))
  1367. {
  1368. LsaTable->FreeClientBuffer(NULL, pvClient);
  1369. goto Cleanup;
  1370. }
  1371. *ProtocolReturnBuffer = pvClient;
  1372. *ReturnBufferLength = cbInfoResponse;
  1373. Cleanup:
  1374. if(pInfoResponse)
  1375. {
  1376. SPExternalFree(pInfoResponse);
  1377. }
  1378. *ProtocolStatus = Status;
  1379. return(STATUS_SUCCESS);
  1380. }
  1381. NTSTATUS
  1382. SpCallPackagePassthrough(
  1383. IN PLSA_CLIENT_REQUEST ClientRequest,
  1384. IN PVOID ProtocolSubmitBuffer,
  1385. IN PVOID ClientBufferBase,
  1386. IN ULONG SubmitBufferLength,
  1387. OUT PVOID *ProtocolReturnBuffer,
  1388. OUT PULONG ReturnBufferLength,
  1389. OUT PNTSTATUS ProtocolStatus
  1390. )
  1391. {
  1392. //
  1393. // NOTE: if other sensitive request types are to be supported,
  1394. // this routine should filter them out prior to calling SpCallPackage.
  1395. // This is required because untrusted code has the opportunity for
  1396. // making genericpassthrough requests.
  1397. //
  1398. PULONG Request ;
  1399. if((ProtocolSubmitBuffer == NULL) || (SubmitBufferLength < sizeof(ULONG)))
  1400. {
  1401. return STATUS_INVALID_PARAMETER;
  1402. }
  1403. Request = (PULONG) ProtocolSubmitBuffer ;
  1404. if ( *Request != SSL_LOOKUP_CERT_MESSAGE )
  1405. return SEC_E_UNSUPPORTED_FUNCTION;
  1406. return SpCallPackage(
  1407. ClientRequest,
  1408. ProtocolSubmitBuffer,
  1409. ClientBufferBase,
  1410. SubmitBufferLength,
  1411. ProtocolReturnBuffer,
  1412. ReturnBufferLength,
  1413. ProtocolStatus
  1414. );
  1415. }
  1416. SECURITY_STATUS SEC_ENTRY
  1417. SpShutdown(void)
  1418. {
  1419. return(SEC_E_UNSUPPORTED_FUNCTION);
  1420. }
  1421. SECURITY_STATUS SEC_ENTRY
  1422. SpSystemLogon( PSECURITY_STRING pName,
  1423. DWORD cbKey,
  1424. PBYTE pbKey,
  1425. DWORD * pdwHandle,
  1426. PTimeStamp ptsExpiry)
  1427. {
  1428. UNREFERENCED_PARAMETER(pName);
  1429. UNREFERENCED_PARAMETER(cbKey);
  1430. UNREFERENCED_PARAMETER(pbKey);
  1431. UNREFERENCED_PARAMETER(pdwHandle);
  1432. UNREFERENCED_PARAMETER(ptsExpiry);
  1433. return(SEC_E_UNSUPPORTED_FUNCTION);
  1434. }
  1435. SECURITY_STATUS SEC_ENTRY
  1436. SpGetUserInfo( PLUID pLogonId,
  1437. ULONG fFlags,
  1438. PSecurityUserData * ppUserInfo)
  1439. {
  1440. UNREFERENCED_PARAMETER(pLogonId);
  1441. UNREFERENCED_PARAMETER(fFlags);
  1442. UNREFERENCED_PARAMETER(ppUserInfo);
  1443. return(SEC_E_UNSUPPORTED_FUNCTION);
  1444. }
  1445. //+---------------------------------------------------------------------------
  1446. //
  1447. // Function: SpSaveCredentials
  1448. //
  1449. // Synopsis: Store credentials (not supported)
  1450. //
  1451. // Arguments: [dwCredHandle] --
  1452. // [CredType] --
  1453. // [pCredentials] --
  1454. //
  1455. //
  1456. // History: 7-26-96 RichardW Created
  1457. //
  1458. // Notes:
  1459. //
  1460. //----------------------------------------------------------------------------
  1461. SECURITY_STATUS SEC_ENTRY
  1462. SpSaveCredentials( LSA_SEC_HANDLE dwCredHandle,
  1463. PSecBuffer pCredentials)
  1464. {
  1465. UNREFERENCED_PARAMETER(dwCredHandle);
  1466. UNREFERENCED_PARAMETER(pCredentials);
  1467. return(SEC_E_UNSUPPORTED_FUNCTION);
  1468. }
  1469. //+---------------------------------------------------------------------------
  1470. //
  1471. // Function: SpGetCredentials
  1472. //
  1473. // Synopsis: Get Credentials (not supported)
  1474. //
  1475. // Arguments: [dwCredHandle] --
  1476. // [CredType] --
  1477. // [pCredentials] --
  1478. //
  1479. // History: 7-26-96 RichardW Created
  1480. //
  1481. // Notes:
  1482. //
  1483. //----------------------------------------------------------------------------
  1484. SECURITY_STATUS SEC_ENTRY
  1485. SpGetCredentials( LSA_SEC_HANDLE dwCredHandle,
  1486. PSecBuffer pCredentials)
  1487. {
  1488. UNREFERENCED_PARAMETER(dwCredHandle);
  1489. UNREFERENCED_PARAMETER(pCredentials);
  1490. return(SEC_E_UNSUPPORTED_FUNCTION);
  1491. }
  1492. //+---------------------------------------------------------------------------
  1493. //
  1494. // Function: SpDeleteCredentials
  1495. //
  1496. // Synopsis: Delete stored creds (not supported)
  1497. //
  1498. // Arguments: [dwCredHandle] --
  1499. // [CredType] --
  1500. // [pKey] --
  1501. //
  1502. // History: 7-26-96 RichardW Created
  1503. //
  1504. // Notes:
  1505. //
  1506. //----------------------------------------------------------------------------
  1507. SECURITY_STATUS SEC_ENTRY
  1508. SpDeleteCredentials(LSA_SEC_HANDLE dwCredHandle,
  1509. PSecBuffer pKey)
  1510. {
  1511. UNREFERENCED_PARAMETER(dwCredHandle);
  1512. UNREFERENCED_PARAMETER(pKey);
  1513. return(SEC_E_UNSUPPORTED_FUNCTION);
  1514. }