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.

562 lines
17 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. iismap.hxx
  5. Abstract:
  6. Headers for classes to handle mapping
  7. --*/
  8. /*
  9. Usage:
  10. 1 mapper class is defined here derived from CIisAcctMapper :
  11. - CIisCertMapper : SSL certificate mapping
  12. An instance of one these classes must be created by the client.
  13. This instance must be initialized ( call to Init() ) and terminated
  14. ( call to Terminate() ) before and after use.
  15. Load() / Save() load and save the current mapping. Changes made to the
  16. mappings are not commited until Save() is called.
  17. The file integrity will be checked at load time, error ERROR_BAD_FORMAT will
  18. be returned if format is corrupted, ERROR_INVALID_ACCESS if the file was
  19. modified by an application without using this library. In the later case
  20. the content is valid, and can be validated by calling Save().
  21. Each class defines a field list ( MappingGetFieldList() ), a field being
  22. defined by its type ( IISMDB_TYPE_* ), displayable name
  23. and maximum width ( characters )
  24. Each class also defines a hierarchy of fields used in the mapping process.
  25. The hierarchy is defined by an array of descriptor ( index in field list array
  26. and mandatory flag. The mandatory flag indicates whether this field must be
  27. present when a new mapping is created, it is an indication intended for the UI )
  28. The hierarchy is accessed by GetHierarchy() and is modified in place.
  29. A call to UpdateHierarchy() is necessary after any modification to the
  30. hierarchy.
  31. An option bit ( GetOptions() & IISMDB_OPTION_EDIT_HIERARCHY ) indicates
  32. whether the hierarcht is editable for a given class or not.
  33. Mapping entries are accessed through GetNbMapping(), GetMapping( 0-based index ).
  34. To add a mapping, call CreateNewMapping() then Add() or delete the created
  35. mapping.
  36. To update a mapping, access it using GetMapping() then call Update().
  37. To delete a mapping, call Delete().
  38. Each mapping is derived from CIisMapping.
  39. Fields are get/set using MappingGetField() / MappingSetField().
  40. Each class storage is controlled by a registry key as defined by
  41. IIS_*_MAPPER_REG. Two values must be created :
  42. - FileLocation:REG_SZ, which is the full path of the file used to store
  43. the mappings
  44. - FileValidator:REG_BINARY, which will be used by this library
  45. to store/check a MD5 digest of the file content to check file integrity
  46. Features specific to SSL certificate mappings ( CIisCertMapper ):
  47. - a list of BLOBs is to be created/edited by the UI through
  48. SetIssuerList()/GetIssuerList().
  49. Each BLOB describes a certificate issuer. Exact format to be defined
  50. by the Crypto team, but can assumed to be ASN.1 description of issuer.
  51. This list will be used by the SSL package to request the client to send
  52. a list of certificates issued by one of the issuer in this list.
  53. */
  54. extern "C" {
  55. #include <md5.h>
  56. }
  57. #ifndef IISMAP_DLLEXP
  58. # ifdef DLL_IMPLEMENTATION
  59. # define IISMAP_DLLEXP __declspec(dllexport)
  60. # ifdef IMPLEMENTATION_EXPORT
  61. # define IRTL_EXPIMP
  62. # else
  63. # undef IRTL_EXPIMP
  64. # endif
  65. # else // !DLL_IMPLEMENTATION
  66. # define IISMAP_DLLEXP __declspec(dllimport)
  67. # define IRTL_EXPIMP extern
  68. # endif // !DLL_IMPLEMENTATION
  69. #endif // !IISMAP_DLLEXP
  70. #include <xbf.hxx>
  71. //
  72. // redefining macro from tssec.hxx because of ugly dependencies
  73. // Issue 04/03/02 jaroslad: value should eventually be consolidated
  74. //
  75. #ifndef IIS_DNLEN
  76. #define IIS_DNLEN (256)
  77. #endif
  78. typedef LPVOID VALID_CTX;
  79. //
  80. // Field types, can be used to associate semantic to each field
  81. // (e.g. not displaying password in clear text but as '*' )
  82. //
  83. #define IISMDB_TYPE_STRING 0 // generic string
  84. #define IISMDB_TYPE_PWD 1 // clear text password
  85. #define IISMDB_TYPE_NTACCT 2 // NT account ([Domain\]UserName)
  86. #define IISMDB_TYPE_ISSUER_O 3 // Certificate Issuer Organization
  87. #define IISMDB_TYPE_ISSUER_OU 4 // Certificate Issuer Organization Unit
  88. #define IISMDB_TYPE_ISSUER_C 5 // Certificate Issuer Country
  89. #define IISMDB_TYPE_SUBJECT_O 6 // Certificate Subject Organization
  90. #define IISMDB_TYPE_SUBJECT_OU 7 // Certificate Subject Organization Unit
  91. #define IISMDB_TYPE_SUBJECT_C 8 // Certificate Subject Country
  92. #define IISMDB_TYPE_SUBJECT_CN 9 // Certificate Subject Name
  93. #define IISMDB_TYPE_ITACCT 10 // Internet account
  94. #define IISMDB_TYPE_ITPWD 11 // Internet password, stored as MD5 digest
  95. #define IISMDB_TYPE_ITREALM 12 // Internet realm
  96. #define IISMDB_TYPE_ITMD5PWD 13 // Internet password, stored as MD5 digest
  97. // of Account ":" Realm ":" Clear-text password
  98. #define IISMDB_TYPE_NTPWD 14 // NT password
  99. #define IISMDB_TYPE_OPTION_MASK 0xff000000
  100. #define IISMDB_TYPE_BINARY 0x80000000
  101. //
  102. // Field indexes for SSL certificates mapping
  103. //
  104. #define IISMDB_INDEX_ISSUER_O 0
  105. #define IISMDB_INDEX_ISSUER_OU 1
  106. #define IISMDB_INDEX_ISSUER_C 2
  107. #define IISMDB_INDEX_SUBJECT_O 3
  108. #define IISMDB_INDEX_SUBJECT_OU 4
  109. #define IISMDB_INDEX_SUBJECT_C 5
  110. #define IISMDB_INDEX_SUBJECT_CN 6
  111. #define IISMDB_INDEX_NT_ACCT 7
  112. #define IISMDB_INDEX_NB 8 // must be last
  113. //
  114. // Client cert to NT acct 1:1 mapping
  115. //
  116. #define IISMDB_INDEX_CERT11_CERT 0
  117. #define IISMDB_INDEX_CERT11_NT_ACCT 1
  118. #define IISMDB_INDEX_CERT11_NAME 2
  119. #define IISMDB_INDEX_CERT11_ENABLED 3
  120. #define IISMDB_INDEX_CERT11_NT_PWD 4
  121. #define IISMDB_INDEX_CERT11_NB 5
  122. // options
  123. // set if hierarchy to be edited by user
  124. #define IISMDB_OPTION_EDIT_HIERARCHY 0x00000001
  125. #define IISMDB_OPTION_ISSUER_LIST 0x00000002
  126. #define IISMDB_CERT_OPTIONS (IISMDB_OPTION_EDIT_HIERARCHY|IISMDB_OPTION_ISSUER_LIST)
  127. #define IISMDB_CERT11_OPTIONS (IISMDB_OPTION_ISSUER_LIST)
  128. #define IISMDB_ITA_OPTIONS 0
  129. #define IISMDB_MD5_OPTIONS 0
  130. // version #
  131. #define IISMDB_VERSION_1 1
  132. #define IISMDB_CURRENT_VERSION IISMDB_VERSION_1
  133. #define IISMDB_FILE_MAGIC_VALUE (('B'<<24)|('D'<<16)|('M'<<8)|('I'))
  134. #define IIS_CERT_MAPPER_REG "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters\\CertMapper"
  135. #define IIS_CERT11_MAPPER_REG "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters\\Cert11Mapper"
  136. #define W3_PARAMS "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters"
  137. #define INSTALL_PATH "InstallPath"
  138. #define MAPPER_GUID "MapperGuid"
  139. // REG_BINARY : MD5 digest of file content
  140. #define FILE_VALIDATOR "FileValidator"
  141. // REG_SZ : file name
  142. #define FILE_LOCATION "FileLocation"
  143. //
  144. // Mapping array allocation extension granularity
  145. //
  146. #define IIS_MAP_BUFF_GRAN 128
  147. typedef struct _Cert_Map {
  148. DWORD cbIssuerLen;
  149. LPBYTE pIssuer;
  150. DWORD cbSubjectLen;
  151. LPBYTE pSubject;
  152. } Cert_Map ;
  153. //
  154. // Field descriptor
  155. //
  156. typedef struct _IISMDB_Fields {
  157. DWORD m_dwType;
  158. LPSTR m_pszDisplayName;
  159. DWORD m_dwResID;
  160. DWORD m_dwMaxLen;
  161. } IISMDB_Fields;
  162. //
  163. // Field Hierarchy descriptor
  164. //
  165. typedef struct _IISMDB_HEntry {
  166. DWORD m_dwIndex;
  167. BOOL m_fMandatory;;
  168. } IISMDB_HEntry;
  169. class CIisAcctMapper;
  170. class CIisMapping {
  171. public:
  172. CIisMapping();
  173. ~CIisMapping() { if ( m_pBuff != NULL ) LocalFree( m_pBuff ); }
  174. //
  175. IISMAP_DLLEXP virtual BOOL Serialize( FILE*, VALID_CTX, LPVOID );
  176. IISMAP_DLLEXP virtual BOOL Deserialize( FILE*, VALID_CTX, LPVOID );
  177. virtual BOOL StoreFieldRef( DWORD /*iIndex*/, LPSTR /*pf*/ ) { return FALSE; }
  178. virtual BOOL StoreFieldRef( DWORD /*iIndex*/, LPSTR /*pf*/, DWORD /*dwL*/ ) { return FALSE; }
  179. virtual BOOL IsCrypt( DWORD /*iIndex*/ ) { return FALSE; }
  180. int Cmp( CIisMapping*, BOOL fCmpForMatch = FALSE );
  181. DWORD GetMask() { return m_dwMask; }
  182. IISMAP_DLLEXP BOOL UpdateMask( IISMDB_HEntry*, DWORD );
  183. IISMAP_DLLEXP BOOL Copy( CIisMapping* );
  184. BOOL StoreField(
  185. LPSTR* ppszFields,
  186. DWORD dwIndex,
  187. DWORD dwNbIndex,
  188. LPSTR pszNew
  189. );
  190. BOOL StoreField(
  191. LPSTR* ppszFields,
  192. LPDWORD ppdwFields,
  193. DWORD dwIndex,
  194. DWORD dwNbIndex,
  195. LPSTR pszNew,
  196. DWORD cNew,
  197. BOOL fIsUuEncoded
  198. );
  199. public:
  200. // stores a copy to storage pointed to by pF
  201. IISMAP_DLLEXP virtual BOOL MappingSetField( DWORD iIndex, LPSTR pF );
  202. IISMAP_DLLEXP virtual BOOL MappingSetField( DWORD iIndex, PBYTE pbF, DWORD cbF, BOOL );
  203. // return a pointer to internal storage
  204. IISMAP_DLLEXP virtual BOOL MappingGetField( DWORD iIndex, LPSTR* );
  205. IISMAP_DLLEXP virtual BOOL MappingGetField( DWORD iIndex, PBYTE*, LPDWORD, BOOL );
  206. IISMAP_DLLEXP virtual UINT GetNbField( LPSTR ** ) { return 0; }
  207. IISMAP_DLLEXP virtual UINT GetNbField( LPSTR **, LPDWORD* ) { return 0; }
  208. IISMAP_DLLEXP virtual BOOL Clone( CIisMapping** ) { return FALSE; }
  209. IISMAP_DLLEXP BOOL CloneEx( CIisMapping**, LPSTR*, LPSTR*, LPDWORD, LPDWORD, UINT );
  210. protected:
  211. LPBYTE m_pBuff;
  212. UINT m_cUsedBuff;
  213. UINT m_cAllocBuff;
  214. CIisAcctMapper *m_pMapper;
  215. DWORD m_dwMask;
  216. } ;
  217. class CCert11Mapping : public CIisMapping {
  218. public:
  219. IISMAP_DLLEXP CCert11Mapping();
  220. IISMAP_DLLEXP CCert11Mapping( CIisAcctMapper* );
  221. IISMAP_DLLEXP ~CCert11Mapping();
  222. //
  223. BOOL Init( LPBYTE pC, DWORD cC, IISMDB_HEntry *pH, DWORD dwH );
  224. BOOL StoreFieldRef( DWORD iIndex, LPSTR pF ) { m_pFields[iIndex] = pF; return TRUE; }
  225. BOOL StoreFieldRef( DWORD iIndex, LPSTR pF, DWORD dwF ) { m_pFields[iIndex] = pF; m_cFields[iIndex] = dwF; return TRUE; }
  226. BOOL IsCrypt( DWORD iIndex ) { return (iIndex == IISMDB_INDEX_CERT11_NT_PWD) ? TRUE : FALSE; }
  227. //
  228. UINT GetNbField(LPSTR **pF) { *pF = m_pFields; return sizeof(m_pFields)/sizeof(LPSTR);}
  229. UINT GetNbField(LPSTR **pF, LPDWORD *pcF) { *pF = m_pFields; *pcF = m_cFields; return sizeof(m_pFields)/sizeof(LPSTR);}
  230. BOOL MappingSetField( DWORD iIndex, LPSTR pF );
  231. BOOL Clone( CIisMapping** ppM)
  232. {
  233. if ( *ppM = new CCert11Mapping( m_pMapper ) )
  234. {
  235. return CloneEx( ppM, ((CCert11Mapping*)*ppM)->m_pFields, m_pFields, ((CCert11Mapping*)*ppM)->m_cFields, m_cFields, IISMDB_INDEX_CERT11_NB );
  236. }
  237. return FALSE;
  238. }
  239. private:
  240. LPSTR m_pFields[IISMDB_INDEX_CERT11_NB];
  241. DWORD m_cFields[IISMDB_INDEX_CERT11_NB];
  242. } ;
  243. //
  244. // BLOB describing an issuer ( ASN.1 format )
  245. //
  246. typedef struct _IssuerAccepted {
  247. DWORD cbIssuerLen;
  248. LPBYTE pbIssuer;
  249. } IssuerAccepted;
  250. //
  251. // Mapping class descriptor ( a class defines the subset of fields used
  252. // to check for a mapping match ).
  253. //
  254. typedef struct _MappingClass {
  255. DWORD dwClass;
  256. DWORD dwFirst;
  257. DWORD dwLast;
  258. } MappingClass;
  259. class CIisAcctMapper {
  260. public:
  261. IISMAP_DLLEXP CIisAcctMapper();
  262. IISMAP_DLLEXP ~CIisAcctMapper();
  263. //
  264. // BOOL* updated with TRUE if 1st call to Init() for this object,
  265. // fMonitorChange used to indicate if change monitoring thread should
  266. // be created. If yes, changes to the database will trigger auto-refresh
  267. // This should be set to FALSE by the mapping Editor ( UI )
  268. //IISMAP_DLLEXP BOOL Init( BOOL*, BOOL fMonitorChange = TRUE );
  269. // fForce control whether instance is terminated even if non balanced
  270. // calls to Init()/Terminate()
  271. //IISMAP_DLLEXP BOOL Terminate( BOOL fForce = FALSE );
  272. // clear all mapping entries
  273. IISMAP_DLLEXP BOOL Reset();
  274. //DWORD UpdateIndication( VOID );
  275. virtual LPSTR GetRegKeyName() { return NULL; }
  276. //
  277. virtual BOOL LoadPrivate( FILE*, VALID_CTX ) { return TRUE; }
  278. virtual BOOL SavePrivate( FILE*, VALID_CTX ) { return TRUE; }
  279. virtual BOOL ResetPrivate() { return TRUE; }
  280. virtual IISMDB_HEntry* GetDefaultHierarchy( LPDWORD pdwN )
  281. { *pdwN = 0; return NULL; }
  282. //
  283. //
  284. IISMAP_DLLEXP void Lock();
  285. IISMAP_DLLEXP void Unlock();
  286. //
  287. IISMAP_DLLEXP BOOL FindMatch( CIisMapping* pQuery, CIisMapping** pResult, LPDWORD pI = NULL );
  288. IISMAP_DLLEXP BOOL UpdateClasses( BOOL fComputeMask = TRUE );
  289. BOOL SortMappings();
  290. public:
  291. //
  292. // to be used by DB clients
  293. //
  294. IISMAP_DLLEXP BOOL MappingGetFieldList(IISMDB_Fields** pF, DWORD* pC )
  295. { *pF = m_pFields; *pC = m_cFields; return TRUE; }
  296. IISMAP_DLLEXP DWORD GetOptions() { return m_dwOptions; }
  297. IISMAP_DLLEXP DWORD GetNbMapping( BOOL fAlt = FALSE ) { return (fAlt && m_pAltMapping) ? m_cAltMapping : m_cMapping; }
  298. IISMAP_DLLEXP BOOL GetMapping( DWORD iIndex, CIisMapping**, BOOL fFromAlt = FALSE, BOOL fPutAlt = FALSE );
  299. IISMAP_DLLEXP BOOL FlushAlternate( BOOL fApply );
  300. IISMAP_DLLEXP virtual CIisMapping* CreateNewMapping() { return NULL; }
  301. IISMAP_DLLEXP virtual BOOL Add( CIisMapping*, BOOL fAlternate = FALSE ); // release ownership of CIisMapping
  302. IISMAP_DLLEXP virtual DWORD AddEx( CIisMapping* ); // release ownership of CIisMapping
  303. IISMAP_DLLEXP BOOL Update( DWORD iIndex, CIisMapping* pM );
  304. IISMAP_DLLEXP BOOL Update( DWORD iIndex );
  305. IISMAP_DLLEXP BOOL Delete( DWORD iIndex, BOOL fUseAlternate = FALSE );
  306. // can return ERROR_INVALID_ACCESS if MD5 signature invalid.
  307. // file was loaded anyway, must Save() to validate.
  308. IISMAP_DLLEXP BOOL Load();
  309. IISMAP_DLLEXP BOOL Save();
  310. IISMAP_DLLEXP IISMDB_HEntry* GetHierarchy( DWORD *pC ) { *pC = m_cHierarchy; return m_pHierarchy; }
  311. IISMAP_DLLEXP BOOL UpdateHierarchy() { return UpdateClasses( TRUE ); }
  312. //
  313. // Create unique ID for this object. Necessary before Load()/Save()
  314. //
  315. IISMAP_DLLEXP BOOL Create( VOID );
  316. IISMAP_DLLEXP BOOL Delete( VOID );
  317. IISMAP_DLLEXP BOOL Serialize( CStoreXBF* );
  318. IISMAP_DLLEXP BOOL Unserialize( CStoreXBF* );
  319. IISMAP_DLLEXP BOOL Unserialize( LPBYTE*, LPDWORD );
  320. IISMAP_DLLEXP BOOL Serialize( VOID );
  321. IISMAP_DLLEXP BOOL Unserialize( VOID );
  322. IISMAP_DLLEXP DWORD GetMappingCount( VOID ) { return m_cMapping; }
  323. private:
  324. static
  325. int __cdecl
  326. QsortIisMappingCmp(
  327. const void *pA,
  328. const void *pB
  329. );
  330. static
  331. int __cdecl
  332. MatchIisMappingCmp(
  333. const void *pA,
  334. const void *pB
  335. );
  336. protected:
  337. CRITICAL_SECTION csLock;
  338. HANDLE m_hNotifyEvent;
  339. BOOL m_fRequestTerminate;
  340. LONG m_cInit;
  341. CIisMapping ** m_pMapping;
  342. DWORD m_cMapping;
  343. CIisMapping ** m_pAltMapping;
  344. DWORD m_cAltMapping;
  345. CHAR m_achFileName[MAX_PATH];
  346. IISMDB_HEntry * m_pHierarchy;
  347. DWORD m_cHierarchy;
  348. MappingClass* m_pClasses;
  349. IISMDB_Fields* m_pFields;
  350. DWORD m_cFields;
  351. DWORD m_dwOptions;
  352. MD5_CTX m_md5;
  353. LPBYTE m_pSesKey;
  354. DWORD m_dwSesKey;
  355. } ;
  356. //
  357. // SSL client certificates 1:1 mapper
  358. //
  359. class CIisCert11Mapper : public CIisAcctMapper {
  360. public:
  361. IISMAP_DLLEXP CIisCert11Mapper();
  362. IISMAP_DLLEXP ~CIisCert11Mapper();
  363. LPSTR GetRegKeyName() { return IIS_CERT11_MAPPER_REG; }
  364. IISMDB_HEntry* GetDefaultHierarchy( LPDWORD pdwN );
  365. IISMAP_DLLEXP CIisMapping* CreateNewMapping() { return (CIisMapping*)new CCert11Mapping(this); }
  366. IISMAP_DLLEXP CIisMapping* CreateNewMapping( LPBYTE pC, DWORD dwC );
  367. BOOL LoadPrivate( FILE*, VALID_CTX );
  368. BOOL SavePrivate( FILE*, VALID_CTX );
  369. BOOL ResetPrivate();
  370. BOOL Add( CIisMapping* );
  371. private:
  372. static
  373. LPSTR
  374. Iisfgets(
  375. LPSTR pBuf,
  376. INT cMax,
  377. FILE* fIn
  378. );
  379. static
  380. INT
  381. Iisfputs(
  382. const char* pBuf,
  383. FILE* fOut
  384. );
  385. private:
  386. IssuerAccepted *m_pIssuers;
  387. DWORD m_cIssuers;
  388. } ;
  389. IISMAP_DLLEXP
  390. BOOL
  391. ReportIisMapEvent(
  392. WORD wType,
  393. DWORD dwEventId,
  394. WORD cNbStr,
  395. LPCTSTR* pStr
  396. );
  397. IISMAP_DLLEXP
  398. BOOL
  399. ReportIisMapEventW(
  400. WORD wType,
  401. DWORD dwEventId,
  402. WORD cNbStr,
  403. LPCWSTR* pStr
  404. );
  405. IISMAP_DLLEXP
  406. BOOL IISuudecode(char * bufcoded,
  407. BYTE * bufout,
  408. DWORD * pcbDecoded,
  409. BOOL fBase64
  410. );
  411. IISMAP_DLLEXP
  412. BOOL IISuuencode( BYTE * bufin,
  413. DWORD nbytes,
  414. BYTE * outptr,
  415. BOOL fBase64 );
  416. IISMAP_DLLEXP
  417. DWORD WINAPI
  418. CreateMapping(
  419. LPWSTR pwszUuIssuer,
  420. LPWSTR pwszUuSubject,
  421. LPWSTR pwszNtAcct
  422. );
  423. IISMAP_DLLEXP
  424. DWORD WINAPI
  425. CheckMapping(
  426. LPWSTR pwszUuIssuer,
  427. LPWSTR pwszUuSubject,
  428. LPWSTR* pwszNtAcct
  429. );
  430. IISMAP_DLLEXP
  431. DWORD WINAPI
  432. SaveMapping(
  433. VOID
  434. );
  435. IISMAP_DLLEXP
  436. VOID
  437. ImportIISCertMappingsToIIS6(
  438. VOID
  439. );
  440. BOOL InitializeMapping( HANDLE );
  441. VOID TerminateMapping();