Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
14 KiB

  1. /////////////////////////////////////////////////////////////
  2. // Copyright(c) 2001, Microsoft Corporation
  3. //
  4. // spdutil.cpp
  5. //
  6. // Created on 3/27/01 by DKalin
  7. // Revisions:
  8. // File created 3/27/01 DKalin
  9. //
  10. // Implementation for the auxiliary functions for text to policy conversion routines
  11. //
  12. // Separated from generic routines in text2pol.cpp and text2spd.cpp
  13. //
  14. /////////////////////////////////////////////////////////////
  15. #include "ipseccmd.h"
  16. int isdnsname(char *szStr)
  17. {
  18. // if there is an alpha character in the string,
  19. // then we consider a DNS name
  20. if ( szStr )
  21. {
  22. for (UINT i = 0; i < strlen(szStr); ++i)
  23. {
  24. if ( isalpha(szStr[i]) )
  25. return 1;
  26. }
  27. }
  28. return 0;
  29. }
  30. // takes inFilter and reflects it to outFilter
  31. // creates GUID and name for outFilter
  32. bool MirrorFilter(IN T2P_FILTER inFilter, OUT T2P_FILTER & outFilter)
  33. {
  34. bool bReturn = true;
  35. memset(&outFilter, 0, sizeof(T2P_FILTER));
  36. outFilter.QMFilterType = inFilter.QMFilterType;
  37. if (inFilter.QMFilterType != QM_TUNNEL_FILTER)
  38. {
  39. // process transport
  40. // GUID first
  41. RPC_STATUS RpcStat = UuidCreate(&outFilter.TransportFilter.gFilterID);
  42. if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
  43. {
  44. sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
  45. RpcStat);
  46. WARN;
  47. bReturn = false;
  48. }
  49. if (bReturn)
  50. {
  51. // now name, add " - Mirror"
  52. WCHAR wszMirrorSuffix[] = L" - Mirror";
  53. int iNameLen = 0;
  54. if (inFilter.TransportFilter.pszFilterName != NULL)
  55. {
  56. iNameLen = wcslen(inFilter.TransportFilter.pszFilterName);
  57. }
  58. WCHAR* pwszTmp = new WCHAR[iNameLen+wcslen(wszMirrorSuffix)+1];
  59. assert(pwszTmp != NULL);
  60. wcscpy(pwszTmp, inFilter.TransportFilter.pszFilterName);
  61. wcscat(pwszTmp, wszMirrorSuffix);
  62. outFilter.TransportFilter.pszFilterName = pwszTmp;
  63. }
  64. // direction
  65. outFilter.TransportFilter.dwDirection = inFilter.TransportFilter.dwDirection;
  66. if (inFilter.TransportFilter.dwDirection == FILTER_DIRECTION_INBOUND)
  67. {
  68. outFilter.TransportFilter.dwDirection = FILTER_DIRECTION_OUTBOUND;
  69. }
  70. if (inFilter.TransportFilter.dwDirection == FILTER_DIRECTION_OUTBOUND)
  71. {
  72. outFilter.TransportFilter.dwDirection = FILTER_DIRECTION_INBOUND;
  73. }
  74. // straight copy stuff
  75. outFilter.TransportFilter.InterfaceType = inFilter.TransportFilter.InterfaceType;
  76. outFilter.TransportFilter.bCreateMirror = inFilter.TransportFilter.bCreateMirror;
  77. outFilter.TransportFilter.dwFlags = inFilter.TransportFilter.dwFlags;
  78. outFilter.TransportFilter.Protocol = inFilter.TransportFilter.Protocol;
  79. outFilter.TransportFilter.dwWeight = inFilter.TransportFilter.dwWeight;
  80. outFilter.TransportFilter.gPolicyID = inFilter.TransportFilter.gPolicyID;
  81. // the reflected stuff
  82. outFilter.TransportFilter.SrcAddr = inFilter.TransportFilter.DesAddr;
  83. outFilter.TransportFilter.DesAddr = inFilter.TransportFilter.SrcAddr;
  84. outFilter.TransportFilter.SrcPort = inFilter.TransportFilter.DesPort;
  85. outFilter.TransportFilter.DesPort = inFilter.TransportFilter.SrcPort;
  86. outFilter.TransportFilter.InboundFilterFlag = inFilter.TransportFilter.OutboundFilterFlag;
  87. outFilter.TransportFilter.OutboundFilterFlag = inFilter.TransportFilter.InboundFilterFlag;
  88. }
  89. else
  90. {
  91. // GUID first
  92. RPC_STATUS RpcStat = UuidCreate(&outFilter.TunnelFilter.gFilterID);
  93. if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
  94. {
  95. sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
  96. RpcStat);
  97. WARN;
  98. bReturn = false;
  99. }
  100. if (bReturn)
  101. {
  102. // now name, add " - Mirror"
  103. WCHAR wszMirrorSuffix[] = L" - Mirror";
  104. int iNameLen = 0;
  105. if (inFilter.TunnelFilter.pszFilterName != NULL)
  106. {
  107. iNameLen = wcslen(inFilter.TunnelFilter.pszFilterName);
  108. }
  109. WCHAR* pwszTmp = new WCHAR[iNameLen+wcslen(wszMirrorSuffix)+1];
  110. assert(pwszTmp != NULL);
  111. wcscpy(pwszTmp, inFilter.TunnelFilter.pszFilterName);
  112. wcscat(pwszTmp, wszMirrorSuffix);
  113. outFilter.TunnelFilter.pszFilterName = pwszTmp;
  114. }
  115. // direction
  116. outFilter.TunnelFilter.dwDirection = inFilter.TunnelFilter.dwDirection;
  117. if (inFilter.TunnelFilter.dwDirection == FILTER_DIRECTION_INBOUND)
  118. {
  119. outFilter.TunnelFilter.dwDirection = FILTER_DIRECTION_OUTBOUND;
  120. }
  121. if (inFilter.TunnelFilter.dwDirection == FILTER_DIRECTION_OUTBOUND)
  122. {
  123. outFilter.TunnelFilter.dwDirection = FILTER_DIRECTION_INBOUND;
  124. }
  125. // straight copy stuff
  126. outFilter.TunnelFilter.InterfaceType = inFilter.TunnelFilter.InterfaceType;
  127. outFilter.TunnelFilter.bCreateMirror = inFilter.TunnelFilter.bCreateMirror;
  128. outFilter.TunnelFilter.dwFlags = inFilter.TunnelFilter.dwFlags;
  129. outFilter.TunnelFilter.Protocol = inFilter.TunnelFilter.Protocol;
  130. outFilter.TunnelFilter.dwWeight = inFilter.TunnelFilter.dwWeight;
  131. outFilter.TunnelFilter.gPolicyID = inFilter.TunnelFilter.gPolicyID;
  132. // the reflected stuff
  133. outFilter.TunnelFilter.SrcAddr = inFilter.TunnelFilter.DesAddr;
  134. outFilter.TunnelFilter.DesAddr = inFilter.TunnelFilter.SrcAddr;
  135. outFilter.TunnelFilter.SrcTunnelAddr = inFilter.TunnelFilter.DesTunnelAddr;
  136. outFilter.TunnelFilter.DesTunnelAddr = inFilter.TunnelFilter.SrcTunnelAddr;
  137. outFilter.TunnelFilter.SrcPort = inFilter.TunnelFilter.DesPort;
  138. outFilter.TunnelFilter.DesPort = inFilter.TunnelFilter.SrcPort;
  139. outFilter.TunnelFilter.InboundFilterFlag = inFilter.TunnelFilter.OutboundFilterFlag;
  140. outFilter.TunnelFilter.OutboundFilterFlag = inFilter.TunnelFilter.InboundFilterFlag;
  141. }
  142. return bReturn;
  143. }
  144. void LoadIkeDefaults(OUT IPSEC_MM_POLICY & IkePol)
  145. {
  146. IkePol.dwOfferCount = 4;
  147. IkePol.pOffers = new IPSEC_MM_OFFER[IkePol.dwOfferCount];
  148. assert(IkePol.pOffers != NULL);
  149. memset(IkePol.pOffers, 0, sizeof(IPSEC_MM_OFFER) * IkePol.dwOfferCount);
  150. // init these
  151. for (UINT i = 0; i < IkePol.dwOfferCount; ++i)
  152. {
  153. IkePol.pOffers[i].dwQuickModeLimit = POTF_DEFAULT_P1REKEY_QMS;
  154. IkePol.pOffers[i].Lifetime.uKeyExpirationKBytes = 0;
  155. IkePol.pOffers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P1REKEY_TIME;
  156. }
  157. IkePol.pOffers[0].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  158. IkePol.pOffers[0].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  159. IkePol.pOffers[0].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
  160. IkePol.pOffers[0].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
  161. IkePol.pOffers[0].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  162. IkePol.pOffers[0].dwDHGroup = POTF_OAKLEY_GROUP2;
  163. IkePol.pOffers[1].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  164. IkePol.pOffers[1].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  165. IkePol.pOffers[1].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
  166. IkePol.pOffers[1].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_MD5;
  167. IkePol.pOffers[1].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  168. IkePol.pOffers[1].dwDHGroup = POTF_OAKLEY_GROUP2;
  169. IkePol.pOffers[2].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  170. IkePol.pOffers[2].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_SHA1;
  171. IkePol.pOffers[2].dwDHGroup = POTF_OAKLEY_GROUP1;
  172. IkePol.pOffers[3].EncryptionAlgorithm.uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  173. IkePol.pOffers[3].EncryptionAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  174. IkePol.pOffers[3].EncryptionAlgorithm.uAlgoRounds = POTF_OAKLEY_ALGOROUNDS;
  175. IkePol.pOffers[3].HashingAlgorithm.uAlgoIdentifier = IPSEC_DOI_AH_MD5;
  176. IkePol.pOffers[3].HashingAlgorithm.uAlgoKeyLen = POTF_OAKLEY_ALGOKEYLEN;
  177. IkePol.pOffers[3].dwDHGroup = POTF_OAKLEY_GROUP1;
  178. }
  179. // Loads the following defaults, in order:
  180. void LoadOfferDefaults(OUT PIPSEC_QM_OFFER & Offers, OUT DWORD & NumOffers)
  181. {
  182. NumOffers = 4;
  183. Offers = new IPSEC_QM_OFFER[NumOffers];
  184. assert(Offers != NULL);
  185. memset(Offers, 0, sizeof(IPSEC_QM_OFFER) * NumOffers);
  186. for (DWORD i = 0; i < NumOffers; ++i)
  187. {
  188. Offers[i].Lifetime.uKeyExpirationKBytes = POTF_DEFAULT_P2REKEY_BYTES;
  189. Offers[i].Lifetime.uKeyExpirationTime = POTF_DEFAULT_P2REKEY_TIME;
  190. Offers[i].bPFSRequired = FALSE;
  191. Offers[i].dwPFSGroup = 0;
  192. Offers[i].dwFlags = 0;
  193. Offers[i].dwNumAlgos = 1; // we don't do AND proposals
  194. Offers[i].Algos[0].Operation = ENCRYPTION;
  195. }
  196. Offers[0].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  197. Offers[0].Algos[0].uSecAlgoIdentifier = HMAC_AH_SHA1;
  198. Offers[1].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_3_DES;
  199. Offers[1].Algos[0].uSecAlgoIdentifier = HMAC_AH_MD5;
  200. Offers[2].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  201. Offers[2].Algos[0].uSecAlgoIdentifier = HMAC_AH_SHA1;
  202. Offers[3].Algos[0].uAlgoIdentifier = IPSEC_DOI_ESP_DES;
  203. Offers[3].Algos[0].uSecAlgoIdentifier = HMAC_AH_MD5;
  204. }
  205. // generate corresponding mainmode filter for inFilter
  206. // creates name and guid for outFilter
  207. bool GenerateMMFilter(IN T2P_FILTER inFilter, OUT MM_FILTER &outFilter)
  208. {
  209. bool bReturn = true;
  210. if (inFilter.QMFilterType == QM_TRANSPORT_FILTER)
  211. {
  212. // transport filter
  213. // GUID first
  214. RPC_STATUS RpcStat = UuidCreate(&outFilter.gFilterID);
  215. if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
  216. {
  217. sprintf(STRLASTERR, "Couldn't get GUID for MM filter - UuidCreate failed with status: %ul\n",
  218. RpcStat);
  219. WARN;
  220. bReturn = false;
  221. }
  222. if (bReturn)
  223. {
  224. // set the name to be equal to the "text2pol " + GUID
  225. WCHAR StringTxt[POTF_MAX_STRLEN];
  226. int iReturn;
  227. wcscpy(StringTxt, L"text2pol ");
  228. iReturn = StringFromGUID2(outFilter.gFilterID, StringTxt+wcslen(StringTxt), POTF_MAX_STRLEN-wcslen(StringTxt));
  229. assert(iReturn != 0);
  230. outFilter.pszFilterName = new WCHAR[wcslen(StringTxt)+1];
  231. assert(outFilter.pszFilterName != NULL);
  232. wcscpy(outFilter.pszFilterName, StringTxt);
  233. }
  234. outFilter.InterfaceType = inFilter.TransportFilter.InterfaceType;
  235. outFilter.bCreateMirror = inFilter.TransportFilter.bCreateMirror;
  236. outFilter.dwFlags = 0; // by default, set to none
  237. outFilter.SrcAddr = inFilter.TransportFilter.SrcAddr;
  238. outFilter.DesAddr = inFilter.TransportFilter.DesAddr;
  239. outFilter.dwDirection = inFilter.TransportFilter.dwDirection;
  240. outFilter.dwWeight = inFilter.TransportFilter.dwWeight;
  241. }
  242. else
  243. {
  244. // tunnel filter
  245. // GUID first
  246. RPC_STATUS RpcStat = UuidCreate(&outFilter.gFilterID);
  247. if (RpcStat != RPC_S_OK && RpcStat != RPC_S_UUID_LOCAL_ONLY)
  248. {
  249. sprintf(STRLASTERR, "Couldn't get GUID for mirror filter - UuidCreate failed with status: %ul\n",
  250. RpcStat);
  251. WARN;
  252. bReturn = false;
  253. }
  254. if (bReturn)
  255. {
  256. // set the name to be equal to the "text2pol " + GUID
  257. WCHAR StringTxt[POTF_MAX_STRLEN];
  258. int iReturn;
  259. wcscpy(StringTxt, L"text2pol ");
  260. iReturn = StringFromGUID2(outFilter.gFilterID, StringTxt+wcslen(StringTxt), POTF_MAX_STRLEN-wcslen(StringTxt));
  261. assert(iReturn != 0);
  262. outFilter.pszFilterName = new WCHAR[wcslen(StringTxt)+1];
  263. assert(outFilter.pszFilterName != NULL);
  264. wcscpy(outFilter.pszFilterName, StringTxt);
  265. }
  266. outFilter.InterfaceType = inFilter.TunnelFilter.InterfaceType;
  267. outFilter.bCreateMirror = TRUE;
  268. outFilter.dwFlags = 0; // by default, set to none
  269. outFilter.SrcAddr.AddrType = IP_ADDR_UNIQUE;
  270. outFilter.SrcAddr.uIpAddr = IP_ADDRESS_ME;
  271. outFilter.SrcAddr.uSubNetMask = IP_ADDRESS_MASK_NONE;
  272. UuidCreateNil(&(outFilter.SrcAddr.gInterfaceID));
  273. outFilter.DesAddr = inFilter.TunnelFilter.DesTunnelAddr;
  274. outFilter.dwDirection = inFilter.TunnelFilter.dwDirection;
  275. outFilter.dwWeight = inFilter.TunnelFilter.dwWeight;
  276. }
  277. return bReturn;
  278. }
  279. DWORD CM_EncodeName ( LPTSTR pszSubjectName, BYTE **EncodedName, DWORD *EncodedNameLength )
  280. {
  281. *EncodedNameLength=0;
  282. if (!CertStrToName(
  283. X509_ASN_ENCODING,
  284. pszSubjectName,
  285. CERT_X500_NAME_STR,
  286. NULL,
  287. NULL,
  288. EncodedNameLength,
  289. NULL)) {
  290. // DebugPrint1(L"Error in CertStrToName %d",GetLastError());
  291. return ERROR_INVALID_PARAMETER;
  292. }
  293. (*EncodedName)= new BYTE[*EncodedNameLength];
  294. assert (*EncodedName);
  295. if (!CertStrToName(
  296. X509_ASN_ENCODING,
  297. pszSubjectName,
  298. CERT_X500_NAME_STR,
  299. NULL,
  300. (*EncodedName),
  301. EncodedNameLength,
  302. NULL)) {
  303. delete (*EncodedName);
  304. (*EncodedName) = 0;
  305. // DebugPrint1(L"Error in CertStrToName %d",GetLastError());
  306. return ERROR_INVALID_PARAMETER;
  307. }
  308. return ERROR_SUCCESS;
  309. }
  310. DWORD CM_DecodeName ( BYTE *EncodedName, DWORD EncodedNameLength, LPTSTR *ppszSubjectName )
  311. {
  312. DWORD DecodedNameLength=0;
  313. CERT_NAME_BLOB CertName;
  314. CertName.cbData = EncodedNameLength;
  315. CertName.pbData = EncodedName;
  316. DecodedNameLength = CertNameToStr(
  317. X509_ASN_ENCODING,
  318. &CertName,
  319. CERT_X500_NAME_STR,
  320. NULL,
  321. NULL);
  322. if (!DecodedNameLength)
  323. return ERROR_INVALID_PARAMETER;
  324. (*ppszSubjectName)= new TCHAR[DecodedNameLength];
  325. assert (*ppszSubjectName);
  326. DecodedNameLength = CertNameToStr(
  327. X509_ASN_ENCODING,
  328. &CertName,
  329. CERT_X500_NAME_STR,
  330. *ppszSubjectName,
  331. DecodedNameLength);
  332. if (!DecodedNameLength)
  333. {
  334. delete (*ppszSubjectName);
  335. (*ppszSubjectName) = 0;
  336. return ERROR_INVALID_PARAMETER;
  337. }
  338. return ERROR_SUCCESS;
  339. }