]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2017-014: res_pjsip - Missing contact header can cause crash
authorKevin Harwell <kharwell@digium.com>
Wed, 20 Dec 2017 22:17:40 +0000 (16:17 -0600)
committerKevin Harwell <kharwell@digium.com>
Fri, 22 Dec 2017 21:39:07 +0000 (15:39 -0600)
Those SIP messages that create dialogs require a contact header to be present.
If the contact header was missing from the message it could cause Asterisk to
crash.

This patch checks to make sure SIP messages that create a dialog contain the
contact header. If the message does not and it is required Asterisk now returns
a "400 Missing Contact header" response. Also added NULL checks when retrieving
the contact header that were missing as a "just in case".

ASTERISK-27480 #close

Change-Id: I1810db87683fc637a9e3e1384a746037fec20afe

res/res_pjsip.c
res/res_pjsip/pjsip_message_filter.c
res/res_pjsip_pubsub.c

index 9e436ae3c72655d9de7cdabaf77c36a4d2f2cf85..4392677e0e38bd6a2d0930d68b6808eeced03fd3 100644 (file)
@@ -3224,7 +3224,7 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
        ast_assert(status != NULL);
 
        contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
-       if (ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
+       if (!contact_hdr || ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
                &selector)) {
                return NULL;
        }
index 978aeb0704b12b7193d08fba39eb5a406b3410c9..8a6321979d14af82efcca5bf3546e952495e3608 100644 (file)
@@ -429,15 +429,27 @@ static pj_bool_t on_rx_process_uris(pjsip_rx_data *rdata)
                return PJ_TRUE;
        }
 
-       while ((contact =
-               (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
-                       contact ? contact->next : NULL))) {
+
+       contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(
+               rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
+
+       if (!contact && pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method)) {
+               /* A contact header is required for dialog creating methods */
+               static const pj_str_t missing_contact = { "Missing Contact header", 22 };
+               pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400,
+                               &missing_contact, NULL, NULL);
+               return PJ_TRUE;
+       }
+
+       while (contact) {
                if (!contact->star && !is_sip_uri(contact->uri)) {
                        print_uri_debug(URI_TYPE_CONTACT, rdata, (pjsip_hdr *)contact);
                        pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata,
                                PJSIP_SC_UNSUPPORTED_URI_SCHEME, NULL, NULL, NULL);
                        return PJ_TRUE;
                }
+               contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(
+                       rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next);
        }
 
        return PJ_FALSE;
index bcf8677284cebaf35de8ef9f9efd68bcdf116445..ba89d042b7dcc6570035477cf8d1265e8bcc696a 100644 (file)
@@ -613,8 +613,12 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
                expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
                sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
 
-               pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
-                       sub_tree->persistence->contact_uri, sizeof(sub_tree->persistence->contact_uri));
+               if (contact_hdr) {
+                       pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, contact_hdr->uri,
+                                       sub_tree->persistence->contact_uri, sizeof(sub_tree->persistence->contact_uri));
+               } else {
+                       ast_log(LOG_WARNING, "Contact not updated due to missing contact header\n");
+               }
 
                /* When receiving a packet on an streaming transport, it's possible to receive more than one SIP
                 * message at a time into the rdata->pkt_info.packet buffer. However, the rdata->msg_info.msg_buf