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
18.0
Ben Ford 5 years ago committed by Kevin Harwell
parent eed50a17e5
commit 7d33320cbe

@ -78,6 +78,9 @@ struct pjsip_tpselector;
AST_VECTOR(ast_sip_service_route_vector, char *); 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 * \brief Structure for SIP transport information
*/ */

@ -233,6 +233,8 @@ struct ast_sip_session {
AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats; AST_VECTOR(, struct ast_rtp_instance_stats *) media_stats;
/*! The direction of the call respective to Asterisk */ /*! The direction of the call respective to Asterisk */
enum ast_sip_session_call_direction call_direction; enum ast_sip_session_call_direction call_direction;
/*! 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); typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);

@ -4445,8 +4445,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; 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 TIMER_INACTIVE 0
#define TIMEOUT_TIMER2 5 #define TIMEOUT_TIMER2 5

@ -2246,7 +2246,6 @@ static pjsip_module session_reinvite_module = {
.on_rx_request = session_reinvite_on_rx_request, .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, void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
ast_sip_session_response_cb on_response) ast_sip_session_response_cb on_response)
{ {
@ -2499,6 +2498,9 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
return NULL; return NULL;
} }
/* Track the number of challenges received on outbound requests */
session->authentication_challenge_count = 0;
/* Fire seesion begin handlers */ /* Fire seesion begin handlers */
handle_session_begin(session); handle_session_begin(session);
@ -2668,6 +2670,11 @@ static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
session = inv->mod_data[session_module.id]; 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, if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata,
tsx->last_tx, &tdata)) { tsx->last_tx, &tdata)) {
return PJ_FALSE; return PJ_FALSE;
@ -4181,6 +4188,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", ast_debug(1, "reINVITE received final response code %d\n",
tsx->status_code); tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407) if ((tsx->status_code == 401 || tsx->status_code == 407)
&& ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth( && !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths, &session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) { e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {
@ -4275,6 +4283,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), (int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
tsx->status_code); tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407) if ((tsx->status_code == 401 || tsx->status_code == 407)
&& ++session->authentication_challenge_count < MAX_RX_CHALLENGES
&& !ast_sip_create_request_with_auth( && !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths, &session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) { e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {

Loading…
Cancel
Save