Index: res/res_pjsip/config_auth.c =================================================================== --- res/res_pjsip/config_auth.c (revision 398279) +++ res/res_pjsip/config_auth.c (working copy) @@ -117,7 +117,7 @@ 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", Index: res/res_pjsip_authenticator_digest.c =================================================================== --- res/res_pjsip_authenticator_digest.c (revision 398279) +++ res/res_pjsip_authenticator_digest.c (working copy) @@ -395,6 +395,9 @@ } 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; Index: res/res_pjsip_outbound_authenticator_digest.c =================================================================== --- res/res_pjsip_outbound_authenticator_digest.c (revision 398279) +++ res/res_pjsip_outbound_authenticator_digest.c (working copy) @@ -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 @@ 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 @@ 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; }