#include "X.h"
#include "os.h"
#include "osdep.h"
#include "dixstruct.h"
#include "swaprep.h"
#ifdef XCSECURITY
#define _SECURITY_SERVER
#include "extensions/security.h"
#endif
static char InvalidPolicyReason[] = "invalid policy specification";
static char PolicyViolationReason[] = "policy violation";
static Bool
AuthCheckSitePolicy(
unsigned short *data_lengthP,
char **dataP,
ClientPtr client,
char **reason)
{
CARD8 *policy = *(CARD8 **)dataP;
int length;
Bool permit;
int nPolicies;
char **sitePolicies;
int nSitePolicies;
Bool found = FALSE;
if ((length = *data_lengthP) < 2) {
*reason = InvalidPolicyReason;
return FALSE;
}
permit = (*policy++ == 0);
nPolicies = (CARD8) *policy++;
length -= 2;
sitePolicies = SecurityGetSitePolicyStrings(&nSitePolicies);
while (nPolicies) {
int strLen, sitePolicy;
if (length == 0) {
*reason = InvalidPolicyReason;
return FALSE;
}
strLen = (CARD8) *policy++;
if (--length < strLen) {
*reason = InvalidPolicyReason;
return FALSE;
}
if (!found)
{
for (sitePolicy = 0; sitePolicy < nSitePolicies; sitePolicy++)
{
char *testPolicy = sitePolicies[sitePolicy];
if ((strLen == strlen(testPolicy)) &&
(strncmp((char *)policy, testPolicy, strLen) == 0))
{
found = TRUE;
break;
}
}
}
policy += strLen;
length -= strLen;
nPolicies--;
}
if (found != permit)
{
*reason = PolicyViolationReason;
return FALSE;
}
*data_lengthP = length;
*dataP = (char *)policy;
return TRUE;
}
XID
AuthSecurityCheck (
unsigned short data_length,
char *data,
ClientPtr client,
char **reason)
{
#ifdef XCSECURITY
xConnSetupPrefix csp;
xReq freq;
if (client->clientState == ClientStateCheckedSecurity)
{
*reason = "repeated security check not permitted";
return (XID) -1;
}
else if (data_length > 0)
{
char policy_mask = *data++;
if (--data_length == 1) {
*reason = InvalidPolicyReason;
return (XID) -1;
}
if (policy_mask & 0x01)
{
*reason = "security policy not implemented";
return (XID) -1;
}
if (policy_mask & 0x02)
{
if (!AuthCheckSitePolicy(&data_length, &data, client, reason))
return (XID) -1;
}
if (data_length > 0) {
*reason = InvalidPolicyReason;
return (XID) -1;
}
}
else if (!GetAccessControl())
{
*reason = "server host access control is disabled";
return (XID) -1;
}
client->clientState = ClientStateCheckingSecurity;
csp.success = 2 ;
csp.lengthReason = 0;
csp.length = 0;
csp.majorVersion = X_PROTOCOL;
csp.minorVersion = X_PROTOCOL_REVISION;
if (client->swapped)
WriteSConnSetupPrefix(client, &csp);
else
(void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
freq.reqType = 1;
freq.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
client->swapped = FALSE;
if (!InsertFakeRequest(client, (char *)&freq, sz_xReq))
{
*reason = "internal error";
return (XID) -1;
}
return (XID) 0;
#else
*reason = "method not supported";
return (XID) -1;
#endif
}