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
185 lines
5.1 KiB
|
|
#include <wininetp.h>
|
|
|
|
#include "map2policy.h"
|
|
|
|
#include "download.h"
|
|
#include "policyref.h"
|
|
#include "p3pparser.h"
|
|
|
|
const char gszP3PWellKnownLocation[] = "/w3c/p3p.xml";
|
|
|
|
#define different(s, p) !(s&&p&&!strcmp(s,p))
|
|
|
|
INTERNETAPI_(int) MapResourceToPolicy(P3PResource *pResource, P3PURL pszPolicy, unsigned long dwSize, P3PSignal *pSignal) {
|
|
|
|
int ret = P3P_Error;
|
|
|
|
MR2P_Request *pRequest = new MR2P_Request(pResource, pszPolicy, dwSize, pSignal);
|
|
if (pRequest) {
|
|
if (!pSignal) {
|
|
ret = pRequest->execute();
|
|
delete pRequest;
|
|
}
|
|
else {
|
|
|
|
DWORD dwThreadID;
|
|
CreateThread(NULL, 0, P3PRequest::ExecRequest, (void*)pRequest, 0, &dwThreadID);
|
|
pSignal->hRequest = pRequest->GetHandle();
|
|
ret = P3P_InProgress;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
INTERNETAPI_(int) GetP3PRequestStatus(P3PHANDLE hObject) {
|
|
|
|
P3PObject *pObject = (P3PObject*) hObject;
|
|
P3PRequest *pRequest = (P3PRequest*) pObject;
|
|
|
|
return pRequest->queryStatus();
|
|
}
|
|
|
|
INTERNETAPI_(int) FreeP3PObject(P3PHANDLE hObject) {
|
|
|
|
P3PObject *pObject = (P3PObject*) hObject;
|
|
pObject->Free();
|
|
return P3P_Done;
|
|
}
|
|
|
|
/*
|
|
Implementation of MR2P_Request class
|
|
*/
|
|
MR2P_Request::MR2P_Request(P3PResource *pResource,
|
|
P3PURL pszPolicy, unsigned long dwSize,
|
|
P3PSignal *pSignal)
|
|
: P3PRequest(pSignal) {
|
|
|
|
static BOOL fNoInterrupt = TRUE;
|
|
|
|
this->pResource = pResource;
|
|
this->pszPolicyOut = pszPolicy;
|
|
this->dwLength = dwSize;
|
|
|
|
cTries = 0;
|
|
ppPriorityOrder = NULL;
|
|
pLookupContext = NULL;
|
|
|
|
pszPolicyInEffect = NULL;
|
|
}
|
|
|
|
MR2P_Request::~MR2P_Request() {
|
|
|
|
delete [] ppPriorityOrder;
|
|
endDownload(hPrimaryIO);
|
|
}
|
|
|
|
int MR2P_Request::execute() {
|
|
|
|
int nDepth = 0;
|
|
P3PResource *pr;
|
|
|
|
/* Clear out parameters */
|
|
*pszPolicyOut = '\0';
|
|
|
|
/* Determine depth of the resource tree */
|
|
for (pr=pResource; pr; pr=pr->pContainer)
|
|
nDepth++;
|
|
|
|
/*
|
|
Construct priority order for trying the policy-reference files.
|
|
According P3P V1 spec, we traverse the tree downwards starting with
|
|
top-level document
|
|
*/
|
|
int current = nDepth;
|
|
ppPriorityOrder = new P3PResource*[nDepth];
|
|
|
|
for (pr=pResource; pr; pr=pr->pContainer)
|
|
ppPriorityOrder[--current] = pr;
|
|
|
|
for (int k=0; k<nDepth; k++) {
|
|
|
|
pLookupContext = pr = ppPriorityOrder[k];
|
|
|
|
char achWellKnownLocation[URL_LIMIT] = "";
|
|
unsigned long dwLength = URL_LIMIT;
|
|
|
|
UrlCombine(pr->pszLocation, gszP3PWellKnownLocation,
|
|
achWellKnownLocation, &dwLength, 0);
|
|
|
|
P3PCURL pszReferrer = pr->pszLocation;
|
|
|
|
/*
|
|
Since policy-refs derived from link-tag, P3P headers or
|
|
the well-known location could be same URL, we avoid trying
|
|
the same PREF multiple times as an optimization
|
|
In order of precedence:
|
|
- Check well known location first -- always defined */
|
|
if (tryPolicyRef(achWellKnownLocation, pszReferrer))
|
|
break;
|
|
|
|
/* ... followed by policy-ref from P3P header, if one exists and
|
|
is different from the well-known location */
|
|
if (pr->pszP3PHeaderRef &&
|
|
different(pr->pszP3PHeaderRef, achWellKnownLocation) &&
|
|
tryPolicyRef(pr->pszP3PHeaderRef, pszReferrer))
|
|
break;
|
|
|
|
/* followed by policy-ref from HTML link tag, if one exists and
|
|
is different from both the well-known location and P3P header */
|
|
if (pr->pszLinkTagRef &&
|
|
different(pr->pszLinkTagRef, achWellKnownLocation) &&
|
|
different(pr->pszLinkTagRef, pr->pszP3PHeaderRef) &&
|
|
tryPolicyRef(pr->pszLinkTagRef, pszReferrer))
|
|
break;
|
|
}
|
|
|
|
int ret = pszPolicyInEffect ? P3P_Done : P3P_NoPolicy;
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool MR2P_Request::tryPolicyRef(P3PCURL pszPolicyRef, P3PCURL pszReferrer) {
|
|
|
|
if (pszPolicyRef==NULL)
|
|
return false;
|
|
|
|
P3PCHAR achFinalLocation[URL_LIMIT];
|
|
unsigned long dwSpace = URL_LIMIT;
|
|
char achFilePath[MAX_PATH];
|
|
|
|
ResourceInfo ri;
|
|
|
|
ri.pszFinalURL = achFinalLocation;
|
|
ri.cbURL = URL_LIMIT;
|
|
ri.pszLocalPath = achFilePath;
|
|
ri.cbPath = MAX_PATH;
|
|
|
|
if (downloadToCache(pszPolicyRef, &ri, &hPrimaryIO, this)>0) {
|
|
|
|
P3PContext context = { ri.pszFinalURL, pszReferrer };
|
|
context.ftExpires = ri.ftExpiryDate;
|
|
|
|
P3PPolicyRef *pPolicyRef = interpretPolicyRef(achFilePath, &context);
|
|
|
|
if (pPolicyRef) {
|
|
|
|
FILETIME ftCurrentTime;
|
|
GetSystemTimeAsFileTime(&ftCurrentTime);
|
|
|
|
if (pPolicyRef->getExpiration() > ftCurrentTime)
|
|
pszPolicyInEffect = pPolicyRef->mapResourceToPolicy(pResource->pszLocation, pResource->pszVerb);
|
|
if (pszPolicyInEffect)
|
|
strncpy(pszPolicyOut, pszPolicyInEffect, dwLength);
|
|
|
|
delete pPolicyRef;
|
|
}
|
|
}
|
|
|
|
/* close the primary-IO handle and set it to NULL */
|
|
endDownload(hPrimaryIO);
|
|
hPrimaryIO = NULL;
|
|
|
|
return (pszPolicyInEffect!=NULL);
|
|
}
|
|
|