示例#1
0
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 */