XSecurity.c revision 485f0483
1caade7ccSmrg/* $Xorg: XSecurity.c,v 1.6 2001/02/09 02:03:49 xorgcvs Exp $ */ 2caade7ccSmrg/* 3caade7ccSmrg 4caade7ccSmrgCopyright 1996, 1998 The Open Group 5caade7ccSmrg 6caade7ccSmrgPermission to use, copy, modify, distribute, and sell this software and its 7caade7ccSmrgdocumentation for any purpose is hereby granted without fee, provided that 8caade7ccSmrgthe above copyright notice appear in all copies and that both that 9caade7ccSmrgcopyright notice and this permission notice appear in supporting 10caade7ccSmrgdocumentation. 11caade7ccSmrg 12caade7ccSmrgThe above copyright notice and this permission notice shall be included in 13caade7ccSmrgall copies or substantial portions of the Software. 14caade7ccSmrg 15caade7ccSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16caade7ccSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17caade7ccSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18caade7ccSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19caade7ccSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20caade7ccSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21caade7ccSmrg 22caade7ccSmrgExcept as contained in this notice, the name of The Open Group shall not be 23caade7ccSmrgused in advertising or otherwise to promote the sale, use or other dealings 24caade7ccSmrgin this Software without prior written authorization from The Open Group. 25caade7ccSmrg 26caade7ccSmrg*/ 27caade7ccSmrg/* $XFree86: xc/lib/Xext/XSecurity.c,v 1.5 2002/10/16 00:37:27 dawes Exp $ */ 28caade7ccSmrg 29caade7ccSmrg#ifdef HAVE_CONFIG_H 30caade7ccSmrg#include <config.h> 31caade7ccSmrg#endif 32caade7ccSmrg#include <X11/Xlibint.h> 33caade7ccSmrg#include <stdio.h> 34caade7ccSmrg#include <X11/extensions/Xext.h> 35caade7ccSmrg#include <X11/extensions/extutil.h> 36485f0483Smrg#include <X11/extensions/securproto.h> 37485f0483Smrg#include <X11/extensions/security.h> 38caade7ccSmrg 39caade7ccSmrgstatic XExtensionInfo _Security_info_data; 40caade7ccSmrgstatic XExtensionInfo *Security_info = &_Security_info_data; 41caade7ccSmrgstatic char *Security_extension_name = SECURITY_EXTENSION_NAME; 42caade7ccSmrg 43caade7ccSmrg#define SecurityCheckExtension(dpy,i,val) \ 44caade7ccSmrg XextCheckExtension (dpy, i, Security_extension_name, val) 45caade7ccSmrg#define SecuritySimpleCheckExtension(dpy,i) \ 46caade7ccSmrg XextSimpleCheckExtension (dpy, i, Security_extension_name) 47caade7ccSmrg 48caade7ccSmrg#define SecurityGetReq(name,req,info) GetReq (name, req); \ 49caade7ccSmrg req->reqType = info->codes->major_opcode; \ 50caade7ccSmrg req->securityReqType = X_##name; 51caade7ccSmrg 52caade7ccSmrg/***************************************************************************** 53caade7ccSmrg * * 54caade7ccSmrg * private utility routines * 55caade7ccSmrg * * 56caade7ccSmrg *****************************************************************************/ 57caade7ccSmrg 58caade7ccSmrg/* 59caade7ccSmrg * find_display - locate the display info block 60caade7ccSmrg */ 61caade7ccSmrgstatic int close_display(Display *dpy, XExtCodes *codes); 62caade7ccSmrgstatic Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire); 63caade7ccSmrgstatic Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire); 64caade7ccSmrgstatic char *error_string(Display *dpy, int code, XExtCodes *codes, 65caade7ccSmrg char *buf, int n); 66caade7ccSmrg 67caade7ccSmrgstatic XExtensionHooks Security_extension_hooks = { 68caade7ccSmrg NULL, /* create_gc */ 69caade7ccSmrg NULL, /* copy_gc */ 70caade7ccSmrg NULL, /* flush_gc */ 71caade7ccSmrg NULL, /* free_gc */ 72caade7ccSmrg NULL, /* create_font */ 73caade7ccSmrg NULL, /* free_font */ 74caade7ccSmrg close_display, /* close_display */ 75caade7ccSmrg wire_to_event, /* wire_to_event */ 76caade7ccSmrg event_to_wire, /* event_to_wire */ 77caade7ccSmrg NULL, /* error */ 78caade7ccSmrg error_string /* error_string */ 79caade7ccSmrg}; 80caade7ccSmrg 81caade7ccSmrgstatic char *security_error_list[] = { 82caade7ccSmrg "BadAuthorization", 83caade7ccSmrg "BadAuthorizationProtocol" 84caade7ccSmrg}; 85caade7ccSmrg 86caade7ccSmrgstatic XEXT_GENERATE_FIND_DISPLAY (find_display, Security_info, 87caade7ccSmrg Security_extension_name, 88caade7ccSmrg &Security_extension_hooks, 89caade7ccSmrg XSecurityNumberEvents, NULL) 90caade7ccSmrg 91caade7ccSmrgstatic XEXT_GENERATE_CLOSE_DISPLAY (close_display, Security_info) 92caade7ccSmrg 93caade7ccSmrgstatic 94caade7ccSmrgXEXT_GENERATE_ERROR_STRING(error_string, Security_extension_name, 95caade7ccSmrg XSecurityNumberErrors, security_error_list) 96caade7ccSmrg 97caade7ccSmrgstatic Bool 98caade7ccSmrgwire_to_event(Display *dpy, XEvent *event, xEvent *wire) 99caade7ccSmrg{ 100caade7ccSmrg XExtDisplayInfo *info = find_display(dpy); 101caade7ccSmrg 102caade7ccSmrg SecurityCheckExtension (dpy, info, False); 103caade7ccSmrg 104caade7ccSmrg switch ((wire->u.u.type & 0x7F) - info->codes->first_event) 105caade7ccSmrg { 106caade7ccSmrg case XSecurityAuthorizationRevoked: 107caade7ccSmrg { 108caade7ccSmrg xSecurityAuthorizationRevokedEvent *rwire = 109caade7ccSmrg (xSecurityAuthorizationRevokedEvent *)wire; 110caade7ccSmrg XSecurityAuthorizationRevokedEvent *revent = 111caade7ccSmrg (XSecurityAuthorizationRevokedEvent *)event; 112caade7ccSmrg 113caade7ccSmrg revent->type = rwire->type & 0x7F; 114caade7ccSmrg revent->serial = _XSetLastRequestRead(dpy, 115caade7ccSmrg (xGenericReply *) wire); 116caade7ccSmrg revent->send_event = (rwire->type & 0x80) != 0; 117caade7ccSmrg revent->display = dpy; 118caade7ccSmrg revent->auth_id = rwire->authId; 119caade7ccSmrg return True; 120caade7ccSmrg } 121caade7ccSmrg } 122caade7ccSmrg return False; 123caade7ccSmrg} 124caade7ccSmrg 125caade7ccSmrgstatic Status 126caade7ccSmrgevent_to_wire(Display *dpy, XEvent *event, xEvent *wire) 127caade7ccSmrg{ 128caade7ccSmrg XExtDisplayInfo *info = find_display(dpy); 129caade7ccSmrg 130caade7ccSmrg SecurityCheckExtension(dpy, info, False); 131caade7ccSmrg 132caade7ccSmrg switch ((event->type & 0x7F) - info->codes->first_event) 133caade7ccSmrg { 134caade7ccSmrg case XSecurityAuthorizationRevoked: 135caade7ccSmrg { 136caade7ccSmrg xSecurityAuthorizationRevokedEvent *rwire = 137caade7ccSmrg (xSecurityAuthorizationRevokedEvent *)wire; 138caade7ccSmrg XSecurityAuthorizationRevokedEvent *revent = 139caade7ccSmrg (XSecurityAuthorizationRevokedEvent *)event; 140caade7ccSmrg rwire->type = revent->type | (revent->send_event ? 0x80 : 0); 141caade7ccSmrg rwire->sequenceNumber = revent->serial & 0xFFFF; 142caade7ccSmrg return True; 143caade7ccSmrg } 144caade7ccSmrg } 145caade7ccSmrg return False; 146caade7ccSmrg} 147caade7ccSmrg 148caade7ccSmrg/***************************************************************************** 149caade7ccSmrg * * 150caade7ccSmrg * Security public interfaces * 151caade7ccSmrg * * 152caade7ccSmrg *****************************************************************************/ 153caade7ccSmrg 154caade7ccSmrgStatus XSecurityQueryExtension ( 155caade7ccSmrg Display *dpy, 156caade7ccSmrg int *major_version_return, 157caade7ccSmrg int *minor_version_return) 158caade7ccSmrg{ 159caade7ccSmrg XExtDisplayInfo *info = find_display (dpy); 160caade7ccSmrg xSecurityQueryVersionReply rep; 161caade7ccSmrg register xSecurityQueryVersionReq *req; 162caade7ccSmrg 163caade7ccSmrg if (!XextHasExtension (info)) 164caade7ccSmrg return (Status)0; /* failure */ 165caade7ccSmrg 166caade7ccSmrg LockDisplay (dpy); 167caade7ccSmrg SecurityGetReq (SecurityQueryVersion, req, info); 168caade7ccSmrg req->majorVersion = SECURITY_MAJOR_VERSION; 169caade7ccSmrg req->minorVersion = SECURITY_MINOR_VERSION; 170caade7ccSmrg 171caade7ccSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { 172caade7ccSmrg UnlockDisplay (dpy); 173caade7ccSmrg SyncHandle (); 174caade7ccSmrg return (Status)0; /* failure */ 175caade7ccSmrg } 176caade7ccSmrg *major_version_return = rep.majorVersion; 177caade7ccSmrg *minor_version_return = rep.minorVersion; 178caade7ccSmrg UnlockDisplay (dpy); 179caade7ccSmrg 180caade7ccSmrg SyncHandle (); 181caade7ccSmrg 182caade7ccSmrg if (*major_version_return != SECURITY_MAJOR_VERSION) 183caade7ccSmrg return (Status)0; /* failure */ 184caade7ccSmrg else 185caade7ccSmrg return (Status)1; /* success */ 186caade7ccSmrg} 187caade7ccSmrg 188caade7ccSmrgXauth * 189caade7ccSmrgXSecurityAllocXauth(void) 190caade7ccSmrg{ 191caade7ccSmrg return Xcalloc(1, sizeof(Xauth)); 192caade7ccSmrg} 193caade7ccSmrg 194caade7ccSmrgvoid 195caade7ccSmrgXSecurityFreeXauth(Xauth *auth) 196caade7ccSmrg{ 197caade7ccSmrg XFree(auth); 198caade7ccSmrg} 199caade7ccSmrg 200caade7ccSmrgstatic int 201caade7ccSmrgOnes(Mask mask) 202caade7ccSmrg{ 203caade7ccSmrg register Mask y; 204caade7ccSmrg 205caade7ccSmrg y = (mask >> 1) &033333333333; 206caade7ccSmrg y = mask - y - ((y >>1) & 033333333333); 207caade7ccSmrg return (((y + (y >> 3)) & 030707070707) % 077); 208caade7ccSmrg} 209caade7ccSmrg 210caade7ccSmrgXauth * 211caade7ccSmrgXSecurityGenerateAuthorization( 212caade7ccSmrg Display *dpy, 213caade7ccSmrg Xauth *auth_in, 214caade7ccSmrg unsigned long valuemask, 215caade7ccSmrg XSecurityAuthorizationAttributes *attributes, 216caade7ccSmrg XSecurityAuthorization *auth_id_return) 217caade7ccSmrg{ 218caade7ccSmrg XExtDisplayInfo *info = find_display (dpy); 219caade7ccSmrg register xSecurityGenerateAuthorizationReq *req; 220caade7ccSmrg xSecurityGenerateAuthorizationReply rep; 221caade7ccSmrg Xauth *auth_return; 222caade7ccSmrg unsigned long values[3]; 223caade7ccSmrg unsigned long *value = values; 224caade7ccSmrg unsigned int nvalues; 225caade7ccSmrg 226caade7ccSmrg *auth_id_return = 0; /* in case we fail */ 227caade7ccSmrg 228caade7ccSmrg /* make sure extension is available */ 229caade7ccSmrg 230caade7ccSmrg SecurityCheckExtension (dpy, info, (Xauth *)NULL); 231caade7ccSmrg 232caade7ccSmrg LockDisplay(dpy); 233caade7ccSmrg SecurityGetReq(SecurityGenerateAuthorization, req, info); 234caade7ccSmrg 235caade7ccSmrg req->nbytesAuthProto = auth_in->name_length; 236caade7ccSmrg req->nbytesAuthData = auth_in->data_length; 237caade7ccSmrg 238caade7ccSmrg /* adjust length to account for auth name and data */ 239caade7ccSmrg req->length += (auth_in->name_length + (unsigned)3) >> 2; 240caade7ccSmrg req->length += (auth_in->data_length + (unsigned)3) >> 2; 241caade7ccSmrg 242caade7ccSmrg /* adjust length to account for list of values */ 243caade7ccSmrg req->valueMask = valuemask & XSecurityAllAuthorizationAttributes; 244caade7ccSmrg nvalues = Ones(req->valueMask); 245caade7ccSmrg req->length += nvalues; 246caade7ccSmrg 247caade7ccSmrg /* send auth name and data */ 248caade7ccSmrg Data(dpy, auth_in->name, auth_in->name_length); 249caade7ccSmrg Data(dpy, auth_in->data, auth_in->data_length); 250caade7ccSmrg 251caade7ccSmrg /* send values */ 252caade7ccSmrg if (valuemask & XSecurityTimeout) *value++ = attributes->timeout; 253caade7ccSmrg if (valuemask & XSecurityTrustLevel) *value++ = attributes->trust_level; 254caade7ccSmrg if (valuemask & XSecurityGroup) *value++ = attributes->group; 255caade7ccSmrg if (valuemask & XSecurityEventMask) *value++ = attributes->event_mask; 256caade7ccSmrg 257caade7ccSmrg nvalues <<= 2; 258caade7ccSmrg Data32(dpy, (long *)values, (long)nvalues); 259caade7ccSmrg 260caade7ccSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) { 261caade7ccSmrg UnlockDisplay (dpy); 262caade7ccSmrg SyncHandle (); 263caade7ccSmrg return (Xauth *)NULL; 264caade7ccSmrg } 265caade7ccSmrg 266caade7ccSmrg *auth_id_return = rep.authId; 267caade7ccSmrg 268caade7ccSmrg /* Allocate space for the Xauth struct and the auth name and data all 269caade7ccSmrg * in one hunk. This lets XSecurityFreeXauth not have to care 270caade7ccSmrg * about whether the auth was allocated here or in 271caade7ccSmrg * XSecurityAllocXauth; in both cases, you just free one pointer. 272caade7ccSmrg */ 273caade7ccSmrg 274caade7ccSmrg if ((auth_return = (Xauth *)Xcalloc(1, 275caade7ccSmrg (sizeof(Xauth) + auth_in->name_length + rep.dataLength)))) 276caade7ccSmrg { 277caade7ccSmrg auth_return->data_length = rep.dataLength; 278caade7ccSmrg auth_return->data = (char *)&auth_return[1]; 279caade7ccSmrg _XReadPad(dpy, auth_return->data, (long)rep.dataLength); 280caade7ccSmrg 281caade7ccSmrg auth_return->name_length = auth_in->name_length; 282caade7ccSmrg auth_return->name = auth_return->data + auth_return->data_length; 283caade7ccSmrg memcpy(auth_return->name, auth_in->name, auth_return->name_length); 284caade7ccSmrg } 285caade7ccSmrg else 286caade7ccSmrg { 287caade7ccSmrg _XEatData(dpy, (unsigned long) (rep.dataLength + 3) & ~3); 288caade7ccSmrg } 289caade7ccSmrg 290caade7ccSmrg UnlockDisplay (dpy); 291caade7ccSmrg SyncHandle (); 292caade7ccSmrg return auth_return; 293caade7ccSmrg 294caade7ccSmrg} /* XSecurityGenerateAuthorization */ 295caade7ccSmrg 296caade7ccSmrgStatus 297caade7ccSmrgXSecurityRevokeAuthorization( 298caade7ccSmrg Display *dpy, 299caade7ccSmrg XSecurityAuthorization auth_id) 300caade7ccSmrg{ 301caade7ccSmrg XExtDisplayInfo *info = find_display (dpy); 302caade7ccSmrg xSecurityRevokeAuthorizationReq *req; 303caade7ccSmrg 304caade7ccSmrg SecurityCheckExtension (dpy, info, 0); 305caade7ccSmrg LockDisplay(dpy); 306caade7ccSmrg SecurityGetReq(SecurityRevokeAuthorization, req, info); 307caade7ccSmrg req->authId = auth_id; 308caade7ccSmrg UnlockDisplay (dpy); 309caade7ccSmrg SyncHandle (); 310caade7ccSmrg return 1; 311caade7ccSmrg} /* XSecurityRevokeAuthorization */ 312