Source code of Windows XP (NT5)
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.

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