203 lines
4.8 KiB
C
203 lines
4.8 KiB
C
|
/*
|
||
|
Copyright 1996, 1998 The Open Group
|
||
|
|
||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||
|
documentation for any purpose is hereby granted without fee, provided that
|
||
|
the above copyright notice appear in all copies and that both that
|
||
|
copyright notice and this permission notice appear in supporting
|
||
|
documentation.
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included
|
||
|
in all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
|
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
Except as contained in this notice, the name of The Open Group shall
|
||
|
not be used in advertising or otherwise to promote the sale, use or
|
||
|
other dealings in this Software without prior written authorization
|
||
|
from The Open Group.
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_DIX_CONFIG_H
|
||
|
#include <dix-config.h>
|
||
|
#endif
|
||
|
|
||
|
#include <X11/X.h>
|
||
|
#include "os.h"
|
||
|
#include "osdep.h"
|
||
|
#include "dixstruct.h"
|
||
|
#include "swaprep.h"
|
||
|
|
||
|
#ifdef XCSECURITY
|
||
|
#include "securitysrv.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; /* need to continue parsing the policy... */
|
||
|
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) /* Extensions policy */
|
||
|
{
|
||
|
/* AuthCheckExtensionPolicy(&data_length, &data, client, reason) */
|
||
|
*reason = "security policy not implemented";
|
||
|
return (XID) -1;
|
||
|
}
|
||
|
|
||
|
if (policy_mask & 0x02) /* Site policy */
|
||
|
{
|
||
|
if (!AuthCheckSitePolicy(&data_length, &data, client, reason))
|
||
|
return (XID) -1;
|
||
|
}
|
||
|
|
||
|
if (data_length > 0) { /* did we consume the whole policy? */
|
||
|
*reason = InvalidPolicyReason;
|
||
|
return (XID) -1;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else if (!GetAccessControl())
|
||
|
{
|
||
|
/*
|
||
|
* The client - possibly the X FireWall Proxy - gave
|
||
|
* no auth data and host-based authorization is turned
|
||
|
* off. In this case, the client should be denied
|
||
|
* access to the X server.
|
||
|
*/
|
||
|
*reason = "server host access control is disabled";
|
||
|
return (XID) -1;
|
||
|
}
|
||
|
|
||
|
client->clientState = ClientStateCheckingSecurity;
|
||
|
|
||
|
csp.success = 2 /* Authenticate */;
|
||
|
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);
|
||
|
|
||
|
/*
|
||
|
* Next time the client sends the real auth data, we want
|
||
|
* ProcEstablishConnection to be called.
|
||
|
*/
|
||
|
|
||
|
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
|
||
|
}
|