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.

459 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. // Policy.h : Declaration of base class for main mode and quick mode
  3. // policies classes
  4. // security WMI provider for SCE
  5. // Copyright (c)1997-2001 Microsoft Corporation
  6. //
  7. // Original Create Date: 4/11/2001
  8. // Original Author: shawnwu
  9. //////////////////////////////////////////////////////////////////////
  10. #pragma once
  11. #include "globals.h"
  12. #include "IPSecBase.h"
  13. extern CComVariant g_varRollbackGuid;
  14. const DWORD DefaultMMPolicyFlag = 0;
  15. const DWORD DefaultQMPolicyFlag = 0;
  16. const DWORD DefaultMMPolicyOfferFlag = 0;
  17. const DWORD DefaultQMPolicyOfferFlag = 0;
  18. const DWORD DefaultaultSoftSAExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
  19. //
  20. // any value is valid. 0 means unlimited
  21. //
  22. const DWORD DefaultQMModeLimit = 32;
  23. //
  24. // either DH_GROUP_1 or DH_GROUP_2 (stronger and more costly)
  25. //
  26. const DWORD DefaultDHGroup = DH_GROUP_1;
  27. //
  28. //IPSEC_DOI_ESP_3_DES is more cost
  29. //
  30. const DWORD DefaultEncryptAlgoID = IPSEC_DOI_ESP_DES;
  31. const DWORD DefaultHashAlgoID = 0;
  32. //
  33. // either is valid, TRUE more cost
  34. //
  35. const BOOL DefaultPFSRequired = FALSE;
  36. const DWORD DefaultPFSGroup = PFS_GROUP_NONE;
  37. const DWORD DefaultNumAlgos = 1;
  38. //
  39. // If ENCRYPTION, then uAlgoIdentifier is the IPSEC_DOI_ESP_DES or IPSEC_DOI_ESP_3_DES
  40. // and uSecAlgoIdentifier can't be HMAC_AH_NONE
  41. // else if AUTHENTICATION then uAlgoIdentifier is IPSEC_DOI_AH_MD5 or IPSEC_DOI_AH_SHA1,
  42. // and uSecAlgoIdentifier should be HMAC_AH_NONE
  43. // else if COMPRESSION, ??
  44. // else if SA_DELETE, ??
  45. //
  46. const IPSEC_OPERATION DefaultQMAlgoOperation = ENCRYPTION;
  47. const ULONG DefaultAlgoID = IPSEC_DOI_ESP_DES;
  48. const HMAC_AH_ALGO DefaultAlgoSecID = HMAC_AH_MD5;
  49. //
  50. // We have two different types of policies in SPD
  51. //
  52. enum EnumPolicyType
  53. {
  54. MainMode_Policy = 1,
  55. QuickMode_Policy = 2,
  56. };
  57. /*
  58. Class description
  59. Naming:
  60. CIPSecPolicy stands for IPSec Policy.
  61. Base class:
  62. CIPSecBase
  63. Purpose of class:
  64. (1) Being a base for both main mode policy and quick mode policy implementations.
  65. Design:
  66. (1) Provide property access (both Put and Get) that are common to both main mode
  67. and quick mode. See GetPolicyFromWbemObj/CreateWbemObjFromPolicy.
  68. (2) Provide rollback support. Both main mode and quick mode have the same logic.
  69. (3) Provide some allocation/deallocation that can be parameterized using template functions.
  70. Use:
  71. (1) Class is designed for inheritance use.
  72. (2) Rollback, GetPolicyFromWbemObj, and CreateWbemObjFromPolicy are the ones
  73. you will use directly, even though all other static ones are also
  74. available for the other classes, they are not intended for such use.
  75. Notes:
  76. (1) It contains several template functions. This reduces the duplicate code.
  77. */
  78. class CIPSecPolicy :
  79. public CIPSecBase
  80. {
  81. protected:
  82. CIPSecPolicy(){}
  83. virtual ~CIPSecPolicy(){}
  84. public:
  85. static
  86. HRESULT Rollback (
  87. IN IWbemServices * pNamespace,
  88. IN LPCWSTR pszRollbackToken,
  89. IN bool bClearAll
  90. );
  91. //
  92. // some template functions
  93. //
  94. /*
  95. Routine Description:
  96. Name:
  97. CIPSecPolicy::GetPolicyFromWbemObj
  98. Functionality:
  99. Given a wbem object representing a policy (either main mode or quick mode), this
  100. function either finds the policy from SPD or creates a new one and fill in the wbem
  101. object's properties into the policy struct.
  102. Virtual:
  103. No.
  104. Arguments:
  105. pInst - The wbem object.
  106. ppPolicy - Receives the policy. This can be PIPSEC_MM_POLICY or PIPSEC_QM_POLICY.
  107. Caller needs to free this by calling FreePolicy;
  108. pbPreExist - Whether SPD allocates the buffer (true) or not (false).
  109. Return Value:
  110. Success:
  111. WBEM_NO_ERROR
  112. Failure:
  113. (1) WBEM_E_INVALID_PARAMETER if ppPolicy == NULL or pdwResumeHandle == NULL.
  114. (2) WBEM_E_NOT_FOUND if the policy is not found.
  115. Notes:
  116. (1) Make sure that you call FreePolicy to free the buffer!
  117. */
  118. template <class Policy>
  119. static
  120. HRESULT GetPolicyFromWbemObj (
  121. IN IWbemClassObject * pInst,
  122. OUT Policy ** ppPolicy,
  123. OUT bool * pbPreExist
  124. )
  125. {
  126. if (pInst == NULL || ppPolicy == NULL || pbPreExist == NULL)
  127. {
  128. return WBEM_E_INVALID_PARAMETER;
  129. }
  130. *ppPolicy = NULL;
  131. *pbPreExist = false;
  132. DWORD dwResumeHandle = 0;
  133. // this var will be re-used again and again. Each should be Clear'ed before reuse.
  134. CComVariant var;
  135. // try to find out if the filter already exists
  136. HRESULT hr = pInst->Get(g_pszPolicyName, 0, &var, NULL, NULL);
  137. if (SUCCEEDED(hr) && var.vt == VT_BSTR)
  138. { // see if this is a filter we already have
  139. hr = FindPolicyByName(var.bstrVal, ppPolicy, &dwResumeHandle);
  140. if (SUCCEEDED(hr))
  141. *pbPreExist = true;
  142. else
  143. {
  144. // can't find it, fine. I will create a new one
  145. hr = AllocPolicy(ppPolicy);
  146. if (SUCCEEDED(hr))
  147. {
  148. (*ppPolicy)->pszPolicyName = NULL;
  149. hr = ::CoCreateGuid(&((*ppPolicy)->gPolicyID));
  150. if (SUCCEEDED(hr))
  151. {
  152. // give it the name
  153. DWORD dwSize = wcslen(var.bstrVal) + 1;
  154. (*ppPolicy)->pszPolicyName = new WCHAR[dwSize];
  155. if (NULL == (*ppPolicy)->pszPolicyName)
  156. hr = WBEM_E_OUT_OF_MEMORY;
  157. else
  158. {
  159. ::memcpy((*ppPolicy)->pszPolicyName, var.bstrVal, dwSize * sizeof(WCHAR));
  160. }
  161. }
  162. }
  163. // dwFlags and pOffers
  164. if (SUCCEEDED(hr))
  165. {
  166. var.Clear();
  167. // dwFlags. We allow this to be missing
  168. if (SUCCEEDED(pInst->Get(g_pszPolicyFlag, 0, &var, NULL, NULL)) && var.vt == VT_I4)
  169. (*ppPolicy)->dwFlags = var.lVal;
  170. else
  171. (*ppPolicy)->dwFlags = 0;
  172. hr = pInst->Get(g_pszOfferCount, 0, &var, NULL, NULL);
  173. if (SUCCEEDED(hr) && var.vt == VT_I4)
  174. {
  175. hr = AllocOffer( &((*ppPolicy)->pOffers), var.lVal);
  176. if (SUCCEEDED(hr))
  177. (*ppPolicy)->dwOfferCount = var.lVal;
  178. }
  179. else
  180. hr = WBEM_E_INVALID_OBJECT;
  181. }
  182. // set up the LifeTime
  183. if (SUCCEEDED(hr))
  184. {
  185. DWORD* pdwTimeKBytes = new DWORD[(*ppPolicy)->dwOfferCount];
  186. if (pdwTimeKBytes == NULL)
  187. hr = WBEM_E_OUT_OF_MEMORY;
  188. else
  189. {
  190. var.Clear();
  191. // we will allow the life-time's expiration time to be missing since we have defaults
  192. // if we successfully get the key life exp time, then set them
  193. if ( SUCCEEDED(pInst->Get(g_pszKeyLifeTime, 0, &var, NULL, NULL)) &&
  194. (var.vt & VT_ARRAY) == VT_ARRAY )
  195. {
  196. hr = ::GetDWORDSafeArrayElements(&var, (*ppPolicy)->dwOfferCount, pdwTimeKBytes);
  197. // if get the exp times
  198. if (SUCCEEDED(hr))
  199. {
  200. for (long l = 0; l < (*ppPolicy)->dwOfferCount; l++)
  201. {
  202. (*ppPolicy)->pOffers[l].Lifetime.uKeyExpirationTime = pdwTimeKBytes[l];
  203. }
  204. }
  205. }
  206. var.Clear();
  207. // set the expiration kbytes, again, we allow the info to be missing since we already has default
  208. if ( SUCCEEDED(pInst->Get(g_pszKeyLifeTimeKBytes, 0, &var, NULL, NULL)) &&
  209. (var.vt & VT_ARRAY) == VT_ARRAY )
  210. {
  211. hr = ::GetDWORDSafeArrayElements(&var, (*ppPolicy)->dwOfferCount, pdwTimeKBytes);
  212. // if get the exp kbytes
  213. if (SUCCEEDED(hr))
  214. {
  215. for (long l = 0; l < (*ppPolicy)->dwOfferCount; l++)
  216. {
  217. (*ppPolicy)->pOffers[l].Lifetime.uKeyExpirationKBytes = pdwTimeKBytes[l];
  218. }
  219. }
  220. }
  221. delete [] pdwTimeKBytes;
  222. }
  223. }
  224. }
  225. }
  226. if (FAILED(hr))
  227. {
  228. FreePolicy(ppPolicy, *pbPreExist);
  229. }
  230. return hr;
  231. };
  232. template<class Policy>
  233. HRESULT CreateWbemObjFromPolicy(Policy* pPolicy, IWbemClassObject* pInst)
  234. {
  235. if (pInst == NULL || pPolicy == NULL)
  236. return WBEM_E_INVALID_PARAMETER;
  237. CComVariant var = pPolicy->pszPolicyName;
  238. HRESULT hr = pInst->Put(g_pszPolicyName, 0, &var, CIM_EMPTY);
  239. // put offer count
  240. if (SUCCEEDED(hr))
  241. {
  242. var.Clear();
  243. var.vt = VT_I4;
  244. // don't really care much about dwFlags
  245. var.lVal = pPolicy->dwFlags;
  246. pInst->Put(g_pszPolicyFlag, 0, &var, CIM_EMPTY);
  247. var.lVal = pPolicy->dwOfferCount;
  248. hr = pInst->Put(g_pszOfferCount, 0, &var, CIM_EMPTY);
  249. }
  250. // put LifeTime
  251. if (SUCCEEDED(hr))
  252. {
  253. // create the a safearray
  254. var.vt = VT_ARRAY | VT_I4;
  255. SAFEARRAYBOUND rgsabound[1];
  256. rgsabound[0].lLbound = 0;
  257. rgsabound[0].cElements = pPolicy->dwOfferCount;
  258. var.parray = ::SafeArrayCreate(VT_I4, 1, rgsabound);
  259. if (var.parray == NULL)
  260. hr = WBEM_E_OUT_OF_MEMORY;
  261. else
  262. {
  263. long lIndecies[1];
  264. // deal with uKeyExpirationTime
  265. for (DWORD dwIndex = 0; SUCCEEDED(hr) && dwIndex < pPolicy->dwOfferCount; dwIndex++)
  266. {
  267. lIndecies[0] = dwIndex;
  268. hr = ::SafeArrayPutElement(var.parray, lIndecies, &(pPolicy->pOffers[dwIndex].Lifetime.uKeyExpirationTime) );
  269. }
  270. if (SUCCEEDED(hr))
  271. hr = pInst->Put(g_pszKeyLifeTime, 0, &var, CIM_EMPTY);
  272. // deal with uKeyExpirationKBytes
  273. for (DWORD dwIndex = 0; SUCCEEDED(hr) && dwIndex < pPolicy->dwOfferCount; dwIndex++)
  274. {
  275. lIndecies[0] = dwIndex;
  276. hr = ::SafeArrayPutElement(var.parray, lIndecies, &(pPolicy->pOffers[dwIndex].Lifetime.uKeyExpirationKBytes) );
  277. }
  278. if (SUCCEEDED(hr))
  279. hr = pInst->Put(g_pszKeyLifeTimeKBytes, 0, &var, CIM_EMPTY);
  280. }
  281. }
  282. return hr;
  283. }
  284. protected:
  285. template<class Policy>
  286. static HRESULT AllocPolicy(Policy** ppPolicy)
  287. {
  288. if (ppPolicy == NULL)
  289. return WBEM_E_INVALID_PARAMETER;
  290. HRESULT hr = WBEM_NO_ERROR;
  291. *ppPolicy = new Policy;
  292. if (*ppPolicy)
  293. {
  294. (*ppPolicy)->pszPolicyName = NULL;
  295. (*ppPolicy)->dwOfferCount = 0;
  296. (*ppPolicy)->pOffers = NULL;
  297. }
  298. else
  299. hr = WBEM_E_OUT_OF_MEMORY;
  300. return hr;
  301. }
  302. static void GetDefaultOfferLifeTime(PIPSEC_MM_OFFER pOffer, DWORD* pdwDefFlag, ULONG* pulTime, ULONG* pulKBytes)
  303. {
  304. *pdwDefFlag = DefaultMMPolicyOfferFlag;
  305. *pulTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
  306. *pulKBytes = DEFAULT_QM_KEY_EXPIRATION_KBYTES;
  307. }
  308. static void GetDefaultOfferLifeTime(PIPSEC_QM_OFFER pOffer, DWORD* pdwDefFlag, ULONG* pulTime, ULONG* pulKBytes)
  309. {
  310. *pdwDefFlag = DefaultQMPolicyOfferFlag;
  311. *pulTime = DEFAULT_QM_KEY_EXPIRATION_TIME;
  312. *pulKBytes = DEFAULT_QM_KEY_EXPIRATION_KBYTES;
  313. }
  314. template<class Offer>
  315. static HRESULT AllocOffer(Offer** ppOffer, long lCount)
  316. {
  317. if (ppOffer == NULL)
  318. return WBEM_E_INVALID_PARAMETER;
  319. *ppOffer = new Offer[lCount];
  320. if (*ppOffer != NULL)
  321. {
  322. ULONG ulTime, ulKBytes;
  323. DWORD dwDefFlag;
  324. GetDefaultOfferLifeTime(*ppOffer, &dwDefFlag, &ulTime, &ulKBytes);
  325. for (long l = 0; l < lCount; l++)
  326. {
  327. (*ppOffer)[l].dwFlags = dwDefFlag;
  328. (*ppOffer)[l].Lifetime.uKeyExpirationTime = ulTime;
  329. (*ppOffer)[l].Lifetime.uKeyExpirationKBytes = ulKBytes;
  330. }
  331. return WBEM_NO_ERROR;
  332. }
  333. else
  334. return WBEM_E_OUT_OF_MEMORY;
  335. }
  336. template<class Policy>
  337. static void FreePolicy(Policy** ppPolicy, bool bPreExist)
  338. {
  339. if (ppPolicy == NULL || *ppPolicy == NULL)
  340. return;
  341. if (bPreExist)
  342. ::SPDApiBufferFree(*ppPolicy);
  343. else
  344. {
  345. delete [] (*ppPolicy)->pszPolicyName;
  346. delete [] (*ppPolicy)->pOffers;
  347. delete *ppPolicy;
  348. }
  349. *ppPolicy = NULL;
  350. };
  351. static HRESULT ClearAllPolicies(IWbemServices* pNamespace);
  352. HRESULT OnAfterAddPolicy(LPCWSTR pszPolicyName, EnumPolicyType eType);
  353. };