/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm, pv_spec_t * _uri_user, hdr_types_t _hftype) { int res; auth_cfg_result_t ret; struct hdr_field* h; auth_body_t* cred; str *uri_user; str user, domain; pv_value_t pv_val; cred = 0; ret = -1; user.s = 0; /* get pre_auth domain from _realm pvar (if exists) */ if (_realm) { if (pv_printf_s(_msg, _realm, &domain) != 0) { LM_ERR("pv_printf_s failed\n"); return -5; } } else { domain.len = 0; domain.s = 0; } switch(auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif ret = -7; goto end; case NONCE_REUSED: ret = AUTH_NONCE_REUSED; goto end; case STALE_NONCE: ret = AUTH_STALE_NONCE; goto end; case ERROR: case BAD_CREDENTIALS: case NOT_AUTHENTICATED: ret = AUTH_ERROR; goto end; case NO_CREDENTIALS: ret = AUTH_NO_CREDENTIALS; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = AUTH_OK; goto end; } cred = (auth_body_t*)h->parsed; /* get uri_user from _uri_user pvap (if exists) or from To/From URI */ if (_uri_user) { if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) { if (pv_val.flags & PV_VAL_STR) { res = radius_authorize_sterman(_msg, &cred->digest, &_msg-> first_line.u.request.method, &pv_val.rs); } else { LM_ERR("uri_user pvar value is not string\n"); ret = AUTH_ERROR; goto end; } } else { LM_ERR("cannot get uri_user pvar value\n"); ret = AUTH_ERROR; goto end; } } else { if (get_uri_user(_msg, &uri_user) < 0) { LM_ERR("To/From URI not found\n"); ret = AUTH_ERROR;; goto end; } user.s = (char *)pkg_malloc(uri_user->len); if (user.s == NULL) { LM_ERR("no pkg memory left for user\n"); ret = -7; goto end; } un_escape(uri_user, &user); res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user); } if (res == 1) { switch(auth_api.post_auth(_msg, h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(_msg, &domain, _hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif ret = -7; break; case ERROR: case NOT_AUTHENTICATED: ret = AUTH_ERROR; break; case AUTHENTICATED: ret = AUTH_OK; break; } } else { ret = AUTH_INVALID_PASSWORD; } end: if (user.s) pkg_free(user.s); if (ret < 0) { if (auth_api.build_challenge(_msg, (cred ? cred->stale : 0), &domain, NULL, NULL, _hftype) < 0) { LM_ERR("while creating challenge\n"); ret = -7; } } return ret; }
/* * Authorize digest credentials */ static inline int authenticate(struct sip_msg* msg, str* realm, hdr_types_t hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str* uri; struct sip_uri puri; str user, did; VALUE_PAIR* received; cred = 0; ret = -1; user.s = 0; received = NULL; switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(msg, realm, hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif case ERROR: case BAD_CREDENTIALS: ret = -3; goto end; case NOT_AUTHENTICATED: ret = -1; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = 1; goto end; } cred = (auth_body_t*)h->parsed; if (use_did) { if (msg->REQ_METHOD == METHOD_REGISTER) { ret = get_to_did(&did, msg); } else { ret = get_from_did(&did, msg); } if (ret == 0) { did.s = DEFAULT_DID; did.len = sizeof(DEFAULT_DID) - 1; } } else { did.len = 0; did.s = 0; } if (get_uri(msg, &uri) < 0) { LOG(L_ERR, "authorize(): From/To URI not found\n"); ret = -1; goto end; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "authorize(): Error while parsing From/To URI\n"); ret = -1; goto end; } user.s = (char *)pkg_malloc(puri.user.len); if (user.s == NULL) { LOG(L_ERR, "authorize: No memory left\n"); ret = -1; goto end; } un_escape(&(puri.user), &user); res = radius_authorize_sterman(&received, msg, &cred->digest, &msg->first_line.u.request.method, &user); if (res == 1) { switch(auth_api.post_auth(msg, h)) { case ERROR: case BAD_CREDENTIALS: ret = -2; break; case NOT_AUTHENTICATED: ret = -1; break; case AUTHENTICATED: if (generate_avps(received) < 0) { ret = -1; break; } ret = 1; break; default: ret = -1; break; } } else { ret = -1; } end: if (received) rc_avpair_free(received); if (user.s) pkg_free(user.s); if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; } } return ret; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, str* _realm, int _hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str* uri; struct sip_uri puri; str user, domain; domain = *_realm; ret = pre_auth_func(_msg, &domain, _hftype, &h); switch(ret) { case ERROR: return 0; case NOT_AUTHORIZED: return -1; case DO_AUTHORIZATION: break; case AUTHORIZED: return 1; } cred = (auth_body_t*)h->parsed; if (get_uri(_msg, &uri) < 0) { LOG(L_ERR, "authorize(): From/To URI not found\n"); return -1; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "authorize(): Error while parsing From/To URI\n"); return -1; } if (puri.host.len != cred->digest.realm.len) { DBG("authorize(): Credentials realm and URI host do not match\n"); return -1; } if (strncasecmp(puri.host.s, cred->digest.realm.s, puri.host.len) != 0) { DBG("authorize(): Credentials realm and URI host do not match\n"); return -1; } user.s = (char *)pkg_malloc(puri.user.len); un_escape(&(puri.user), &user); /* Clear the rpid buffer from previous value */ rpid.len = 0; res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user, &rpid); pkg_free(user.s); if (res == 1) { ret = post_auth_func(_msg, h, &rpid); switch(ret) { case ERROR: return 0; case NOT_AUTHORIZED: return -1; case AUTHORIZED: return 1; default: return -1; } } return -1; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _msg, pv_elem_t* _realm, pv_spec_t * _uri_user, int _hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str *uri_user; str user, domain; pv_value_t pv_val; /* get pre_auth domain from _realm pvar (if exists) */ if (_realm) { if (pv_printf_s(_msg, _realm, &domain)!=0) { LM_ERR("pv_printf_s failed\n"); return AUTH_ERROR; } } else { /* get pre_auth domain from To/From header */ domain.len = 0; domain.s = 0; } ret = auth_api.pre_auth(_msg, &domain, _hftype, &h); if (ret != DO_AUTHORIZATION) return ret; cred = (auth_body_t*)h->parsed; /* get uri_user from _uri_user pvap (if exists) or from To/From URI */ if (_uri_user) { if (pv_get_spec_value(_msg, _uri_user, &pv_val) == 0) { if (pv_val.flags & PV_VAL_STR) { res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &pv_val.rs); } else { LM_ERR("uri_user pvar value is not string\n"); return AUTH_ERROR; } } else { LM_ERR("cannot get uri_user pvar value\n"); return AUTH_ERROR; } } else { if (get_uri_user(_msg, &uri_user) < 0) { LM_ERR("To/From URI not found\n"); return AUTH_ERROR; } user.s = (char *)pkg_malloc(uri_user->len); if (user.s == NULL) { LM_ERR("no pkg memory left for user\n"); return AUTH_ERROR; } un_escape(uri_user, &user); res = radius_authorize_sterman(_msg, &cred->digest, &_msg->first_line.u.request.method, &user); pkg_free(user.s); } if (res == 1) { ret = auth_api.post_auth(_msg, h); return ret; } return AUTH_ERROR; }