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.

609 lines
12 KiB

  1. #ifndef _SSPIPROVIDER_HXX_
  2. #define _SSPIPROVIDER_HXX_
  3. #define NTDIGEST_SP_NAME "wdigest"
  4. class SSPI_CONTEXT_STATE : public W3_MAIN_CONTEXT_STATE
  5. {
  6. public:
  7. SSPI_CONTEXT_STATE(
  8. const CHAR * pszCredentials
  9. )
  10. {
  11. DBG_ASSERT( pszCredentials != NULL );
  12. _pszCredentials = pszCredentials;
  13. }
  14. HRESULT
  15. SetPackage(
  16. const CHAR * pszPackage
  17. )
  18. {
  19. return _strPackage.Copy( pszPackage );
  20. }
  21. const CHAR *
  22. QueryPackage(
  23. VOID
  24. )
  25. {
  26. return _strPackage.QueryStr();
  27. }
  28. const CHAR *
  29. QueryCredentials(
  30. VOID
  31. ) const
  32. {
  33. return _pszCredentials;
  34. }
  35. STRA *
  36. QueryResponseHeader(
  37. VOID
  38. )
  39. {
  40. return &_strResponseHeader;
  41. }
  42. BOOL
  43. Cleanup(
  44. W3_MAIN_CONTEXT *
  45. )
  46. {
  47. delete this;
  48. return TRUE;
  49. }
  50. private:
  51. STRA _strPackage;
  52. const CHAR * _pszCredentials;
  53. STRA _strResponseHeader;
  54. };
  55. class SSPI_AUTH_PROVIDER : public AUTH_PROVIDER
  56. {
  57. public:
  58. SSPI_AUTH_PROVIDER( DWORD dwAuthType )
  59. {
  60. m_dwAuthType = dwAuthType;
  61. }
  62. virtual ~SSPI_AUTH_PROVIDER()
  63. {
  64. }
  65. virtual
  66. HRESULT
  67. Initialize(
  68. DWORD dwInternalId
  69. );
  70. virtual
  71. VOID
  72. Terminate(
  73. VOID
  74. );
  75. virtual
  76. HRESULT
  77. DoesApply(
  78. W3_MAIN_CONTEXT * pMainContext,
  79. BOOL * pfApplies
  80. );
  81. virtual
  82. HRESULT
  83. DoAuthenticate(
  84. W3_MAIN_CONTEXT * pMainContext,
  85. BOOL * pfFilterFinished
  86. );
  87. virtual
  88. HRESULT
  89. OnAccessDenied(
  90. W3_MAIN_CONTEXT * pMainContext
  91. );
  92. DWORD
  93. QueryAuthType(
  94. VOID
  95. )
  96. {
  97. return m_dwAuthType;
  98. }
  99. private:
  100. DWORD m_dwAuthType;
  101. };
  102. #define SSPI_CREDENTIAL_SIGNATURE CREATE_SIGNATURE( 'SCCS' )
  103. #define SSPI_CREDENTIAL_FREE_SIGNATURE CREATE_SIGNATURE( 'fCCS' )
  104. class SSPI_CREDENTIAL
  105. {
  106. public:
  107. SSPI_CREDENTIAL()
  108. : m_dwSignature ( SSPI_CREDENTIAL_SIGNATURE ),
  109. m_strPackageName( m_rgPackageName, sizeof( m_rgPackageName ) ),
  110. m_cbMaxTokenLen ( 0 ),
  111. m_fSupportsEncoding( FALSE )
  112. {
  113. m_ListEntry.Flink = NULL;
  114. SecInvalidateHandle( &m_hCredHandle );
  115. }
  116. ~SSPI_CREDENTIAL()
  117. {
  118. DBG_ASSERT( CheckSignature() );
  119. m_dwSignature = SSPI_CREDENTIAL_FREE_SIGNATURE;
  120. if ( SecIsValidHandle( &m_hCredHandle ) )
  121. {
  122. FreeCredentialsHandle( &m_hCredHandle );
  123. }
  124. }
  125. BOOL
  126. CheckSignature(
  127. VOID
  128. ) const
  129. {
  130. return m_dwSignature == SSPI_CREDENTIAL_SIGNATURE;
  131. }
  132. BOOL
  133. QuerySupportsEncoding(
  134. VOID
  135. ) const
  136. {
  137. return m_fSupportsEncoding;
  138. }
  139. STRA *
  140. QueryPackageName(
  141. VOID
  142. )
  143. {
  144. return &m_strPackageName;
  145. }
  146. DWORD
  147. QueryMaxTokenSize(
  148. VOID
  149. )
  150. {
  151. return m_cbMaxTokenLen;
  152. }
  153. CredHandle *
  154. QueryCredHandle(
  155. VOID
  156. )
  157. {
  158. return &m_hCredHandle;
  159. }
  160. static
  161. HRESULT
  162. Initialize(
  163. VOID
  164. );
  165. static
  166. VOID
  167. Terminate(
  168. VOID
  169. );
  170. static
  171. HRESULT
  172. GetCredential(
  173. CHAR * pszPackage,
  174. SSPI_CREDENTIAL ** ppCredential
  175. );
  176. static
  177. VOID
  178. RemoveCredentialFromCache(
  179. SSPI_CREDENTIAL * pCredential
  180. );
  181. private:
  182. DWORD m_dwSignature;
  183. CHAR m_rgPackageName[ 64 ];
  184. STRA m_strPackageName;
  185. LIST_ENTRY m_ListEntry;
  186. //
  187. // Handle to the server's credentials
  188. //
  189. CredHandle m_hCredHandle;
  190. //
  191. // Used for SSPI, max message token size
  192. //
  193. ULONG m_cbMaxTokenLen;
  194. //
  195. // Do we need to uudecode/encode buffers when dealing with this package
  196. //
  197. BOOL m_fSupportsEncoding;
  198. //
  199. // Global lock
  200. //
  201. static CRITICAL_SECTION sm_csCredentials;
  202. //
  203. // Global credential list
  204. //
  205. static LIST_ENTRY sm_CredentialListHead;
  206. };
  207. #define SSPI_CONTEXT_SIGNATURE CREATE_SIGNATURE( 'SXCS' )
  208. #define SSPI_CONTEXT_FREE_SIGNATURE CREATE_SIGNATURE( 'fXCS' )
  209. class SSPI_SECURITY_CONTEXT : public CONNECTION_AUTH_CONTEXT
  210. {
  211. public:
  212. SSPI_SECURITY_CONTEXT(
  213. SSPI_CREDENTIAL * pCredential,
  214. BOOL fDigestAuth = FALSE
  215. )
  216. {
  217. DBG_ASSERT( pCredential != NULL );
  218. _pCredential = pCredential;
  219. SetSignature( SSPI_CONTEXT_SIGNATURE );
  220. _fIsComplete = FALSE;
  221. _fHaveAContext = FALSE;
  222. _fDigestAuth = fDigestAuth;
  223. SecInvalidateHandle( &_hCtxtHandle );
  224. }
  225. virtual ~SSPI_SECURITY_CONTEXT()
  226. {
  227. SetSignature( SSPI_CONTEXT_FREE_SIGNATURE );
  228. if ( _fHaveAContext )
  229. {
  230. if( _fDigestAuth )
  231. {
  232. DBG_ASSERT( g_pW3Server->QueryDigestContextCache() );
  233. //
  234. // On connection close, we are adding this full formed
  235. // security context handle to our Digest context handle
  236. // cache, cause the security context can be used to
  237. // process other requests from different connections
  238. // (per Digest protocol)
  239. //
  240. if( FAILED( g_pW3Server->QueryDigestContextCache()->
  241. AddContextCacheEntry( &_hCtxtHandle ) ) )
  242. {
  243. if ( SecIsValidHandle( &_hCtxtHandle ) )
  244. {
  245. if (g_pW3Server->QueryDigestContextCache()->QueryTraceLog() != NULL)
  246. {
  247. WriteRefTraceLogEx(g_pW3Server->QueryDigestContextCache()->QueryTraceLog(),
  248. 0,
  249. (PVOID)_hCtxtHandle.dwLower,
  250. (PVOID)_hCtxtHandle.dwUpper,
  251. NULL,
  252. NULL);
  253. }
  254. DeleteSecurityContext( &_hCtxtHandle );
  255. }
  256. }
  257. }
  258. else
  259. {
  260. if ( SecIsValidHandle( &_hCtxtHandle ) )
  261. {
  262. DeleteSecurityContext( &_hCtxtHandle );
  263. }
  264. }
  265. }
  266. }
  267. SSPI_CREDENTIAL *
  268. QueryCredentials(
  269. VOID
  270. )
  271. {
  272. return _pCredential;
  273. }
  274. VOID
  275. SetCredentials(
  276. SSPI_CREDENTIAL * pCredential
  277. )
  278. {
  279. _pCredential = pCredential;
  280. }
  281. CtxtHandle *
  282. QueryContextHandle(
  283. VOID
  284. )
  285. {
  286. return &_hCtxtHandle;
  287. }
  288. VOID
  289. SetContextHandle(
  290. CtxtHandle ctxtHandle
  291. )
  292. {
  293. _fHaveAContext = TRUE;
  294. _hCtxtHandle = ctxtHandle;
  295. }
  296. BOOL
  297. CheckSignature(
  298. VOID
  299. )
  300. {
  301. return QuerySignature() == SSPI_CONTEXT_SIGNATURE;
  302. }
  303. VOID *
  304. operator new(
  305. #if DBG
  306. size_t size
  307. #else
  308. size_t
  309. #endif
  310. )
  311. {
  312. DBG_ASSERT( size == sizeof( SSPI_SECURITY_CONTEXT ) );
  313. DBG_ASSERT( sm_pachSSPISecContext != NULL );
  314. return sm_pachSSPISecContext->Alloc();
  315. }
  316. VOID
  317. operator delete(
  318. VOID * pSSPISecContext
  319. )
  320. {
  321. DBG_ASSERT( pSSPISecContext != NULL );
  322. DBG_ASSERT( sm_pachSSPISecContext != NULL );
  323. DBG_REQUIRE( sm_pachSSPISecContext->Free( pSSPISecContext ) );
  324. }
  325. virtual
  326. BOOL
  327. Cleanup(
  328. VOID
  329. )
  330. {
  331. delete this;
  332. return TRUE;
  333. }
  334. BOOL
  335. QueryIsComplete(
  336. VOID
  337. ) const
  338. {
  339. return _fIsComplete;
  340. }
  341. VOID
  342. SetIsComplete(
  343. BOOL fIsComplete
  344. )
  345. {
  346. _fIsComplete = fIsComplete;
  347. }
  348. VOID
  349. SetContextAttributes(
  350. ULONG ulContextAttributes
  351. )
  352. {
  353. _ulContextAttributes = ulContextAttributes;
  354. }
  355. ULONG
  356. QueryContextAttributes(
  357. VOID
  358. )
  359. {
  360. return _ulContextAttributes;
  361. }
  362. static
  363. HRESULT
  364. Initialize(
  365. VOID
  366. );
  367. static
  368. VOID
  369. Terminate(
  370. VOID
  371. );
  372. private:
  373. SSPI_CREDENTIAL * _pCredential;
  374. //
  375. // Do we have a context set? If so we should delete it on cleanup
  376. //
  377. BOOL _fHaveAContext;
  378. //
  379. // Is the handshake complete?
  380. //
  381. BOOL _fIsComplete;
  382. //
  383. // Handle to the partially formed context
  384. //
  385. CtxtHandle _hCtxtHandle;
  386. //
  387. // Attributes of the established context
  388. //
  389. ULONG _ulContextAttributes;
  390. //
  391. // Allocation cache for SSPI_SECURITY_CONTEXT
  392. //
  393. //
  394. // Is this Digest authentication
  395. //
  396. BOOL _fDigestAuth;
  397. static ALLOC_CACHE_HANDLER * sm_pachSSPISecContext;
  398. };
  399. class SSPI_USER_CONTEXT : public W3_USER_CONTEXT
  400. {
  401. public:
  402. SSPI_USER_CONTEXT( AUTH_PROVIDER * pProvider )
  403. : W3_USER_CONTEXT( pProvider )
  404. {
  405. _hImpersonationToken = NULL;
  406. _hPrimaryToken = NULL;
  407. _fSetAccountPwdExpiry = FALSE;
  408. _pSecurityContext = NULL;
  409. }
  410. virtual ~SSPI_USER_CONTEXT()
  411. {
  412. if ( _hImpersonationToken != NULL )
  413. {
  414. CloseHandle( _hImpersonationToken );
  415. _hImpersonationToken = NULL;
  416. }
  417. if ( _hPrimaryToken != NULL )
  418. {
  419. CloseHandle( _hPrimaryToken );
  420. _hPrimaryToken = NULL;
  421. }
  422. }
  423. HRESULT
  424. Create(
  425. SSPI_SECURITY_CONTEXT * pSecurityContext,
  426. W3_MAIN_CONTEXT * pMainContext
  427. );
  428. WCHAR *
  429. QueryUserName(
  430. VOID
  431. )
  432. {
  433. return _strUserName.QueryStr();
  434. }
  435. WCHAR *
  436. QueryPassword(
  437. VOID
  438. )
  439. {
  440. return L"";
  441. }
  442. DWORD
  443. QueryAuthType(
  444. VOID
  445. )
  446. {
  447. return QueryProvider()->QueryAuthType();
  448. }
  449. virtual
  450. HRESULT
  451. GetSspiInfo(
  452. BYTE * pCredHandle,
  453. DWORD cbCredHandle,
  454. BYTE * pCtxtHandle,
  455. DWORD cbCtxtHandle
  456. )
  457. {
  458. if ( cbCredHandle < sizeof( CredHandle ) ||
  459. cbCtxtHandle < sizeof( CtxtHandle ) )
  460. {
  461. return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
  462. }
  463. memcpy( pCredHandle,
  464. _pSecurityContext->QueryCredentials()->QueryCredHandle(),
  465. sizeof( CredHandle ) );
  466. memcpy( pCtxtHandle,
  467. _pSecurityContext->QueryContextHandle(),
  468. sizeof( CtxtHandle ) );
  469. return NO_ERROR;
  470. }
  471. HANDLE
  472. QueryImpersonationToken(
  473. VOID
  474. )
  475. {
  476. DBG_ASSERT( _hImpersonationToken != NULL );
  477. return _hImpersonationToken;
  478. }
  479. HANDLE
  480. QueryPrimaryToken(
  481. VOID
  482. );
  483. STRA *
  484. QueryAuthToken(
  485. VOID
  486. )
  487. {
  488. return &_strAuthToken;
  489. }
  490. LARGE_INTEGER *
  491. QueryExpiry(
  492. VOID
  493. ) ;
  494. private:
  495. HANDLE _hImpersonationToken;
  496. HANDLE _hPrimaryToken;
  497. STRU _strUserName;
  498. STRU _strPackageName;
  499. DWORD _dwAuthType;
  500. LARGE_INTEGER _AccountPwdExpiry;
  501. BOOL _fSetAccountPwdExpiry;
  502. SSPI_SECURITY_CONTEXT * _pSecurityContext;
  503. STRA _strAuthToken;
  504. };
  505. #endif