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
This commit is contained in:
Ben Ford
2020-11-02 10:29:31 -06:00
parent a581fcfe0c
commit 01b7ac0d59
4 changed files with 17 additions and 3 deletions

View File

@@ -75,6 +75,9 @@ struct pjsip_tpselector;
/*! \brief Maximum number of ciphers supported for a TLS transport */
#define SIP_TLS_MAX_CIPHERS 64
/*! Maximum number of challenges before assuming that we are in a loop */
#define MAX_RX_CHALLENGES 10
/*!
* \brief Structure for SIP transport information
*/

View File

@@ -171,6 +171,8 @@ struct ast_sip_session {
pjsip_uri *request_uri;
/*! Joint capabilities */
struct ast_format_cap *joint_caps;
/*! 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);

View File

@@ -3833,8 +3833,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

View File

@@ -1210,7 +1210,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)
{
@@ -1508,12 +1507,17 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
ao2_ref(session, -1);
return NULL;
}
/* Track the number of challenges received on outbound requests */
session->authentication_challenge_count = 0;
AST_LIST_TRAVERSE(&session->supplements, iter, next) {
if (iter->session_begin) {
iter->session_begin(session);
}
}
/* Avoid unnecessary ref manipulation to return a session */
ret_session = session;
session = NULL;
@@ -1680,6 +1684,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, "Initial INVITE reached maximum number of auth attempts.\n");
return PJ_FALSE;
}
if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata, tsx,
&tdata)) {
return PJ_FALSE;
@@ -2882,6 +2891,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, &tdata)) {
@@ -2976,6 +2986,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, &tdata)) {