From bbf5fbbd8c6aa4ec2e8b48da1926b24a32632ca5 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 13 Sep 2013 14:44:43 +0000 Subject: Change how realms are handled for outbound authentication. With this change, if no realm is specified in an outbound auth section, then we will simply match the realm that was present in the 401/407 challenge. (closes issue ASTERISK-22471) Reported by George Joseph (closes issue ASTERISK-22386) Reported by Rusty Newton Patches: outbound_auth_realm_v4.patch uploaded by George Joseph (License #6322) ........ Merged revisions 399059 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@399082 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/res_pjsip/config_auth.c | 2 +- res/res_pjsip_authenticator_digest.c | 3 +++ res/res_pjsip_outbound_authenticator_digest.c | 37 ++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/res/res_pjsip/config_auth.c b/res/res_pjsip/config_auth.c index e5deb2d89..860f33b56 100644 --- a/res/res_pjsip/config_auth.c +++ b/res/res_pjsip/config_auth.c @@ -117,7 +117,7 @@ int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery) ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "md5_cred", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds)); ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "realm", - "asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm)); + "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm)); ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime", "32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime)); ast_sorcery_object_field_register_custom(sorcery, SIP_SORCERY_AUTH_TYPE, "auth_type", diff --git a/res/res_pjsip_authenticator_digest.c b/res/res_pjsip_authenticator_digest.c index b2c6cccb4..cc312b1e0 100644 --- a/res/res_pjsip_authenticator_digest.c +++ b/res/res_pjsip_authenticator_digest.c @@ -395,6 +395,9 @@ static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint } for (i = 0; i < endpoint->inbound_auths.num; ++i) { + if (ast_strlen_zero(auths[i]->realm)) { + ast_string_field_set(auths[i], realm, "asterisk"); + } verify_res[i] = verify(auths[i], rdata, tdata->pool); if (verify_res[i] == AUTH_SUCCESS) { res = AST_SIP_AUTHENTICATION_SUCCESS; diff --git a/res/res_pjsip_outbound_authenticator_digest.c b/res/res_pjsip_outbound_authenticator_digest.c index 3072db18a..58eae5550 100644 --- a/res/res_pjsip_outbound_authenticator_digest.c +++ b/res/res_pjsip_outbound_authenticator_digest.c @@ -31,10 +31,30 @@ #include "asterisk/module.h" #include "asterisk/strings.h" -static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, const struct ast_sip_auth_array *array) +static pjsip_www_authenticate_hdr *get_auth_header(pjsip_rx_data *challenge) { + pjsip_hdr_e search_type; + + if (challenge->msg_info.msg->line.status.code == PJSIP_SC_UNAUTHORIZED) { + search_type = PJSIP_H_WWW_AUTHENTICATE; + } else if (challenge->msg_info.msg->line.status.code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) { + search_type = PJSIP_H_PROXY_AUTHENTICATE; + } else { + ast_log(LOG_ERROR, + "Status code %d was received when it should have been 401 or 407.\n", + challenge->msg_info.msg->line.status.code); + return NULL ; + } + + return pjsip_msg_find_hdr(challenge->msg_info.msg, search_type, NULL); + +} + +static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, + const struct ast_sip_auth_array *array, pjsip_rx_data *challenge) { struct ast_sip_auth **auths = ast_alloca(array->num * sizeof(*auths)); pjsip_cred_info *auth_creds = ast_alloca(array->num * sizeof(*auth_creds)); + pjsip_www_authenticate_hdr *auth_hdr = NULL; int res = 0; int i; @@ -43,8 +63,19 @@ static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_ses goto cleanup; } + auth_hdr = get_auth_header(challenge); + if (auth_hdr == NULL) { + res = -1; + ast_log(LOG_ERROR, "Unable to find authenticate header in challenge.\n"); + goto cleanup; + } + for (i = 0; i < array->num; ++i) { - pj_cstr(&auth_creds[i].realm, auths[i]->realm); + if (ast_strlen_zero(auths[i]->realm)) { + pj_cstr(&auth_creds[i].realm, auth_hdr->challenge.common.realm.ptr); + } else { + pj_cstr(&auth_creds[i].realm, auths[i]->realm); + } pj_cstr(&auth_creds[i].username, auths[i]->auth_user); pj_cstr(&auth_creds[i].scheme, "digest"); switch (auths[i]->type) { @@ -80,7 +111,7 @@ static int digest_create_request_with_auth(const struct ast_sip_auth_array *auth return -1; } - if (set_outbound_authentication_credentials(&auth_sess, auths)) { + if (set_outbound_authentication_credentials(&auth_sess, auths, challenge)) { ast_log(LOG_WARNING, "Failed to set authentication credentials\n"); return -1; } -- cgit v1.2.3