Bool winGenerateAuthorization(void) { Bool fFreeAuth = FALSE; SecurityAuthorizationPtr pAuth = NULL; /* Call OS layer to generate authorization key */ g_authId = GenerateAuthorization(strlen(AUTH_NAME), AUTH_NAME, 0, NULL, &g_uiAuthDataLen, &g_pAuthData); if ((XID) ~0L == g_authId) { ErrorF("winGenerateAuthorization - GenerateAuthorization failed\n"); goto auth_bailout; } else { winDebug("winGenerateAuthorization - GenerateAuthorization success!\n" "AuthDataLen: %d AuthData: %s\n", g_uiAuthDataLen, g_pAuthData); } #ifdef XCSECURITY /* Allocate structure for additional auth information */ pAuth = (SecurityAuthorizationPtr) malloc(sizeof(SecurityAuthorizationRec)); if (!(pAuth)) { ErrorF("winGenerateAuthorization - Failed allocating " "SecurityAuthorizationPtr.\n"); goto auth_bailout; } /* Fill in the auth fields */ pAuth->id = g_authId; pAuth->timeout = 0; /* live for x seconds after refcnt == 0 */ pAuth->group = None; pAuth->trustLevel = XSecurityClientTrusted; pAuth->refcnt = 1; /* this auth must stick around */ pAuth->secondsRemaining = 0; pAuth->timer = NULL; pAuth->eventClients = NULL; /* Add the authorization to the server's auth list */ if (!AddResource(g_authId, SecurityAuthorizationResType, pAuth)) { ErrorF("winGenerateAuthorization - AddResource failed for auth.\n"); fFreeAuth = TRUE; goto auth_bailout; } /* Don't free the auth data, since it is still used internally */ pAuth = NULL; #endif return TRUE; auth_bailout: if (fFreeAuth) free(pAuth); return FALSE; }
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 */