diff options
author | Kevin Harwell <kharwell@digium.com> | 2017-12-20 16:17:40 -0600 |
---|---|---|
committer | Kevin Harwell <kharwell@digium.com> | 2017-12-22 15:38:56 -0600 |
commit | 53799318bc040a2082904df86d42ab08790b47ec (patch) | |
tree | dc70a7d09fe65fecd32d5d0e31ce7b723ef4babd | |
parent | ce3d56920b15facbb64b3caf0d823a3f57c0dded (diff) |
AST-2017-014: res_pjsip - Missing contact header can cause crash
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
-rw-r--r-- | res/res_pjsip.c | 2 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_message_filter.c | 18 | ||||
-rw-r--r-- | res/res_pjsip_pubsub.c | 8 |
3 files changed, 22 insertions, 6 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 1fce19b8a..392f9a6f2 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -3241,7 +3241,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; } diff --git a/res/res_pjsip/pjsip_message_filter.c b/res/res_pjsip/pjsip_message_filter.c index 085d9787e..427aec740 100644 --- a/res/res_pjsip/pjsip_message_filter.c +++ b/res/res_pjsip/pjsip_message_filter.c @@ -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; diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index d921aa388..88005b85c 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -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 |