int XaceHookSelectionAccess(ClientPtr client, Selection **ppSel, Mask access_mode) { XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success }; CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec); return rec.status; }
void XaceHookAuditEnd(ClientPtr ptr, int result) { XaceAuditRec rec = { ptr, result }; /* call callbacks, there is no return value. */ CallCallbacks(&XaceHooks[XACE_AUDIT_END], &rec); }
int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin, PropertyPtr *ppProp, Mask access_mode) { XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success }; CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec); return rec.status; }
/* * Called to free privates at object deletion time. */ _X_EXPORT void dixFreePrivates(PrivateRec *privates) { PrivateRec *ptr, *next; PrivateDescRec *item; PrivateCallbackRec calldata; /* first pass calls the delete callbacks */ for (ptr = privates; ptr; ptr = ptr->next) { item = findItem(ptr->key); if (item) { calldata.key = ptr->key; calldata.value = &ptr->value; CallCallbacks(&item->deletefuncs, &calldata); } } /* second pass frees the memory */ ptr = privates; while (ptr) { next = ptr->next; xfree(ptr); ptr = next; } }
/* * Allocate a private and attach it to an existing object. */ _X_EXPORT pointer * dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) { PrivateDescRec *item = findItem(key); PrivateRec *ptr; unsigned size = sizeof(PrivateRec); if (item) size += item->size; ptr = (PrivateRec *)xcalloc(size, 1); if (!ptr) return NULL; ptr->key = key; ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL; ptr->next = *privates; *privates = ptr; /* call any init funcs and return */ if (item) { PrivateCallbackRec calldata = { key, &ptr->value }; CallCallbacks(&item->initfuncs, &calldata); } return &ptr->value; }
static _X_INLINE void CallSelectionCallback(Selection *pSel, ClientPtr client, SelectionCallbackKind kind) { SelectionInfoRec info = { pSel, client, kind }; CallCallbacks(&SelectionCallback, &info); }
static _X_INLINE void CallResourceStateCallback(ResourceState state, ResourceRec * res) { if (ResourceStateCallback) { ResourceStateInfoRec rsi = { state, res->id, res->type, res->value }; CallCallbacks(&ResourceStateCallback, &rsi); } }
int XaceHookDispatch(ClientPtr client, int major) { /* Call the extension dispatch hook */ ExtensionEntry *ext = GetExtensionEntry(major); XaceExtAccessRec erec = { client, ext, DixUseAccess, Success }; if (ext) CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &erec); /* On error, pretend extension doesn't exist */ return (erec.status == Success) ? Success : BadRequest; }
/* Special-cased hook functions. Called by Xserver. */ int XaceHookDispatch(ClientPtr client, int major) { /* Call the audit begin callback, there is no return value. */ XaceAuditRec rec = { client, 0 }; CallCallbacks(&XaceHooks[XACE_AUDIT_BEGIN], &rec); if (major < 128) { /* Call the core dispatch hook */ XaceCoreDispatchRec rec = { client, Success /* default allow */ }; CallCallbacks(&XaceHooks[XACE_CORE_DISPATCH], &rec); return rec.status; } else { /* Call the extension dispatch hook */ ExtensionEntry *ext = GetExtensionEntry(major); XaceExtAccessRec rec = { client, ext, DixUseAccess, Success }; if (ext) CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &rec); /* On error, pretend extension doesn't exist */ return (rec.status == Success) ? Success : BadRequest; } }
/* Entry point for hook functions. Called by Xserver. */ int XaceHook(int hook, ...) { pointer calldata; /* data passed to callback */ int *prv = NULL; /* points to return value from callback */ va_list ap; /* argument list */ va_start(ap, hook); /* Marshal arguments for passing to callback. * Each callback has its own case, which sets up a structure to hold * the arguments and integer return parameter, or in some cases just * sets calldata directly to a single argument (with no return result) */ switch (hook) { case XACE_RESOURCE_ACCESS: { XaceResourceAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.id = va_arg(ap, XID); rec.rtype = va_arg(ap, RESTYPE); rec.res = va_arg(ap, pointer); rec.ptype = va_arg(ap, RESTYPE); rec.parent = va_arg(ap, pointer); rec.access_mode = va_arg(ap, Mask); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_DEVICE_ACCESS: { XaceDeviceAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.dev = va_arg(ap, DeviceIntPtr); rec.access_mode = va_arg(ap, Mask); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_SEND_ACCESS: { XaceSendAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.dev = va_arg(ap, DeviceIntPtr); rec.pWin = va_arg(ap, WindowPtr); rec.events = va_arg(ap, xEventPtr); rec.count = va_arg(ap, int); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_RECEIVE_ACCESS: { XaceReceiveAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.pWin = va_arg(ap, WindowPtr); rec.events = va_arg(ap, xEventPtr); rec.count = va_arg(ap, int); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_CLIENT_ACCESS: { XaceClientAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.target = va_arg(ap, ClientPtr); rec.access_mode = va_arg(ap, Mask); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_EXT_ACCESS: { XaceExtAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.ext = va_arg(ap, ExtensionEntry*); rec.access_mode = DixGetAttrAccess; rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_SERVER_ACCESS: { XaceServerAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.access_mode = va_arg(ap, Mask); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_SCREEN_ACCESS: case XACE_SCREENSAVER_ACCESS: { XaceScreenAccessRec rec; rec.client = va_arg(ap, ClientPtr); rec.screen = va_arg(ap, ScreenPtr); rec.access_mode = va_arg(ap, Mask); rec.status = Success; /* default allow */ calldata = &rec; prv = &rec.status; break; } case XACE_AUTH_AVAIL: { XaceAuthAvailRec rec; rec.client = va_arg(ap, ClientPtr); rec.authId = va_arg(ap, XID); calldata = &rec; break; } case XACE_KEY_AVAIL: { XaceKeyAvailRec rec; rec.event = va_arg(ap, xEventPtr); rec.keybd = va_arg(ap, DeviceIntPtr); rec.count = va_arg(ap, int); calldata = &rec; break; } default: { va_end(ap); return 0; /* unimplemented hook number */ } } va_end(ap); /* call callbacks and return result, if any. */ CallCallbacks(&XaceHooks[hook], calldata); return prv ? *prv : Success; }
/* Entry point for hook functions. Called by Xserver. */ int XaceHook(int hook, ...) { union { XaceResourceAccessRec res; XaceDeviceAccessRec dev; XaceSendAccessRec send; XaceReceiveAccessRec recv; XaceClientAccessRec client; XaceExtAccessRec ext; XaceServerAccessRec server; XaceScreenAccessRec screen; XaceAuthAvailRec auth; XaceKeyAvailRec key; } u; int *prv = NULL; /* points to return value from callback */ va_list ap; /* argument list */ if (!XaceHooks[hook]) return Success; va_start(ap, hook); /* Marshal arguments for passing to callback. * Each callback has its own case, which sets up a structure to hold * the arguments and integer return parameter, or in some cases just * sets calldata directly to a single argument (with no return result) */ switch (hook) { case XACE_RESOURCE_ACCESS: u.res.client = va_arg(ap, ClientPtr); u.res.id = va_arg(ap, XID); u.res.rtype = va_arg(ap, RESTYPE); u.res.res = va_arg(ap, pointer); u.res.ptype = va_arg(ap, RESTYPE); u.res.parent = va_arg(ap, pointer); u.res.access_mode = va_arg(ap, Mask); u.res.status = Success; /* default allow */ prv = &u.res.status; break; case XACE_DEVICE_ACCESS: u.dev.client = va_arg(ap, ClientPtr); u.dev.dev = va_arg(ap, DeviceIntPtr); u.dev.access_mode = va_arg(ap, Mask); u.dev.status = Success; /* default allow */ prv = &u.dev.status; break; case XACE_SEND_ACCESS: u.send.client = va_arg(ap, ClientPtr); u.send.dev = va_arg(ap, DeviceIntPtr); u.send.pWin = va_arg(ap, WindowPtr); u.send.events = va_arg(ap, xEventPtr); u.send.count = va_arg(ap, int); u.send.status = Success; /* default allow */ prv = &u.send.status; break; case XACE_RECEIVE_ACCESS: u.recv.client = va_arg(ap, ClientPtr); u.recv.pWin = va_arg(ap, WindowPtr); u.recv.events = va_arg(ap, xEventPtr); u.recv.count = va_arg(ap, int); u.recv.status = Success; /* default allow */ prv = &u.recv.status; break; case XACE_CLIENT_ACCESS: u.client.client = va_arg(ap, ClientPtr); u.client.target = va_arg(ap, ClientPtr); u.client.access_mode = va_arg(ap, Mask); u.client.status = Success; /* default allow */ prv = &u.client.status; break; case XACE_EXT_ACCESS: u.ext.client = va_arg(ap, ClientPtr); u.ext.ext = va_arg(ap, ExtensionEntry *); u.ext.access_mode = DixGetAttrAccess; u.ext.status = Success; /* default allow */ prv = &u.ext.status; break; case XACE_SERVER_ACCESS: u.server.client = va_arg(ap, ClientPtr); u.server.access_mode = va_arg(ap, Mask); u.server.status = Success; /* default allow */ prv = &u.server.status; break; case XACE_SCREEN_ACCESS: case XACE_SCREENSAVER_ACCESS: u.screen.client = va_arg(ap, ClientPtr); u.screen.screen = va_arg(ap, ScreenPtr); u.screen.access_mode = va_arg(ap, Mask); u.screen.status = Success; /* default allow */ prv = &u.screen.status; break; case XACE_AUTH_AVAIL: u.auth.client = va_arg(ap, ClientPtr); u.auth.authId = va_arg(ap, XID); break; case XACE_KEY_AVAIL: u.key.event = va_arg(ap, xEventPtr); u.key.keybd = va_arg(ap, DeviceIntPtr); u.key.count = va_arg(ap, int); break; default: va_end(ap); return 0; /* unimplemented hook number */ } va_end(ap); /* call callbacks and return result, if any. */ CallCallbacks(&XaceHooks[hook], &u); return prv ? *prv : Success; }
/* Entry point for hook functions. Called by Xserver. */ int XaceHook(int hook, ...) { pointer calldata; /* data passed to callback */ int *prv = NULL; /* points to return value from callback */ va_list ap; /* argument list */ va_start(ap, hook); /* Marshal arguments for passing to callback. * Each callback has its own case, which sets up a structure to hold * the arguments and integer return parameter, or in some cases just * sets calldata directly to a single argument (with no return result) */ switch (hook) { case XACE_RESOURCE_ACCESS: { XaceResourceAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, XID), va_arg(ap, RESTYPE), va_arg(ap, pointer), va_arg(ap, RESTYPE), va_arg(ap, pointer), va_arg(ap, Mask), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_DEVICE_ACCESS: { XaceDeviceAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, DeviceIntPtr), va_arg(ap, Mask), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_SEND_ACCESS: { XaceSendAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, DeviceIntPtr), va_arg(ap, WindowPtr), va_arg(ap, xEventPtr), va_arg(ap, int), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_RECEIVE_ACCESS: { XaceReceiveAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, WindowPtr), va_arg(ap, xEventPtr), va_arg(ap, int), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_CLIENT_ACCESS: { XaceClientAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, ClientPtr), va_arg(ap, Mask), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_EXT_ACCESS: { XaceExtAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, ExtensionEntry*), DixGetAttrAccess, Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_SERVER_ACCESS: { XaceServerAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, Mask), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_SCREEN_ACCESS: case XACE_SCREENSAVER_ACCESS: { XaceScreenAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, ScreenPtr), va_arg(ap, Mask), Success /* default allow */ }; calldata = &rec; prv = &rec.status; break; } case XACE_AUTH_AVAIL: { XaceAuthAvailRec rec = { va_arg(ap, ClientPtr), va_arg(ap, XID) }; calldata = &rec; break; } case XACE_KEY_AVAIL: { XaceKeyAvailRec rec = { va_arg(ap, xEventPtr), va_arg(ap, DeviceIntPtr), va_arg(ap, int) }; calldata = &rec; break; } default: { va_end(ap); return 0; /* unimplemented hook number */ } } va_end(ap); /* call callbacks and return result, if any. */ CallCallbacks(&XaceHooks[hook], calldata); return prv ? *prv : Success; } /* XaceCensorImage * * Called after pScreen->GetImage to prevent pieces or trusted windows from * being returned in image data from an untrusted window. * * Arguments: * client is the client doing the GetImage. * pVisibleRegion is the visible region of the window. * widthBytesLine is the width in bytes of one horizontal line in pBuf. * pDraw is the source window. * x, y, w, h is the rectangle of image data from pDraw in pBuf. * format is the format of the image data in pBuf: ZPixmap or XYPixmap. * pBuf is the image data. * * Returns: nothing. * * Side Effects: * Any part of the rectangle (x, y, w, h) that is outside the visible * region of the window will be destroyed (overwritten) in pBuf. */ void XaceCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h, format, pBuf) ClientPtr client; RegionPtr pVisibleRegion; long widthBytesLine; DrawablePtr pDraw; int x, y, w, h; unsigned int format; char * pBuf; { ScreenPtr pScreen; RegionRec imageRegion; /* region representing x,y,w,h */ RegionRec censorRegion; /* region to obliterate */ BoxRec imageBox; int nRects; pScreen = pDraw->pScreen; imageBox.x1 = x; imageBox.y1 = y; imageBox.x2 = x + w; imageBox.y2 = y + h; REGION_INIT(pScreen, &imageRegion, &imageBox, 1); REGION_NULL(pScreen, &censorRegion); /* censorRegion = imageRegion - visibleRegion */ REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion); nRects = REGION_NUM_RECTS(&censorRegion); if (nRects > 0) { /* we have something to censor */ GCPtr pScratchGC = NULL; PixmapPtr pPix = NULL; xRectangle *pRects = NULL; Bool failed = FALSE; int depth = 1; int bitsPerPixel = 1; int i; BoxPtr pBox; /* convert region to list-of-rectangles for PolyFillRect */ pRects = (xRectangle *)xalloc(nRects * sizeof(xRectangle)); if (!pRects) { failed = TRUE; goto failSafe; } for (pBox = REGION_RECTS(&censorRegion), i = 0; i < nRects; i++, pBox++) { pRects[i].x = pBox->x1; pRects[i].y = pBox->y1 - imageBox.y1; pRects[i].width = pBox->x2 - pBox->x1; pRects[i].height = pBox->y2 - pBox->y1; } /* use pBuf as a fake pixmap */ if (format == ZPixmap) { depth = pDraw->depth; bitsPerPixel = pDraw->bitsPerPixel; } pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h, depth, bitsPerPixel, widthBytesLine, (pointer)pBuf); if (!pPix) { failed = TRUE; goto failSafe; } pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen); if (!pScratchGC) { failed = TRUE; goto failSafe; } ValidateGC(&pPix->drawable, pScratchGC); (* pScratchGC->ops->PolyFillRect)(&pPix->drawable, pScratchGC, nRects, pRects); failSafe: if (failed) { /* Censoring was not completed above. To be safe, wipe out * all the image data so that nothing trusted gets out. */ bzero(pBuf, (int)(widthBytesLine * h)); } if (pRects) xfree(pRects); if (pScratchGC) FreeScratchGC(pScratchGC); if (pPix) FreeScratchPixmapHeader(pPix); } REGION_UNINIT(pScreen, &imageRegion); REGION_UNINIT(pScreen, &censorRegion); } /* XaceCensorImage */
int WriteToClient(ClientPtr who, int count, const void *__buf) { OsCommPtr oc; ConnectionOutputPtr oco; int padBytes; const char *buf = __buf; #ifdef DEBUG_COMMUNICATION Bool multicount = FALSE; #endif if (!count || !who || who == serverClient || who->clientGone) return 0; oc = who->osPrivate; oco = oc->output; #ifdef DEBUG_COMMUNICATION { char info[128]; xError *err; xGenericReply *rep; xEvent *ev; if (!who->replyBytesRemaining) { switch (buf[0]) { case X_Reply: rep = (xGenericReply *) buf; if (rep->sequenceNumber == who->sequence) { snprintf(info, 127, "Xreply: type: 0x%x data: 0x%x " "len: %i seq#: 0x%x", rep->type, rep->data1, rep->length, rep->sequenceNumber); multicount = TRUE; } break; case X_Error: err = (xError *) buf; snprintf(info, 127, "Xerror: Code: 0x%x resID: 0x%x maj: 0x%x " "min: %x", err->errorCode, err->resourceID, err->minorCode, err->majorCode); break; default: if ((buf[0] & 0x7f) == KeymapNotify) snprintf(info, 127, "KeymapNotifyEvent: %i", buf[0]); else { ev = (xEvent *) buf; snprintf(info, 127, "XEvent: type: 0x%x detail: 0x%x " "seq#: 0x%x", ev->u.u.type, ev->u.u.detail, ev->u.u.sequenceNumber); } } ErrorF("REPLY: ClientIDX: %i %s\n", who->index, info); } else multicount = TRUE; } #endif if (!oco) { if ((oco = FreeOutputs)) { FreeOutputs = oco->next; } else if (!(oco = AllocateOutputBuffer())) { if (oc->trans_conn) { _XSERVTransDisconnect(oc->trans_conn); _XSERVTransClose(oc->trans_conn); oc->trans_conn = NULL; } MarkClientException(who); return -1; } oc->output = oco; } padBytes = padding_for_int32(count); if (ReplyCallback) { ReplyInfoRec replyinfo; replyinfo.client = who; replyinfo.replyData = buf; replyinfo.dataLenBytes = count + padBytes; replyinfo.padBytes = padBytes; if (who->replyBytesRemaining) { /* still sending data of an earlier reply */ who->replyBytesRemaining -= count + padBytes; replyinfo.startOfReply = FALSE; replyinfo.bytesRemaining = who->replyBytesRemaining; CallCallbacks((&ReplyCallback), (void *) &replyinfo); } else if (who->clientState == ClientStateRunning && buf[0] == X_Reply) { /* start of new reply */ CARD32 replylen; unsigned long bytesleft; replylen = ((const xGenericReply *) buf)->length; if (who->swapped) swapl(&replylen); bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes; replyinfo.startOfReply = TRUE; replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft; CallCallbacks((&ReplyCallback), (void *) &replyinfo); } } #ifdef DEBUG_COMMUNICATION else if (multicount) { if (who->replyBytesRemaining) { who->replyBytesRemaining -= (count + padBytes); } else { CARD32 replylen; replylen = ((xGenericReply *) buf)->length; who->replyBytesRemaining = (replylen * 4) + SIZEOF(xReply) - count - padBytes; } } #endif if (oco->count == 0 || oco->count + count + padBytes > oco->size) { FD_CLR(oc->fd, &OutputPending); if (!XFD_ANYSET(&OutputPending)) { CriticalOutputPending = FALSE; NewOutputPending = FALSE; } if (FlushCallback) CallCallbacks(&FlushCallback, NULL); return FlushClient(who, oc, buf, count); } NewOutputPending = TRUE; FD_SET(oc->fd, &OutputPending); memmove((char *) oco->buf + oco->count, buf, count); oco->count += count; if (padBytes) { memset(oco->buf + oco->count, '\0', padBytes); oco->count += padBytes; } return count; }
void FlushAllOutput(void) { register int index, base; register fd_mask mask; /* raphael */ OsCommPtr oc; register ClientPtr client; Bool newoutput = NewOutputPending; #if defined(WIN32) fd_set newOutputPending; #endif if (FlushCallback) CallCallbacks(&FlushCallback, NULL); if (!newoutput) return; /* * It may be that some client still has critical output pending, * but he is not yet ready to receive it anyway, so we will * simply wait for the select to tell us when he's ready to receive. */ CriticalOutputPending = FALSE; NewOutputPending = FALSE; #ifndef WIN32 for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) { mask = OutputPending.fds_bits[base]; OutputPending.fds_bits[base] = 0; while (mask) { index = ffs(mask) - 1; mask &= ~lowbit(mask); if ((index = ConnectionTranslation[(base * (sizeof(fd_mask) * 8)) + index]) == 0) continue; client = clients[index]; if (client->clientGone) continue; oc = (OsCommPtr) client->osPrivate; if (FD_ISSET(oc->fd, &ClientsWithInput)) { FD_SET(oc->fd, &OutputPending); /* set the bit again */ NewOutputPending = TRUE; } else (void) FlushClient(client, oc, (char *) NULL, 0); } } #else /* WIN32 */ FD_ZERO(&newOutputPending); for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++) { index = XFD_FD(&OutputPending, base); if ((index = GetConnectionTranslation(index)) == 0) continue; client = clients[index]; if (client->clientGone) continue; oc = (OsCommPtr) client->osPrivate; if (FD_ISSET(oc->fd, &ClientsWithInput)) { FD_SET(oc->fd, &newOutputPending); /* set the bit again */ NewOutputPending = TRUE; } else (void) FlushClient(client, oc, (char *) NULL, 0); } XFD_COPYSET(&newOutputPending, &OutputPending); #endif /* WIN32 */ }
static int ProcSecurityGenerateAuthorization( ClientPtr client) { REQUEST(xSecurityGenerateAuthorizationReq); int len; /* request length in CARD32s*/ Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */ SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */ int err; /* error to return from this function */ XID authId; /* authorization ID assigned by os layer */ xSecurityGenerateAuthorizationReply rep; /* reply struct */ unsigned int trustLevel; /* trust level of new auth */ XID group; /* group of new auth */ CARD32 timeout; /* timeout of new auth */ CARD32 *values; /* list of supplied attributes */ char *protoname; /* auth proto name sent in request */ char *protodata; /* auth proto data sent in request */ unsigned int authdata_len; /* # bytes of generated auth data */ char *pAuthdata; /* generated auth data */ Mask eventMask; /* what events on this auth does client want */ /* check request length */ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); len = bytes_to_int32(SIZEOF(xSecurityGenerateAuthorizationReq)); len += bytes_to_int32(stuff->nbytesAuthProto); len += bytes_to_int32(stuff->nbytesAuthData); values = ((CARD32 *)stuff) + len; len += Ones(stuff->valueMask); if (client->req_len != len) return BadLength; /* check valuemask */ if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes) { client->errorValue = stuff->valueMask; return BadValue; } /* check timeout */ timeout = 60; if (stuff->valueMask & XSecurityTimeout) { timeout = *values++; } /* check trustLevel */ trustLevel = XSecurityClientUntrusted; if (stuff->valueMask & XSecurityTrustLevel) { trustLevel = *values++; if (trustLevel != XSecurityClientTrusted && trustLevel != XSecurityClientUntrusted) { client->errorValue = trustLevel; return BadValue; } } /* check group */ group = None; if (stuff->valueMask & XSecurityGroup) { group = *values++; if (SecurityValidateGroupCallback) { SecurityValidateGroupInfoRec vgi; vgi.group = group; vgi.valid = FALSE; CallCallbacks(&SecurityValidateGroupCallback, (pointer)&vgi); /* if nobody said they recognized it, it's an error */ if (!vgi.valid) { client->errorValue = group; return BadValue; } } } /* check event mask */ eventMask = 0; if (stuff->valueMask & XSecurityEventMask) { eventMask = *values++; if (eventMask & ~XSecurityAllEventMasks) { client->errorValue = eventMask; return BadValue; } } protoname = (char *)&stuff[1]; protodata = protoname + bytes_to_int32(stuff->nbytesAuthProto); /* call os layer to generate the authorization */ authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname, stuff->nbytesAuthData, protodata, &authdata_len, &pAuthdata); if ((XID) ~0L == authId) { err = SecurityErrorBase + XSecurityBadAuthorizationProtocol; goto bailout; } /* now that we've added the auth, remember to remove it if we have to * abort the request for some reason (like allocation failure) */ removeAuth = TRUE; /* associate additional information with this auth ID */ pAuth = malloc(sizeof(SecurityAuthorizationRec)); if (!pAuth) { err = BadAlloc; goto bailout; } /* fill in the auth fields */ pAuth->id = authId; pAuth->timeout = timeout; pAuth->group = group; pAuth->trustLevel = trustLevel; pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */ pAuth->secondsRemaining = 0; pAuth->timer = NULL; pAuth->eventClients = NULL; /* handle event selection */ if (eventMask) { err = SecurityEventSelectForAuthorization(pAuth, client, eventMask); if (err != Success) goto bailout; } if (!AddResource(authId, SecurityAuthorizationResType, pAuth)) { err = BadAlloc; goto bailout; } /* start the timer ticking */ if (pAuth->timeout != 0) SecurityStartAuthorizationTimer(pAuth); /* tell client the auth id and data */ rep.type = X_Reply; rep.length = bytes_to_int32(authdata_len); rep.sequenceNumber = client->sequence; rep.authId = authId; rep.dataLength = authdata_len; if (client->swapped) { char n; swapl(&rep.length, n); swaps(&rep.sequenceNumber, n); swapl(&rep.authId, n); swaps(&rep.dataLength, n); } WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply), (char *)&rep); WriteToClient(client, authdata_len, pAuthdata); SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n", client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout, pAuth->group, eventMask); /* the request succeeded; don't call RemoveAuthorization or free pAuth */ return Success; bailout: if (removeAuth) RemoveAuthorization(stuff->nbytesAuthProto, protoname, authdata_len, pAuthdata); free(pAuth); return err; } /* ProcSecurityGenerateAuthorization */
int LbxSendConnSetup(ClientPtr client, char *reason) { int dlength; int i, ndex, lim, wndex; CARD32 dataBuf[16]; xLbxConnSetupPrefix csp; NewClientInfoRec nci; LbxProxyPtr proxy = LbxProxy(client); if (reason) { SendConnSetup(client, reason); LbxForceOutput(proxy); /* expedient to avoid another state variable */ return (client->noClientException); } IncrementClientCount(); client->requestVector = client->swapped ? SwappedProcVector : ProcVector; client->sequence = 0; dataBuf[0] = client->clientAsMask; csp.success = TRUE; csp.majorVersion = connSetupPrefix.majorVersion; csp.minorVersion = connSetupPrefix.minorVersion; csp.tag = 0; #ifdef XAPPGROUP if (!client->appgroup) { #endif csp.changeType = 1; /* LbxNormalDeltas */ csp.length = 2 + /* tag + resource-id-base */ screenInfo.numScreens; /* input-mask per screen */ wndex = 0; ndex = 1; lim = screenInfo.numScreens; #ifdef XAPPGROUP } else { csp.changeType = 2; /* LbxAppGroupDeltas */ csp.length = 7 + /* tag, res-id-base, root, visual, colormap, b&w-pix */ 1 + screenInfo.numScreens - screenInfo.numVideoScreens; XagGetDeltaInfo (client, &dataBuf[1]); for (i = 0; i < MAXSCREENS; i++) { if ((CARD32) WindowTable[i]->drawable.id == dataBuf[1]) { dataBuf[6] = WindowTable[i]->eventMask | wOtherEventMasks(WindowTable[i]); break; } } wndex = screenInfo.numVideoScreens; ndex = 7; lim = screenInfo.numScreens - screenInfo.numVideoScreens; } #endif for (i = 0; i < lim; i++, ndex++, wndex++) { dataBuf[ndex] = WindowTable[wndex]->eventMask | wOtherEventMasks(WindowTable[wndex]); } dlength = (csp.length - 1) << 2; if (LbxProxyClient(proxy)->swapped) { swaps(&csp.length, i); } if (client->swapped) { LbxWriteSConnSetupPrefix(client, &csp); SwapLongs(dataBuf, (1 + screenInfo.numScreens)); WriteToClient(client, dlength, (pointer) dataBuf); } else { WriteToClient(client, sizeof(xLbxConnSetupPrefix), (char *) &csp); WriteToClient(client, dlength, (pointer) dataBuf); } LbxForceOutput(proxy); /* expedient to avoid another state variable */ client->clientState = ClientStateRunning; if (ClientStateCallback) { if (LbxProxyClient(proxy)->swapped != client->swapped) { swaps(&csp.length, i); } nci.client = client; nci.prefix = (xConnSetupPrefix*) &csp; nci.setup = (xConnSetup *) ConnectionInfo; CallCallbacks(&ClientStateCallback, (pointer) &nci); } return client->noClientException; }