diff options
Diffstat (limited to 'os/secauth.c')
-rw-r--r-- | os/secauth.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/os/secauth.c b/os/secauth.c new file mode 100644 index 000000000..a73f4e718 --- /dev/null +++ b/os/secauth.c @@ -0,0 +1,201 @@ +/* $Xorg: secauth.c,v 1.5 2001/02/15 02:06:01 coskrey Exp $ */ +/* +Copyright 1996, 1998, 2001 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. +*/ + +#include "X.h" +#include "os.h" +#include "osdep.h" +#include "dixstruct.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(data_lengthP, dataP, client, reason) + 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 > 0) { + 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 (data_length, data, client, reason) + unsigned short data_length; + char *data; + ClientPtr client; + char **reason; +{ +#ifdef XCSECURITY + OsCommPtr oc = (OsCommPtr)client->osPrivate; + register ConnectionInputPtr oci = oc->input; + 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 +} |