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.

185 lines
5.1 KiB

  1. #include <wininetp.h>
  2. #include "map2policy.h"
  3. #include "download.h"
  4. #include "policyref.h"
  5. #include "p3pparser.h"
  6. const char gszP3PWellKnownLocation[] = "/w3c/p3p.xml";
  7. #define different(s, p) !(s&&p&&!strcmp(s,p))
  8. INTERNETAPI_(int) MapResourceToPolicy(P3PResource *pResource, P3PURL pszPolicy, unsigned long dwSize, P3PSignal *pSignal) {
  9. int ret = P3P_Error;
  10. MR2P_Request *pRequest = new MR2P_Request(pResource, pszPolicy, dwSize, pSignal);
  11. if (pRequest) {
  12. if (!pSignal) {
  13. ret = pRequest->execute();
  14. delete pRequest;
  15. }
  16. else {
  17. DWORD dwThreadID;
  18. CreateThread(NULL, 0, P3PRequest::ExecRequest, (void*)pRequest, 0, &dwThreadID);
  19. pSignal->hRequest = pRequest->GetHandle();
  20. ret = P3P_InProgress;
  21. }
  22. }
  23. return ret;
  24. }
  25. INTERNETAPI_(int) GetP3PRequestStatus(P3PHANDLE hObject) {
  26. P3PObject *pObject = (P3PObject*) hObject;
  27. P3PRequest *pRequest = (P3PRequest*) pObject;
  28. return pRequest->queryStatus();
  29. }
  30. INTERNETAPI_(int) FreeP3PObject(P3PHANDLE hObject) {
  31. P3PObject *pObject = (P3PObject*) hObject;
  32. pObject->Free();
  33. return P3P_Done;
  34. }
  35. /*
  36. Implementation of MR2P_Request class
  37. */
  38. MR2P_Request::MR2P_Request(P3PResource *pResource,
  39. P3PURL pszPolicy, unsigned long dwSize,
  40. P3PSignal *pSignal)
  41. : P3PRequest(pSignal) {
  42. static BOOL fNoInterrupt = TRUE;
  43. this->pResource = pResource;
  44. this->pszPolicyOut = pszPolicy;
  45. this->dwLength = dwSize;
  46. cTries = 0;
  47. ppPriorityOrder = NULL;
  48. pLookupContext = NULL;
  49. pszPolicyInEffect = NULL;
  50. }
  51. MR2P_Request::~MR2P_Request() {
  52. delete [] ppPriorityOrder;
  53. endDownload(hPrimaryIO);
  54. }
  55. int MR2P_Request::execute() {
  56. int nDepth = 0;
  57. P3PResource *pr;
  58. /* Clear out parameters */
  59. *pszPolicyOut = '\0';
  60. /* Determine depth of the resource tree */
  61. for (pr=pResource; pr; pr=pr->pContainer)
  62. nDepth++;
  63. /*
  64. Construct priority order for trying the policy-reference files.
  65. According P3P V1 spec, we traverse the tree downwards starting with
  66. top-level document
  67. */
  68. int current = nDepth;
  69. ppPriorityOrder = new P3PResource*[nDepth];
  70. for (pr=pResource; pr; pr=pr->pContainer)
  71. ppPriorityOrder[--current] = pr;
  72. for (int k=0; k<nDepth; k++) {
  73. pLookupContext = pr = ppPriorityOrder[k];
  74. char achWellKnownLocation[URL_LIMIT] = "";
  75. unsigned long dwLength = URL_LIMIT;
  76. UrlCombine(pr->pszLocation, gszP3PWellKnownLocation,
  77. achWellKnownLocation, &dwLength, 0);
  78. P3PCURL pszReferrer = pr->pszLocation;
  79. /*
  80. Since policy-refs derived from link-tag, P3P headers or
  81. the well-known location could be same URL, we avoid trying
  82. the same PREF multiple times as an optimization
  83. In order of precedence:
  84. - Check well known location first -- always defined */
  85. if (tryPolicyRef(achWellKnownLocation, pszReferrer))
  86. break;
  87. /* ... followed by policy-ref from P3P header, if one exists and
  88. is different from the well-known location */
  89. if (pr->pszP3PHeaderRef &&
  90. different(pr->pszP3PHeaderRef, achWellKnownLocation) &&
  91. tryPolicyRef(pr->pszP3PHeaderRef, pszReferrer))
  92. break;
  93. /* followed by policy-ref from HTML link tag, if one exists and
  94. is different from both the well-known location and P3P header */
  95. if (pr->pszLinkTagRef &&
  96. different(pr->pszLinkTagRef, achWellKnownLocation) &&
  97. different(pr->pszLinkTagRef, pr->pszP3PHeaderRef) &&
  98. tryPolicyRef(pr->pszLinkTagRef, pszReferrer))
  99. break;
  100. }
  101. int ret = pszPolicyInEffect ? P3P_Done : P3P_NoPolicy;
  102. return ret;
  103. }
  104. bool MR2P_Request::tryPolicyRef(P3PCURL pszPolicyRef, P3PCURL pszReferrer) {
  105. if (pszPolicyRef==NULL)
  106. return false;
  107. P3PCHAR achFinalLocation[URL_LIMIT];
  108. unsigned long dwSpace = URL_LIMIT;
  109. char achFilePath[MAX_PATH];
  110. ResourceInfo ri;
  111. ri.pszFinalURL = achFinalLocation;
  112. ri.cbURL = URL_LIMIT;
  113. ri.pszLocalPath = achFilePath;
  114. ri.cbPath = MAX_PATH;
  115. if (downloadToCache(pszPolicyRef, &ri, &hPrimaryIO, this)>0) {
  116. P3PContext context = { ri.pszFinalURL, pszReferrer };
  117. context.ftExpires = ri.ftExpiryDate;
  118. P3PPolicyRef *pPolicyRef = interpretPolicyRef(achFilePath, &context);
  119. if (pPolicyRef) {
  120. FILETIME ftCurrentTime;
  121. GetSystemTimeAsFileTime(&ftCurrentTime);
  122. if (pPolicyRef->getExpiration() > ftCurrentTime)
  123. pszPolicyInEffect = pPolicyRef->mapResourceToPolicy(pResource->pszLocation, pResource->pszVerb);
  124. if (pszPolicyInEffect)
  125. strncpy(pszPolicyOut, pszPolicyInEffect, dwLength);
  126. delete pPolicyRef;
  127. }
  128. }
  129. /* close the primary-IO handle and set it to NULL */
  130. endDownload(hPrimaryIO);
  131. hPrimaryIO = NULL;
  132. return (pszPolicyInEffect!=NULL);
  133. }