206 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /* $Xorg: secauth.c,v 1.4 2001/02/09 02:05:23 xorgcvs Exp $ */
 | |
| /*
 | |
| 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.
 | |
| */
 | |
| /* $XFree86: xc/programs/Xserver/os/secauth.c,v 1.10 2001/08/01 00:44:59 tsi Exp $ */
 | |
| 
 | |
| #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
 | |
| #define _SECURITY_SERVER
 | |
| #include <X11/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; /* 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
 | |
| }
 |