From: Ben Ford Date: Mon, 2 Nov 2020 16:29:31 +0000 (-0600) Subject: AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit. X-Git-Tag: 17.8.1~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2de5dddaac9dc99fb6c99fcedf5a796cc595e371;p=thirdparty%2Fasterisk.git AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit. If Asterisk sends out an INVITE and receives a challenge with a different nonce value each time, it will continuously send out INVITEs, even if the call is hung up. The endpoint must be configured for outbound authentication for this to occur. A limit has been set on outbound INVITEs so that, once reached, Asterisk will stop sending INVITEs and the transaction will terminate. ASTERISK-29013 Change-Id: I2d001ca745b00ca8aa12030f2240cd72363b46f7 --- diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 1daf166de7..635f511081 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -77,6 +77,9 @@ struct pjsip_tpselector; AST_VECTOR(ast_sip_service_route_vector, char *); +/*! Maximum number of challenges before assuming that we are in a loop */ +#define MAX_RX_CHALLENGES 10 + /*! * \brief Structure for SIP transport information */ diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index d8b215e53d..bdced250d1 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -219,8 +219,10 @@ struct ast_sip_session { enum ast_sip_dtmf_mode dtmf; /*! Initial incoming INVITE Request-URI. NULL otherwise. */ pjsip_uri *request_uri; - /* Media statistics for negotiated RTP streams */ + /*! Media statistics for negotiated RTP streams */ AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats; + /*! Number of challenges received during outgoing requests to determine if we are in a loop */ + unsigned int authentication_challenge_count:4; }; typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata); diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 3936a25ced..8cccd2ac50 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -4116,8 +4116,6 @@ static pj_bool_t does_method_match(const pj_str_t *message_method, const char *s return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE; } -/*! Maximum number of challenges before assuming that we are in a loop */ -#define MAX_RX_CHALLENGES 10 #define TIMER_INACTIVE 0 #define TIMEOUT_TIMER2 5 diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index e1e917443e..89df631d22 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2222,7 +2222,6 @@ static pjsip_module session_reinvite_module = { .on_rx_request = session_reinvite_on_rx_request, }; - void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata, ast_sip_session_response_cb on_response) { @@ -2474,6 +2473,9 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, return NULL; } + /* Track the number of challenges received on outbound requests */ + session->authentication_challenge_count = 0; + /* Fire seesion begin handlers */ handle_session_begin(session); @@ -2643,6 +2645,11 @@ static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata) session = inv->mod_data[session_module.id]; + if (++session->authentication_challenge_count > MAX_RX_CHALLENGES) { + ast_debug(3, "%s: Initial INVITE reached maximum number of auth attempts.\n", ast_sip_session_get_name(session)); + return PJ_FALSE; + } + if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata, tsx->last_tx, &tdata)) { return PJ_FALSE; @@ -4090,6 +4097,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans ast_debug(1, "reINVITE received final response code %d\n", tsx->status_code); if ((tsx->status_code == 401 || tsx->status_code == 407) + && ++session->authentication_challenge_count < MAX_RX_CHALLENGES && !ast_sip_create_request_with_auth( &session->endpoint->outbound_auths, e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) { @@ -4184,6 +4192,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans (int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name), tsx->status_code); if ((tsx->status_code == 401 || tsx->status_code == 407) + && ++session->authentication_challenge_count < MAX_RX_CHALLENGES && !ast_sip_create_request_with_auth( &session->endpoint->outbound_auths, e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {