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.

1603 lines
38 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. // Module : parser_util.cpp
  3. //
  4. // Purpose : All utility functions used by the parser
  5. //
  6. // Developers Name : N.Surendra Sai / Vunnam Kondal Rao
  7. //
  8. // History :
  9. //
  10. // Date Author Comments
  11. //
  12. // 27 Aug 2001
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "nshipsec.h"
  16. extern HINSTANCE g_hModule;
  17. extern void *g_AllocPtr[MAX_ARGS];
  18. extern STORAGELOCATION g_StorageLocation;
  19. extern DWORD ValidateBool(IN LPTSTR ppcTok);
  20. //////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Function : ListToSecMethod()
  23. //
  24. // Date of Creation : 12 Sept 2001
  25. //
  26. // Parameters : IN LPTSTR szText // string to convert
  27. // IN OUT IPSEC_MM_OFFER SecMethod // target struct to be filled.
  28. //
  29. // Return : DWORD
  30. // T2P_OK
  31. // T2P_NULL_STRING
  32. // T2P_GENERAL_PARSE_ERROR
  33. // T2P_DUP_ALGS
  34. // T2P_INVALID_P1GROUP
  35. // T2P_P1GROUP_MISSING
  36. //
  37. // Description : converts string to Phase 1 offer
  38. //
  39. // History :
  40. //
  41. // Date Author Comments
  42. //
  43. //////////////////////////////////////////////////////////////////////////////
  44. DWORD
  45. ListToSecMethod(
  46. IN LPTSTR szText,
  47. IN OUT IPSEC_MM_OFFER &SecMethod
  48. )
  49. {
  50. DWORD dwReturn = T2P_OK;
  51. _TCHAR szTmp[MAX_STR_LEN] = {0};
  52. LPTSTR pString1 = NULL;
  53. LPTSTR pString2 = NULL;
  54. BOOL bEncryption = FALSE;
  55. BOOL bAuthentication = FALSE;
  56. if (szText == NULL)
  57. {
  58. dwReturn = T2P_NULL_STRING;
  59. BAIL_OUT;
  60. }
  61. if (_tcslen(szText) < MAX_STR_LEN)
  62. {
  63. _tcsncpy(szTmp, szText,MAX_STR_LEN-1);
  64. }
  65. else
  66. {
  67. dwReturn = T2P_GENERAL_PARSE_ERROR;
  68. BAIL_OUT;
  69. }
  70. pString1 = _tcschr(szTmp, POTF_P1_TOKEN);
  71. pString2 = _tcsrchr(szTmp, POTF_P1_TOKEN);
  72. if ((pString1 != NULL) && (pString2 != NULL) && (pString1 != pString2))
  73. {
  74. *pString1 = '\0';
  75. *pString2 = '\0';
  76. ++pString1;
  77. ++pString2;
  78. // we allow the hash and encryption to be specified in either
  79. // the first or second field
  80. if (_tcsicmp(szTmp, POTF_P1_DES) == 0)
  81. {
  82. bEncryption = true;
  83. SecMethod.EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_DES;
  84. SecMethod.EncryptionAlgorithm.uAlgoKeyLen = SecMethod.EncryptionAlgorithm.uAlgoRounds = 0;
  85. }
  86. else if (_tcsicmp(szTmp, POTF_P1_3DES) == 0)
  87. {
  88. bEncryption = true;
  89. SecMethod.EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_3_DES;
  90. SecMethod.EncryptionAlgorithm.uAlgoKeyLen = SecMethod.EncryptionAlgorithm.uAlgoRounds = 0;
  91. }
  92. else if (_tcsicmp(szTmp, POTF_P1_MD5) == 0)
  93. {
  94. bAuthentication = true;
  95. SecMethod.HashingAlgorithm.uAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
  96. SecMethod.HashingAlgorithm.uAlgoKeyLen = SecMethod.HashingAlgorithm.uAlgoRounds = 0;
  97. }
  98. else if ( (_tcsicmp(szTmp, POTF_P1_SHA1) == 0) )
  99. {
  100. bAuthentication = true;
  101. SecMethod.HashingAlgorithm.uAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
  102. SecMethod.HashingAlgorithm.uAlgoKeyLen = SecMethod.HashingAlgorithm.uAlgoRounds = 0;
  103. }
  104. else
  105. {
  106. // parse error
  107. dwReturn = T2P_GENERAL_PARSE_ERROR;
  108. }
  109. if (_tcsicmp(pString1, POTF_P1_DES) == 0 && !bEncryption)
  110. {
  111. bEncryption = true;
  112. SecMethod.EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_DES;
  113. SecMethod.EncryptionAlgorithm.uAlgoKeyLen = SecMethod.EncryptionAlgorithm.uAlgoRounds = 0;
  114. }
  115. else if (_tcsicmp(pString1, POTF_P1_3DES) == 0 && !bEncryption)
  116. {
  117. bEncryption = true;
  118. SecMethod.EncryptionAlgorithm.uAlgoIdentifier = CONF_ALGO_3_DES;
  119. SecMethod.EncryptionAlgorithm.uAlgoKeyLen = SecMethod.EncryptionAlgorithm.uAlgoRounds = 0;
  120. }
  121. else if (_tcsicmp(pString1, POTF_P1_MD5) == 0 && !bAuthentication)
  122. {
  123. bAuthentication = true;
  124. SecMethod.HashingAlgorithm.uAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
  125. SecMethod.HashingAlgorithm.uAlgoKeyLen = SecMethod.HashingAlgorithm.uAlgoRounds = 0;
  126. }
  127. else if ((_tcsicmp(pString1, POTF_P1_SHA1) == 0) && !bAuthentication)
  128. {
  129. bAuthentication = true;
  130. SecMethod.HashingAlgorithm.uAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
  131. SecMethod.HashingAlgorithm.uAlgoKeyLen = SecMethod.HashingAlgorithm.uAlgoRounds = 0;
  132. }
  133. else
  134. {
  135. // parse error
  136. dwReturn = T2P_GENERAL_PARSE_ERROR;
  137. }
  138. // now for the group
  139. if (isdigit(pString2[0]))
  140. {
  141. switch (pString2[0])
  142. {
  143. case '1' :
  144. SecMethod.dwDHGroup = POTF_OAKLEY_GROUP1;
  145. break;
  146. case '2' :
  147. SecMethod.dwDHGroup = POTF_OAKLEY_GROUP2;
  148. break;
  149. case '3' :
  150. SecMethod.dwDHGroup = POTF_OAKLEY_GROUP2048;
  151. break;
  152. default :
  153. dwReturn = T2P_INVALID_P1GROUP;
  154. break;
  155. }
  156. }
  157. else
  158. {
  159. dwReturn = T2P_P1GROUP_MISSING;
  160. }
  161. }
  162. else
  163. {
  164. dwReturn = T2P_GENERAL_PARSE_ERROR;
  165. }
  166. error:
  167. return dwReturn;
  168. }
  169. //////////////////////////////////////////////////////////////////////////////
  170. //
  171. // Function : StringToRootcaAuth()
  172. //
  173. // Date of Creation : 13th Aug 2001
  174. //
  175. // Parameters : IN szText // String to be converted
  176. // IN OUT AuthInfo // Target struct to be filled
  177. //
  178. // Return : DWORD
  179. // T2P_OK
  180. // T2P_NO_PRESHARED_KEY
  181. // T2P_INVALID_AUTH_METHOD
  182. // T2P_ENCODE_FAILED
  183. // T2P_NULL_STRING
  184. //
  185. // Description : This Function takes user input authentication string, validates
  186. // and puts into Main mode auth info structure
  187. //
  188. // History :
  189. //
  190. // Date Author Comments
  191. //
  192. //////////////////////////////////////////////////////////////////////////////
  193. DWORD
  194. StringToRootcaAuth(
  195. IN LPTSTR szText,
  196. IN OUT INT_IPSEC_MM_AUTH_INFO &AuthInfo
  197. )
  198. {
  199. DWORD dwStatus = ERROR_SUCCESS,dwReturn = T2P_OK;
  200. LPTSTR szTemp = NULL;
  201. DWORD dwTextLen = 0;
  202. DWORD dwInfoLen = 0;
  203. LPBYTE pbInfo = NULL;
  204. if (szText == NULL)
  205. {
  206. dwReturn = T2P_NULL_STRING;
  207. BAIL_OUT;
  208. }
  209. AuthInfo.pAuthInfo = NULL;
  210. AuthInfo.dwAuthInfoSize = 0;
  211. dwTextLen = _tcslen(szText);
  212. dwInfoLen = _tcslen(szText);
  213. szTemp = (LPTSTR) calloc(dwInfoLen+1,sizeof(_TCHAR));
  214. if(szTemp == NULL)
  215. {
  216. dwReturn = ERROR_OUTOFMEMORY;
  217. BAIL_OUT;
  218. }
  219. AuthInfo.AuthMethod = IKE_RSA_SIGNATURE;
  220. _tcsncpy(szTemp, szText, dwInfoLen);
  221. AuthInfo.dwAuthInfoSize = _tcslen(szTemp)+1;
  222. pbInfo = (LPBYTE) new _TCHAR[AuthInfo.dwAuthInfoSize];
  223. if(pbInfo == NULL)
  224. {
  225. dwReturn = ERROR_OUTOFMEMORY;
  226. BAIL_OUT;
  227. }
  228. memcpy(pbInfo, szTemp, sizeof(TCHAR)*AuthInfo.dwAuthInfoSize);
  229. AuthInfo.dwAuthInfoSize *= sizeof(WCHAR);
  230. AuthInfo.pAuthInfo = pbInfo;
  231. LPBYTE asnCert = NULL;
  232. dwStatus = EncodeCertificateName((LPTSTR) AuthInfo.pAuthInfo,&asnCert,&AuthInfo.dwAuthInfoSize);
  233. delete [] AuthInfo.pAuthInfo;
  234. AuthInfo.pAuthInfo = NULL;
  235. if(dwStatus == ERROR_SUCCESS )
  236. {
  237. AuthInfo.pAuthInfo = asnCert;
  238. dwReturn = T2P_OK;
  239. }
  240. else
  241. {
  242. if(dwStatus == ERROR_OUTOFMEMORY) // Either there was a error out of memory
  243. {
  244. dwReturn = ERROR_OUTOFMEMORY;
  245. BAIL_OUT;
  246. }
  247. AuthInfo.pAuthInfo = NULL;
  248. AuthInfo.dwAuthInfoSize = 0;
  249. dwReturn = T2P_ENCODE_FAILED; // ... else the encode failed.
  250. }
  251. error:
  252. if (szTemp)
  253. {
  254. free(szTemp);
  255. }
  256. return dwReturn;
  257. }
  258. //////////////////////////////////////////////////////////////////////////////
  259. //
  260. // Function : ListToOffer()
  261. //
  262. // Date of Creation : 13th Aug 2001
  263. //
  264. // Parameters : IN LPTSTR szText // string to convert
  265. // IN OUT IPSEC_QM_OFFER &Offer // target struct to be filled.
  266. //
  267. // Return : DWORD
  268. // T2P_OK
  269. // T2P_NULL_STRING
  270. // T2P_P2_SECLIFE_INVALID
  271. // T2P_P2_KBLIFE_INVALID
  272. // T2P_INVALID_P2REKEY_UNIT
  273. // T2P_INVALID_HASH_ALG
  274. // T2P_GENERAL_PARSE_ERROR
  275. // T2P_DUP_ALGS
  276. // T2P_NONE_NONE
  277. // T2P_INCOMPLETE_ESPALGS
  278. // T2P_INVALID_IPSECPROT
  279. // T2P_P2_KBLIFE_INVALID
  280. // T2P_AHESP_INVALID
  281. //
  282. // Description : Converts string to Phase 2 offer (quick mode)
  283. //
  284. // History :
  285. //
  286. // Date Author Comments
  287. //
  288. //////////////////////////////////////////////////////////////////////////////
  289. DWORD
  290. ListToOffer(
  291. IN LPTSTR szText,
  292. IN OUT IPSEC_QM_OFFER &Offer
  293. )
  294. {
  295. DWORD dwReturn = T2P_OK,dwStatus = 0;
  296. _TCHAR szTmp[MAX_STR_LEN] = {0};
  297. LPTSTR pAnd = NULL,pOptions = NULL,pString = NULL;
  298. BOOL bLifeSpecified = FALSE;
  299. BOOL bDataSpecified = FALSE;
  300. if (szText == NULL)
  301. {
  302. dwReturn = T2P_NULL_STRING;
  303. BAIL_OUT;
  304. }
  305. Offer.dwNumAlgos = 0;
  306. Offer.dwPFSGroup = 0;
  307. if (_tcslen(szText) < MAX_STR_LEN)
  308. {
  309. _tcsncpy(szTmp, szText,MAX_STR_LEN-1);
  310. }
  311. else
  312. {
  313. dwReturn = T2P_GENERAL_PARSE_ERROR;
  314. BAIL_OUT;
  315. }
  316. pOptions = _tcsrchr(szTmp, POTF_NEGPOL_CLOSE);
  317. if ((pOptions != NULL) && *(pOptions + 1) != '\0' && *(pOptions + 1) == POTF_PT_TOKEN && *(pOptions + 2) != '\0')
  318. {
  319. ++pOptions; // we have crossed ']'
  320. *pOptions = '\0'; // We have zero'd *pOption
  321. ++pOptions; // we have crossed ':'
  322. pString = _tcschr(pOptions, POTF_REKEY_TOKEN);
  323. if (pString != NULL)
  324. {
  325. *pString = '\0';
  326. ++pString;
  327. switch (pString[_tcslen(pString) - 1]) // First parse Last one ie out of 200K/300S ->300S
  328. {
  329. case 'k' :
  330. case 'K' :
  331. bDataSpecified = TRUE;
  332. pString[_tcslen(pString) - 1] = '\0';
  333. dwStatus = _stscanf(pString,_TEXT("%u"),&Offer.Lifetime.uKeyExpirationKBytes);
  334. if (dwStatus != 1)
  335. {
  336. dwReturn = T2P_P2_KBLIFE_INVALID;
  337. }
  338. else
  339. {
  340. if (!IsWithinLimit(Offer.Lifetime.uKeyExpirationKBytes,P2_Kb_LIFE_MIN,P2_Kb_LIFE_MAX) )
  341. {
  342. dwReturn = T2P_P2_KBLIFE_INVALID;
  343. }
  344. }
  345. break;
  346. case 's' :
  347. case 'S' :
  348. bLifeSpecified = TRUE;
  349. pString[_tcslen(pString) - 1] = '\0';
  350. dwStatus = _stscanf(pString,_TEXT("%u"),&Offer.Lifetime.uKeyExpirationTime);
  351. if (dwStatus != 1)
  352. {
  353. dwReturn = T2P_P2_SECLIFE_INVALID;
  354. }
  355. else if (!IsWithinLimit(Offer.Lifetime.uKeyExpirationTime,P2_Sec_LIFE_MIN,P2_Sec_LIFE_MAX) )
  356. {
  357. dwReturn = T2P_P2_SECLIFE_INVALID;
  358. }
  359. break;
  360. default :
  361. dwReturn = T2P_P2_KS_INVALID;
  362. break;
  363. }
  364. }
  365. if(dwReturn == T2P_OK)
  366. {
  367. switch (pOptions[_tcslen(pOptions) - 1])
  368. {
  369. case 'k' :
  370. case 'K' :
  371. if(!bDataSpecified )
  372. {
  373. pOptions[_tcslen(pOptions) - 1] = '\0';
  374. dwStatus = _stscanf(pOptions,_TEXT("%u"),&Offer.Lifetime.uKeyExpirationKBytes);
  375. if (dwStatus != 1)
  376. {
  377. dwReturn = T2P_P2_KBLIFE_INVALID;
  378. }
  379. else if (!IsWithinLimit(Offer.Lifetime.uKeyExpirationKBytes,P2_Kb_LIFE_MIN,P2_Kb_LIFE_MAX) )
  380. {
  381. dwReturn = T2P_P2_KBLIFE_INVALID;
  382. }
  383. }
  384. else
  385. {
  386. dwReturn = T2P_P2_KS_INVALID;
  387. }
  388. break;
  389. case 's' :
  390. case 'S' :
  391. if(!bLifeSpecified )
  392. {
  393. pOptions[_tcslen(pOptions) - 1] = '\0';
  394. dwStatus = _stscanf(pOptions,_TEXT("%u"),&Offer.Lifetime.uKeyExpirationTime);
  395. if (dwStatus != 1)
  396. {
  397. dwReturn = T2P_P2REKEY_TOO_LOW;
  398. }
  399. else if (!IsWithinLimit(Offer.Lifetime.uKeyExpirationTime,P2_Sec_LIFE_MIN,P2_Sec_LIFE_MAX) )
  400. {
  401. dwReturn = T2P_P2_SECLIFE_INVALID;
  402. }
  403. }
  404. else
  405. {
  406. dwReturn = T2P_P2_KS_INVALID;
  407. }
  408. break;
  409. default :
  410. dwReturn = T2P_INVALID_P2REKEY_UNIT;
  411. break;
  412. }
  413. }
  414. }
  415. if(dwReturn==T2P_OK)
  416. {
  417. pAnd = _tcschr(szTmp, POTF_NEGPOL_AND);
  418. if ( pAnd != NULL )
  419. {
  420. //
  421. // we have an AND proposal
  422. //
  423. *pAnd = '\0';
  424. ++pAnd;
  425. dwReturn = TextToAlgoInfo(szTmp, Offer.Algos[Offer.dwNumAlgos]);
  426. ++Offer.dwNumAlgos;
  427. if ( T2P_SUCCESS(dwReturn) )
  428. {
  429. dwReturn = TextToAlgoInfo(pAnd, Offer.Algos[Offer.dwNumAlgos]);
  430. if( (Offer.Algos[Offer.dwNumAlgos].Operation) == (Offer.Algos[Offer.dwNumAlgos-1].Operation) )
  431. {
  432. dwReturn = T2P_AHESP_INVALID;
  433. }
  434. ++Offer.dwNumAlgos;
  435. }
  436. }
  437. else
  438. {
  439. dwReturn = TextToAlgoInfo(szTmp, Offer.Algos[Offer.dwNumAlgos]);
  440. ++Offer.dwNumAlgos;
  441. }
  442. }
  443. error:
  444. return dwReturn;
  445. }
  446. //////////////////////////////////////////////////////////////////////////////
  447. //
  448. // Function : TextToAlgoInfo()
  449. //
  450. // Date of Creation : 26th Aug 2001
  451. //
  452. // Parameters : IN LPTSTR szText // string to convert
  453. // IN OUT IPSEC_QM_ALGO &algoInfo // target struct to be filled.
  454. //
  455. // Return : DWORD
  456. // T2P_OK
  457. // T2P_INVALID_HASH_ALG
  458. // T2P_GENERAL_PARSE_ERROR
  459. // T2P_DUP_ALGS
  460. // T2P_NONE_NONE
  461. // T2P_INCOMPLETE_ESPALGS
  462. // T2P_INVALID_IPSECPROT
  463. // T2P_NULL_STRING
  464. //
  465. // Description : Converts string to IPSEC_QM_ALGO,parses AH[alg] or ESP[hashalg,confalg]
  466. //
  467. // History :
  468. //
  469. // Date Author Comments
  470. //
  471. //////////////////////////////////////////////////////////////////////////////
  472. DWORD
  473. TextToAlgoInfo(
  474. IN LPTSTR szText,
  475. OUT IPSEC_QM_ALGO & algoInfo
  476. )
  477. {
  478. DWORD dwReturn = T2P_OK;
  479. _TCHAR szTmp[MAX_STR_LEN] = {0};
  480. LPTSTR pOpen = NULL,pClose = NULL,pString = NULL;
  481. BOOL bEncryption = FALSE; // these are used for processing Auth+Encryption
  482. BOOL bAuthentication= FALSE; // defaults to NONE+NONE
  483. if (szText == NULL)
  484. {
  485. dwReturn = T2P_NULL_STRING;
  486. BAIL_OUT;
  487. }
  488. if (_tcslen(szText) < MAX_STR_LEN)
  489. {
  490. _tcsncpy(szTmp, szText,MAX_STR_LEN-1);
  491. }
  492. else
  493. {
  494. dwReturn = T2P_GENERAL_PARSE_ERROR;
  495. BAIL_OUT;
  496. }
  497. algoInfo.uAlgoKeyLen = algoInfo.uAlgoRounds = 0;
  498. pOpen = _tcschr(szTmp, POTF_NEGPOL_OPEN);
  499. pClose = _tcsrchr(szTmp, POTF_NEGPOL_CLOSE);
  500. if ((pOpen != NULL) && (pClose != NULL) && (*(pClose + 1) == '\0')) // defense
  501. {
  502. *pOpen = '\0';
  503. *pClose = '\0';
  504. ++pOpen;
  505. if (_tcsicmp(szTmp, POTF_NEGPOL_AH) == 0)
  506. {
  507. algoInfo.Operation = AUTHENTICATION;
  508. if (_tcsicmp(pOpen, POTF_NEGPOL_MD5) == 0)
  509. {
  510. algoInfo.uAlgoIdentifier = AUTH_ALGO_MD5;
  511. }
  512. else if (_tcsicmp(pOpen, POTF_NEGPOL_SHA1) == 0)
  513. {
  514. algoInfo.uAlgoIdentifier = AUTH_ALGO_SHA1;
  515. }
  516. else
  517. {
  518. dwReturn = T2P_INVALID_HASH_ALG;
  519. }
  520. }
  521. else if (_tcsicmp(szTmp, POTF_NEGPOL_ESP) == 0)
  522. {
  523. algoInfo.Operation = ENCRYPTION;
  524. pString = _tcschr(pOpen, POTF_ESPTRANS_TOKEN);
  525. if (pString != NULL)
  526. {
  527. *pString = '\0';
  528. ++pString;
  529. // we allow the hash and encryption to be specified in either
  530. // the first or second field
  531. if (_tcsicmp(pOpen, POTF_NEGPOL_DES) == 0)
  532. {
  533. bEncryption = true;
  534. algoInfo.uAlgoIdentifier = CONF_ALGO_DES;
  535. }
  536. else if (_tcsicmp(pOpen, POTF_NEGPOL_3DES) == 0)
  537. {
  538. bEncryption = true;
  539. algoInfo.uAlgoIdentifier = CONF_ALGO_3_DES;
  540. }
  541. else if (_tcsicmp(pOpen, POTF_NEGPOL_MD5) == 0)
  542. {
  543. bAuthentication = true;
  544. algoInfo.uSecAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
  545. }
  546. else if (_tcsicmp(pOpen, POTF_NEGPOL_SHA1) == 0)
  547. {
  548. bAuthentication = true;
  549. algoInfo.uSecAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
  550. }
  551. else if (_tcsicmp(pOpen, POTF_NEGPOL_NONE) != 0)
  552. {
  553. //
  554. // parse error
  555. //
  556. dwReturn = T2P_GENERAL_PARSE_ERROR;
  557. BAIL_OUT;
  558. }
  559. // now the second one
  560. if (_tcsicmp(pString, POTF_NEGPOL_DES) == 0 && !bEncryption)
  561. {
  562. bEncryption = true;
  563. algoInfo.uAlgoIdentifier = CONF_ALGO_DES;
  564. }
  565. else if (_tcsicmp(pString, POTF_NEGPOL_3DES) == 0 && !bEncryption)
  566. {
  567. bEncryption = true;
  568. algoInfo.uAlgoIdentifier = CONF_ALGO_3_DES;
  569. }
  570. else if (_tcsicmp(pString, POTF_NEGPOL_MD5) == 0 && !bAuthentication)
  571. {
  572. bAuthentication = true;
  573. algoInfo.uSecAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
  574. }
  575. else if ((_tcsicmp(pString, POTF_NEGPOL_SHA1) == 0) && !bAuthentication)
  576. {
  577. bAuthentication = true;
  578. algoInfo.uSecAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
  579. }
  580. else if (_tcsicmp(pString, POTF_NEGPOL_NONE) != 0)
  581. {
  582. //
  583. // parse error
  584. //
  585. dwReturn = T2P_GENERAL_PARSE_ERROR;
  586. }
  587. // now, fill in the NONE policies or detect NONE, NONE
  588. if (!bAuthentication && !bEncryption)
  589. {
  590. dwReturn = T2P_NONE_NONE;
  591. }
  592. else if (!bAuthentication)
  593. {
  594. algoInfo.uSecAlgoIdentifier = HMAC_AUTH_ALGO_NONE;
  595. }
  596. else if (!bEncryption)
  597. {
  598. algoInfo.uAlgoIdentifier = CONF_ALGO_NONE;
  599. }
  600. }
  601. else // error
  602. {
  603. dwReturn = T2P_INCOMPLETE_ESPALGS;
  604. }
  605. }
  606. else
  607. {
  608. dwReturn = T2P_INVALID_IPSECPROT;
  609. }
  610. }
  611. else // error
  612. {
  613. dwReturn = T2P_GENERAL_PARSE_ERROR;
  614. }
  615. error:
  616. return dwReturn;
  617. }
  618. //////////////////////////////////////////////////////////////////////////////
  619. //
  620. // Function : LoadQMOfferDefaults()
  621. //
  622. // Date of Creation : 12th Aug 2001
  623. //
  624. // Parameters : IN OUT Offer // target struct to be filled.
  625. //
  626. // Description : Fills the Default values for Quick mode offer structure
  627. //
  628. // History :
  629. //
  630. // Date Author Comments
  631. //
  632. //////////////////////////////////////////////////////////////////////////////
  633. VOID
  634. LoadQMOfferDefaults(
  635. IN OUT IPSEC_QM_OFFER & Offer
  636. )
  637. {
  638. Offer.Lifetime.uKeyExpirationTime = POTF_DEFAULT_P2REKEY_TIME;
  639. Offer.Lifetime.uKeyExpirationKBytes = POTF_DEFAULT_P2REKEY_BYTES;
  640. Offer.dwFlags = 0;
  641. Offer.bPFSRequired = FALSE;
  642. Offer.dwPFSGroup = 0;
  643. Offer.dwNumAlgos = 2;
  644. Offer.dwReserved = 0;
  645. Offer.Algos[0].Operation = ENCRYPTION;
  646. Offer.Algos[0].uAlgoIdentifier = 0;
  647. Offer.Algos[0].uSecAlgoIdentifier = (HMAC_AUTH_ALGO_ENUM)0;
  648. Offer.Algos[0].uAlgoKeyLen = 0;
  649. Offer.Algos[0].uSecAlgoKeyLen = 0;
  650. Offer.Algos[0].uAlgoRounds = 0;
  651. Offer.Algos[0].uSecAlgoRounds = 0;
  652. Offer.Algos[0].MySpi = 0;
  653. Offer.Algos[0].PeerSpi = 0;
  654. Offer.Algos[1].Operation = (IPSEC_OPERATION)0;
  655. Offer.Algos[1].uAlgoIdentifier = 0;
  656. Offer.Algos[1].uSecAlgoIdentifier = (HMAC_AUTH_ALGO_ENUM)0;
  657. Offer.Algos[1].uAlgoKeyLen = 0;
  658. Offer.Algos[1].uSecAlgoKeyLen = 0;
  659. Offer.Algos[1].uAlgoRounds = 0;
  660. Offer.Algos[1].uSecAlgoRounds = 0;
  661. Offer.Algos[1].MySpi = 0;
  662. Offer.Algos[1].PeerSpi = 0;
  663. }
  664. //////////////////////////////////////////////////////////////////////////////
  665. //
  666. // Function : LoadSecMethodDefaults()
  667. //
  668. // Date of Creation: 7th Aug 2001
  669. //
  670. // Parameters : IN OUT SecMethod // Struct which is filled with default values
  671. //
  672. // Return : VOID
  673. //
  674. // Description : It Fills default values for IPSEC_MM_OFFER
  675. //
  676. // Revision History:
  677. //
  678. // Date Author Comments
  679. //
  680. //////////////////////////////////////////////////////////////////////////////
  681. VOID
  682. LoadSecMethodDefaults(
  683. IN OUT IPSEC_MM_OFFER &SecMethod
  684. )
  685. {
  686. SecMethod.Lifetime.uKeyExpirationTime = POTF_DEFAULT_P1REKEY_TIME;
  687. SecMethod.Lifetime.uKeyExpirationKBytes = 0;
  688. SecMethod.dwFlags = 0;
  689. SecMethod.dwQuickModeLimit = POTF_DEFAULT_P1REKEY_QMS;
  690. SecMethod.dwDHGroup = 0;
  691. SecMethod.EncryptionAlgorithm.uAlgoIdentifier = 0;
  692. SecMethod.EncryptionAlgorithm.uAlgoKeyLen = 0;
  693. SecMethod.EncryptionAlgorithm.uAlgoRounds = 0;
  694. SecMethod.HashingAlgorithm.uAlgoIdentifier = 0;
  695. SecMethod.HashingAlgorithm.uAlgoKeyLen = 0;
  696. SecMethod.HashingAlgorithm.uAlgoRounds = 0;
  697. }
  698. //////////////////////////////////////////////////////////////////////////////
  699. //
  700. // Function : LoadKerbAuthInfo()
  701. //
  702. // Date of Creation : 08th Jan 2002
  703. //
  704. // Parameters : IN LPTSTR pszInput,
  705. // OUT PPARSER_PKT pParser,
  706. // IN DWORD dwTagType,
  707. // IN PDWORD pdwUsed,
  708. // IN DWORD dwCount,
  709. //
  710. // Return : ERROR_SUCESS
  711. // ERROR_INVALID_OPTION_VALUE
  712. // ERROR_OUTOFMEMORY
  713. //
  714. // Description : Validates Yes/No
  715. //
  716. //
  717. // History :
  718. //
  719. // Date Author Comments
  720. //
  721. //////////////////////////////////////////////////////////////////////////////
  722. DWORD
  723. LoadKerbAuthInfo(
  724. IN LPTSTR pszInput,
  725. OUT PPARSER_PKT pParser,
  726. IN DWORD dwTagType,
  727. IN PDWORD pdwUsed,
  728. IN DWORD dwCount
  729. )
  730. {
  731. DWORD dwReturn = ERROR_SUCCESS;
  732. DWORD dwStatus = 0;
  733. PSTA_MM_AUTH_METHODS pMMInfo = NULL;
  734. PSTA_AUTH_METHODS pInfo = NULL;
  735. if (*pdwUsed > MAX_ARGS_LIMIT)
  736. {
  737. dwReturn = ERROR_OUT_OF_STRUCTURES;
  738. BAIL_OUT;
  739. }
  740. pInfo = new STA_AUTH_METHODS;
  741. if (!pInfo)
  742. {
  743. dwReturn = ERROR_OUTOFMEMORY;
  744. BAIL_OUT;
  745. }
  746. dwStatus = ValidateBool(pszInput);
  747. if (dwStatus != ARG_YES)
  748. {
  749. if (dwStatus == ARG_NO)
  750. {
  751. // valid parameter, but we don't enter any auth info
  752. dwStatus = ERROR_SUCCESS;
  753. }
  754. else
  755. {
  756. dwStatus = ERRCODE_INVALID_ARG;
  757. }
  758. // if we get here, we didn't have a yes param value for kerberos, so don't
  759. // generate the auth info structure
  760. BAIL_OUT;
  761. }
  762. // Generate the auth info
  763. //
  764. dwReturn = GenerateKerbAuthInfo(&pMMInfo);
  765. if (dwReturn != NO_ERROR)
  766. {
  767. BAIL_OUT;
  768. }
  769. pInfo->pAuthMethodInfo = pMMInfo;
  770. pInfo->dwNumAuthInfos = 1;
  771. pInfo->pAuthMethodInfo->dwSequence = dwCount;
  772. // Update the parser
  773. //
  774. pParser->Cmd[dwCount].dwStatus = VALID_TOKEN; // one auth info struct
  775. pParser->Cmd[dwCount].pArg = pInfo;
  776. pParser->Cmd[dwCount].dwCmdToken = dwTagType;
  777. pInfo = NULL;
  778. error:
  779. if (pInfo)
  780. {
  781. delete pInfo;
  782. }
  783. return dwReturn;
  784. }
  785. //////////////////////////////////////////////////////////////////////////////
  786. //
  787. // Function : LoadPskAuthInfo()
  788. //
  789. // Date of Creation : 08th Jan 2002
  790. //
  791. // Parameters : IN LPTSTR pszInput,
  792. // OUT PPARSER_PKT pParser,
  793. // IN DWORD dwTagType,
  794. // IN PDWORD pdwUsed,
  795. // IN DWORD dwCount,
  796. //
  797. // Return : ERROR_SUCESS
  798. // ERROR_INVALID_OPTION_VALUE
  799. // ERROR_OUTOFMEMORY
  800. //
  801. // Description : Validates string
  802. //
  803. //
  804. // History :
  805. //
  806. // Date Author Comments
  807. //
  808. //////////////////////////////////////////////////////////////////////////////
  809. DWORD
  810. LoadPskAuthInfo(
  811. IN LPTSTR pszInput,
  812. OUT PPARSER_PKT pParser,
  813. IN DWORD dwTagType,
  814. IN PDWORD pdwUsed,
  815. IN DWORD dwCount
  816. )
  817. {
  818. DWORD dwReturn = ERROR_SUCCESS;
  819. DWORD dwStatus = 0;
  820. PSTA_MM_AUTH_METHODS pMMInfo = NULL;
  821. PSTA_AUTH_METHODS pInfo = NULL;
  822. if (*pdwUsed > MAX_ARGS_LIMIT)
  823. {
  824. dwReturn = ERROR_OUT_OF_STRUCTURES;
  825. BAIL_OUT;
  826. }
  827. pInfo = new STA_AUTH_METHODS;
  828. if (!pInfo)
  829. {
  830. dwReturn = ERROR_OUTOFMEMORY;
  831. BAIL_OUT;
  832. }
  833. // verify there really is a string there
  834. //
  835. if (pszInput[0] == _TEXT('\0'))
  836. {
  837. dwReturn = ERRCODE_INVALID_ARG;
  838. BAIL_OUT;
  839. }
  840. // Generate the auth info
  841. //
  842. dwReturn = GeneratePskAuthInfo(&pMMInfo, pszInput);
  843. if (dwReturn != NO_ERROR)
  844. {
  845. BAIL_OUT;
  846. }
  847. pInfo->pAuthMethodInfo = pMMInfo;
  848. pInfo->dwNumAuthInfos = 1;
  849. pInfo->pAuthMethodInfo->dwSequence = dwCount;
  850. // Update the parser
  851. //
  852. pParser->Cmd[dwCount].dwStatus = VALID_TOKEN; // one auth info struct
  853. pParser->Cmd[dwCount].pArg = pInfo;
  854. pParser->Cmd[dwCount].dwCmdToken = dwTagType;
  855. pInfo = NULL;
  856. error:
  857. if (pInfo)
  858. {
  859. delete pInfo;
  860. }
  861. return dwReturn;
  862. }
  863. //////////////////////////////////////////////////////////////////////////////
  864. //
  865. // Function : EncodeCertificateName()
  866. //
  867. // Date of Creation : 21st Aug 2001
  868. //
  869. // Parameters : LPTSTR pszSubjectName,
  870. // BYTE **EncodedName,
  871. // PDWORD pEncodedNameLength
  872. //
  873. // Return : DWORD
  874. //
  875. // Description : This function encodes the certificate name based on the user input.
  876. //
  877. // History :
  878. //
  879. // Date Author Comments
  880. //
  881. //////////////////////////////////////////////////////////////////////////////
  882. DWORD
  883. EncodeCertificateName (
  884. LPTSTR pszSubjectName,
  885. BYTE **EncodedName,
  886. PDWORD pdwEncodedNameLength
  887. )
  888. {
  889. *pdwEncodedNameLength=0; DWORD dwReturn = ERROR_SUCCESS;
  890. if (!CertStrToName( X509_ASN_ENCODING,
  891. pszSubjectName,
  892. CERT_X500_NAME_STR,
  893. NULL,
  894. NULL,
  895. pdwEncodedNameLength,
  896. NULL))
  897. {
  898. dwReturn = ERROR_INVALID_PARAMETER;
  899. }
  900. if(dwReturn == ERROR_SUCCESS)
  901. {
  902. (*EncodedName)= new BYTE[*pdwEncodedNameLength];
  903. if(*EncodedName)
  904. {
  905. if (!CertStrToName( X509_ASN_ENCODING,
  906. pszSubjectName,
  907. CERT_X500_NAME_STR,
  908. NULL,
  909. (*EncodedName),
  910. pdwEncodedNameLength,
  911. NULL))
  912. {
  913. delete (*EncodedName);
  914. (*EncodedName) = 0;
  915. dwReturn = ERROR_INVALID_PARAMETER;
  916. }
  917. }
  918. else
  919. {
  920. dwReturn = ERROR_OUTOFMEMORY;
  921. }
  922. }
  923. return dwReturn;
  924. }
  925. DWORD
  926. GenerateKerbAuthInfo(
  927. OUT STA_MM_AUTH_METHODS** ppInfo
  928. )
  929. {
  930. DWORD dwReturn = NO_ERROR;
  931. STA_MM_AUTH_METHODS* pInfo = new STA_MM_AUTH_METHODS;
  932. if (pInfo == NULL)
  933. {
  934. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  935. BAIL_OUT;
  936. }
  937. ZeroMemory(pInfo, sizeof(STA_MM_AUTH_METHODS));
  938. pInfo->pAuthenticationInfo = new INT_IPSEC_MM_AUTH_INFO;
  939. if (pInfo->pAuthenticationInfo == NULL)
  940. {
  941. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  942. BAIL_OUT;
  943. }
  944. ZeroMemory(pInfo->pAuthenticationInfo, sizeof(INT_IPSEC_MM_AUTH_INFO));
  945. // Indicate kerberos
  946. //
  947. pInfo->pAuthenticationInfo->AuthMethod = IKE_SSPI;
  948. *ppInfo = pInfo;
  949. error:
  950. if (dwReturn != NO_ERROR)
  951. {
  952. if (pInfo)
  953. {
  954. if (pInfo->pAuthenticationInfo)
  955. {
  956. delete pInfo->pAuthenticationInfo;
  957. }
  958. delete pInfo;
  959. }
  960. }
  961. return dwReturn;
  962. }
  963. DWORD
  964. GeneratePskAuthInfo(
  965. OUT STA_MM_AUTH_METHODS** ppInfo,
  966. IN LPTSTR lpKey
  967. )
  968. {
  969. DWORD dwReturn = NO_ERROR;
  970. size_t uiKeyLen = 0;
  971. STA_MM_AUTH_METHODS* pInfo = NULL;
  972. LPTSTR lpLocalKey;
  973. // Allocate the info struct
  974. //
  975. pInfo = new STA_MM_AUTH_METHODS;
  976. if (pInfo == NULL)
  977. {
  978. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  979. BAIL_OUT;
  980. }
  981. ZeroMemory(pInfo, sizeof(STA_MM_AUTH_METHODS));
  982. pInfo->pAuthenticationInfo = new INT_IPSEC_MM_AUTH_INFO;
  983. if (pInfo->pAuthenticationInfo == NULL)
  984. {
  985. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  986. BAIL_OUT;
  987. }
  988. ZeroMemory(pInfo->pAuthenticationInfo, sizeof(INT_IPSEC_MM_AUTH_INFO));
  989. dwReturn = NsuStringLen(lpKey, &uiKeyLen);
  990. if (dwReturn != ERROR_SUCCESS)
  991. {
  992. BAIL_OUT;
  993. }
  994. lpLocalKey = new TCHAR[uiKeyLen];
  995. _tcsncpy(lpLocalKey, lpKey, uiKeyLen);
  996. // Indicate psk
  997. //
  998. pInfo->pAuthenticationInfo->AuthMethod= IKE_PRESHARED_KEY;
  999. pInfo->pAuthenticationInfo->pAuthInfo = (LPBYTE)lpLocalKey;
  1000. pInfo->pAuthenticationInfo->dwAuthInfoSize = uiKeyLen * sizeof(WCHAR);
  1001. *ppInfo = pInfo;
  1002. error:
  1003. if (dwReturn != NO_ERROR)
  1004. {
  1005. if (pInfo)
  1006. {
  1007. if (pInfo->pAuthenticationInfo)
  1008. {
  1009. delete pInfo->pAuthenticationInfo;
  1010. }
  1011. delete pInfo;
  1012. }
  1013. }
  1014. return dwReturn;
  1015. }
  1016. DWORD
  1017. GenerateRootcaAuthInfo(
  1018. OUT STA_MM_AUTH_METHODS** ppInfo,
  1019. IN LPTSTR lpRootcaInfo
  1020. )
  1021. {
  1022. DWORD dwReturn = NO_ERROR;
  1023. DWORD dwStatus = NO_ERROR;
  1024. size_t uiCertInfoLen = 0;
  1025. BOOL bCertMapSpecified = FALSE;
  1026. BOOL bCertMapping = FALSE;
  1027. BOOL bCRPExclude = FALSE;
  1028. STA_MM_AUTH_METHODS* pInfo = NULL;
  1029. PINT_IPSEC_MM_AUTH_INFO pMMAuthInfo = NULL;
  1030. // Allocate the info struct
  1031. //
  1032. pInfo = new STA_MM_AUTH_METHODS;
  1033. if (pInfo == NULL)
  1034. {
  1035. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  1036. BAIL_OUT;
  1037. }
  1038. ZeroMemory(pInfo, sizeof(STA_MM_AUTH_METHODS));
  1039. if (_tcsicmp(lpRootcaInfo,_TEXT("\0")) != 0)
  1040. {
  1041. pMMAuthInfo = new INT_IPSEC_MM_AUTH_INFO;
  1042. if(pMMAuthInfo == NULL)
  1043. {
  1044. dwReturn = ERROR_OUTOFMEMORY;
  1045. BAIL_OUT;
  1046. }
  1047. CheckForCertParamsAndRemove(lpRootcaInfo, &bCertMapSpecified, &bCertMapping, &bCRPExclude);
  1048. dwStatus = StringToRootcaAuth(lpRootcaInfo,*(pMMAuthInfo));
  1049. pInfo->bCertMappingSpecified = bCertMapSpecified;
  1050. pInfo->bCertMapping = bCertMapping;
  1051. pInfo->bCRPExclude = bCRPExclude;
  1052. pInfo->pAuthenticationInfo = pMMAuthInfo;
  1053. pMMAuthInfo = NULL;
  1054. if((dwStatus != T2P_OK) || (dwReturn != ERROR_SUCCESS) )
  1055. {
  1056. switch(dwStatus)
  1057. {
  1058. case ERROR_OUTOFMEMORY :
  1059. PrintErrorMessage(WIN32_ERR,ERROR_OUTOFMEMORY,NULL);
  1060. dwReturn = RETURN_NO_ERROR;
  1061. break;
  1062. default :
  1063. break;
  1064. }
  1065. PrintErrorMessage(IPSEC_ERR, 0, ERRCODE_ENCODE_FAILED);
  1066. dwReturn = RETURN_NO_ERROR;
  1067. BAIL_OUT;
  1068. }
  1069. }
  1070. *ppInfo = pInfo;
  1071. pInfo = NULL;
  1072. error:
  1073. if (pInfo)
  1074. {
  1075. if (pInfo->pAuthenticationInfo)
  1076. {
  1077. delete pInfo->pAuthenticationInfo;
  1078. }
  1079. delete pInfo;
  1080. }
  1081. if (pMMAuthInfo)
  1082. {
  1083. delete pMMAuthInfo;
  1084. }
  1085. return dwReturn;
  1086. }
  1087. //////////////////////////////////////////////////////////////////////////////
  1088. //
  1089. // Function : CheckForCertParamsAndRemove()
  1090. //
  1091. // Date of Creation : 28th Jan 2002
  1092. //
  1093. // Parameters : IN szText // Input String
  1094. // OUT BOOL CertMapSpecified // Certificate contains CertMap Option
  1095. // OUT BOOL CertMap // User Specified CertMap Option
  1096. // OUT BOOL CRPExclude // User specified CRP option
  1097. //
  1098. // Return : DWORD
  1099. // T2P_INVALID_AUTH_METHOD
  1100. // T2P_NULL_STRING
  1101. //
  1102. // Description : This Function takes user input authentication cert string, validates
  1103. // cert map and puts into Main mode auth info structure
  1104. //
  1105. // History :
  1106. //
  1107. // Date Author Comments
  1108. //
  1109. //////////////////////////////////////////////////////////////////////////////
  1110. DWORD
  1111. MatchKeywordAndFillValues(
  1112. const TCHAR * lptString,
  1113. const TCHAR * lptKeyword,
  1114. size_t uiKeyLen,
  1115. PBOOL pbSpecified,
  1116. PBOOL pbValue
  1117. )
  1118. {
  1119. const TCHAR TOKEN_YES [] = _TEXT("yes");
  1120. const TCHAR TOKEN_NO [] = _TEXT("no");
  1121. if ((_tcsnicmp(lptString, lptKeyword, uiKeyLen) == 0) && (lptString[uiKeyLen] == _TEXT(':')))
  1122. {
  1123. if (*pbSpecified)
  1124. {
  1125. return ERROR_TOKEN_ALREADY_IN_USE;
  1126. }
  1127. *pbSpecified = TRUE;
  1128. if (_tcsnicmp((LPTSTR)(&lptString[uiKeyLen+1]), TOKEN_YES, sizeof(TOKEN_YES)/sizeof(TCHAR) - 1) == 0)
  1129. {
  1130. *pbValue = TRUE;
  1131. }
  1132. else if (_tcsnicmp((LPTSTR)(&lptString[uiKeyLen+1]), TOKEN_NO, sizeof(TOKEN_NO)/sizeof(TCHAR) - 1) == 0)
  1133. {
  1134. *pbValue = FALSE;
  1135. }
  1136. else
  1137. {
  1138. return ERROR_INVALID_PARAMETER;
  1139. }
  1140. }
  1141. else
  1142. {
  1143. return ERROR_INVALID_DATA;
  1144. }
  1145. return ERROR_SUCCESS;
  1146. }
  1147. DWORD
  1148. CheckForCertParamsAndRemove(
  1149. IN OUT LPTSTR szText,
  1150. OUT PBOOL pbCertMapSpecified,
  1151. OUT PBOOL pbCertMap,
  1152. OUT PBOOL pbCRPExclude
  1153. )
  1154. {
  1155. DWORD dwReturn = ERROR_SUCCESS;
  1156. *pbCertMapSpecified = FALSE;
  1157. BOOL bCRPExcludeSpecified = FALSE;
  1158. BOOL bIsMatch = TRUE;
  1159. const TCHAR TOKEN_CERTMAP [] = _TEXT("certmap");
  1160. const TCHAR TOKEN_CRP_EXCLUDE [] = _TEXT("excludecaname");
  1161. // find end of string
  1162. size_t uiStrLen = 0;
  1163. dwReturn = NsuStringLen(szText, &uiStrLen);
  1164. if (dwReturn != ERROR_SUCCESS)
  1165. {
  1166. BAIL_OUT;
  1167. }
  1168. LPTSTR szTextTemp = szText + uiStrLen - 1;
  1169. while (bIsMatch && (!bCRPExcludeSpecified || !(*pbCertMapSpecified)))
  1170. {
  1171. // work back to last whitespace before last non-whitespace
  1172. while ((*szTextTemp == _TEXT(' ')) || (*szTextTemp == _TEXT('\t')))
  1173. {
  1174. *szTextTemp = _TEXT('\0');
  1175. --szTextTemp;
  1176. }
  1177. // we can't go past the start of the string, and in fact it is invalid if the cert string starts with a parameter,
  1178. // so parse accordingly
  1179. while ((szTextTemp > szText) && (*szTextTemp != _TEXT(' ')) && (*szTextTemp != _TEXT('\t')))
  1180. {
  1181. --szTextTemp;
  1182. }
  1183. if (szTextTemp == szText)
  1184. {
  1185. // we are at the start of the whole string, so there is no appropriate parameter portion or
  1186. // the certmap is invalid... just return we didn't find anything and let cert parsing figure it out
  1187. dwReturn = ERROR_SUCCESS;
  1188. BAIL_OUT;
  1189. }
  1190. ++szTextTemp;
  1191. dwReturn = MatchKeywordAndFillValues(
  1192. szTextTemp,
  1193. TOKEN_CERTMAP,
  1194. sizeof(TOKEN_CERTMAP)/sizeof(TCHAR) - 1,
  1195. pbCertMapSpecified,
  1196. pbCertMap
  1197. );
  1198. switch(dwReturn)
  1199. {
  1200. case ERROR_SUCCESS:
  1201. break;
  1202. case ERROR_INVALID_DATA:
  1203. dwReturn = MatchKeywordAndFillValues(
  1204. szTextTemp,
  1205. TOKEN_CRP_EXCLUDE,
  1206. sizeof(TOKEN_CRP_EXCLUDE)/sizeof(TCHAR) - 1,
  1207. &bCRPExcludeSpecified,
  1208. pbCRPExclude
  1209. );
  1210. switch (dwReturn)
  1211. {
  1212. case ERROR_INVALID_DATA:
  1213. // we didn't match either parameter, so we're done
  1214. bIsMatch = FALSE;
  1215. dwReturn = ERROR_SUCCESS;
  1216. break;
  1217. case ERROR_SUCCESS:
  1218. break;
  1219. case ERROR_TOKEN_ALREADY_IN_USE:
  1220. case ERROR_INVALID_PARAMETER:
  1221. default:
  1222. BAIL_OUT;
  1223. break;
  1224. }
  1225. break;
  1226. case ERROR_TOKEN_ALREADY_IN_USE:
  1227. case ERROR_INVALID_PARAMETER:
  1228. default:
  1229. BAIL_OUT;
  1230. break;
  1231. }
  1232. // chop the certmap portion if it existed... we already know we are not altering anything _before_
  1233. // the start of the passed string because of the while loops above
  1234. if (bIsMatch)
  1235. {
  1236. --szTextTemp;
  1237. while ((szTextTemp > szText) && ((*szTextTemp == _TEXT(' ')) || (*szTextTemp == _TEXT('\t'))))
  1238. {
  1239. --szTextTemp;
  1240. }
  1241. ++szTextTemp;
  1242. *szTextTemp = _TEXT('\0');
  1243. }
  1244. }
  1245. error:
  1246. return dwReturn;
  1247. }
  1248. ///////////////////////////////////////////////////////////////////////////////
  1249. //
  1250. // ProcessEscapedCharacters
  1251. //
  1252. // every occurrence of \' in the string is shortened to "
  1253. //
  1254. // Notes:
  1255. // * this transformation occurs in place and the new string is properly
  1256. // null-terminated
  1257. // * it is not up to this routine to determine if number of quotes match,
  1258. // only to properly place interpreted escaped characters where they
  1259. // originally existed in the input string
  1260. //
  1261. // Return values:
  1262. // ERR_INVALID_ARG
  1263. // ERROR_SUCCESS
  1264. //
  1265. ///////////////////////////////////////////////////////////////////////////////
  1266. DWORD ProcessEscapedCharacters(LPTSTR lptString)
  1267. {
  1268. DWORD dwReturn = ERROR_SUCCESS;
  1269. _TCHAR* src = lptString;
  1270. _TCHAR* dst = lptString;
  1271. while (*src != _TEXT('\0'))
  1272. {
  1273. switch(*src)
  1274. {
  1275. case _TEXT('\\'):
  1276. // take proper action based on escaped character found
  1277. ++src;
  1278. switch(*src)
  1279. {
  1280. case _TEXT('\''):
  1281. *dst = _TEXT('\"');
  1282. break;
  1283. default:
  1284. dwReturn = ERR_INVALID_ARG;
  1285. BAIL_OUT;
  1286. break;
  1287. }
  1288. break;
  1289. default:
  1290. // copy directly, keep processing
  1291. *dst = *src;
  1292. break;
  1293. }
  1294. ++dst;
  1295. ++src;
  1296. }
  1297. error:
  1298. // null-terminate the string as-is, even if processing failed
  1299. *dst = _TEXT('\0');
  1300. return dwReturn;
  1301. }
  1302. VOID
  1303. AddAuthMethod(
  1304. PRULEDATA pRuleData,
  1305. PSTA_MM_AUTH_METHODS pMMAuth,
  1306. size_t *pIndex
  1307. )
  1308. {
  1309. if (pMMAuth)
  1310. {
  1311. //Certificate to account mapping issue is taken care here
  1312. if(pMMAuth->bCertMappingSpecified)
  1313. {
  1314. if((g_StorageLocation.dwLocation==IPSEC_REGISTRY_PROVIDER && IsDomainMember(g_StorageLocation.pszMachineName))||(g_StorageLocation.dwLocation==IPSEC_DIRECTORY_PROVIDER))
  1315. {
  1316. if(pMMAuth->bCertMapping)
  1317. {
  1318. pMMAuth->pAuthenticationInfo->dwAuthFlags|= IPSEC_MM_CERT_AUTH_ENABLE_ACCOUNT_MAP;
  1319. }
  1320. else
  1321. {
  1322. pMMAuth->pAuthenticationInfo->dwAuthFlags &= ~IPSEC_MM_CERT_AUTH_ENABLE_ACCOUNT_MAP;
  1323. }
  1324. }
  1325. else
  1326. {
  1327. if(pMMAuth->bCertMapping)
  1328. {
  1329. PrintMessageFromModule(g_hModule,SET_STATIC_POLICY_INVALID_CERTMAP_MSG);
  1330. }
  1331. }
  1332. }
  1333. else
  1334. {
  1335. pMMAuth->pAuthenticationInfo->dwAuthFlags &= ~IPSEC_MM_CERT_AUTH_ENABLE_ACCOUNT_MAP;
  1336. }
  1337. if(pMMAuth->bCRPExclude)
  1338. {
  1339. pMMAuth->pAuthenticationInfo->dwAuthFlags |= IPSEC_MM_CERT_AUTH_DISABLE_CERT_REQUEST;
  1340. }
  1341. else
  1342. {
  1343. pMMAuth->pAuthenticationInfo->dwAuthFlags &= ~IPSEC_MM_CERT_AUTH_DISABLE_CERT_REQUEST;
  1344. }
  1345. pRuleData->AuthInfos.pAuthMethodInfo[*pIndex].pAuthenticationInfo = pMMAuth->pAuthenticationInfo;
  1346. pMMAuth->pAuthenticationInfo = NULL;
  1347. ++(*pIndex);
  1348. }
  1349. }
  1350. VOID
  1351. AddAuthMethod(
  1352. PRULEDATA pRuleData,
  1353. PSTA_AUTH_METHODS pAuthMethods,
  1354. size_t *pIndex
  1355. )
  1356. {
  1357. if (pAuthMethods)
  1358. {
  1359. AddAuthMethod(pRuleData, pAuthMethods->pAuthMethodInfo, pIndex);
  1360. }
  1361. }
  1362. DWORD
  1363. AddAllAuthMethods(
  1364. PRULEDATA pRuleData,
  1365. PSTA_AUTH_METHODS pKerbAuth,
  1366. PSTA_AUTH_METHODS pPskAuth,
  1367. PSTA_MM_AUTH_METHODS *ppRootcaMMAuth,
  1368. BOOL bAddDefaults
  1369. )
  1370. {
  1371. DWORD dwReturn = ERROR_SUCCESS;
  1372. PSTA_AUTH_METHODS paSingletons[2];
  1373. size_t uiNumSingletons = 0;
  1374. size_t uiNumRootca = 0;
  1375. size_t uiNumAuthMethods = pRuleData->AuthInfos.dwNumAuthInfos;
  1376. size_t uiRootIndex = 0;
  1377. size_t uiSingletonIndex = 0;
  1378. size_t uiNumAuths = 0;
  1379. if (pRuleData->bAuthMethodSpecified)
  1380. {
  1381. pRuleData->dwAuthInfos = uiNumAuthMethods;
  1382. pRuleData->AuthInfos.pAuthMethodInfo = new STA_MM_AUTH_METHODS[uiNumAuthMethods];
  1383. if(pRuleData->AuthInfos.pAuthMethodInfo == NULL)
  1384. {
  1385. dwReturn = ERROR_OUTOFMEMORY;
  1386. BAIL_OUT;
  1387. }
  1388. paSingletons[0] = pKerbAuth;
  1389. paSingletons[1] = pPskAuth;
  1390. // swap if pKerbAuth doesn't exist, or if both exist and sequence is out of order
  1391. if (!pKerbAuth || (pPskAuth && (pKerbAuth->pAuthMethodInfo->dwSequence > pPskAuth->pAuthMethodInfo->dwSequence)))
  1392. {
  1393. paSingletons[0] = pPskAuth;
  1394. paSingletons[1] = pKerbAuth;
  1395. }
  1396. uiNumSingletons = (pKerbAuth ? 1 : 0);
  1397. uiNumSingletons += (pPskAuth ? 1 : 0);
  1398. uiNumRootca = uiNumAuthMethods - uiNumSingletons;
  1399. while (uiSingletonIndex< uiNumSingletons)
  1400. {
  1401. while ((uiRootIndex < uiNumRootca) && (ppRootcaMMAuth[uiRootIndex]->dwSequence <= paSingletons[uiSingletonIndex]->pAuthMethodInfo->dwSequence))
  1402. {
  1403. AddAuthMethod(pRuleData, ppRootcaMMAuth[uiRootIndex], &uiNumAuths);
  1404. ++uiRootIndex;
  1405. }
  1406. AddAuthMethod(pRuleData, paSingletons[uiSingletonIndex], &uiNumAuths);
  1407. ++uiSingletonIndex;
  1408. }
  1409. while (uiRootIndex < uiNumRootca)
  1410. {
  1411. AddAuthMethod(pRuleData, ppRootcaMMAuth[uiRootIndex], &uiNumAuths);
  1412. ++uiRootIndex;
  1413. }
  1414. }
  1415. else if (bAddDefaults)
  1416. {
  1417. DWORD dwLocation=IPSEC_REGISTRY_PROVIDER;
  1418. LPTSTR pszMachineName=NULL;
  1419. dwReturn = CopyStorageInfo(&pszMachineName,dwLocation);
  1420. BAIL_ON_WIN32_ERROR(dwReturn);
  1421. PINT_IPSEC_MM_AUTH_INFO pAuthenticationInfo = NULL;
  1422. if(dwLocation==IPSEC_REGISTRY_PROVIDER)
  1423. {
  1424. dwReturn=SmartDefaults(&pAuthenticationInfo, pszMachineName, &(pRuleData->dwAuthInfos), FALSE);
  1425. }
  1426. else
  1427. {
  1428. dwReturn=SmartDefaults(&pAuthenticationInfo, NULL, &(pRuleData->dwAuthInfos), TRUE);
  1429. }
  1430. if(dwReturn==ERROR_SUCCESS)
  1431. {
  1432. //this conversion is required to get the additional certmap info
  1433. //for details , refer the following function
  1434. dwReturn = ConvertMMAuthToStaticLocal(pAuthenticationInfo, pRuleData->dwAuthInfos, pRuleData->AuthInfos);
  1435. pRuleData->AuthInfos.dwNumAuthInfos = pRuleData->dwAuthInfos;
  1436. }
  1437. if(pszMachineName)
  1438. {
  1439. delete [] pszMachineName;
  1440. }
  1441. }
  1442. error:
  1443. return dwReturn;
  1444. }