Example #1
0
/*
 * Request the authorization server framework to verify the authorization 
 * information in the specified request in rdata.
 */
PJ_DEF(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,
					   pjsip_rx_data *rdata,
					   int *status_code)
{
    pjsip_authorization_hdr *h_auth;
    pjsip_msg *msg = rdata->msg_info.msg;
    pjsip_hdr_e htype;
    pj_str_t acc_name;
    pjsip_cred_info cred_info;
    pj_status_t status;

    PJ_ASSERT_RETURN(auth_srv && rdata, PJ_EINVAL);
    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG);

    htype = auth_srv->is_proxy ? PJSIP_H_PROXY_AUTHORIZATION : 
				 PJSIP_H_AUTHORIZATION;

    /* Initialize status with 200. */
    *status_code = 200;

    /* Find authorization header for our realm. */
    h_auth = (pjsip_authorization_hdr*) pjsip_msg_find_hdr(msg, htype, NULL);
    while (h_auth) {
	if (!pj_stricmp(&h_auth->credential.common.realm, &auth_srv->realm))
	    break;

	h_auth = h_auth->next;
	if (h_auth == (void*) &msg->hdr) {
	    h_auth = NULL;
	    break;
	}

	h_auth=(pjsip_authorization_hdr*)pjsip_msg_find_hdr(msg,htype,h_auth);
    }

    if (!h_auth) {
	*status_code = auth_srv->is_proxy ? 407 : 401;
	return PJSIP_EAUTHNOAUTH;
    }

    /* Check authorization scheme. */
    if (pj_stricmp(&h_auth->scheme, &pjsip_DIGEST_STR) == 0)
	acc_name = h_auth->credential.digest.username;
    else {
	*status_code = auth_srv->is_proxy ? 407 : 401;
	return PJSIP_EINVALIDAUTHSCHEME;
    }

    /* Find the credential information for the account. */
    status = (*auth_srv->lookup)(rdata->tp_info.pool, &auth_srv->realm,
				 &acc_name, &cred_info);
    if (status != PJ_SUCCESS) {
	*status_code = PJSIP_SC_FORBIDDEN;
	return status;
    }

    /* Authenticate with the specified credential. */
    status = pjsip_auth_verify(h_auth, &msg->line.req.method.name, 
			       &cred_info);
    if (status != PJ_SUCCESS) {
	*status_code = PJSIP_SC_FORBIDDEN;
    }
    return status;
}
PJ_DEF(pj_status_t) pjsip_auth_srv_verify3( pjsip_auth_srv *auth_srv,
					    pjsip_msg *msg,
					    pj_pool_t *pool,
					    int *status_code,
					    void *lookup_data)
{
    pjsip_authorization_hdr *h_auth;
    pjsip_hdr_e htype;
    pj_str_t realm;
    pj_str_t acc_name;
    pjsip_cred_info cred_info;
    pj_bool_t invalid_auth_scheme = PJ_FALSE;
    pj_bool_t forbidden = PJ_FALSE;
    pj_bool_t succeeded = PJ_FALSE;
    pj_status_t status;

    PJ_ASSERT_RETURN(auth_srv && msg, PJ_EINVAL);
    PJ_ASSERT_RETURN(msg->type == PJSIP_REQUEST_MSG, PJSIP_ENOTREQUESTMSG);

    htype = auth_srv->is_proxy ? PJSIP_H_PROXY_AUTHORIZATION : 
				 PJSIP_H_AUTHORIZATION;

    /* Find authorization header(s) for our realm and process them. */
    h_auth = (pjsip_authorization_hdr*) pjsip_msg_find_hdr(msg, htype, NULL);
    while (h_auth) {
	realm = h_auth->credential.common.realm;
	if (((auth_srv->realm.slen == 1) &&
             (auth_srv->realm.ptr[0] == '*')) ||
            (!pj_stricmp(&realm, &auth_srv->realm))) {

	    /* Check authorization scheme. */
	    if (pj_stricmp(&h_auth->scheme, &pjsip_DIGEST_STR) == 0) {
		acc_name = h_auth->credential.digest.username;

		    pjsip_auth_lookup_cred_param param;
		    pj_bzero(&param, sizeof(param));
		    param.realm = realm;
		    param.acc_name = acc_name;
		    param.msg = msg;

		/* Find the credential information for the account. */
		if (auth_srv->lookup3) {
		    status = (*auth_srv->lookup3)(pool, &param,
						  &cred_info, lookup_data);
		/* Find the credential information for the account. */
		} else if (auth_srv->lookup2) {
		    status = (*auth_srv->lookup2)(pool, &param,
						  &cred_info);
		} else {
		    status = (*auth_srv->lookup)(pool, &realm,
						 &acc_name, &cred_info);
		}

		/* Authenticate with the specified credential. */
		if (status == PJ_SUCCESS) {
		    status = pjsip_auth_verify(h_auth,
					       &msg->line.req.method.name,
					       &cred_info);
		}

		if (status == PJ_SUCCESS) {
		    succeeded = PJ_TRUE;
		    break;
		} else {
		    if (status == PJSIP_EAUTHNOAUTH)
		        invalid_auth_scheme = PJ_TRUE;
		    else
		        forbidden = PJ_TRUE;
		}
	    } else {
                invalid_auth_scheme = PJ_TRUE;
	    }
        }

	h_auth = h_auth->next;
	if (h_auth == (void*) &msg->hdr) {
	    h_auth = NULL;
	    break;
	}

	h_auth=(pjsip_authorization_hdr*)pjsip_msg_find_hdr(msg,htype,h_auth);
    }

    /* Work out the status code and return code.  Because there may have been
     * multiple authorization headers, we have an order of precedence:
     * Success > forbidden > invalid auth scheme > no auth
     */
    *status_code = succeeded ? 200 :
                   forbidden ? PJSIP_SC_FORBIDDEN :
                   auth_srv->is_proxy ? 407 : 401;
    return succeeded ? PJ_SUCCESS :
	   forbidden ? status :
	   invalid_auth_scheme ? PJSIP_EINVALIDAUTHSCHEME :
	   PJSIP_EAUTHNOAUTH;
}