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.

4011 lines
70 KiB

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