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