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.

222 lines
5.8 KiB

  1. #include <wininetp.h>
  2. #include "p3ppolicy.h"
  3. #include "download.h"
  4. #include "xmlwrapper.h"
  5. #define CheckAndRelease(p) { if (p) p->Release(); }
  6. INTERNETAPI_(int) GetP3PPolicy(P3PCURL pszPolicyURL, HANDLE hDestination, P3PCXSL pszXSLtransform, P3PSignal *pSignal) {
  7. Policy_Request *pRequest = new Policy_Request(pszPolicyURL, hDestination, pszXSLtransform, pSignal);
  8. int result = P3P_Error;
  9. if (pRequest) {
  10. if (pSignal) {
  11. DWORD dwThreadID;
  12. CreateThread(NULL, 0, P3PRequest::ExecRequest, (void*)pRequest, 0, &dwThreadID);
  13. result = P3P_InProgress;
  14. pSignal->hRequest = (P3PHANDLE) pRequest;
  15. }
  16. else {
  17. result = pRequest->execute();
  18. delete pRequest;
  19. }
  20. }
  21. return result;
  22. }
  23. /*
  24. Implementation of Policy_Request object
  25. */
  26. Policy_Request::Policy_Request(P3PCURL pszP3PPolicy, HANDLE hDest, P3PCXSL pszXSLtransform, P3PSignal *pSignal)
  27. : P3PRequest(pSignal) {
  28. this->pszPolicyID = strdup(pszP3PPolicy);
  29. this->pwszStyleSheet = pszXSLtransform;
  30. this->hDestination = hDest;
  31. pszInlineName = strchr(pszPolicyID, '#');
  32. if (pszInlineName)
  33. *pszInlineName++ = '\0';
  34. }
  35. Policy_Request::~Policy_Request() {
  36. free(pszPolicyID);
  37. endDownload(hPrimaryIO);
  38. }
  39. bool Policy_Request::policyExpired(IXMLDOMDocument *pDocument, const char *pszPolicyID) {
  40. /* If no expiration is given in the document,
  41. it defaults to 24hr lifetime (P3Pv1 spec) */
  42. bool fExpired = false;
  43. /* Find an EXPIRY element contained in a POLICIES element.
  44. Simply searching for EXPIRY will not work because in the case
  45. of inline policies, we can have more than one tag in a document */
  46. TreeNode *pTree = createXMLtree(pDocument),
  47. *pPolicies = pTree ?
  48. pTree->find("POLICIES") :
  49. NULL,
  50. *pExpiry = pPolicies ?
  51. pPolicies->find("EXPIRY", 1) :
  52. NULL;
  53. if (pExpiry) {
  54. FILETIME ftExpires = { 0x0, 0x0 };
  55. if (const char *pszAbsExpiry = pExpiry->attribute("date"))
  56. setExpiration(pszPolicyID, pszAbsExpiry, FALSE, &ftExpires);
  57. else if (const char *pszRelExpiry = pExpiry->attribute("max-age"))
  58. setExpiration(pszPolicyID, pszRelExpiry, TRUE, &ftExpires);
  59. FILETIME ftNow;
  60. GetSystemTimeAsFileTime(&ftNow);
  61. if (ftNow>ftExpires)
  62. fExpired = true;
  63. }
  64. delete pTree;
  65. return fExpired;
  66. }
  67. int Policy_Request::execute() {
  68. IXMLDOMElement *pRootNode = NULL;
  69. IXMLDOMNode *pPolicyElem = NULL;
  70. IXMLDOMDocument *pDocument = NULL;
  71. int result = P3P_Failed;
  72. char achFinalLocation[URL_LIMIT];
  73. char achFilePath[MAX_PATH];
  74. ResourceInfo ri;
  75. ri.pszFinalURL = achFinalLocation;
  76. ri.cbURL = URL_LIMIT;
  77. ri.pszLocalPath = achFilePath;
  78. ri.cbPath = MAX_PATH;
  79. int docsize = downloadToCache(pszPolicyID, &ri, &hPrimaryIO, this);
  80. if (docsize<=0) {
  81. result = P3P_NotFound;
  82. goto EndRequest;
  83. }
  84. P3PCURL pszFinalURL = achFinalLocation;
  85. pDocument = parseXMLDocument(achFilePath);
  86. if (!pDocument) {
  87. result = P3P_FormatErr;
  88. goto EndRequest;
  89. }
  90. if (policyExpired(pDocument, pszPolicyID)) {
  91. result = P3P_Expired;
  92. goto EndRequest;
  93. }
  94. HRESULT hr;
  95. /* Inline policy? */
  96. if (pszInlineName) {
  97. /* YES-- use XPath query to locate correct name */
  98. char achXPathQuery[URL_LIMIT];
  99. wsprintf(achXPathQuery, "//POLICY[@name=\"%s\"]", pszInlineName);
  100. BSTR bsQuery = ASCII2unicode(achXPathQuery);
  101. hr = pDocument->selectSingleNode(bsQuery, &pPolicyElem);
  102. SysFreeString(bsQuery);
  103. }
  104. else {
  105. pDocument->get_documentElement(&pRootNode);
  106. if (pRootNode)
  107. pRootNode->QueryInterface(IID_IXMLDOMElement, (void**) &pPolicyElem);
  108. }
  109. if (!pPolicyElem) {
  110. result = P3P_FormatErr;
  111. goto EndRequest;
  112. }
  113. BSTR bsPolicy = NULL;
  114. /* Apply optional XSL transform */
  115. if (pwszStyleSheet) {
  116. /* This XSL transformation only works on XMLDOMDocument objects, not
  117. fragments or individual XMLDOMNodes. */
  118. IXMLDOMDocument
  119. *pXSLdoc = createXMLDocument(),
  120. *pPolicyDoc = createXMLDocument();
  121. if (!(pXSLdoc && pPolicyDoc))
  122. goto ReleaseXML;
  123. BSTR bsFragment = NULL;
  124. VARIANT_BOOL
  125. fLoadPolicy = FALSE,
  126. fLoadXSL = FALSE;
  127. pPolicyElem->get_xml(&bsFragment);
  128. if (bsFragment) {
  129. pPolicyDoc->loadXML(bsFragment, &fLoadPolicy);
  130. SysFreeString(bsFragment);
  131. }
  132. else
  133. goto ReleaseXML;
  134. if (BSTR bsStyleSheet = (BSTR) pwszStyleSheet)
  135. pXSLdoc->loadXML(bsStyleSheet, &fLoadXSL);
  136. if (fLoadPolicy && fLoadXSL)
  137. pPolicyDoc->transformNode(pXSLdoc, &bsPolicy);
  138. else
  139. result = P3P_XMLError;
  140. ReleaseXML:
  141. CheckAndRelease(pPolicyDoc);
  142. CheckAndRelease(pXSLdoc);
  143. }
  144. else if (pPolicyElem)
  145. pPolicyElem->get_xml(&bsPolicy);
  146. if (bsPolicy) {
  147. int cbBytes = SysStringByteLen(bsPolicy);
  148. unsigned long dwWritten;
  149. /* need BOM (byte order marker) for Unicode content.
  150. NOTE: this logic assumes we are writing at beggining of a file. */
  151. WriteFile(hDestination, "\xFF\xFE", 2, &dwWritten, NULL);
  152. WriteFile(hDestination, bsPolicy, cbBytes, &dwWritten, NULL);
  153. SysFreeString(bsPolicy);
  154. result = P3P_Success;
  155. }
  156. EndRequest:
  157. /* release the DOM interfaces */
  158. CheckAndRelease(pPolicyElem);
  159. CheckAndRelease(pRootNode);
  160. CheckAndRelease(pDocument);
  161. /* close the primary-IO handle and set it to NULL */
  162. endDownload(hPrimaryIO);
  163. hPrimaryIO = NULL;
  164. return result;
  165. }