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. */
    if (auth_srv->lookup2) {
	pjsip_auth_lookup_cred_param param;

	pj_bzero(&param, sizeof(param));
	param.realm = auth_srv->realm;
	param.acc_name = acc_name;
	param.rdata = rdata;
	status = (*auth_srv->lookup2)(rdata->tp_info.pool, &param, &cred_info);
	if (status != PJ_SUCCESS) {
	    *status_code = PJSIP_SC_FORBIDDEN;
	    return status;
	}
    } else {
	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_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;

     
    *status_code = 200;

     
    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;
    }

     
    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;
    }

     
    if (auth_srv->lookup2) {
	pjsip_auth_lookup_cred_param param;

	pj_bzero(&param, sizeof(param));
	param.realm = auth_srv->realm;
	param.acc_name = acc_name;
	param.rdata = rdata;
	status = (*auth_srv->lookup2)(rdata->tp_info.pool, &param, &cred_info);
	if (status != PJ_SUCCESS) {
	    *status_code = PJSIP_SC_FORBIDDEN;
	    return status;
	}
    } else {
	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;
	}
    }

     
    status = pjsip_auth_verify(h_auth, &msg->line.req.method.name, 
			       &cred_info);
    if (status != PJ_SUCCESS) {
	*status_code = PJSIP_SC_FORBIDDEN;
    }
    return status;
}