/*! * \brief Check authentication using Digest scheme * * This function will check an incoming message against configured authentication * options. If \b any of the incoming Authorization headers result in successful * authentication, then authentication is considered successful. * * \see ast_sip_check_authentication */ static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata) { struct ast_sip_auth **auths; enum digest_verify_result *verify_res; enum ast_sip_check_auth_result res; int i; int failures = 0; size_t auth_size; RAII_VAR(struct ast_sip_endpoint *, artificial_endpoint, ast_sip_get_artificial_endpoint(), ao2_cleanup); auth_size = AST_VECTOR_SIZE(&endpoint->inbound_auths); auths = ast_alloca(auth_size * sizeof(*auths)); verify_res = ast_alloca(auth_size * sizeof(*verify_res)); if (!auths) { return AST_SIP_AUTHENTICATION_ERROR; } if (endpoint == artificial_endpoint) { auths[0] = ast_sip_get_artificial_auth(); } else if (ast_sip_retrieve_auths(&endpoint->inbound_auths, auths)) { res = AST_SIP_AUTHENTICATION_ERROR; goto cleanup; } for (i = 0; i < auth_size; ++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; goto cleanup; } if (verify_res[i] == AUTH_FAIL) { failures++; } } for (i = 0; i < auth_size; ++i) { challenge(auths[i]->realm, tdata, rdata, verify_res[i] == AUTH_STALE); } if (failures == auth_size) { res = AST_SIP_AUTHENTICATION_FAILED; } else { res = AST_SIP_AUTHENTICATION_CHALLENGE; } cleanup: ast_sip_cleanup_auths(auths, auth_size); return res; }
static void global_loaded(const char *object_type) { char default_realm[MAX_REALM_LENGTH + 1]; struct ast_sip_auth *fake_auth; char *identifier_order; /* Update using_auth_username */ identifier_order = ast_sip_get_endpoint_identifier_order(); if (identifier_order) { char *identify_method; char *io_copy = ast_strdupa(identifier_order); int new_using = 0; ast_free(identifier_order); while ((identify_method = ast_strip(strsep(&io_copy, ",")))) { if (!strcmp(identify_method, "auth_username")) { new_using = 1; break; } } using_auth_username = new_using; } /* Update default_realm of artificial_auth */ ast_sip_get_default_realm(default_realm, sizeof(default_realm)); fake_auth = ast_sip_get_artificial_auth(); if (!fake_auth || strcmp(fake_auth->realm, default_realm)) { ao2_cleanup(fake_auth); fake_auth = alloc_artificial_auth(default_realm); if (fake_auth) { ao2_global_obj_replace_unref(artificial_auth, fake_auth); } } ao2_cleanup(fake_auth); ast_sip_get_unidentified_request_thresholds(&unidentified_count, &unidentified_period, &unidentified_prune_interval); /* Clean out the old task, if any */ ast_sched_clean_by_callback(prune_context, prune_task, clean_task); /* Have to do something with the return value to shut up the stupid compiler. */ if (ast_sched_add_variable(prune_context, unidentified_prune_interval * 1000, prune_task, NULL, 1) < 0) { return; } }