]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2020-002 - res_pjsip: Stop sending INVITEs after challenge limit.
authorBen Ford <bford@digium.com>
Mon, 2 Nov 2020 16:29:31 +0000 (10:29 -0600)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Thu, 5 Nov 2020 16:30:26 +0000 (10:30 -0600)
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

include/asterisk/res_pjsip.h
include/asterisk/res_pjsip_session.h
res/res_pjsip.c
res/res_pjsip_session.c

index dee8d2d024547887140f6fb0e790569256a60b98..2047db3c9119a6e55a35dffa81f5448968827f07 100644 (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
  */
index 0f9a7998b365dd6a9511ec1a12046c9c90726b79..9c90a593ce129d6c330f80ad4c75f8e81c055386 100644 (file)
@@ -223,8 +223,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);
index 90438d444e565e7f21383a410a2c54c2fba34a8b..b6e5918ed2a6bf6f74f4c5dbcb00c6f2d8a025b8 100644 (file)
@@ -4055,8 +4055,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
 
index e8c8fdf4b74c4e56aa91c8389369e982f944716e..dce5f786abf43d2a6a7a779515ea1554b7e7eb49 100644 (file)
@@ -2848,7 +2848,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)
 {
@@ -3102,6 +3101,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);
 
@@ -3271,6 +3273,10 @@ static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
        }
        ast_debug(3, "%s: Initial INVITE is being challenged.\n", ast_sip_session_get_name(session));
 
+       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)) {
@@ -4638,6 +4644,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
                                                        ast_sip_session_get_name(session),
                                                        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)) {
@@ -4731,6 +4738,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)) {