Windows2003-3790/inetcore/wininet/p3p/map2policy.cpp
2020-09-30 16:53:55 +02:00

186 lines
5.1 KiB
C++

#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);
}