📄 security.c
字号:
/* associate additional information with this auth ID */ pAuth = (SecurityAuthorizationPtr)xalloc(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 = (authdata_len + 3) >> 2; rep.sequenceNumber = client->sequence; rep.authId = authId; rep.dataLength = authdata_len; if (client->swapped) { register 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 */ removeAuth = FALSE; pAuth = NULL; err = client->noClientException;bailout: if (removeAuth) RemoveAuthorization(stuff->nbytesAuthProto, protoname, authdata_len, pAuthdata); if (pAuth) xfree(pAuth); return err;} /* ProcSecurityGenerateAuthorization */static intProcSecurityRevokeAuthorization(client) ClientPtr client;{ REQUEST(xSecurityRevokeAuthorizationReq); SecurityAuthorizationPtr pAuth; /* paranoia: this "can't happen" because this extension is hidden * from untrusted clients, but just in case... */ if (client->trustLevel != XSecurityClientTrusted) return BadRequest; REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq); pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(client, stuff->authId, SecurityAuthorizationResType, SecurityDestroyAccess); if (!pAuth) return SecurityErrorBase + XSecurityBadAuthorization; FreeResource(stuff->authId, RT_NONE); return Success;} /* ProcSecurityRevokeAuthorization */static intProcSecurityDispatch(client) ClientPtr client;{ REQUEST(xReq); switch (stuff->data) { case X_SecurityQueryVersion: return ProcSecurityQueryVersion(client); case X_SecurityGenerateAuthorization: return ProcSecurityGenerateAuthorization(client); case X_SecurityRevokeAuthorization: return ProcSecurityRevokeAuthorization(client); default: return BadRequest; }} /* ProcSecurityDispatch */static intSProcSecurityQueryVersion(client) ClientPtr client;{ REQUEST(xSecurityQueryVersionReq); register char n; swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xSecurityQueryVersionReq); swaps(&stuff->majorVersion, n); swaps(&stuff->minorVersion,n); return ProcSecurityQueryVersion(client);} /* SProcSecurityQueryVersion */static intSProcSecurityGenerateAuthorization(client) ClientPtr client;{ REQUEST(xSecurityGenerateAuthorizationReq); register char n; CARD32 *values; unsigned long nvalues; swaps(&stuff->length, n); REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); swaps(&stuff->nbytesAuthProto, n); swaps(&stuff->nbytesAuthData, n); swapl(&stuff->valueMask, n); values = (CARD32 *)(&stuff[1]) + ((stuff->nbytesAuthProto + (unsigned)3) >> 2) + ((stuff->nbytesAuthData + (unsigned)3) >> 2); nvalues = (((CARD32 *)stuff) + stuff->length) - values; SwapLongs(values, nvalues); return ProcSecurityGenerateAuthorization(client);} /* SProcSecurityGenerateAuthorization */static intSProcSecurityRevokeAuthorization(client) ClientPtr client;{ REQUEST(xSecurityRevokeAuthorizationReq); register char n; swaps(&stuff->length, n); REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq); swapl(&stuff->authId, n); return ProcSecurityRevokeAuthorization(client);} /* SProcSecurityRevokeAuthorization */static intSProcSecurityDispatch(client) ClientPtr client;{ REQUEST(xReq); switch (stuff->data) { case X_SecurityQueryVersion: return SProcSecurityQueryVersion(client); case X_SecurityGenerateAuthorization: return SProcSecurityGenerateAuthorization(client); case X_SecurityRevokeAuthorization: return SProcSecurityRevokeAuthorization(client); default: return BadRequest; }} /* SProcSecurityDispatch */static void SwapSecurityAuthorizationRevokedEvent(from, to) xSecurityAuthorizationRevokedEvent *from, *to;{ to->type = from->type; to->detail = from->detail; cpswaps(from->sequenceNumber, to->sequenceNumber); cpswapl(from->authId, to->authId);}/* SecurityDetermineEventPropogationLimits * * This is a helper function for SecurityCheckDeviceAccess. * * Arguments: * dev is the device for which the starting and stopping windows for * event propogation should be determined. * The values pointed to by ppWin and ppStopWin are not used. * * Returns: * ppWin is filled in with a pointer to the window at which event * propogation for the given device should start given the current * state of the server (pointer position, window layout, etc.) * ppStopWin is filled in with the window at which event propogation * should stop; events should not go to ppStopWin. * * Side Effects: none. */static voidSecurityDetermineEventPropogationLimits(dev, ppWin, ppStopWin) DeviceIntPtr dev; WindowPtr *ppWin; WindowPtr *ppStopWin;{ WindowPtr pFocusWin = dev->focus ? dev->focus->win : NoneWin; if (pFocusWin == NoneWin) { /* no focus -- events don't go anywhere */ *ppWin = *ppStopWin = NULL; return; } if (pFocusWin == PointerRootWin) { /* focus follows the pointer */ *ppWin = GetSpriteWindow(); *ppStopWin = NULL; /* propogate all the way to the root */ } else { /* a real window is set for the focus */ WindowPtr pSpriteWin = GetSpriteWindow(); *ppStopWin = pFocusWin->parent; /* don't go past the focus window */ /* if the pointer is in a subwindow of the focus window, start * at that subwindow, else start at the focus window itself */ if (IsParent(pFocusWin, pSpriteWin)) *ppWin = pSpriteWin; else *ppWin = pFocusWin; }} /* SecurityDetermineEventPropogationLimits *//* SecurityCheckDeviceAccess * * Arguments: * client is the client attempting to access a device. * dev is the device being accessed. * fromRequest is TRUE if the device access is a direct result of * the client executing some request and FALSE if it is a * result of the server trying to send an event (e.g. KeymapNotify) * to the client. * Returns: * TRUE if the device access should be allowed, else FALSE. * * Side Effects: * An audit message is generated if access is denied. */BoolSecurityCheckDeviceAccess(client, dev, fromRequest) ClientPtr client; DeviceIntPtr dev; Bool fromRequest;{ WindowPtr pWin, pStopWin; Bool untrusted_got_event; Bool found_event_window; Mask eventmask; int reqtype; /* trusted clients always allowed to do anything */ if (client->trustLevel == XSecurityClientTrusted) return TRUE; /* device security other than keyboard is not implemented yet */ if (dev != inputInfo.keyboard) return TRUE; /* some untrusted client wants access */ if (fromRequest) { reqtype = ((xReq *)client->requestBuffer)->reqType; switch (reqtype) { /* never allow these */ case X_ChangeKeyboardMapping: case X_ChangeKeyboardControl: case X_SetModifierMapping: SecurityAudit("client %d attempted request %d\n", client->index, reqtype); return FALSE; default: break; } } untrusted_got_event = FALSE; found_event_window = FALSE; if (dev->grab) { untrusted_got_event = ((rClient(dev->grab))->trustLevel != XSecurityClientTrusted); } else { SecurityDetermineEventPropogationLimits(dev, &pWin, &pStopWin); eventmask = KeyPressMask | KeyReleaseMask; while ( (pWin != pStopWin) && !found_event_window) { OtherClients *other; if (pWin->eventMask & eventmask) { found_event_window = TRUE; client = wClient(pWin); if (client->trustLevel != XSecurityClientTrusted) { untrusted_got_event = TRUE; } } if (wOtherEventMasks(pWin) & eventmask) { found_event_window = TRUE; for (other = wOtherClients(pWin); other; other = other->next) { if (other->mask & eventmask) { client = rClient(other); if (client->trustLevel != XSecurityClientTrusted) { untrusted_got_event = TRUE; break; } } } } if (wDontPropagateMask(pWin) & eventmask) break; pWin = pWin->parent; } /* while propogating the event */ } /* allow access by untrusted clients only if an event would have gone * to an untrusted client */ if (!untrusted_got_event) { char *devname = dev->name; if (!devname) devname = "unnamed"; if (fromRequest) SecurityAudit("client %d attempted request %d device %d (%s)\n", client->index, reqtype, dev->id, devname); else SecurityAudit("client %d attempted to access device %d (%s)\n", client->index, dev->id, devname); } return untrusted_got_event;} /* SecurityCheckDeviceAccess *//* SecurityAuditResourceIDAccess * * Arguments: * client is the client doing the resource access. * id is the resource id. * * Returns: NULL * * Side Effects: * An audit message is generated with details of the denied * resource access. */static pointerSecurityAuditResourceIDAccess(client, id) ClientPtr client; XID id;{ int cid = CLIENT_ID(id); int reqtype = ((xReq *)client->requestBuffer)->reqType; switch (reqtype) { case X_ChangeProperty: case X_DeleteProperty: case X_GetProperty: { xChangePropertyReq *req = (xChangePropertyReq *)client->requestBuffer; int propertyatom = req->property; char *propertyname = NameForAtom(propertyatom); SecurityAudit("client %d attempted request %d with window 0x%x property %s of client %d\n", client->index, reqtype, id, propertyname, cid); break; } default: { SecurityAudit("client %d attempted request %d with resource 0x%x of client %d\n", client->index, reqtype, id, cid); break; } } return NULL;} /* SecurityAuditResourceIDAccess *//* SecurityCheckResourceIDAccess * * This function gets plugged into client->CheckAccess and is called from * SecurityLookupIDByType/Class to determine if the client can access the * resource. * * Arguments: * client is the client doing the resource access. * id is the resource id. * rtype is its type or class. * access_mode represents the intended use of the resource; see * resource.h. * rval is a pointer to the resource structure for this resource. * * Returns: * If access is granted, the value of rval that was passed in, else NULL. * * Side Effects: * Disallowed resource accesses are audited. */static pointerSecurityCheckResourceIDAccess(client, id, rtype, access_mode, rval) ClientPtr client; XID id; RESTYPE rtype; Mask access_mode; pointer rval;{ int cid = CLIENT_ID(id); int reqtype = ((xReq *)client->requestBuffer)->reqType; if (SecurityUnknownAccess == access_mode) return rval; /* for compatibility, we have to allow access */ switch (reqtype) { /* these are always allowed */ case X_QueryTree: case X_TranslateCoords: case X_GetGeometry: /* property access is controlled in SecurityCheckPropertyAccess */ case X_GetProperty: case X_ChangeProperty: case X_DeleteProperty: case X_RotateProperties: case X_ListProperties: return rval; default: break; } if (cid != 0) { /* not a server-owned resource */ /* * The following 'if' restricts clients to only access resources at * the same trustLevel. Since there are currently only two trust levels, * and trusted clients never call this function, this degenerates into * saying that untrusted clients can only access resources of other * untrusted clients. One way to add the notion of groups would be to * allow values other than Trusted (0) and Untrusted (1) for this field. * Clients at the same trust level would be able to use each other's * resources, but not those of clients at other trust levels. I haven't * tried it, but this probably mostly works already. The obvious * competing alternative for grouping clients for security purposes is to * use app groups. dpw */ if (client->trustLevel == clients[cid]->trustLevel#ifdef XAPPGROUP || (RT_COLORMAP == rtype && XagDefaultColormap (client) == (Colormap) id)#endif ) return rval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -