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.

4547 lines
78 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. iiscmr.cxx
  5. Abstract:
  6. Classes to handle cert wildcard mapping
  7. Author:
  8. Philippe Choquier (phillich) 17-oct-1996
  9. --*/
  10. #define _CRYPT32_
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <wincrypt.h>
  15. #include <schnlsp.h>
  16. //#include <crypt32l.h>
  17. #if 1 // DBCS
  18. #include <mbstring.h>
  19. #endif
  20. #include "xbf.hxx"
  21. extern "C" {
  22. #include <immd5.h>
  23. }
  24. #include <iis64.h>
  25. #include <iismap.hxx>
  26. #include "iismaprc.h"
  27. #include "mapmsg.h"
  28. #include <iiscmr.hxx>
  29. #include <icrypt.hxx>
  30. #include <dbgutil.h>
  31. typedef
  32. WINCRYPT32API
  33. PCCERT_CONTEXT
  34. (WINAPI* PFNCertCreateCertificateContext)(
  35. IN DWORD dwCertEncodingType,
  36. IN const BYTE *pbCertEncoded,
  37. IN DWORD cbCertEncoded
  38. );
  39. typedef
  40. WINCRYPT32API
  41. BOOL
  42. (WINAPI* PFNCertFreeCertificateContext)(
  43. IN PCCERT_CONTEXT pCertContext
  44. );
  45. typedef
  46. WINCRYPT32API
  47. BOOL
  48. (WINAPI* PFNCryptDecodeObject)(
  49. IN DWORD dwCertEncodingType,
  50. IN LPCSTR lpszStructType,
  51. IN const BYTE *pbEncoded,
  52. IN DWORD cbEncoded,
  53. IN DWORD dwFlags,
  54. OUT void *pvStructInfo,
  55. IN OUT DWORD *pcbStructInfo
  56. );
  57. typedef
  58. WINCRYPT32API
  59. BOOL
  60. (WINAPI* PFNCertGetCertificateContextProperty)(
  61. IN PCCERT_CONTEXT pCertContext,
  62. IN DWORD dwPropId,
  63. OUT void *pvData,
  64. IN OUT DWORD *pcbData
  65. );
  66. //
  67. // GLOBALS
  68. //
  69. //
  70. // definition of ASN.1 <> X.509 name conversion
  71. //
  72. MAP_ASN aMapAsn[] = {
  73. { szOID_COUNTRY_NAME, "", IDS_CMR_ASN_C },
  74. { szOID_ORGANIZATION_NAME, "", IDS_CMR_ASN_O },
  75. { szOID_ORGANIZATIONAL_UNIT_NAME, "", IDS_CMR_ASN_OU },
  76. { szOID_COMMON_NAME, "", IDS_CMR_ASN_CN },
  77. { szOID_LOCALITY_NAME, "", IDS_CMR_ASN_L },
  78. { szOID_STATE_OR_PROVINCE_NAME, "", IDS_CMR_ASN_S },
  79. { szOID_TITLE, "", IDS_CMR_ASN_T },
  80. { szOID_GIVEN_NAME, "", IDS_CMR_ASN_GN },
  81. { szOID_INITIALS, "", IDS_CMR_ASN_I },
  82. { "1.2.840.113549.1.9.1", "", IDS_CMR_ASN_Email },
  83. { "1.2.840.113549.1.9.8", "", IDS_CMR_ASN_Addr }, // warning: can include CR/LF
  84. } ;
  85. HINSTANCE hSchannel = NULL;
  86. HINSTANCE hCapi2Lib = NULL;
  87. SSL_GET_ISSUERS_FN pfnGetDefaultIssuers = NULL;
  88. PFNCertCreateCertificateContext
  89. pfnCertCreateCertificateContext = NULL;
  90. PFNCertFreeCertificateContext
  91. pfnCertFreeCertificateContext = NULL;
  92. PFNCryptDecodeObject
  93. pfnCryptDecodeObject = NULL;
  94. PFNCertGetCertificateContextProperty
  95. pfnCertGetCertificateContextProperty = NULL;
  96. char HEXTOA[] = "0123456789abcdef";
  97. MAP_FIELD aMapField[] = {
  98. { CERT_FIELD_ISSUER, IDS_CMR_X509FLD_IS, "" },
  99. { CERT_FIELD_SUBJECT, IDS_CMR_X509FLD_SU, "" },
  100. { CERT_FIELD_SERIAL_NUMBER, IDS_CMR_X509FLD_SN, "" },
  101. } ;
  102. DWORD adwFieldFlags[]={
  103. CERT_FIELD_FLAG_CONTAINS_SUBFIELDS,
  104. CERT_FIELD_FLAG_CONTAINS_SUBFIELDS,
  105. 0,
  106. };
  107. //
  108. // Global functions
  109. //
  110. BOOL
  111. Unserialize(
  112. LPBYTE* ppB,
  113. LPDWORD pC,
  114. LPDWORD pU
  115. )
  116. /*++
  117. Routine Description:
  118. Unserialize a DWORD
  119. pU is updated with DWORD from *ppB, ppB & pC are updated
  120. Arguments:
  121. ppB - ptr to addr of buffer
  122. pC - ptr to byte count in buffer
  123. pU - ptr to DWORD where to unserialize
  124. Return Value:
  125. TRUE if successful, FALSE on error
  126. --*/
  127. {
  128. DWORD dwTemp; // added to handle 64 bit alignment problems
  129. if ( *pC >= sizeof( DWORD ) )
  130. {
  131. dwTemp = **ppB;
  132. *pU = dwTemp;
  133. *ppB += sizeof(DWORD);
  134. *pC -= sizeof(DWORD);
  135. return TRUE;
  136. }
  137. return FALSE;
  138. }
  139. BOOL
  140. Unserialize(
  141. LPBYTE* ppB,
  142. LPDWORD pC,
  143. LPBOOL pU
  144. )
  145. /*++
  146. Routine Description:
  147. Unserialize a BOOL
  148. pU is updated with BOOL from *ppB, ppB & pC are updated
  149. Arguments:
  150. ppB - ptr to addr of buffer
  151. pC - ptr to byte count in buffer
  152. pU - ptr to BOOL where to unserialize
  153. Return Value:
  154. TRUE if successful, FALSE on error
  155. --*/
  156. {
  157. BOOL bTemp; // added to handle 64 bit alignment problems
  158. if ( *pC >= sizeof( BOOL ) )
  159. {
  160. bTemp = **ppB;
  161. *pU = bTemp;
  162. *ppB += sizeof(BOOL);
  163. *pC -= sizeof(BOOL);
  164. return TRUE;
  165. }
  166. return FALSE;
  167. }
  168. //
  169. // Extensible buffer class
  170. //
  171. BOOL
  172. CStoreXBF::Need(
  173. DWORD dwNeed
  174. )
  175. /*++
  176. Routine Description:
  177. Insure that CStoreXBF can store at least dwNeed bytes
  178. including bytes already stored.
  179. Arguments:
  180. dwNeed - minimum of bytes available for storage
  181. Return Value:
  182. TRUE if successful, FALSE on error
  183. --*/
  184. {
  185. if ( dwNeed > m_cAllocBuff )
  186. {
  187. dwNeed = ((dwNeed + m_cGrain)/m_cGrain)*m_cGrain;
  188. LPBYTE pN = (LPBYTE)LocalAlloc( LMEM_FIXED, dwNeed );
  189. if ( pN == NULL )
  190. {
  191. return FALSE;
  192. }
  193. if ( m_cUsedBuff )
  194. {
  195. memcpy( pN, m_pBuff, m_cUsedBuff );
  196. }
  197. m_cAllocBuff = dwNeed;
  198. LocalFree( m_pBuff );
  199. m_pBuff = pN;
  200. }
  201. return TRUE;
  202. }
  203. BOOL
  204. CStoreXBF::Save(
  205. HANDLE hFile
  206. )
  207. /*++
  208. Routine Description:
  209. Save to file
  210. Arguments:
  211. hFile - file handle
  212. Return Value:
  213. TRUE if successful, FALSE on error
  214. --*/
  215. {
  216. DWORD dwWritten;
  217. return WriteFile( hFile, GetBuff(), GetUsed(), &dwWritten, NULL ) &&
  218. dwWritten == GetUsed();
  219. }
  220. BOOL
  221. CStoreXBF::Load(
  222. HANDLE hFile
  223. )
  224. /*++
  225. Routine Description:
  226. Load from file
  227. Arguments:
  228. hFile - file handle
  229. Return Value:
  230. TRUE if successful, FALSE on error
  231. --*/
  232. {
  233. DWORD dwS = GetFileSize( hFile, NULL );
  234. DWORD dwRead;
  235. if ( dwS != 0xffffffff &&
  236. Need( dwS ) &&
  237. ReadFile( hFile, GetBuff(), dwS, &dwRead, NULL ) &&
  238. dwRead == dwS )
  239. {
  240. m_cUsedBuff = dwRead;
  241. return TRUE;
  242. }
  243. m_cUsedBuff = 0;
  244. return FALSE;
  245. }
  246. BOOL
  247. Serialize(
  248. CStoreXBF* pX,
  249. DWORD dw
  250. )
  251. /*++
  252. Routine Description:
  253. Serialize a DWORD in CStoreXBF
  254. Arguments:
  255. pX - ptr to CStoreXBF where to add serialized DWORD
  256. dw - DWORD to serialize
  257. Return Value:
  258. TRUE if successful, FALSE on error
  259. --*/
  260. {
  261. return pX->Append( (LPBYTE)&dw, sizeof(dw) );
  262. }
  263. BOOL
  264. Serialize(
  265. CStoreXBF* pX,
  266. BOOL f
  267. )
  268. /*++
  269. Routine Description:
  270. Serialize a BOOL in CStoreXBF
  271. Arguments:
  272. pX - ptr to CStoreXBF where to add serialized BOOL
  273. f - BOOL to serialize
  274. Return Value:
  275. TRUE if successful, FALSE on error
  276. --*/
  277. {
  278. return pX->Append( (LPBYTE)&f, sizeof(f) );
  279. }
  280. DWORD
  281. CPtrXBF::AddPtr(
  282. LPVOID pV
  283. )
  284. /*++
  285. Routine Description:
  286. Add a ptr to array
  287. Arguments:
  288. pV - ptr to be added at end of array
  289. Return Value:
  290. index ( 0-based ) in array where added or INDEX_ERROR if error
  291. --*/
  292. {
  293. DWORD i = GetNbPtr();
  294. if ( Append( (LPBYTE)&pV, sizeof(pV)) )
  295. {
  296. return i;
  297. }
  298. return INDEX_ERROR;
  299. }
  300. DWORD
  301. CPtrXBF::InsertPtr(
  302. DWORD iBefore,
  303. LPVOID pV
  304. )
  305. /*++
  306. Routine Description:
  307. Insert a ptr to array
  308. Arguments:
  309. iBefore - index where to insert entry, or 0xffffffff if add to array
  310. pV - ptr to be inserted
  311. Return Value:
  312. index ( 0-based ) in array where added or INDEX_ERROR if error
  313. --*/
  314. {
  315. if ( iBefore == INDEX_ERROR || iBefore >= GetNbPtr() )
  316. {
  317. return AddPtr( pV );
  318. }
  319. if ( AddPtr( NULL ) != INDEX_ERROR )
  320. {
  321. memmove( GetBuff()+(iBefore+1)*sizeof(LPVOID),
  322. GetBuff()+iBefore*sizeof(LPVOID),
  323. GetUsed()-(iBefore+1)*sizeof(LPVOID) );
  324. SetPtr( iBefore, pV );
  325. return iBefore;
  326. }
  327. return INDEX_ERROR;
  328. }
  329. BOOL
  330. CPtrXBF::DeletePtr(
  331. DWORD i
  332. )
  333. /*++
  334. Routine Description:
  335. Delete a ptr from array
  336. Arguments:
  337. i - index of ptr to delete
  338. Return Value:
  339. TRUE if success, otherwise FALSE
  340. --*/
  341. {
  342. memmove( GetBuff()+i*sizeof(LPVOID),
  343. GetBuff()+(i+1)*sizeof(LPVOID),
  344. GetUsed()-(i+1)*sizeof(LPVOID) );
  345. DecreaseUse( sizeof(LPVOID) );
  346. return TRUE;
  347. }
  348. BOOL
  349. CPtrXBF::Unserialize(
  350. LPBYTE* ppB,
  351. LPDWORD pC,
  352. DWORD cNbEntry
  353. )
  354. /*++
  355. Routine Description:
  356. Unserialize a ptr array
  357. Arguments:
  358. ppB - ptr to addr of buffer to unserialize from
  359. pC - ptr to count of bytes in buffer
  360. cNbEntry - # of ptr to unserialize from buffer
  361. Return Value:
  362. TRUE if success, otherwise FALSE
  363. --*/
  364. {
  365. Reset();
  366. if ( *pC >= cNbEntry * sizeof(LPVOID) &&
  367. Append( *ppB, cNbEntry * sizeof(LPVOID) ) )
  368. {
  369. *ppB += cNbEntry * sizeof(LPVOID);
  370. *pC -= cNbEntry * sizeof(LPVOID);
  371. return TRUE;
  372. }
  373. return FALSE;
  374. }
  375. BOOL
  376. CPtrXBF::Serialize(
  377. CStoreXBF* pX
  378. )
  379. /*++
  380. Routine Description:
  381. Serialize a ptr array
  382. Arguments:
  383. pX - ptr to CStoreXBF to serialize to
  384. Return Value:
  385. TRUE if success, otherwise FALSE
  386. --*/
  387. {
  388. return pX->Append( (LPBYTE)GetBuff(), (DWORD)GetUsed() );
  389. }
  390. DWORD
  391. CPtrDwordXBF::AddPtr(
  392. DWORD pV
  393. )
  394. /*++
  395. Routine Description:
  396. Add a ptr to array
  397. Arguments:
  398. pV - ptr to be added at end of array
  399. Return Value:
  400. index ( 0-based ) in array where added or INDEX_ERROR if error
  401. --*/
  402. {
  403. DWORD i = GetNbPtr();
  404. if ( Append( (LPBYTE)&pV, sizeof(pV)) )
  405. {
  406. return i;
  407. }
  408. return INDEX_ERROR;
  409. }
  410. DWORD
  411. CPtrDwordXBF::InsertPtr(
  412. DWORD iBefore,
  413. DWORD pV
  414. )
  415. /*++
  416. Routine Description:
  417. Insert a ptr to array
  418. Arguments:
  419. iBefore - index where to insert entry, or 0xffffffff if add to array
  420. pV - ptr to be inserted
  421. Return Value:
  422. index ( 0-based ) in array where added or INDEX_ERROR if error
  423. --*/
  424. {
  425. if ( iBefore == INDEX_ERROR || iBefore >= GetNbPtr() )
  426. {
  427. return AddPtr( pV );
  428. }
  429. if ( AddPtr( NULL ) != INDEX_ERROR )
  430. {
  431. memmove( GetBuff()+(iBefore+1)*sizeof(DWORD),
  432. GetBuff()+iBefore*sizeof(DWORD),
  433. GetUsed()-(iBefore+1)*sizeof(DWORD) );
  434. SetPtr( iBefore, pV );
  435. return iBefore;
  436. }
  437. return INDEX_ERROR;
  438. }
  439. BOOL
  440. CPtrDwordXBF::DeletePtr(
  441. DWORD i
  442. )
  443. /*++
  444. Routine Description:
  445. Delete a ptr from array
  446. Arguments:
  447. i - index of ptr to delete
  448. Return Value:
  449. TRUE if success, otherwise FALSE
  450. --*/
  451. {
  452. memmove( GetBuff()+i*sizeof(DWORD),
  453. GetBuff()+(i+1)*sizeof(DWORD),
  454. GetUsed()-(i+1)*sizeof(DWORD) );
  455. DecreaseUse( sizeof(LPVOID) );
  456. return TRUE;
  457. }
  458. BOOL
  459. CPtrDwordXBF::Unserialize(
  460. LPBYTE* ppB,
  461. LPDWORD pC,
  462. DWORD cNbEntry
  463. )
  464. /*++
  465. Routine Description:
  466. Unserialize a ptr array
  467. Arguments:
  468. ppB - ptr to addr of buffer to unserialize from
  469. pC - ptr to count of bytes in buffer
  470. cNbEntry - # of ptr to unserialize from buffer
  471. Return Value:
  472. TRUE if success, otherwise FALSE
  473. --*/
  474. {
  475. Reset();
  476. if ( *pC >= cNbEntry * sizeof(DWORD))
  477. {
  478. if (Append( *ppB, cNbEntry * sizeof(DWORD) ))
  479. {
  480. *ppB += cNbEntry * sizeof(DWORD);
  481. *pC -= cNbEntry * sizeof(DWORD);
  482. return TRUE;
  483. }
  484. }
  485. return FALSE;
  486. }
  487. BOOL
  488. CPtrDwordXBF::Serialize(
  489. CStoreXBF* pX
  490. )
  491. /*++
  492. Routine Description:
  493. Serialize a ptr array
  494. Arguments:
  495. pX - ptr to CStoreXBF to serialize to
  496. Return Value:
  497. TRUE if success, otherwise FALSE
  498. --*/
  499. {
  500. return pX->Append( (LPBYTE)GetBuff(), (DWORD)GetUsed() );
  501. }
  502. BOOL
  503. CAllocString::Set(
  504. LPSTR pS
  505. )
  506. /*++
  507. Routine Description:
  508. Set a string content, freeing prior content if any
  509. Arguments:
  510. pS - string to copy
  511. Return Value:
  512. TRUE if successful, FALSE on error
  513. --*/
  514. {
  515. size_t l;
  516. Reset();
  517. if ( m_pStr = (LPSTR)LocalAlloc( LMEM_FIXED, l = strlen(pS)+1 ) )
  518. {
  519. memcpy( m_pStr, pS, l );
  520. return TRUE;
  521. }
  522. return FALSE;
  523. }
  524. BOOL
  525. CAllocString::Append(
  526. LPSTR pS
  527. )
  528. /*++
  529. Routine Description:
  530. Append a string content
  531. Arguments:
  532. pS - string to append
  533. Return Value:
  534. TRUE if successful, FALSE on error
  535. --*/
  536. {
  537. size_t l = m_pStr ? strlen(m_pStr ) : 0;
  538. size_t nl;
  539. LPSTR pStr;
  540. if ( pStr = (LPSTR)LocalAlloc( LMEM_FIXED, l + (nl = strlen(pS)+1 )) )
  541. {
  542. memcpy( pStr, m_pStr, l );
  543. memcpy( pStr+l, pS, nl );
  544. //
  545. // Free the old block before we blow it away.
  546. //
  547. Reset();
  548. m_pStr = pStr;
  549. return TRUE;
  550. }
  551. return FALSE;
  552. }
  553. BOOL
  554. CAllocString::Unserialize(
  555. LPBYTE* ppb,
  556. LPDWORD pc
  557. )
  558. /*++
  559. Routine Description:
  560. Unserialize a string
  561. Arguments:
  562. ppB - ptr to addr of buffer to unserialize from
  563. pC - ptr to count of bytes in buffer
  564. Return Value:
  565. TRUE if success, otherwise FALSE
  566. --*/
  567. {
  568. DWORD dwL;
  569. if ( ::Unserialize( ppb, pc, &dwL ) &&
  570. (m_pStr = (LPSTR)LocalAlloc( LMEM_FIXED, dwL + 1)) )
  571. {
  572. memcpy( m_pStr, *ppb, dwL );
  573. m_pStr[dwL] = '\0';
  574. *ppb += dwL;
  575. *pc -= dwL;
  576. return TRUE;
  577. }
  578. return FALSE;
  579. }
  580. BOOL
  581. CAllocString::Serialize(
  582. CStoreXBF* pX
  583. )
  584. /*++
  585. Routine Description:
  586. Serialize a string
  587. Arguments:
  588. pX - ptr to CStoreXBF to serialize to
  589. Return Value:
  590. TRUE if success, otherwise FALSE
  591. --*/
  592. {
  593. LPSTR pS = m_pStr ? m_pStr : "";
  594. return ::Serialize( pX, (DWORD)strlen(pS) ) && pX->Append( pS );
  595. }
  596. BOOL
  597. CBlob::Set(
  598. LPBYTE pStr,
  599. DWORD cStr
  600. )
  601. /*++
  602. Routine Description:
  603. Store a buffer in a blob object
  604. buffer is copied inside blob
  605. blob is reset before copy
  606. Arguments:
  607. pStr - ptr to buffer to copy
  608. cStr - length of buffer
  609. Return Value:
  610. TRUE if success, otherwise FALSE
  611. --*/
  612. {
  613. Reset();
  614. return InitSet( pStr, cStr);
  615. }
  616. BOOL
  617. CBlob::InitSet(
  618. LPBYTE pStr,
  619. DWORD cStr
  620. )
  621. /*++
  622. Routine Description:
  623. Store a buffer in a blob object
  624. buffer is copied inside blob
  625. blob is not reset before copy, initial blob content ignored
  626. Arguments:
  627. pStr - ptr to buffer to copy
  628. cStr - length of buffer
  629. Return Value:
  630. TRUE if success, otherwise FALSE
  631. --*/
  632. {
  633. if ( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, cStr ) )
  634. {
  635. memcpy( m_pStr, pStr, cStr );
  636. m_cStr = cStr;
  637. return TRUE;
  638. }
  639. return FALSE;
  640. }
  641. BOOL
  642. CBlob::Unserialize(
  643. LPBYTE* ppB,
  644. LPDWORD pC
  645. )
  646. /*++
  647. Routine Description:
  648. Unserialize a blob
  649. Arguments:
  650. ppB - ptr to addr of buffer to unserialize from
  651. pC - ptr to count of bytes in buffer
  652. Return Value:
  653. TRUE if success, otherwise FALSE
  654. --*/
  655. {
  656. Reset();
  657. if ( ::Unserialize( ppB, pC, &m_cStr ) &&
  658. *pC >= m_cStr &&
  659. ( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cStr ) ) )
  660. {
  661. memcpy( m_pStr, *ppB, m_cStr );
  662. *ppB += m_cStr;
  663. *pC -= m_cStr;
  664. }
  665. else
  666. {
  667. m_cStr = 0;
  668. return FALSE;
  669. }
  670. return TRUE;
  671. }
  672. BOOL
  673. CBlob::Serialize(
  674. CStoreXBF* pX
  675. )
  676. /*++
  677. Routine Description:
  678. Serialize a blob
  679. Arguments:
  680. pX - ptr to CStoreXBF to serialize to
  681. Return Value:
  682. TRUE if success, otherwise FALSE
  683. --*/
  684. {
  685. return ::Serialize( pX, m_cStr ) &&
  686. pX->Append( m_pStr, m_cStr );
  687. }
  688. CStrPtrXBF::~CStrPtrXBF(
  689. )
  690. /*++
  691. Routine Description:
  692. CStrPtrXBF destructor
  693. Arguments:
  694. None
  695. Return Value:
  696. Nothing
  697. --*/
  698. {
  699. DWORD iM = GetNbPtr();
  700. UINT i;
  701. for ( i = 0 ; i < iM ; ++i )
  702. {
  703. ((CAllocString*)GetPtrAddr(i))->Reset();
  704. }
  705. }
  706. DWORD
  707. CStrPtrXBF::AddEntry(
  708. LPSTR pS
  709. )
  710. /*++
  711. Routine Description:
  712. Add a string to array
  713. string content is copied in array
  714. Arguments:
  715. pS - string to be added at end of array
  716. Return Value:
  717. index ( 0-based ) in array where added or INDEX_ERROR if error
  718. --*/
  719. {
  720. DWORD i;
  721. if ( (i = AddPtr( NULL )) != INDEX_ERROR )
  722. {
  723. return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
  724. }
  725. return INDEX_ERROR;
  726. }
  727. DWORD
  728. CStrPtrXBF::InsertEntry(
  729. DWORD iBefore,
  730. LPSTR pS
  731. )
  732. /*++
  733. Routine Description:
  734. Insert a string in array
  735. string content is copied in array
  736. Arguments:
  737. iBefore - index where to insert entry, or 0xffffffff if add to array
  738. pS - string to be inserted in array
  739. Return Value:
  740. index ( 0-based ) in array where added or INDEX_ERROR if error
  741. --*/
  742. {
  743. DWORD i;
  744. if ( (i = InsertPtr( iBefore, NULL )) != INDEX_ERROR )
  745. {
  746. return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
  747. }
  748. return INDEX_ERROR;
  749. }
  750. BOOL
  751. CStrPtrXBF::DeleteEntry(
  752. DWORD i
  753. )
  754. /*++
  755. Routine Description:
  756. Delete a string from array
  757. Arguments:
  758. i - index of string to delete
  759. Return Value:
  760. TRUE if success, otherwise FALSE
  761. --*/
  762. {
  763. if ( i < GetNbPtr() )
  764. {
  765. ((CAllocString*)GetPtrAddr(i))->Reset();
  766. DeletePtr( i );
  767. return TRUE;
  768. }
  769. return FALSE;
  770. }
  771. BOOL
  772. CStrPtrXBF::Unserialize(
  773. LPBYTE* ppB,
  774. LPDWORD pC,
  775. DWORD cNbEntry
  776. )
  777. /*++
  778. Routine Description:
  779. Unserialize a string array
  780. Arguments:
  781. ppB - ptr to addr of buffer
  782. pC - ptr to byte count in buffer
  783. cNbEntry - # of entry to unserialize
  784. Return Value:
  785. TRUE if successful, FALSE on error
  786. --*/
  787. {
  788. UINT i;
  789. Reset();
  790. CAllocString empty;
  791. for ( i = 0 ; i < cNbEntry ; ++i )
  792. {
  793. if ( !Append( (LPBYTE)&empty, sizeof(empty)) ||
  794. !((CAllocString*)GetPtrAddr(i))->Unserialize( ppB, pC ) )
  795. {
  796. return FALSE;
  797. }
  798. }
  799. return TRUE;
  800. }
  801. BOOL
  802. CStrPtrXBF::Serialize(
  803. CStoreXBF* pX
  804. )
  805. /*++
  806. Routine Description:
  807. Serialize a string array
  808. Arguments:
  809. pX - ptr to CStoreXBF where to add serialized DWORD
  810. Return Value:
  811. TRUE if successful, FALSE on error
  812. --*/
  813. {
  814. UINT i;
  815. for ( i = 0 ; i < GetNbEntry() ; ++i )
  816. {
  817. if ( !((CAllocString*)GetPtrAddr(i))->Serialize( pX ) )
  818. {
  819. return FALSE;
  820. }
  821. }
  822. return TRUE;
  823. }
  824. CBlobXBF::~CBlobXBF(
  825. )
  826. /*++
  827. Routine Description:
  828. CBlobXBF destructor
  829. Arguments:
  830. None
  831. Return Value:
  832. Nothing
  833. --*/
  834. {
  835. DWORD iM = GetUsed()/sizeof(CBlob);
  836. UINT i;
  837. for ( i = 0 ; i < iM ; ++i )
  838. {
  839. GetBlob(i)->Reset();
  840. }
  841. }
  842. VOID CBlobXBF::Reset(
  843. )
  844. /*++
  845. Routine Description:
  846. Reset the blob content to NULL
  847. Arguments:
  848. None
  849. Return Value:
  850. Nothing
  851. --*/
  852. {
  853. DWORD iM = GetUsed()/sizeof(CBlob);
  854. UINT i;
  855. for ( i = 0 ; i < iM ; ++i )
  856. {
  857. GetBlob(i)->Reset();
  858. }
  859. CStoreXBF::Reset();
  860. }
  861. DWORD
  862. CBlobXBF::AddEntry(
  863. LPBYTE pS,
  864. DWORD cS
  865. )
  866. /*++
  867. Routine Description:
  868. Add a buffer to blob array
  869. buffer content is copied in array
  870. Arguments:
  871. pS - buffer to be added at end of array
  872. cS - length of buffer
  873. Return Value:
  874. index ( 0-based ) in array where added or INDEX_ERROR if error
  875. --*/
  876. {
  877. DWORD i = GetNbEntry();
  878. if ( Append( (LPBYTE)&pS, sizeof(CBlob) ) )
  879. {
  880. return GetBlob(i)->InitSet( pS, cS ) ? i : INDEX_ERROR;
  881. }
  882. return INDEX_ERROR;
  883. }
  884. DWORD
  885. CBlobXBF::InsertEntry(
  886. DWORD iBefore,
  887. LPSTR pS,
  888. DWORD cS )
  889. /*++
  890. Routine Description:
  891. Insert a buffer in blob array
  892. buffer content is copied in array
  893. Arguments:
  894. iBefore - index where to insert entry, or 0xffffffff if add to array
  895. pS - buffer to be inserted in array
  896. cS - length of buffer
  897. Return Value:
  898. index ( 0-based ) in array where added or INDEX_ERROR if error
  899. --*/
  900. {
  901. DWORD i;
  902. if ( iBefore == INDEX_ERROR || iBefore >= GetNbEntry() )
  903. {
  904. return AddEntry( (LPBYTE)pS, cS );
  905. }
  906. if ( iBefore < GetNbEntry() && Append( (LPBYTE)&pS, sizeof(CBlob) ) )
  907. {
  908. memmove( GetBuff()+(iBefore+1)*sizeof(CBlob),
  909. GetBuff()+iBefore*sizeof(CBlob),
  910. GetUsed()-(iBefore+1)*sizeof(CBlob) );
  911. return GetBlob(iBefore)->InitSet( (LPBYTE)pS, cS ) ? iBefore : INDEX_ERROR;
  912. }
  913. return INDEX_ERROR;
  914. }
  915. BOOL
  916. CBlobXBF::DeleteEntry(
  917. DWORD i
  918. )
  919. /*++
  920. Routine Description:
  921. Delete a entry from blob array
  922. Arguments:
  923. i - index of string to delete
  924. Return Value:
  925. TRUE if success, otherwise FALSE
  926. --*/
  927. {
  928. if ( i < GetNbEntry() )
  929. {
  930. GetBlob(i)->Reset();
  931. memmove( GetBuff()+i*sizeof(CBlob),
  932. GetBuff()+(i+1)*sizeof(CBlob),
  933. GetUsed()-(i+1)*sizeof(CBlob) );
  934. DecreaseUse( sizeof(CBlob) );
  935. return TRUE;
  936. }
  937. return FALSE;
  938. }
  939. BOOL
  940. CBlobXBF::Unserialize(
  941. LPBYTE* ppB,
  942. LPDWORD pC,
  943. DWORD cNbEntry )
  944. /*++
  945. Routine Description:
  946. Unserialize a blob array
  947. Arguments:
  948. ppB - ptr to addr of buffer to unserialize from
  949. pC - ptr to count of bytes in buffer
  950. cNbEntry - # of ptr to unserialize from buffer
  951. Return Value:
  952. TRUE if success, otherwise FALSE
  953. --*/
  954. {
  955. UINT i;
  956. Reset();
  957. CBlob empty;
  958. for ( i = 0 ; i < cNbEntry ; ++i )
  959. {
  960. if ( !Append( (LPBYTE)&empty, sizeof(empty) ) ||
  961. !GetBlob(i)->Unserialize( ppB, pC ) )
  962. {
  963. return FALSE;
  964. }
  965. }
  966. return TRUE;
  967. }
  968. BOOL
  969. CBlobXBF::Serialize(
  970. CStoreXBF* pX
  971. )
  972. /*++
  973. Routine Description:
  974. Serialize a blob array
  975. Arguments:
  976. pX - ptr to CStoreXBF where to add serialized blob
  977. Return Value:
  978. TRUE if successful, FALSE on error
  979. --*/
  980. {
  981. UINT i;
  982. for ( i = 0 ; i < GetNbEntry() ; ++i )
  983. {
  984. if ( !GetBlob(i)->Serialize( pX ) )
  985. {
  986. return FALSE;
  987. }
  988. }
  989. return TRUE;
  990. }
  991. CDecodedCert::CDecodedCert(
  992. PCERT_CONTEXT pCert
  993. )
  994. /*++
  995. Routine Description:
  996. Constructor
  997. Store a reference to cert ( cert data is NOT copied )
  998. Arguments:
  999. pCert - cert
  1000. Return Value:
  1001. Nothing
  1002. --*/
  1003. {
  1004. UINT i;
  1005. for ( i = 0 ; i < CERT_FIELD_LAST ; ++i )
  1006. {
  1007. aniFields[i] = NULL;
  1008. }
  1009. pCertCtx = (PCCERT_CONTEXT)pCert;
  1010. }
  1011. CDecodedCert::~CDecodedCert(
  1012. )
  1013. /*++
  1014. Routine Description:
  1015. Destructor
  1016. Arguments:
  1017. None
  1018. Return Value:
  1019. Nothing
  1020. --*/
  1021. {
  1022. UINT i;
  1023. for ( i = 0 ; i < CERT_FIELD_LAST ; ++i )
  1024. {
  1025. if ( aniFields[i] != NULL )
  1026. {
  1027. LocalFree( aniFields[i] );
  1028. }
  1029. }
  1030. }
  1031. BOOL
  1032. CDecodedCert::GetIssuer(
  1033. LPVOID* ppCert,
  1034. LPDWORD pcCert
  1035. )
  1036. /*++
  1037. Routine Description:
  1038. Get the issuer portion of a cert
  1039. Returns a reference : issuer is NOT copied
  1040. Arguments:
  1041. ppCert - updated with ptr to issuer
  1042. pcCert - updated with issuer byte count
  1043. Return Value:
  1044. TRUE if successful, FALSE on error
  1045. --*/
  1046. {
  1047. if ( pCertCtx == NULL )
  1048. {
  1049. return FALSE;
  1050. }
  1051. *ppCert = pCertCtx->pCertInfo->Issuer.pbData;
  1052. *pcCert = pCertCtx->pCertInfo->Issuer.cbData;
  1053. return TRUE;
  1054. }
  1055. PCERT_RDN_ATTR *
  1056. CDecodedCert::GetSubField(
  1057. CERT_FIELD_ID fi,
  1058. LPSTR pszAsnName,
  1059. LPDWORD pcElements
  1060. )
  1061. /*++
  1062. Routine Description:
  1063. Returns a cert sub-field ( e.g. Issuer.O ). There may be multiple entries
  1064. for a given subfield. This functions returns an array of attribute values
  1065. Arguments:
  1066. fi - cert field where sub-field is located
  1067. pszAsnName - ASN.1 name of sub-field inside fi
  1068. pcElements - Number of elements returned in array
  1069. Return Value:
  1070. ptr to array of pointers to attribute blobs if success, otherwise NULL
  1071. --*/
  1072. {
  1073. CERT_NAME_BLOB* pBlob;
  1074. DWORD cbNameInfo;
  1075. PCERT_NAME_INFO pNameInfo;
  1076. DWORD cRDN;
  1077. DWORD cAttr;
  1078. PCERT_RDN pRDN;
  1079. PCERT_RDN_ATTR pAttr;
  1080. PCERT_RDN_ATTR* pAttrValues = NULL;
  1081. DWORD cRet = 0;
  1082. DWORD cMaxRet = 0;
  1083. if ( pfnCertCreateCertificateContext == NULL ||
  1084. pfnCryptDecodeObject == NULL )
  1085. {
  1086. SetLastError(ERROR_PROC_NOT_FOUND);
  1087. return NULL;
  1088. }
  1089. *pcElements = 0;
  1090. switch( fi )
  1091. {
  1092. case CERT_FIELD_ISSUER:
  1093. pBlob = &pCertCtx->pCertInfo->Issuer;
  1094. break;
  1095. case CERT_FIELD_SUBJECT:
  1096. pBlob = &pCertCtx->pCertInfo->Subject;
  1097. break;
  1098. case CERT_FIELD_SERIAL_NUMBER:
  1099. pAttrValues = (PCERT_RDN_ATTR*)
  1100. LocalAlloc( LPTR, sizeof( PCERT_RDN_ATTR ) );
  1101. if ( pAttrValues == NULL )
  1102. {
  1103. return NULL;
  1104. }
  1105. *pcElements = 1;
  1106. //
  1107. // Setup a CERT_RDN_ATTR so that GetSubField() can always return a
  1108. // pointer to an array of CERT_RDN_ATTRs
  1109. //
  1110. SerialNumber.dwValueType = CERT_RDN_OCTET_STRING;
  1111. SerialNumber.Value = pCertCtx->pCertInfo->SerialNumber;
  1112. pAttrValues[ 0 ] = &SerialNumber;
  1113. return pAttrValues;
  1114. default:
  1115. return NULL;
  1116. }
  1117. if ( pszAsnName == NULL )
  1118. {
  1119. return NULL;
  1120. }
  1121. if ( (pNameInfo = aniFields[fi]) == NULL )
  1122. {
  1123. if (!(*pfnCryptDecodeObject)(X509_ASN_ENCODING,
  1124. (LPCSTR)X509_NAME,
  1125. pBlob->pbData,
  1126. pBlob->cbData,
  1127. 0,
  1128. NULL,
  1129. &cbNameInfo))
  1130. {
  1131. return NULL;
  1132. }
  1133. if (NULL == (pNameInfo = (PCERT_NAME_INFO)LocalAlloc(LMEM_FIXED,cbNameInfo)))
  1134. {
  1135. return NULL;
  1136. }
  1137. if (!(*pfnCryptDecodeObject)(X509_ASN_ENCODING,
  1138. (LPCSTR)X509_NAME,
  1139. pBlob->pbData,
  1140. pBlob->cbData,
  1141. 0,
  1142. pNameInfo,
  1143. &cbNameInfo))
  1144. {
  1145. LocalFree( pNameInfo );
  1146. return NULL;
  1147. }
  1148. aniFields[fi] = pNameInfo;
  1149. }
  1150. for (cRDN = pNameInfo->cRDN, pRDN = pNameInfo->rgRDN; cRDN > 0; cRDN--, pRDN++)
  1151. {
  1152. for ( cAttr = pRDN->cRDNAttr, pAttr = pRDN->rgRDNAttr ; cAttr > 0 ; cAttr--, ++pAttr )
  1153. {
  1154. if ( !strcmp( pAttr->pszObjId, pszAsnName ) )
  1155. {
  1156. if ( ( cRet + 1 ) > cMaxRet )
  1157. {
  1158. cMaxRet += 10;
  1159. if ( pAttrValues )
  1160. {
  1161. pAttrValues = (PCERT_RDN_ATTR*)
  1162. LocalReAlloc( pAttrValues,
  1163. sizeof( PCERT_RDN_ATTR ) * cMaxRet,
  1164. LMEM_MOVEABLE );
  1165. }
  1166. else
  1167. {
  1168. pAttrValues = (PCERT_RDN_ATTR*)
  1169. LocalAlloc( LPTR,
  1170. sizeof( PCERT_RDN_ATTR ) * cMaxRet );
  1171. }
  1172. if ( pAttrValues == NULL )
  1173. {
  1174. return NULL;
  1175. }
  1176. }
  1177. pAttrValues[ cRet ] = pAttr;
  1178. cRet++;
  1179. }
  1180. }
  1181. }
  1182. *pcElements = cRet;
  1183. return pAttrValues;
  1184. }
  1185. CIssuerStore::CIssuerStore(
  1186. )
  1187. /*++
  1188. Routine Description:
  1189. Constructor
  1190. Arguments:
  1191. None
  1192. Return Value:
  1193. Nothing
  1194. --*/
  1195. {
  1196. INITIALIZE_CRITICAL_SECTION( &m_csLock );
  1197. m_fValid = TRUE;
  1198. }
  1199. CIssuerStore::~CIssuerStore(
  1200. )
  1201. /*++
  1202. Routine Description:
  1203. Destructor
  1204. Arguments:
  1205. None
  1206. Return Value:
  1207. Nothing
  1208. --*/
  1209. {
  1210. DeleteCriticalSection( &m_csLock );
  1211. }
  1212. BOOL
  1213. CIssuerStore::LoadServerAcceptedIssuers(
  1214. )
  1215. /*++
  1216. Routine Description:
  1217. Load the list of recognized issuers from schannel
  1218. Arguments:
  1219. None
  1220. Return Value:
  1221. TRUE if success, otherwise FALSE
  1222. --*/
  1223. {
  1224. //
  1225. // IIS 5 : this should not get called any more because the list of
  1226. // trusted issuers isn't specific to cert mapping any more but is done
  1227. // at a virtual server level; also, the IIS 4 UI to set up such a list is
  1228. // being removed
  1229. //
  1230. DBG_ASSERT( TRUE );
  1231. MD5_CTX md5;
  1232. DWORD dwLen = 0;
  1233. LPBYTE pCerts;
  1234. BOOL fSt = FALSE;
  1235. UINT i;
  1236. if ( pfnGetDefaultIssuers &&
  1237. (pfnGetDefaultIssuers)( NULL, &dwLen ) )
  1238. {
  1239. if ( !(pCerts = (LPBYTE)LocalAlloc( LMEM_FIXED, dwLen )) )
  1240. {
  1241. m_fValid = FALSE;
  1242. return FALSE;
  1243. }
  1244. if ( (pfnGetDefaultIssuers)( pCerts, &dwLen ) )
  1245. {
  1246. fSt = TRUE;
  1247. while ( dwLen && GETDBLEN(pCerts) <= dwLen )
  1248. {
  1249. CHAR achMd5[sizeof(md5.digest)*2 + 1];
  1250. MD5Init( &md5 );
  1251. MD5Update( &md5, pCerts + DBLEN_SIZE, GETDBLEN(pCerts) );
  1252. MD5Final( &md5 );
  1253. for ( i = 0 ; i < sizeof(md5.digest) ; ++i )
  1254. {
  1255. achMd5[i*2] = HEXTOA[md5.digest[i]>>4];
  1256. achMd5[i*2+1] = HEXTOA[md5.digest[i]&0xf];
  1257. }
  1258. achMd5[sizeof(md5.digest)*2] = '\0';
  1259. if ( m_pIssuerNames.AddEntry( achMd5 ) == INDEX_ERROR ||
  1260. m_IssuerCerts.AddEntry( pCerts + DBLEN_SIZE,
  1261. (DWORD)GETDBLEN(pCerts) )
  1262. == INDEX_ERROR )
  1263. {
  1264. m_fValid = FALSE;
  1265. fSt = FALSE;
  1266. break;
  1267. }
  1268. dwLen -= GETDBLEN(pCerts) + DBLEN_SIZE;
  1269. pCerts += GETDBLEN(pCerts) + DBLEN_SIZE;
  1270. }
  1271. }
  1272. LocalFree( pCerts );
  1273. }
  1274. return fSt;
  1275. }
  1276. VOID
  1277. CIssuerStore::Reset(
  1278. )
  1279. /*++
  1280. Routine Description:
  1281. Reset issuer list
  1282. Arguments:
  1283. None
  1284. Return Value:
  1285. None
  1286. --*/
  1287. {
  1288. m_pIssuerNames.Reset();
  1289. m_IssuerCerts.Reset();
  1290. m_fValid = TRUE;
  1291. }
  1292. BOOL
  1293. CIssuerStore::Unserialize(
  1294. CStoreXBF* pX
  1295. )
  1296. /*++
  1297. Routine Description:
  1298. Unserialize issuer list
  1299. Arguments:
  1300. pX - CStoreXBF to unserialize from
  1301. Return Value:
  1302. TRUE if success, otherwise FALSE
  1303. --*/
  1304. {
  1305. LPBYTE pb = pX->GetBuff();
  1306. DWORD dw = pX->GetUsed();
  1307. return Unserialize( &pb, &dw );
  1308. }
  1309. BOOL
  1310. CIssuerStore::Unserialize(
  1311. LPBYTE* ppb,
  1312. LPDWORD pc
  1313. )
  1314. /*++
  1315. Routine Description:
  1316. Unserialize issuer list
  1317. Arguments:
  1318. ppB - ptr to addr of buffer to unserialize from
  1319. pC - ptr to count of bytes in buffer
  1320. Return Value:
  1321. TRUE if success, otherwise FALSE
  1322. --*/
  1323. {
  1324. DWORD dwC;
  1325. Reset();
  1326. if ( ::Unserialize( ppb, pc, &dwC ) &&
  1327. m_pIssuerNames.Unserialize( ppb, pc, dwC ) &&
  1328. m_IssuerCerts.Unserialize( ppb, pc, dwC ) )
  1329. {
  1330. return TRUE;
  1331. }
  1332. m_fValid = FALSE;
  1333. return FALSE;
  1334. }
  1335. BOOL
  1336. CIssuerStore::Serialize(
  1337. CStoreXBF* pX
  1338. )
  1339. /*++
  1340. Routine Description:
  1341. Serialize issuer list
  1342. Arguments:
  1343. pX - CStoreXBF to serialize to
  1344. Return Value:
  1345. TRUE if success, otherwise FALSE
  1346. --*/
  1347. {
  1348. if ( !m_fValid )
  1349. {
  1350. return FALSE;
  1351. }
  1352. return ::Serialize( pX, (DWORD)GetNbIssuers() ) &&
  1353. m_pIssuerNames.Serialize( pX ) &&
  1354. m_IssuerCerts.Serialize( pX );
  1355. }
  1356. BOOL
  1357. CIssuerStore::GetIssuer(
  1358. DWORD i,
  1359. LPSTR* ppszIssuerName,
  1360. LPBYTE* ppIssuer,
  1361. LPDWORD pcIssuer
  1362. )
  1363. /*++
  1364. Routine Description:
  1365. Get issuer from list based on index
  1366. Arguments:
  1367. i - index ( 0-based ) of issuer to retrieve
  1368. ppszIssuerName - updated with ptr to issuer ID
  1369. ppIssuer - updated with ptr to DER encoded issuer
  1370. pcIssuer - updated with byte count in issuer
  1371. Return Value:
  1372. TRUE if success, otherwise FALSE
  1373. --*/
  1374. {
  1375. if ( !m_fValid )
  1376. {
  1377. return FALSE;
  1378. }
  1379. if ( (*ppszIssuerName = m_pIssuerNames.GetEntry( i )) &&
  1380. m_IssuerCerts.GetEntry( i, ppIssuer, pcIssuer ) )
  1381. {
  1382. return TRUE;
  1383. }
  1384. return FALSE;
  1385. }
  1386. BOOL
  1387. CIssuerStore::GetIssuerByName(
  1388. LPSTR pszIssuerName,
  1389. LPBYTE* ppIssuer,
  1390. LPDWORD pcIssuer
  1391. )
  1392. /*++
  1393. Routine Description:
  1394. Get issuer from list based on ID
  1395. Arguments:
  1396. pszIssuerName - issuer ID
  1397. ppIssuer - updated with ptr to DER encoded issuer
  1398. pcIssuer - updated with byte count in issuer
  1399. Return Value:
  1400. TRUE if success, otherwise FALSE
  1401. --*/
  1402. {
  1403. UINT iI;
  1404. UINT iMax;
  1405. if ( !m_fValid )
  1406. {
  1407. return FALSE;
  1408. }
  1409. iMax = GetNbIssuers();
  1410. for ( iI = 0 ; iI < iMax ; ++iI )
  1411. {
  1412. if ( !strcmp( pszIssuerName, m_pIssuerNames.GetEntry( iI ) ) )
  1413. {
  1414. return m_IssuerCerts.GetEntry( iI, ppIssuer, pcIssuer );
  1415. }
  1416. }
  1417. return FALSE;
  1418. }
  1419. CCertGlobalRuleInfo::CCertGlobalRuleInfo(
  1420. )
  1421. /*++
  1422. Routine Description:
  1423. Constructor
  1424. Arguments:
  1425. None
  1426. Return Value:
  1427. Nothing
  1428. --*/
  1429. {
  1430. m_fValid = TRUE;
  1431. m_fEnabled = TRUE;
  1432. }
  1433. CCertGlobalRuleInfo::~CCertGlobalRuleInfo(
  1434. )
  1435. /*++
  1436. Routine Description:
  1437. Destructor
  1438. Arguments:
  1439. None
  1440. Return Value:
  1441. Nothing
  1442. --*/
  1443. {
  1444. }
  1445. BOOL
  1446. CCertGlobalRuleInfo::Reset(
  1447. )
  1448. /*++
  1449. Routine Description:
  1450. Reset to default values
  1451. Arguments:
  1452. None
  1453. Return Value:
  1454. Nothing
  1455. --*/
  1456. {
  1457. m_Order.Reset();
  1458. m_fValid = TRUE;
  1459. m_fEnabled = TRUE;
  1460. return TRUE;
  1461. }
  1462. BOOL
  1463. CCertGlobalRuleInfo::AddRuleOrder(
  1464. )
  1465. /*++
  1466. Routine Description:
  1467. Add a rule at end of rule order array
  1468. Arguments:
  1469. None
  1470. Return Value:
  1471. TRUE if success, otherwise FALSE
  1472. --*/
  1473. {
  1474. DWORD i;
  1475. if ( (i = m_Order.AddPtr( NULL )) != INDEX_ERROR )
  1476. {
  1477. // m_Order.SetPtr( i, (LPVOID) i );
  1478. m_Order.SetPtr( i, i );
  1479. return TRUE;
  1480. }
  1481. m_fValid = FALSE;
  1482. return FALSE;
  1483. }
  1484. BOOL
  1485. CCertGlobalRuleInfo::DeleteRuleById(
  1486. DWORD dwId,
  1487. BOOL DecrementAbove
  1488. )
  1489. /*++
  1490. Routine Description:
  1491. Delete a rule based on index in rules array
  1492. Arguments:
  1493. dwId - index in rules array
  1494. DecrementAbove - flag indicating if items with a index above dwID need
  1495. to be decremented. This is usually caused by the item being removed
  1496. from the main array.
  1497. Return Value:
  1498. TRUE if success, otherwise FALSE
  1499. --*/
  1500. {
  1501. UINT iO;
  1502. UINT iMax = m_Order.GetNbPtr();
  1503. DWORD id;
  1504. for ( iO = 0 ; iO < iMax ; ++iO )
  1505. {
  1506. // if it equals dwID, remove it
  1507. if ( (DWORD_PTR)m_Order.GetPtr( iO ) == dwId )
  1508. {
  1509. m_Order.DeletePtr( iO );
  1510. if ( DecrementAbove )
  1511. {
  1512. // if we have been asked to decrement the remaining items,
  1513. // need to do this in another loop here. Yuck. - Boyd
  1514. iMax = m_Order.GetNbPtr();
  1515. for ( iO = 0 ; iO < iMax ; ++iO )
  1516. {
  1517. // the id in question
  1518. id = (DWORD)((DWORD_PTR)m_Order.GetPtr( iO ));
  1519. // if it is bigger, decrement by one
  1520. if ( id > dwId )
  1521. {
  1522. id--;
  1523. // put it back in place
  1524. // m_Order.SetPtr( iO, (LPVOID) id ); //SUNDOWN ALERT
  1525. m_Order.SetPtr( iO, id ); //SUNDOWN ALERT
  1526. }
  1527. }
  1528. }
  1529. // return early
  1530. return TRUE;
  1531. }
  1532. }
  1533. m_fValid = FALSE;
  1534. return FALSE;
  1535. }
  1536. BOOL
  1537. CCertGlobalRuleInfo::SerializeGlobalRuleInfo(
  1538. CStoreXBF* pX
  1539. )
  1540. /*++
  1541. Routine Description:
  1542. Serialize mapper global information
  1543. Arguments:
  1544. pX - ptr to CStoreXBF to serialize to
  1545. Return Value:
  1546. TRUE if success, otherwise FALSE
  1547. --*/
  1548. {
  1549. return ::Serialize( pX, GetRuleOrderCount() ) &&
  1550. pX->Append( (LPBYTE)GetRuleOrderArray(),
  1551. sizeof(DWORD)*GetRuleOrderCount() ) &&
  1552. ::Serialize( pX, m_fEnabled );
  1553. }
  1554. BOOL
  1555. CCertGlobalRuleInfo::UnserializeGlobalRuleInfo(
  1556. LPBYTE* ppB,
  1557. LPDWORD pC
  1558. )
  1559. /*++
  1560. Routine Description:
  1561. Unserialize mapper global info
  1562. Arguments:
  1563. ppB - ptr to addr of buffer to unserialize from
  1564. pC - ptr to count of bytes in buffer
  1565. Return Value:
  1566. TRUE if success, otherwise FALSE
  1567. --*/
  1568. {
  1569. DWORD dwO;
  1570. Reset();
  1571. return ::Unserialize( ppB, pC, &dwO ) &&
  1572. m_Order.Unserialize( ppB, pC, dwO ) &&
  1573. ::Unserialize( ppB, pC, &m_fEnabled );
  1574. }
  1575. CCertMapRule::CCertMapRule(
  1576. )
  1577. /*++
  1578. Routine Description:
  1579. Constructor
  1580. Arguments:
  1581. None
  1582. Return Value:
  1583. Nothing
  1584. --*/
  1585. {
  1586. m_fEnabled = TRUE;
  1587. m_fDenyAccess = FALSE;
  1588. m_fMatchAllIssuers = TRUE;
  1589. m_fValid = TRUE;
  1590. }
  1591. CCertMapRule::~CCertMapRule(
  1592. )
  1593. /*++
  1594. Routine Description:
  1595. Desctructor
  1596. Arguments:
  1597. None
  1598. Return Value:
  1599. Nothing
  1600. --*/
  1601. {
  1602. }
  1603. VOID
  1604. CCertMapRule::Reset(
  1605. )
  1606. /*++
  1607. Routine Description:
  1608. Reset to default values
  1609. Arguments:
  1610. None
  1611. Return Value:
  1612. Nothing
  1613. --*/
  1614. {
  1615. m_fEnabled = TRUE;
  1616. m_fDenyAccess = FALSE;
  1617. m_fMatchAllIssuers = TRUE;
  1618. m_fValid = TRUE;
  1619. m_asRuleName.Reset();
  1620. m_asAccount.Reset();
  1621. m_asPassword.Reset();
  1622. m_ElemsContent.Reset();
  1623. m_ElemsSubfield.Reset();
  1624. m_ElemsField.Reset();
  1625. m_ElemsFlags.Reset();
  1626. m_Issuers.Reset();
  1627. m_IssuersAcceptStatus.Reset();
  1628. }
  1629. BOOL
  1630. CCertMapRule::Unserialize(
  1631. CStoreXBF* pX
  1632. )
  1633. /*++
  1634. Routine Description:
  1635. Unserialize a mapping rule
  1636. Arguments:
  1637. pX - ptr to CStoreXBF to unserialize from
  1638. Return Value:
  1639. TRUE if successful, FALSE on error
  1640. --*/
  1641. {
  1642. LPBYTE pb = pX->GetBuff();
  1643. DWORD dw = pX->GetUsed();
  1644. return Unserialize( &pb, &dw );
  1645. }
  1646. BOOL
  1647. CCertMapRule::Unserialize(
  1648. LPBYTE* ppb,
  1649. LPDWORD pc
  1650. )
  1651. /*++
  1652. Routine Description:
  1653. Unserialize a mapping rule
  1654. Arguments:
  1655. ppB - ptr to addr of buffer
  1656. pC - ptr to byte count in buffer
  1657. Return Value:
  1658. TRUE if successful, FALSE on error
  1659. --*/
  1660. {
  1661. DWORD dwEl;
  1662. DWORD dwIs;
  1663. Reset();
  1664. if ( m_asRuleName.Unserialize( ppb, pc ) &&
  1665. m_asAccount.Unserialize( ppb, pc ) &&
  1666. m_asPassword.Unserialize( ppb, pc ) &&
  1667. ::Unserialize( ppb, pc, &m_fEnabled ) &&
  1668. ::Unserialize( ppb, pc, &m_fDenyAccess ) &&
  1669. ::Unserialize( ppb, pc, &dwEl ) &&
  1670. m_ElemsContent.Unserialize( ppb, pc, dwEl ) &&
  1671. m_ElemsSubfield.Unserialize( ppb, pc, dwEl ) &&
  1672. m_ElemsField.Unserialize( ppb, pc, dwEl ) &&
  1673. m_ElemsFlags.Unserialize( ppb, pc, dwEl ) &&
  1674. ::Unserialize( ppb, pc, &dwIs ) &&
  1675. m_Issuers.Unserialize( ppb, pc, dwIs ) &&
  1676. m_IssuersAcceptStatus.Unserialize( ppb, pc, dwIs ) &&
  1677. ::Unserialize( ppb, pc, &m_fMatchAllIssuers ) )
  1678. {
  1679. return TRUE;
  1680. }
  1681. m_fValid = FALSE;
  1682. return FALSE;
  1683. }
  1684. BOOL
  1685. CCertMapRule::Serialize(
  1686. CStoreXBF* pX
  1687. )
  1688. /*++
  1689. Routine Description:
  1690. Serialize a rule mapping in CStoreXBF
  1691. Arguments:
  1692. pX - ptr to CStoreXBF where to add serialized DWORD
  1693. Return Value:
  1694. TRUE if successful, FALSE on error
  1695. --*/
  1696. {
  1697. DWORD dwEl;
  1698. DWORD dwIs;
  1699. if ( m_fValid &&
  1700. m_asRuleName.Serialize( pX ) &&
  1701. m_asAccount.Serialize( pX ) &&
  1702. m_asPassword.Serialize( pX ) &&
  1703. ::Serialize( pX, m_fEnabled ) &&
  1704. ::Serialize( pX, m_fDenyAccess ) &&
  1705. ::Serialize( pX, GetRuleElemCount() ) &&
  1706. m_ElemsContent.Serialize( pX ) &&
  1707. m_ElemsSubfield.Serialize( pX ) &&
  1708. m_ElemsField.Serialize( pX ) &&
  1709. m_ElemsFlags.Serialize( pX ) &&
  1710. ::Serialize( pX, m_Issuers.GetNbEntry() ) &&
  1711. m_Issuers.Serialize( pX ) &&
  1712. m_IssuersAcceptStatus.Serialize( pX ) &&
  1713. ::Serialize( pX, m_fMatchAllIssuers ) )
  1714. {
  1715. return TRUE;
  1716. }
  1717. return FALSE;
  1718. }
  1719. BOOL
  1720. CCertMapRule::SetRuleAccount(
  1721. LPSTR pszAcct
  1722. )
  1723. /*++
  1724. Routine Description:
  1725. Set NT account returned by this rule if match
  1726. Arguments:
  1727. pszAcct - NT account to use
  1728. Return Value:
  1729. TRUE if successful, FALSE on error
  1730. error ERROR_INVALID_NAME if replacement name ( %subfield% ) invalid
  1731. --*/
  1732. {
  1733. LPSTR pR;
  1734. LPSTR pD;
  1735. //
  1736. // Check replacement field valid
  1737. //
  1738. if ( pR = strchr( pszAcct, '%' ) )
  1739. {
  1740. ++pR;
  1741. if ( !(pD = strchr( pR, '%' )) )
  1742. {
  1743. SetLastError( ERROR_INVALID_NAME );
  1744. return FALSE;
  1745. }
  1746. *pD = '\0';
  1747. if ( !MapSubFieldToAsn1( pR ) )
  1748. {
  1749. *pD = '%';
  1750. SetLastError( ERROR_INVALID_NAME );
  1751. return FALSE;
  1752. }
  1753. *pD = '%';
  1754. }
  1755. return m_asAccount.Set( pszAcct );
  1756. }
  1757. // return ERROR_INVALID_NAME if no match
  1758. BOOL
  1759. CCertMapRule::Match(
  1760. CDecodedCert* pC,
  1761. CDecodedCert* pAuth,
  1762. LPSTR pszAcct,
  1763. LPSTR pszPwd,
  1764. LPBOOL pfDenied
  1765. )
  1766. /*++
  1767. Routine Description:
  1768. Check if rule match certificate
  1769. Arguments:
  1770. pC - client certificate
  1771. pAuth - certifying authority
  1772. pszAcct - updated with NT account on success,
  1773. assumed to be at least UNLEN+DNLEN+1 long
  1774. pszPwd - updated with NT password on success,
  1775. assumed to be at least UNLEN long
  1776. pfDenied - updated with deny access status for this match on success
  1777. TRUE if access is denied for this match, otherwise FALSE
  1778. Return Value:
  1779. TRUE if successful, FALSE on error
  1780. Errors:
  1781. ERROR_ARENA_TRASHED if rule internal state is invalid
  1782. ERROR_INVALID_NAME if no match
  1783. --*/
  1784. {
  1785. UINT i;
  1786. UINT iMax;
  1787. DWORD cObjLen;
  1788. DWORD cMatch = 0;
  1789. BOOL fSt;
  1790. LPBYTE pMatch = NULL;
  1791. INT iRet;
  1792. BOOL fCaseInsensitive;
  1793. PCERT_RDN_ATTR * pAttrValues;
  1794. DWORD cAttrValues;
  1795. DWORD cAttr;
  1796. PBYTE pContent;
  1797. BOOL fConverted;
  1798. PBYTE pConverted;
  1799. if ( !m_fEnabled )
  1800. {
  1801. return FALSE;
  1802. }
  1803. if ( !m_fValid )
  1804. {
  1805. SetLastError( ERROR_ARENA_TRASHED );
  1806. return FALSE;
  1807. }
  1808. iMax = GetRuleElemCount();
  1809. for ( i = 0 ; i < iMax ; ++i )
  1810. {
  1811. m_ElemsContent.GetEntry( i, &pMatch, &cMatch );
  1812. --cMatch;
  1813. if( pAttrValues = pC->GetSubField(
  1814. (CERT_FIELD_ID)((UINT_PTR)m_ElemsField.GetPtr(i)),
  1815. m_ElemsSubfield.GetEntry( i ), &cAttrValues ) )
  1816. {
  1817. fCaseInsensitive = (DWORD)((DWORD_PTR)m_ElemsFlags.GetPtr(i) & CMR_FLAGS_CASE_INSENSITIVE);
  1818. for ( cAttr = 0;
  1819. cAttr < cAttrValues;
  1820. cAttr++ )
  1821. {
  1822. fConverted = FALSE;
  1823. pContent = pAttrValues[ cAttr ]->Value.pbData;
  1824. cObjLen = pAttrValues[ cAttr ]->Value.cbData;
  1825. if ( pAttrValues[ cAttr ]->dwValueType == CERT_RDN_UNICODE_STRING )
  1826. {
  1827. WCHAR * pNewBuffer;
  1828. cObjLen /= sizeof( WCHAR );
  1829. //
  1830. // Convert UNICODE cert value to multibyte
  1831. //
  1832. iRet = WideCharToMultiByte( CP_ACP,
  1833. 0,
  1834. (WCHAR*) pContent,
  1835. cObjLen,
  1836. NULL,
  1837. 0,
  1838. NULL,
  1839. NULL );
  1840. if ( !iRet )
  1841. {
  1842. fSt = FALSE;
  1843. break;
  1844. }
  1845. pConverted = (PBYTE) LocalAlloc( LPTR, iRet );
  1846. if ( pConverted == NULL )
  1847. {
  1848. fSt = FALSE;
  1849. break;
  1850. }
  1851. iRet = WideCharToMultiByte( CP_ACP,
  1852. 0,
  1853. (WCHAR*) pContent,
  1854. cObjLen,
  1855. (CHAR*) pConverted,
  1856. iRet,
  1857. NULL,
  1858. NULL );
  1859. if ( !iRet )
  1860. {
  1861. fSt = FALSE;
  1862. LocalFree( pConverted );
  1863. break;
  1864. }
  1865. fConverted = TRUE;
  1866. pContent = (PBYTE) pConverted;
  1867. cObjLen = iRet;
  1868. }
  1869. switch ( pMatch[0] )
  1870. {
  1871. case MATCH_ALL:
  1872. fSt = cObjLen == cMatch &&
  1873. ( fCaseInsensitive ?
  1874. !_memicmp( pMatch+1, pContent, cObjLen ) :
  1875. !memcmp( pMatch+1, pContent, cObjLen ) );
  1876. break;
  1877. case MATCH_FIRST:
  1878. fSt = cObjLen >= cMatch &&
  1879. ( fCaseInsensitive ?
  1880. !_memicmp( pMatch+1, pContent, cMatch ) :
  1881. !memcmp( pMatch+1, pContent, cMatch ) );
  1882. break;
  1883. case MATCH_LAST:
  1884. fSt = cObjLen >= cMatch &&
  1885. ( fCaseInsensitive ?
  1886. !_memicmp( pMatch+1, pContent+cObjLen-cMatch, cMatch ) :
  1887. !memcmp( pMatch+1, pContent+cObjLen-cMatch, cMatch ) );
  1888. break;
  1889. case MATCH_IN:
  1890. fSt = memstr( pContent, cObjLen, pMatch + 1, cMatch, fCaseInsensitive ) != NULL;
  1891. break;
  1892. default:
  1893. fSt = FALSE;
  1894. }
  1895. if ( fConverted )
  1896. {
  1897. LocalFree( pConverted );
  1898. pConverted = NULL;
  1899. }
  1900. if ( fSt )
  1901. {
  1902. break;
  1903. }
  1904. }
  1905. LocalFree( pAttrValues );
  1906. pAttrValues = NULL;
  1907. if ( !fSt )
  1908. {
  1909. break;
  1910. }
  1911. }
  1912. else if ( cMatch )
  1913. {
  1914. // non empty rule on n/a subfield : stop looking other matches
  1915. break;
  1916. }
  1917. }
  1918. //
  1919. // if client cert match, check issuers
  1920. //
  1921. if ( i == iMax )
  1922. {
  1923. LPBYTE pStoreIssuer;
  1924. LPVOID pCertIssuer;
  1925. DWORD dwStoreIssuer;
  1926. DWORD dwCertIssuer;
  1927. DWORD iI;
  1928. DWORD iMax;
  1929. LPSTR pszIssuerName;
  1930. BOOL fEnabled;
  1931. BOOL fSt = TRUE;
  1932. #if 0 // For IIS 5, there's no list of accepted issuers for mappings
  1933. //
  1934. // Check issuer matches
  1935. //
  1936. if ( !(fSt = GetMatchAllIssuer()) )
  1937. {
  1938. if ( pAuth->GetIssuer( &pCertIssuer, &dwCertIssuer ) )
  1939. {
  1940. pIssuerStore->Lock();
  1941. iMax = GetIssuerCount();
  1942. for ( iI = 0 ; iI < iMax ; ++iI )
  1943. {
  1944. if ( GetIssuerEntry( iI,
  1945. &fEnabled,
  1946. &pszIssuerName ) &&
  1947. fEnabled &&
  1948. pIssuerStore->GetIssuerByName( pszIssuerName,
  1949. &pStoreIssuer,
  1950. &dwStoreIssuer ) &&
  1951. dwStoreIssuer == dwCertIssuer &&
  1952. !memcmp( pStoreIssuer,
  1953. pCertIssuer,
  1954. dwCertIssuer ) )
  1955. {
  1956. fSt = TRUE;
  1957. break;
  1958. }
  1959. }
  1960. pIssuerStore->Unlock();
  1961. }
  1962. else
  1963. {
  1964. fSt = FALSE;
  1965. }
  1966. }
  1967. #endif //if 0
  1968. if ( fSt )
  1969. {
  1970. *pfDenied = m_fDenyAccess;
  1971. LPSTR pA = GetRuleAccount();
  1972. LPSTR pR;
  1973. LPSTR pD;
  1974. DWORD dwLen;
  1975. if ( pA )
  1976. {
  1977. if ( pR = strchr( pA, '%' ) )
  1978. {
  1979. ++pR;
  1980. // copy domain
  1981. #if 1 // DBCS enabling for user name
  1982. if ( pD = (PCHAR)_mbschr( (PUCHAR)pA, '\\' ) )
  1983. #else
  1984. if ( pD = strchr( pA, '\\' ) )
  1985. #endif
  1986. {
  1987. memcpy( pszAcct, pA, DIFF(pD - pA) + 1 );
  1988. pszAcct += pD - pA + 1;
  1989. }
  1990. // extract field
  1991. if ( pD = strchr( pR, '%' ) )
  1992. {
  1993. memcpy( pszAcct, pR, DIFF(pD - pR) );
  1994. pszAcct[ pD - pR ] = '\0';
  1995. pAttrValues = pC->GetSubField( CERT_FIELD_SUBJECT,
  1996. MapSubFieldToAsn1( pszAcct ),
  1997. &cAttrValues );
  1998. if ( pAttrValues != NULL )
  1999. {
  2000. memcpy( pszAcct,
  2001. pAttrValues[ 0 ]->Value.pbData,
  2002. pAttrValues[ 0 ]->Value.cbData );
  2003. pszAcct[ pAttrValues[ 0 ]->Value.cbData ] = '\0';
  2004. strcpy( pszPwd, GetRulePassword() );
  2005. LocalFree( pAttrValues );
  2006. pAttrValues = NULL;
  2007. }
  2008. else
  2009. {
  2010. SetLastError( ERROR_INVALID_NAME );
  2011. fSt = FALSE;
  2012. }
  2013. }
  2014. else
  2015. {
  2016. SetLastError( ERROR_INVALID_NAME );
  2017. fSt = FALSE;
  2018. }
  2019. }
  2020. else
  2021. {
  2022. strcpy( pszAcct, pA );
  2023. strcpy( pszPwd, GetRulePassword() );
  2024. }
  2025. }
  2026. else
  2027. {
  2028. SetLastError( ERROR_INVALID_PARAMETER );
  2029. fSt = FALSE;
  2030. }
  2031. }
  2032. return fSt;
  2033. }
  2034. SetLastError( ERROR_INVALID_NAME );
  2035. return FALSE;
  2036. }
  2037. BOOL
  2038. CCertMapRule::GetRuleElem(
  2039. DWORD i,
  2040. CERT_FIELD_ID* pfiField,
  2041. LPSTR* ppContent,
  2042. LPDWORD pcContent,
  2043. LPSTR* ppSubField,
  2044. LPDWORD pdwFlags
  2045. )
  2046. /*++
  2047. Routine Description:
  2048. Access a rule element
  2049. Arguments:
  2050. i - index ( 0-based ) of element to access
  2051. pfiField - updated with CERT_FIELD_ID of this element
  2052. ppContent - updated with ptr to match binary form
  2053. pcContent - updated with length of match binary form
  2054. ppSubField - updated with ASN.1 name of cert sub-field for match
  2055. pdwFlags - updated with flags
  2056. Return Value:
  2057. TRUE if successful, FALSE on error
  2058. --*/
  2059. {
  2060. if ( !m_fValid )
  2061. {
  2062. SetLastError( ERROR_ARENA_TRASHED );
  2063. return FALSE;
  2064. }
  2065. if ( (*ppSubField = m_ElemsSubfield.GetEntry( i )) &&
  2066. m_ElemsContent.GetEntry( i, (LPBYTE*)ppContent, pcContent ) )
  2067. {
  2068. *pfiField = (CERT_FIELD_ID)((UINT_PTR)m_ElemsField.GetPtr( i ));
  2069. if ( pdwFlags )
  2070. {
  2071. *pdwFlags = (DWORD)((DWORD_PTR)m_ElemsFlags.GetPtr( i ));
  2072. }
  2073. return TRUE;
  2074. }
  2075. return FALSE;
  2076. }
  2077. BOOL
  2078. CCertMapRule::DeleteRuleElem(
  2079. DWORD i
  2080. )
  2081. /*++
  2082. Routine Description:
  2083. Delete a rule element
  2084. Arguments:
  2085. i - index ( 0-based ) of element to delete
  2086. Return Value:
  2087. TRUE if successful, FALSE on error
  2088. --*/
  2089. {
  2090. if ( !m_fValid )
  2091. {
  2092. SetLastError( ERROR_ARENA_TRASHED );
  2093. return FALSE;
  2094. }
  2095. if ( m_ElemsContent.DeleteEntry( i ) &&
  2096. m_ElemsSubfield.DeleteEntry( i ) &&
  2097. m_ElemsField.DeletePtr( i ) &&
  2098. m_ElemsFlags.DeletePtr( i ) )
  2099. {
  2100. return TRUE;
  2101. }
  2102. m_fValid = FALSE;
  2103. return FALSE;
  2104. }
  2105. BOOL
  2106. CCertMapRule::DeleteRuleElemsByField(
  2107. CERT_FIELD_ID fiField
  2108. )
  2109. /*++
  2110. Routine Description:
  2111. Delete rule elements based on CERT_FIELD_ID
  2112. Arguments:
  2113. fiField - CERT_FIELD_ID of elements to delete
  2114. Return Value:
  2115. TRUE if successful ( even if no element deleted ), FALSE on error
  2116. --*/
  2117. {
  2118. UINT i;
  2119. UINT iMax;
  2120. if ( !m_fValid )
  2121. {
  2122. SetLastError( ERROR_ARENA_TRASHED );
  2123. return FALSE;
  2124. }
  2125. iMax = GetRuleElemCount();
  2126. for ( i = 0 ; i < iMax ; ++i )
  2127. {
  2128. if ( fiField == (CERT_FIELD_ID)((UINT_PTR)m_ElemsField.GetPtr(i) ))
  2129. {
  2130. if ( !DeleteRuleElem( i ) )
  2131. {
  2132. m_fValid = FALSE;
  2133. return FALSE;
  2134. }
  2135. --i;
  2136. }
  2137. }
  2138. return TRUE;
  2139. }
  2140. DWORD
  2141. CCertMapRule::AddRuleElem(
  2142. DWORD iBefore,
  2143. CERT_FIELD_ID fiField,
  2144. LPSTR pszSubField,
  2145. LPBYTE pContent,
  2146. DWORD cContent,
  2147. DWORD dwFlags
  2148. )
  2149. /*++
  2150. Routine Description:
  2151. Add a rule element
  2152. Arguments:
  2153. iBefore - index ( 0-based ) of where to insert in list,
  2154. 0xffffffff to append to list
  2155. fiField - CERT_FIELD_ID of this element
  2156. pSubField - ASN.1 name of cert sub-field for match
  2157. pContent - ptr to match binary form
  2158. cContent - length of match binary form
  2159. dwFlags - flags ( CMR_FLAGS_* )
  2160. Return Value:
  2161. TRUE if successful, FALSE on error
  2162. --*/
  2163. {
  2164. if ( !m_fValid )
  2165. {
  2166. SetLastError( ERROR_ARENA_TRASHED );
  2167. return FALSE;
  2168. }
  2169. if ( m_ElemsContent.InsertEntry( iBefore, (LPSTR)pContent, cContent ) != INDEX_ERROR &&
  2170. m_ElemsSubfield.InsertEntry( iBefore, pszSubField ) != INDEX_ERROR &&
  2171. m_ElemsField.InsertPtr( iBefore, (LPVOID)fiField ) != INDEX_ERROR &&
  2172. m_ElemsFlags.InsertPtr( iBefore, ULongToPtr(dwFlags) ) != INDEX_ERROR )
  2173. {
  2174. return TRUE;
  2175. }
  2176. m_fValid = FALSE;
  2177. return FALSE;
  2178. }
  2179. BOOL
  2180. CCertMapRule::GetIssuerEntry(
  2181. DWORD i,
  2182. LPBOOL pfS,
  2183. LPSTR* ppszI
  2184. )
  2185. /*++
  2186. Routine Description:
  2187. Get issuer entry from issuer list
  2188. Arguments:
  2189. i - index ( 0-based ) of element to delete
  2190. pfS - updated with issuer accept status
  2191. ppszI - updated with ptr to issuer ID
  2192. Return Value:
  2193. TRUE if successful ( even if no element deleted ), FALSE on error
  2194. --*/
  2195. {
  2196. if ( i < m_Issuers.GetNbEntry() )
  2197. {
  2198. *ppszI = m_Issuers.GetEntry( i );
  2199. *pfS = (BOOL) ((DWORD_PTR)m_IssuersAcceptStatus.GetPtr( i ));
  2200. return TRUE;
  2201. }
  2202. return FALSE;
  2203. }
  2204. BOOL
  2205. CCertMapRule::GetIssuerEntryByName(
  2206. LPSTR pszName,
  2207. LPBOOL pfS
  2208. )
  2209. /*++
  2210. Routine Description:
  2211. Get issuer entry from issuer list
  2212. Arguments:
  2213. pszName - issuer ID
  2214. pfS - updated with issuer accept status
  2215. Return Value:
  2216. TRUE if successful ( even if no element deleted ), FALSE on error
  2217. --*/
  2218. {
  2219. UINT i;
  2220. UINT iMx = m_Issuers.GetNbEntry();
  2221. for ( i = 0 ; i < iMx ; ++i )
  2222. {
  2223. if ( !strcmp( m_Issuers.GetEntry( i ), pszName ) )
  2224. {
  2225. *pfS = (BOOL) ((DWORD_PTR)m_IssuersAcceptStatus.GetPtr( i ));
  2226. return TRUE;
  2227. }
  2228. }
  2229. return FALSE;
  2230. }
  2231. BOOL
  2232. CCertMapRule::SetIssuerEntryAcceptStatus(
  2233. DWORD i,
  2234. BOOL fAcceptStatus
  2235. )
  2236. /*++
  2237. Routine Description:
  2238. Set issuer entry accept status
  2239. Arguments:
  2240. i - index ( 0-based ) of element to update
  2241. fAcceptStatus - issuer accept status
  2242. Return Value:
  2243. TRUE if successful, FALSE on error
  2244. --*/
  2245. {
  2246. return m_IssuersAcceptStatus.SetPtr( i, ULongToPtr(fAcceptStatus) );
  2247. }
  2248. BOOL
  2249. CCertMapRule::AddIssuerEntry(
  2250. LPSTR pszName,
  2251. BOOL fAcceptStatus
  2252. )
  2253. /*++
  2254. Routine Description:
  2255. Add issuer entry to issuer list
  2256. Arguments:
  2257. pszName - issuer ID
  2258. fAcceptStatus - issuer accept status
  2259. Return Value:
  2260. TRUE if success, otherwise FALSE
  2261. --*/
  2262. {
  2263. if ( m_Issuers.AddEntry( pszName ) != INDEX_ERROR &&
  2264. m_IssuersAcceptStatus.AddPtr( ULongToPtr((ULONG)fAcceptStatus) ) != INDEX_ERROR )
  2265. {
  2266. return TRUE;
  2267. }
  2268. m_fValid = FALSE;
  2269. return FALSE;
  2270. }
  2271. BOOL
  2272. CCertMapRule::DeleteIssuerEntry(
  2273. DWORD i
  2274. )
  2275. /*++
  2276. Routine Description:
  2277. Delete an issuer entry
  2278. Arguments:
  2279. i - index ( 0-based ) of element to delete
  2280. Return Value:
  2281. TRUE if successful, FALSE on error
  2282. --*/
  2283. {
  2284. if ( m_Issuers.DeleteEntry( i ) &&
  2285. m_IssuersAcceptStatus.DeletePtr( i ) )
  2286. {
  2287. return TRUE;
  2288. }
  2289. return FALSE;
  2290. }
  2291. CIisRuleMapper::CIisRuleMapper(
  2292. )
  2293. /*++
  2294. Routine Description:
  2295. Constructor
  2296. Arguments:
  2297. None
  2298. Return Value:
  2299. Nothing
  2300. --*/
  2301. {
  2302. INITIALIZE_CRITICAL_SECTION( &m_csLock );
  2303. m_fValid = TRUE;
  2304. }
  2305. CIisRuleMapper::~CIisRuleMapper(
  2306. )
  2307. /*++
  2308. Routine Description:
  2309. Destructor
  2310. Arguments:
  2311. None
  2312. Return Value:
  2313. Nothing
  2314. --*/
  2315. {
  2316. UINT i;
  2317. UINT iMax = GetRuleCount();
  2318. for ( i = 0 ; i < iMax ; ++i )
  2319. {
  2320. delete (CCertMapRule*)GetRule( i );
  2321. }
  2322. DeleteCriticalSection( &m_csLock );
  2323. }
  2324. BOOL
  2325. CIisRuleMapper::Reset(
  2326. )
  2327. /*++
  2328. Routine Description:
  2329. Reset to default values
  2330. Arguments:
  2331. None
  2332. Return Value:
  2333. Nothing
  2334. --*/
  2335. {
  2336. m_GlobalRuleInfo.Reset();
  2337. UINT i;
  2338. UINT iMax = GetRuleCount();
  2339. for ( i = 0 ; i < iMax ; ++i )
  2340. {
  2341. delete (CCertMapRule*)GetRule( i );
  2342. }
  2343. m_Rules.Reset();
  2344. m_fValid = TRUE;
  2345. return TRUE;
  2346. }
  2347. BOOL
  2348. CIisRuleMapper::Load(
  2349. LPSTR pszInstanceId
  2350. )
  2351. /*++
  2352. Routine Description:
  2353. Load a serialized mapper from file
  2354. Arguments:
  2355. pszInstanceId - filename
  2356. Return Value:
  2357. TRUE if success, otherwise FALSE
  2358. --*/
  2359. {
  2360. CStoreXBF sxSer;
  2361. DWORD dwMx;
  2362. LPBYTE pb;
  2363. DWORD c;
  2364. CCertMapRule * pR;
  2365. DWORD ir;
  2366. HANDLE hFile;
  2367. UINT i;
  2368. BOOL fSt = FALSE;
  2369. if ( (hFile = CreateFile( pszInstanceId,
  2370. GENERIC_READ,
  2371. FILE_SHARE_READ|FILE_SHARE_WRITE,
  2372. NULL,
  2373. OPEN_EXISTING,
  2374. FILE_ATTRIBUTE_NORMAL,
  2375. NULL )) != INVALID_HANDLE_VALUE &&
  2376. sxSer.Load( hFile ) )
  2377. {
  2378. fSt = Unserialize( &sxSer );
  2379. }
  2380. if ( hFile != INVALID_HANDLE_VALUE )
  2381. {
  2382. CloseHandle( hFile );
  2383. }
  2384. return fSt;
  2385. }
  2386. BOOL
  2387. CIisRuleMapper::Save(
  2388. LPSTR pszInstanceId
  2389. )
  2390. /*++
  2391. Routine Description:
  2392. Save a mapper to file
  2393. Arguments:
  2394. pszInstanceId - filename
  2395. Return Value:
  2396. TRUE if success, otherwise FALSE
  2397. --*/
  2398. {
  2399. CStoreXBF sxSer( 1024 );
  2400. HANDLE hFile;
  2401. BOOL fSt = FALSE;
  2402. if ( Serialize( &sxSer ) )
  2403. {
  2404. if ( (hFile = CreateFile( pszInstanceId,
  2405. GENERIC_WRITE,
  2406. FILE_SHARE_READ|FILE_SHARE_WRITE,
  2407. NULL,
  2408. CREATE_ALWAYS,
  2409. FILE_ATTRIBUTE_NORMAL,
  2410. NULL )) != INVALID_HANDLE_VALUE &&
  2411. sxSer.Save( hFile ) )
  2412. {
  2413. fSt = TRUE;
  2414. }
  2415. if ( hFile != INVALID_HANDLE_VALUE )
  2416. {
  2417. CloseHandle( hFile );
  2418. }
  2419. }
  2420. return fSt;
  2421. }
  2422. BOOL
  2423. CIisRuleMapper::Unserialize(
  2424. CStoreXBF* pX
  2425. )
  2426. /*++
  2427. Routine Description:
  2428. Unserialize rule mapper
  2429. Arguments:
  2430. pX - CStoreXBF to unserialize from
  2431. Return Value:
  2432. TRUE if success, otherwise FALSE
  2433. --*/
  2434. {
  2435. LPBYTE pb = pX->GetBuff();
  2436. DWORD dw = pX->GetUsed();
  2437. return Unserialize( &pb, &dw );
  2438. }
  2439. #if defined( CRYPT_RULE_MAPPER )
  2440. BOOL
  2441. CIisRuleMapper::Unserialize(
  2442. LPBYTE* ppb,
  2443. LPDWORD pc
  2444. )
  2445. /*++
  2446. Routine Description:
  2447. Unserialize rule mapper
  2448. Arguments:
  2449. ppB - ptr to addr of buffer
  2450. pC - ptr to byte count in buffer
  2451. Return Value:
  2452. TRUE if success, otherwise FALSE
  2453. --*/
  2454. {
  2455. DWORD dwMx;
  2456. CCertMapRule * pR;
  2457. DWORD ir;
  2458. HANDLE hFile;
  2459. UINT i;
  2460. BOOL fSt = FALSE;
  2461. IIS_CRYPTO_STORAGE storage;
  2462. DWORD dwType;
  2463. if ( (IISCryptoGetBlobLength( (PIIS_CRYPTO_BLOB)*ppb ) > *pc ) ||
  2464. FAILED(storage.Initialize( (PIIS_CRYPTO_BLOB)*ppb)) )
  2465. {
  2466. return FALSE;
  2467. }
  2468. LockRules();
  2469. Reset();
  2470. *pc -= IISCryptoGetBlobLength( (PIIS_CRYPTO_BLOB)*ppb );
  2471. *ppb += IISCryptoGetBlobLength( (PIIS_CRYPTO_BLOB)*ppb );
  2472. if ( SUCCEEDED(storage.DecryptData( (PVOID*)ppb, pc, &dwType,
  2473. (PIIS_CRYPTO_BLOB)*ppb )) &&
  2474. m_GlobalRuleInfo.UnserializeGlobalRuleInfo( ppb, pc ) &&
  2475. ::Unserialize( ppb, pc, &dwMx ) )
  2476. {
  2477. fSt = TRUE;
  2478. for ( i = 0 ; i < dwMx ; ++i )
  2479. {
  2480. if ( !(pR = new CCertMapRule()) ||
  2481. (ir = m_Rules.AddPtr( (LPVOID)pR )) == INDEX_ERROR ||
  2482. !pR->Unserialize( ppb, pc ) )
  2483. {
  2484. fSt = FALSE;
  2485. m_fValid = FALSE;
  2486. if ( pR != NULL )
  2487. {
  2488. delete pR;
  2489. }
  2490. break;
  2491. }
  2492. }
  2493. }
  2494. else
  2495. {
  2496. m_fValid = FALSE;
  2497. }
  2498. UnlockRules();
  2499. return fSt;
  2500. }
  2501. BOOL
  2502. CIisRuleMapper::Serialize(
  2503. CStoreXBF* psxSer
  2504. )
  2505. /*++
  2506. Routine Description:
  2507. Serialize all rules
  2508. Arguments:
  2509. psxSer - ptr to CStoreXBF where to serialize
  2510. Return Value:
  2511. TRUE if successful, FALSE on error
  2512. --*/
  2513. {
  2514. BOOL fSt = FALSE;
  2515. UINT i;
  2516. DWORD dwMx;
  2517. CStoreXBF sxSer;
  2518. IIS_CRYPTO_STORAGE storage;
  2519. PIIS_CRYPTO_BLOB blob;
  2520. DWORD dwSesKey;
  2521. LPBYTE pB;
  2522. LockRules();
  2523. if ( m_fValid )
  2524. {
  2525. dwMx = m_Rules.GetNbPtr();
  2526. if ( m_GlobalRuleInfo.SerializeGlobalRuleInfo( &sxSer ) &&
  2527. ::Serialize( &sxSer, dwMx ) )
  2528. {
  2529. fSt = TRUE;
  2530. for ( i = 0 ; i < dwMx ; ++i )
  2531. {
  2532. if ( !GetRule(i)->Serialize( &sxSer ) )
  2533. {
  2534. fSt = FALSE;
  2535. break;
  2536. }
  2537. }
  2538. }
  2539. }
  2540. UnlockRules();
  2541. if ( fSt )
  2542. {
  2543. //
  2544. // Encrypt blob
  2545. //
  2546. fSt = FALSE;
  2547. storage.Initialize();
  2548. if ( SUCCEEDED(storage.GetSessionKeyBlob( &blob )) )
  2549. {
  2550. dwSesKey = IISCryptoGetBlobLength( blob );
  2551. if ( psxSer->Append( (LPBYTE)blob, (DWORD)dwSesKey ) &&
  2552. SUCCEEDED(storage.EncryptData( (PIIS_CRYPTO_BLOB*)&pB,
  2553. sxSer.GetBuff(),
  2554. sxSer.GetUsed(), REG_BINARY )) &&
  2555. psxSer->Append( (LPBYTE)pB,
  2556. (DWORD)IISCryptoGetBlobLength( (PIIS_CRYPTO_BLOB)pB )) )
  2557. {
  2558. IISCryptoFreeBlob( (PIIS_CRYPTO_BLOB)pB );
  2559. fSt = TRUE;
  2560. }
  2561. }
  2562. }
  2563. return fSt;
  2564. }
  2565. #else
  2566. BOOL
  2567. CIisRuleMapper::Unserialize(
  2568. LPBYTE* ppb,
  2569. LPDWORD pc
  2570. )
  2571. /*++
  2572. Routine Description:
  2573. Unserialize rule mapper
  2574. Arguments:
  2575. ppB - ptr to addr of buffer
  2576. pC - ptr to byte count in buffer
  2577. Return Value:
  2578. TRUE if success, otherwise FALSE
  2579. --*/
  2580. {
  2581. DWORD dwMx;
  2582. CCertMapRule * pR;
  2583. DWORD ir;
  2584. HANDLE hFile;
  2585. UINT i;
  2586. BOOL fSt = FALSE;
  2587. LockRules();
  2588. Reset();
  2589. if ( m_GlobalRuleInfo.UnserializeGlobalRuleInfo( ppb, pc ) &&
  2590. ::Unserialize( ppb, pc, &dwMx ) )
  2591. {
  2592. fSt = TRUE;
  2593. for ( i = 0 ; i < dwMx ; ++i )
  2594. {
  2595. if ( !(pR = new CCertMapRule()) ||
  2596. (ir = m_Rules.AddPtr( (LPVOID)pR )) == INDEX_ERROR ||
  2597. !pR->Unserialize( ppb, pc ) )
  2598. {
  2599. fSt = FALSE;
  2600. m_fValid = FALSE;
  2601. if ( pR != NULL )
  2602. {
  2603. delete pR;
  2604. }
  2605. break;
  2606. }
  2607. }
  2608. }
  2609. else
  2610. {
  2611. m_fValid = FALSE;
  2612. }
  2613. UnlockRules();
  2614. return fSt;
  2615. }
  2616. BOOL
  2617. CIisRuleMapper::Serialize(
  2618. CStoreXBF* psxSer
  2619. )
  2620. /*++
  2621. Routine Description:
  2622. Serialize all rules
  2623. Arguments:
  2624. psxSer - ptr to CStoreXBF where to serialize
  2625. Return Value:
  2626. TRUE if successful, FALSE on error
  2627. --*/
  2628. {
  2629. BOOL fSt = FALSE;
  2630. UINT i;
  2631. DWORD dwMx;
  2632. LockRules();
  2633. if ( m_fValid )
  2634. {
  2635. dwMx = m_Rules.GetNbPtr();
  2636. if ( m_GlobalRuleInfo.SerializeGlobalRuleInfo( psxSer ) &&
  2637. ::Serialize( psxSer, dwMx ) )
  2638. {
  2639. fSt = TRUE;
  2640. for ( i = 0 ; i < dwMx ; ++i )
  2641. {
  2642. if ( !GetRule(i)->Serialize( psxSer ) )
  2643. {
  2644. fSt = FALSE;
  2645. break;
  2646. }
  2647. }
  2648. }
  2649. }
  2650. UnlockRules();
  2651. return fSt;
  2652. }
  2653. #endif
  2654. BOOL
  2655. CIisRuleMapper::DeleteRule(
  2656. DWORD dwI
  2657. )
  2658. /*++
  2659. Routine Description:
  2660. Delete a rule
  2661. Arguments:
  2662. dwI - index ( 0-based ) of rule to delete
  2663. Return Value:
  2664. TRUE if successful, FALSE on error
  2665. --*/
  2666. {
  2667. if ( dwI < GetRuleCount() )
  2668. {
  2669. if ( m_Rules.DeletePtr( dwI ) &&
  2670. m_GlobalRuleInfo.DeleteRuleById( dwI, TRUE ) )
  2671. {
  2672. return TRUE;
  2673. }
  2674. m_fValid = FALSE;
  2675. }
  2676. return FALSE;
  2677. }
  2678. DWORD
  2679. CIisRuleMapper::AddRule(
  2680. )
  2681. /*++
  2682. Routine Description:
  2683. Add an empty rule
  2684. Arguments:
  2685. None
  2686. Return Value:
  2687. index of added rule or INDEX_ERROR if error
  2688. --*/
  2689. {
  2690. CCertMapRule *pR;
  2691. DWORD i;
  2692. if ( pR = new CCertMapRule() )
  2693. {
  2694. if ( (i = m_Rules.AddPtr( (LPVOID)pR )) != INDEX_ERROR )
  2695. {
  2696. if ( m_GlobalRuleInfo.AddRuleOrder() )
  2697. {
  2698. return i;
  2699. }
  2700. m_fValid = FALSE;
  2701. /* INTRINSA suppress = leaks */
  2702. return INDEX_ERROR;
  2703. }
  2704. m_fValid = FALSE;
  2705. delete pR;
  2706. }
  2707. return INDEX_ERROR;
  2708. }
  2709. DWORD
  2710. CIisRuleMapper::AddRule(
  2711. CCertMapRule *pR
  2712. )
  2713. /*++
  2714. Routine Description:
  2715. Add a rule
  2716. Arguments:
  2717. pR - rule to add
  2718. Return Value:
  2719. index of added rule or INDEX_ERROR if error
  2720. --*/
  2721. {
  2722. DWORD i;
  2723. if ( (i = m_Rules.AddPtr( (LPVOID)pR )) != INDEX_ERROR )
  2724. {
  2725. if ( m_GlobalRuleInfo.AddRuleOrder() )
  2726. {
  2727. return i;
  2728. }
  2729. }
  2730. m_fValid = FALSE;
  2731. return INDEX_ERROR;
  2732. }
  2733. BOOL
  2734. CIisRuleMapper::Match(
  2735. PCERT_CONTEXT pCert,
  2736. PCERT_CONTEXT pAuth,
  2737. LPSTR pszAcct,
  2738. LPSTR pszPwd
  2739. )
  2740. /*++
  2741. Routine Description:
  2742. Check if rule match certificate
  2743. WARNING: must be called inside lock
  2744. Arguments:
  2745. pCert - client cert
  2746. pAuth - Certifying Authority or NULL if not recognized
  2747. cbLen - ptr to DER encoded cert
  2748. pszAcct - updated with NT account on success,
  2749. assumed to be at least UNLEN+DNLEN+1 long
  2750. pszPwd - updated with NT password on success,
  2751. assumed to be at least UNLEN+1 long
  2752. Return Value:
  2753. TRUE if successful, FALSE on error
  2754. Errors:
  2755. ERROR_ARENA_TRASHED if rule internal state is invalid
  2756. ERROR_INVALID_NAME if no match
  2757. ERROR_ACCESS_DENIED if match and denied access
  2758. --*/
  2759. {
  2760. UINT iR;
  2761. UINT iMax;
  2762. LPDWORD pdwOrder;
  2763. CDecodedCert dcCert( pCert );
  2764. CDecodedCert dcAuth( pAuth );
  2765. BOOL fSt = FALSE;
  2766. BOOL fDenied;
  2767. LockRules();
  2768. if ( !IsValid() || !m_GlobalRuleInfo.IsValid() )
  2769. {
  2770. SetLastError( ERROR_ARENA_TRASHED );
  2771. goto ex;
  2772. }
  2773. if ( !m_GlobalRuleInfo.GetRulesEnabled() )
  2774. {
  2775. SetLastError( ERROR_INVALID_NAME );
  2776. goto ex;
  2777. }
  2778. iMax = GetRuleCount();
  2779. if ( iMax == 0 )
  2780. {
  2781. SetLastError( ERROR_INVALID_NAME );
  2782. goto ex;
  2783. }
  2784. pdwOrder = m_GlobalRuleInfo.GetRuleOrderArray();
  2785. for ( iR = 0 ; iR < iMax ; ++iR )
  2786. {
  2787. if ( ((CCertMapRule*)m_Rules.GetPtr(pdwOrder[iR]))->Match(
  2788. &dcCert, &dcAuth, pszAcct, pszPwd, &fDenied ) )
  2789. {
  2790. if ( fDenied )
  2791. {
  2792. SetLastError( ERROR_ACCESS_DENIED );
  2793. fSt = FALSE;
  2794. }
  2795. else
  2796. {
  2797. fSt = TRUE;
  2798. }
  2799. break;
  2800. }
  2801. }
  2802. ex:
  2803. UnlockRules();
  2804. return fSt;
  2805. }
  2806. CERT_FIELD_ID
  2807. MapFieldToId(
  2808. LPSTR pField
  2809. )
  2810. /*++
  2811. Routine Description:
  2812. Map field name ( "Issuer", ... ) to ID
  2813. Arguments:
  2814. pField - field name
  2815. Return Value:
  2816. CERT_FIELD_ID of field or CERT_FIELD_ERROR if error
  2817. --*/
  2818. {
  2819. UINT x;
  2820. for ( x = 0 ; x < sizeof(aMapField)/sizeof(MAP_FIELD) ; ++x )
  2821. {
  2822. if ( !_stricmp( pField, aMapField[x].pTextName ) )
  2823. {
  2824. return aMapField[x].dwId;
  2825. }
  2826. }
  2827. return CERT_FIELD_ERROR;
  2828. }
  2829. LPSTR
  2830. MapIdToField(
  2831. CERT_FIELD_ID dwId
  2832. )
  2833. /*++
  2834. Routine Description:
  2835. Map ID to field name ( "Issuer", ... )
  2836. Arguments:
  2837. dwId - field ID
  2838. Return Value:
  2839. TRUE if successful, FALSE on error
  2840. --*/
  2841. {
  2842. UINT x;
  2843. for ( x = 0 ; x < sizeof(aMapField)/sizeof(MAP_FIELD) ; ++x )
  2844. {
  2845. if ( dwId == aMapField[x].dwId )
  2846. {
  2847. return aMapField[x].pTextName;
  2848. }
  2849. }
  2850. return NULL;
  2851. }
  2852. DWORD
  2853. GetIdFlags(
  2854. CERT_FIELD_ID dwId
  2855. )
  2856. /*++
  2857. Routine Description:
  2858. Get flags for specified ID
  2859. Arguments:
  2860. dwId - field ID
  2861. Return Value:
  2862. ID flags if success, otherwise 0xffffffff
  2863. --*/
  2864. {
  2865. if ( dwId < CERT_FIELD_LAST )
  2866. {
  2867. return adwFieldFlags[dwId];
  2868. }
  2869. return 0xffffffff;
  2870. }
  2871. LPSTR
  2872. MapSubFieldToAsn1(
  2873. LPSTR pszSubField
  2874. )
  2875. /*++
  2876. Routine Description:
  2877. Map field name ( "OU", ... ) to ASN.1 name
  2878. Arguments:
  2879. pszSubField - subfield name
  2880. Return Value:
  2881. ptr to ASN.1 name or NULL if error
  2882. --*/
  2883. {
  2884. UINT x;
  2885. for ( x = 0 ; x < sizeof(aMapAsn)/sizeof(MAP_ASN) ; ++x )
  2886. {
  2887. if ( !strcmp( pszSubField, aMapAsn[x].pTextName ) )
  2888. {
  2889. return aMapAsn[x].pAsnName;
  2890. }
  2891. }
  2892. return NULL;
  2893. }
  2894. LPSTR
  2895. MapAsn1ToSubField(
  2896. LPSTR pszAsn1
  2897. )
  2898. /*++
  2899. Routine Description:
  2900. Map ID to field name ( "OU", ... )
  2901. Arguments:
  2902. pszAsn1 - ASN.1 name
  2903. Return Value:
  2904. sub field name or ASN.1 name if conversion not found
  2905. --*/
  2906. {
  2907. UINT x;
  2908. for ( x = 0 ; x < sizeof(aMapAsn)/sizeof(MAP_ASN) ; ++x )
  2909. {
  2910. if ( !strcmp( pszAsn1, aMapAsn[x].pAsnName ) )
  2911. {
  2912. return aMapAsn[x].pTextName;
  2913. }
  2914. }
  2915. return pszAsn1;
  2916. }
  2917. LPSTR
  2918. EnumerateKnownSubFields(
  2919. DWORD dwIndex
  2920. )
  2921. /*++
  2922. Routine Description:
  2923. Get subfield name from index (0-based )
  2924. Arguments:
  2925. dwIndex - enumerator ( 0-based )
  2926. Return Value:
  2927. sub field name or NULL if no more subfields
  2928. --*/
  2929. {
  2930. if ( dwIndex < sizeof(aMapAsn)/sizeof(MAP_ASN) )
  2931. {
  2932. return aMapAsn[dwIndex].pTextName;
  2933. }
  2934. return NULL;
  2935. }
  2936. VOID
  2937. InitializeWildcardMapping(
  2938. HANDLE hModule
  2939. )
  2940. /*++
  2941. Routine Description:
  2942. Initialize wildcard mapping
  2943. Arguments:
  2944. hModule - module handle of this DLL
  2945. Return Value:
  2946. Nothing
  2947. --*/
  2948. {
  2949. // load schannel
  2950. if ( hSchannel = LoadLibrary( "schannel.dll" ) )
  2951. {
  2952. pfnGetDefaultIssuers = (SSL_GET_ISSUERS_FN)GetProcAddress( hSchannel,
  2953. "SslGetDefaultIssuers" );
  2954. }
  2955. #if 1
  2956. if ( hCapi2Lib = LoadLibrary("crypt32.dll") )
  2957. {
  2958. pfnCertCreateCertificateContext = (PFNCertCreateCertificateContext)GetProcAddress(hCapi2Lib, "CertCreateCertificateContext");
  2959. pfnCertFreeCertificateContext = (PFNCertFreeCertificateContext)GetProcAddress(hCapi2Lib, "CertFreeCertificateContext");
  2960. pfnCryptDecodeObject = (PFNCryptDecodeObject)GetProcAddress(hCapi2Lib, "CryptDecodeObject");
  2961. pfnCertGetCertificateContextProperty = (PFNCertGetCertificateContextProperty)GetProcAddress(hCapi2Lib, "CertGetCertificateContextProperty");
  2962. }
  2963. #else
  2964. hCapi2Lib = NULL;
  2965. pfnCertCreateCertificateContext = CertCreateCertificateContext;
  2966. pfnCertFreeCertificateContext = CertFreeCertificateContext;
  2967. pfnCryptDecodeObject = CryptDecodeObject;
  2968. pfnCertGetCertificateContextProperty = CertGetCertificateContextProperty;
  2969. #endif
  2970. LPVOID p;
  2971. UINT i;
  2972. UINT l;
  2973. CHAR achTmp[128];
  2974. for ( i = 0 ; i < sizeof(aMapAsn)/sizeof(MAP_ASN) ; ++ i )
  2975. {
  2976. if ( !(l = LoadString( (HINSTANCE)hModule, aMapAsn[i].dwResId, achTmp, sizeof(achTmp) )) ||
  2977. !(p = LocalAlloc( LMEM_FIXED, l+1 )) )
  2978. {
  2979. p = (LPVOID)"";
  2980. }
  2981. else
  2982. {
  2983. memcpy( p, achTmp, l+1 );
  2984. }
  2985. aMapAsn[i].pTextName = (LPSTR)p;
  2986. }
  2987. for ( i = 0 ; i < sizeof(aMapField)/sizeof(MAP_FIELD) ; ++ i )
  2988. {
  2989. if ( !(l = LoadString( (HINSTANCE)hModule, aMapField[i].dwResId, achTmp, sizeof(achTmp) )) ||
  2990. !(p = LocalAlloc( LMEM_FIXED, l+1 )) )
  2991. {
  2992. p = (LPVOID)"";
  2993. }
  2994. else
  2995. {
  2996. memcpy( p, achTmp, l+1 );
  2997. }
  2998. aMapField[i].pTextName = (LPSTR)p;
  2999. }
  3000. }
  3001. VOID
  3002. TerminateWildcardMapping(
  3003. )
  3004. /*++
  3005. Routine Description:
  3006. Terminate wildcard mapping
  3007. Arguments:
  3008. None
  3009. Return Value:
  3010. Nothing
  3011. --*/
  3012. {
  3013. UINT i;
  3014. if ( hSchannel != NULL )
  3015. {
  3016. FreeLibrary( hSchannel );
  3017. }
  3018. if ( hCapi2Lib != NULL )
  3019. {
  3020. FreeLibrary( hCapi2Lib );
  3021. }
  3022. for ( i = 0 ; i < sizeof(aMapAsn)/sizeof(MAP_ASN) ; ++ i )
  3023. {
  3024. if ( aMapAsn[i].pTextName[0] )
  3025. {
  3026. LocalFree( aMapAsn[i].pTextName );
  3027. }
  3028. }
  3029. for ( i = 0 ; i < sizeof(aMapField)/sizeof(MAP_FIELD) ; ++ i )
  3030. {
  3031. if ( aMapField[i].pTextName[0] )
  3032. {
  3033. LocalFree( aMapField[i].pTextName );
  3034. }
  3035. }
  3036. }
  3037. BOOL
  3038. MatchRequestToBinary(
  3039. LPSTR pszReq,
  3040. LPBYTE* ppbBin,
  3041. LPDWORD pdwBin )
  3042. /*++
  3043. Routine Description:
  3044. Convert from match request user format ( e.g. "*msft*"
  3045. to internal binary format
  3046. Arguments:
  3047. pszReq - match in user format
  3048. ppbBin - updated with ptr to alloced binary format,
  3049. to be freed by calling FreeMatchConversion()
  3050. pdwBin - updated with binary format length
  3051. Return Value:
  3052. TRUE if success, otherwise FALSE
  3053. --*/
  3054. {
  3055. LPSTR pReq;
  3056. DWORD cReq;
  3057. LPBYTE pBin;
  3058. MATCH_TYPES mt;
  3059. if ( !pszReq)
  3060. {
  3061. *ppbBin = NULL;
  3062. *pdwBin = 0;
  3063. return FALSE;
  3064. }
  3065. pReq = pszReq;
  3066. cReq = strlen( pReq );
  3067. if ( !cReq )
  3068. {
  3069. mt = MATCH_ALL;
  3070. }
  3071. else
  3072. {
  3073. if ( pReq[0] == '*' )
  3074. {
  3075. if ( pReq[cReq-1] == '*' && cReq > 1 )
  3076. {
  3077. mt = MATCH_IN;
  3078. cReq -= 2;
  3079. }
  3080. else
  3081. {
  3082. mt = MATCH_LAST;
  3083. cReq -= 1;
  3084. }
  3085. ++pReq;
  3086. }
  3087. else if ( pReq[cReq-1] == '*' )
  3088. {
  3089. mt = MATCH_FIRST;
  3090. cReq -= 1;
  3091. }
  3092. else
  3093. {
  3094. mt = MATCH_ALL;
  3095. }
  3096. }
  3097. if ( !(pBin = (LPBYTE)LocalAlloc( LMEM_FIXED, cReq + 1 )) )
  3098. {
  3099. return FALSE;
  3100. }
  3101. pBin[0] = (UINT)mt;
  3102. memcpy( pBin+1, pReq, cReq );
  3103. *ppbBin = pBin;
  3104. *pdwBin = cReq + 1;
  3105. return TRUE;
  3106. }
  3107. BOOL
  3108. BinaryToMatchRequest(
  3109. LPBYTE pbBin,
  3110. DWORD dwBin,
  3111. LPSTR* ppszReq
  3112. )
  3113. /*++
  3114. Routine Description:
  3115. Convert from internal binary format to
  3116. match request user format ( e.g. "*msft*"
  3117. Arguments:
  3118. pbBin - ptr to binary format,
  3119. dwBin - binary format length
  3120. ppszReq - updated with ptr to alloced match in user format
  3121. to be freed by calling FreeMatchConversion()
  3122. Return Value:
  3123. TRUE if success, otherwise FALSE
  3124. --*/
  3125. {
  3126. BOOL fPre;
  3127. BOOL fPost;
  3128. UINT cMatch = dwBin + 1;
  3129. LPSTR pMatch;
  3130. if ( !pbBin || !dwBin )
  3131. {
  3132. *ppszReq = NULL;
  3133. return FALSE;
  3134. }
  3135. switch ( (MATCH_TYPES)(UINT)pbBin[0] )
  3136. {
  3137. case MATCH_ALL:
  3138. fPre = FALSE;
  3139. fPost = FALSE;
  3140. break;
  3141. case MATCH_LAST:
  3142. fPre = TRUE;
  3143. fPost = FALSE;
  3144. ++cMatch;
  3145. break;
  3146. case MATCH_FIRST:
  3147. fPre = FALSE;
  3148. fPost = TRUE;
  3149. ++cMatch;
  3150. break;
  3151. case MATCH_IN:
  3152. fPre = TRUE;
  3153. fPost = TRUE;
  3154. cMatch += 2;
  3155. break;
  3156. default:
  3157. return FALSE;
  3158. }
  3159. if ( !(pMatch = (LPSTR)LocalAlloc( LMEM_FIXED, cMatch )) )
  3160. {
  3161. return FALSE;
  3162. }
  3163. *ppszReq = pMatch;
  3164. if ( fPre )
  3165. {
  3166. *pMatch++ = '*';
  3167. }
  3168. memcpy( pMatch, pbBin + 1, dwBin - 1 );
  3169. pMatch += dwBin - 1;
  3170. if ( fPost )
  3171. {
  3172. *pMatch++ = '*';
  3173. }
  3174. *pMatch = '\0';
  3175. return TRUE;
  3176. }
  3177. VOID
  3178. FreeMatchConversion(
  3179. LPVOID pvFree
  3180. )
  3181. /*++
  3182. Routine Description:
  3183. Free result of binary to/from user format conversion
  3184. Arguments:
  3185. pvFree - buffer to free
  3186. Return Value:
  3187. Nothing
  3188. --*/
  3189. {
  3190. if ( pvFree != NULL )
  3191. {
  3192. LocalFree( pvFree );
  3193. }
  3194. }
  3195. LPBYTE
  3196. memstr(
  3197. LPBYTE pStr,
  3198. UINT cStr,
  3199. LPBYTE pSub,
  3200. UINT cSub,
  3201. BOOL fCaseInsensitive
  3202. )
  3203. /*++
  3204. Routine Description:
  3205. Find 1st occurence of block of memory inside buffer
  3206. Arguments:
  3207. pStr - buffer where to search
  3208. cStr - length of pStr
  3209. pSub - buffer to search for in pStr
  3210. cSub - length of pSub
  3211. fCaseInsensitive - TRUE is case insensitive search
  3212. Return Value:
  3213. Ptr to 1st occurence of pSub in pStr or NULL if not found
  3214. --*/
  3215. {
  3216. LPBYTE p;
  3217. LPBYTE pN;
  3218. if ( cSub > cStr )
  3219. {
  3220. return NULL;
  3221. }
  3222. UINT ch = *pSub;
  3223. if ( fCaseInsensitive )
  3224. {
  3225. if ( cStr >= cSub &&
  3226. cSub )
  3227. {
  3228. cStr -= cSub - 1;
  3229. for ( p = pStr ; cStr ; ++p, --cStr )
  3230. {
  3231. if ( !_memicmp( p, pSub, cSub ) )
  3232. {
  3233. return p;
  3234. }
  3235. }
  3236. }
  3237. }
  3238. else
  3239. {
  3240. for ( p = pStr ; pN = (LPBYTE)memchr( p, ch, cStr ) ; )
  3241. {
  3242. if ( !memcmp( pN, pSub, cSub ) )
  3243. {
  3244. return pN;
  3245. }
  3246. cStr -= (UINT)(pN - p + 1);
  3247. p = pN + 1;
  3248. }
  3249. }
  3250. return NULL;
  3251. }
  3252. VOID
  3253. FreeCIisRuleMapper(
  3254. LPVOID pMapper
  3255. )
  3256. /*++
  3257. Routine Description:
  3258. Delete a CIisRuleMapper
  3259. Arguments:
  3260. pMapper - ptr to mapper
  3261. Returns:
  3262. Nothing
  3263. --*/
  3264. {
  3265. delete (CIisRuleMapper*)pMapper;
  3266. }
  3267. BOOL
  3268. IsCertificateVerified(
  3269. PCCERT_CONTEXT pCertContext
  3270. )
  3271. {
  3272. DWORD fVerified = FALSE;
  3273. DWORD dwVerified = sizeof(fVerified);
  3274. if ( pfnCertGetCertificateContextProperty == NULL )
  3275. {
  3276. SetLastError(ERROR_PROC_NOT_FOUND);
  3277. return FALSE;
  3278. }
  3279. #ifndef CERT_PROP_VERIFIED
  3280. #define CERT_PROP_VERIFIED (CERT_FIRST_USER_PROP_ID+3)
  3281. #endif
  3282. // Check if this is a verified cert chain
  3283. if(!pfnCertGetCertificateContextProperty(pCertContext,
  3284. CERT_PROP_VERIFIED,
  3285. &fVerified,
  3286. &dwVerified))
  3287. {
  3288. #if 0
  3289. char achE[80];
  3290. wsprintf( achE, "Error %d\n", GetLastError() );
  3291. OutputDebugString( achE );
  3292. #endif
  3293. fVerified = FALSE;
  3294. }
  3295. return fVerified;
  3296. }
  3297. BOOL
  3298. GetDefaultIssuers(
  3299. LPBYTE pIssuer,
  3300. DWORD * pdwIssuer
  3301. )
  3302. {
  3303. if ( pfnGetDefaultIssuers == NULL )
  3304. {
  3305. SetLastError(ERROR_PROC_NOT_FOUND);
  3306. return FALSE;
  3307. }
  3308. return pfnGetDefaultIssuers(pIssuer, pdwIssuer);
  3309. }