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
222 lines
5.8 KiB
|
|
#include <wininetp.h>
|
|
|
|
#include "p3ppolicy.h"
|
|
#include "download.h"
|
|
#include "xmlwrapper.h"
|
|
|
|
#define CheckAndRelease(p) { if (p) p->Release(); }
|
|
|
|
INTERNETAPI_(int) GetP3PPolicy(P3PCURL pszPolicyURL, HANDLE hDestination, P3PCXSL pszXSLtransform, P3PSignal *pSignal) {
|
|
|
|
Policy_Request *pRequest = new Policy_Request(pszPolicyURL, hDestination, pszXSLtransform, pSignal);
|
|
int result = P3P_Error;
|
|
|
|
if (pRequest) {
|
|
if (pSignal) {
|
|
DWORD dwThreadID;
|
|
CreateThread(NULL, 0, P3PRequest::ExecRequest, (void*)pRequest, 0, &dwThreadID);
|
|
result = P3P_InProgress;
|
|
pSignal->hRequest = (P3PHANDLE) pRequest;
|
|
}
|
|
else {
|
|
result = pRequest->execute();
|
|
delete pRequest;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
Implementation of Policy_Request object
|
|
*/
|
|
Policy_Request::Policy_Request(P3PCURL pszP3PPolicy, HANDLE hDest, P3PCXSL pszXSLtransform, P3PSignal *pSignal)
|
|
: P3PRequest(pSignal) {
|
|
|
|
this->pszPolicyID = strdup(pszP3PPolicy);
|
|
this->pwszStyleSheet = pszXSLtransform;
|
|
this->hDestination = hDest;
|
|
|
|
pszInlineName = strchr(pszPolicyID, '#');
|
|
if (pszInlineName)
|
|
*pszInlineName++ = '\0';
|
|
}
|
|
|
|
Policy_Request::~Policy_Request() {
|
|
|
|
free(pszPolicyID);
|
|
endDownload(hPrimaryIO);
|
|
}
|
|
|
|
bool Policy_Request::policyExpired(IXMLDOMDocument *pDocument, const char *pszPolicyID) {
|
|
|
|
/* If no expiration is given in the document,
|
|
it defaults to 24hr lifetime (P3Pv1 spec) */
|
|
bool fExpired = false;
|
|
|
|
/* Find an EXPIRY element contained in a POLICIES element.
|
|
Simply searching for EXPIRY will not work because in the case
|
|
of inline policies, we can have more than one tag in a document */
|
|
TreeNode *pTree = createXMLtree(pDocument),
|
|
*pPolicies = pTree ?
|
|
pTree->find("POLICIES") :
|
|
NULL,
|
|
*pExpiry = pPolicies ?
|
|
pPolicies->find("EXPIRY", 1) :
|
|
NULL;
|
|
|
|
if (pExpiry) {
|
|
|
|
FILETIME ftExpires = { 0x0, 0x0 };
|
|
|
|
if (const char *pszAbsExpiry = pExpiry->attribute("date"))
|
|
setExpiration(pszPolicyID, pszAbsExpiry, FALSE, &ftExpires);
|
|
else if (const char *pszRelExpiry = pExpiry->attribute("max-age"))
|
|
setExpiration(pszPolicyID, pszRelExpiry, TRUE, &ftExpires);
|
|
|
|
FILETIME ftNow;
|
|
GetSystemTimeAsFileTime(&ftNow);
|
|
if (ftNow>ftExpires)
|
|
fExpired = true;
|
|
}
|
|
|
|
delete pTree;
|
|
return fExpired;
|
|
}
|
|
|
|
int Policy_Request::execute() {
|
|
|
|
IXMLDOMElement *pRootNode = NULL;
|
|
IXMLDOMNode *pPolicyElem = NULL;
|
|
IXMLDOMDocument *pDocument = NULL;
|
|
|
|
int result = P3P_Failed;
|
|
char achFinalLocation[URL_LIMIT];
|
|
char achFilePath[MAX_PATH];
|
|
|
|
ResourceInfo ri;
|
|
|
|
ri.pszFinalURL = achFinalLocation;
|
|
ri.cbURL = URL_LIMIT;
|
|
ri.pszLocalPath = achFilePath;
|
|
ri.cbPath = MAX_PATH;
|
|
|
|
int docsize = downloadToCache(pszPolicyID, &ri, &hPrimaryIO, this);
|
|
|
|
if (docsize<=0) {
|
|
result = P3P_NotFound;
|
|
goto EndRequest;
|
|
}
|
|
|
|
P3PCURL pszFinalURL = achFinalLocation;
|
|
|
|
pDocument = parseXMLDocument(achFilePath);
|
|
|
|
if (!pDocument) {
|
|
result = P3P_FormatErr;
|
|
goto EndRequest;
|
|
}
|
|
|
|
if (policyExpired(pDocument, pszPolicyID)) {
|
|
result = P3P_Expired;
|
|
goto EndRequest;
|
|
}
|
|
|
|
HRESULT hr;
|
|
|
|
/* Inline policy? */
|
|
if (pszInlineName) {
|
|
|
|
/* YES-- use XPath query to locate correct name */
|
|
char achXPathQuery[URL_LIMIT];
|
|
|
|
wsprintf(achXPathQuery, "//POLICY[@name=\"%s\"]", pszInlineName);
|
|
|
|
BSTR bsQuery = ASCII2unicode(achXPathQuery);
|
|
hr = pDocument->selectSingleNode(bsQuery, &pPolicyElem);
|
|
SysFreeString(bsQuery);
|
|
}
|
|
else {
|
|
pDocument->get_documentElement(&pRootNode);
|
|
if (pRootNode)
|
|
pRootNode->QueryInterface(IID_IXMLDOMElement, (void**) &pPolicyElem);
|
|
}
|
|
|
|
if (!pPolicyElem) {
|
|
result = P3P_FormatErr;
|
|
goto EndRequest;
|
|
}
|
|
|
|
BSTR bsPolicy = NULL;
|
|
|
|
/* Apply optional XSL transform */
|
|
if (pwszStyleSheet) {
|
|
|
|
/* This XSL transformation only works on XMLDOMDocument objects, not
|
|
fragments or individual XMLDOMNodes. */
|
|
IXMLDOMDocument
|
|
*pXSLdoc = createXMLDocument(),
|
|
*pPolicyDoc = createXMLDocument();
|
|
|
|
if (!(pXSLdoc && pPolicyDoc))
|
|
goto ReleaseXML;
|
|
|
|
BSTR bsFragment = NULL;
|
|
VARIANT_BOOL
|
|
fLoadPolicy = FALSE,
|
|
fLoadXSL = FALSE;
|
|
|
|
pPolicyElem->get_xml(&bsFragment);
|
|
if (bsFragment) {
|
|
pPolicyDoc->loadXML(bsFragment, &fLoadPolicy);
|
|
SysFreeString(bsFragment);
|
|
}
|
|
else
|
|
goto ReleaseXML;
|
|
|
|
if (BSTR bsStyleSheet = (BSTR) pwszStyleSheet)
|
|
pXSLdoc->loadXML(bsStyleSheet, &fLoadXSL);
|
|
|
|
if (fLoadPolicy && fLoadXSL)
|
|
pPolicyDoc->transformNode(pXSLdoc, &bsPolicy);
|
|
else
|
|
result = P3P_XMLError;
|
|
|
|
ReleaseXML:
|
|
CheckAndRelease(pPolicyDoc);
|
|
CheckAndRelease(pXSLdoc);
|
|
}
|
|
else if (pPolicyElem)
|
|
pPolicyElem->get_xml(&bsPolicy);
|
|
|
|
if (bsPolicy) {
|
|
|
|
int cbBytes = SysStringByteLen(bsPolicy);
|
|
|
|
unsigned long dwWritten;
|
|
|
|
/* need BOM (byte order marker) for Unicode content.
|
|
NOTE: this logic assumes we are writing at beggining of a file. */
|
|
WriteFile(hDestination, "\xFF\xFE", 2, &dwWritten, NULL);
|
|
|
|
WriteFile(hDestination, bsPolicy, cbBytes, &dwWritten, NULL);
|
|
|
|
SysFreeString(bsPolicy);
|
|
result = P3P_Success;
|
|
}
|
|
|
|
EndRequest:
|
|
/* release the DOM interfaces */
|
|
CheckAndRelease(pPolicyElem);
|
|
CheckAndRelease(pRootNode);
|
|
CheckAndRelease(pDocument);
|
|
|
|
/* close the primary-IO handle and set it to NULL */
|
|
endDownload(hPrimaryIO);
|
|
hPrimaryIO = NULL;
|
|
|
|
return result;
|
|
}
|
|
|