From 4dc0593088419a73f1551a6d690e1cd5bfe1cc0e Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 2 Jun 2010 03:03:43 +0000 Subject: Fixed #1092 (Crash when receiving various messages with "Contact: *" header format) git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3190 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsip-ua/sip_inv.c | 22 ++++++++++++++++++++++ pjsip/src/pjsip/sip_dialog.c | 36 ++++++++++++++++++++---------------- pjsip/src/pjsua-lib/pjsua_acc.c | 9 ++++++--- pjsip/src/pjsua-lib/pjsua_im.c | 2 +- pjsip/src/pjsua-lib/pjsua_pres.c | 2 +- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index eb2c20f3..94ec987e 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -750,6 +750,7 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata, pjsip_allow_hdr *allow; pjsip_supported_hdr *sup_hdr; pjsip_require_hdr *req_hdr; + pjsip_contact_hdr *c_hdr; int code = 200; unsigned rem_option = 0; pj_status_t status = PJ_SUCCESS; @@ -784,6 +785,27 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata, /* Init response header list */ pj_list_init(&res_hdr_list); + /* Check the Contact header */ + c_hdr = (pjsip_contact_hdr*) + pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL); + if (!c_hdr || !c_hdr->uri) { + /* Missing Contact header or Contact contains "*" */ + pjsip_warning_hdr *w; + pj_str_t warn_text; + + warn_text = pj_str("Bad/missing Contact header"); + w = pjsip_warning_hdr_create(rdata->tp_info.pool, 399, + pjsip_endpt_name(endpt), + &warn_text); + if (w) { + pj_list_push_back(&res_hdr_list, w); + } + + code = PJSIP_SC_BAD_REQUEST; + status = PJSIP_ERRNO_FROM_SIP_STATUS(code); + goto on_return; + } + /* Check the request body, see if it's something that we support, * only when the body hasn't been parsed before. */ diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c index 2cfeca0d..c46e84ec 100644 --- a/pjsip/src/pjsip/sip_dialog.c +++ b/pjsip/src/pjsip/sip_dialog.c @@ -432,8 +432,9 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua, pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, pos); if (contact_hdr) { - if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && - !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) + if (!contact_hdr->uri || + (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && + !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri))) { pos = (pjsip_hdr*)contact_hdr->next; if (pos == &rdata->msg_info.msg->hdr) @@ -611,7 +612,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg, /* Find Contact header in the response */ contact = (const pjsip_contact_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL); - if (contact == NULL) + if (contact == NULL || contact->uri == NULL) return PJSIP_EMISSINGHDR; /* Create the dialog. */ @@ -1501,7 +1502,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_respond( pjsip_dialog *dlg, } -/* This function is called by user agent upon receiving incoming response +/* This function is called by user agent upon receiving incoming request * message. */ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata ) @@ -1588,10 +1589,11 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata ) contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); - if (contact && (dlg->remote.contact==NULL || - pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, - dlg->remote.contact->uri, - contact->uri))) + if (contact && contact->uri && + (dlg->remote.contact==NULL || + pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, + dlg->remote.contact->uri, + contact->uri))) { dlg->remote.contact = (pjsip_contact_hdr*) pjsip_hdr_clone(dlg->pool, contact); @@ -1793,10 +1795,11 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); - if (contact && (dlg->remote.contact==NULL || - pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, - dlg->remote.contact->uri, - contact->uri))) + if (contact && contact->uri && + (dlg->remote.contact==NULL || + pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, + dlg->remote.contact->uri, + contact->uri))) { dlg->remote.contact = (pjsip_contact_hdr*) pjsip_hdr_clone(dlg->pool, contact); @@ -1843,10 +1846,11 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata ) contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); - if (contact && (dlg->remote.contact==NULL || - pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, - dlg->remote.contact->uri, - contact->uri))) + if (contact && contact->uri && + (dlg->remote.contact==NULL || + pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, + dlg->remote.contact->uri, + contact->uri))) { dlg->remote.contact = (pjsip_contact_hdr*) pjsip_hdr_clone(dlg->pool, contact); diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index ba46d368..ad25152f 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -2237,9 +2237,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, pos); if (h_contact) { - uri = (pjsip_uri*) pjsip_uri_get_uri(h_contact->uri); - if (!PJSIP_URI_SCHEME_IS_SIP(uri) && - !PJSIP_URI_SCHEME_IS_SIPS(uri)) + if (h_contact->uri) + uri = (pjsip_uri*) pjsip_uri_get_uri(h_contact->uri); + else + uri = NULL; + if (!uri || (!PJSIP_URI_SCHEME_IS_SIP(uri) && + !PJSIP_URI_SCHEME_IS_SIPS(uri))) { pos = (pjsip_hdr*)h_contact->next; if (pos == &rdata->msg_info.msg->hdr) diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c index 282f7311..3be344d4 100644 --- a/pjsip/src/pjsua-lib/pjsua_im.c +++ b/pjsip/src/pjsua-lib/pjsua_im.c @@ -169,7 +169,7 @@ void pjsua_im_process_pager(int call_id, const pj_str_t *from, contact_hdr = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); - if (contact_hdr) { + if (contact_hdr && contact_hdr->uri) { contact.ptr = (char*) pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE); contact.slen = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 620c7cd7..651dad19 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -1610,7 +1610,7 @@ static void pjsua_evsub_on_tsx_state(pjsip_evsub *sub, contact_hdr = (pjsip_contact_hdr*) pjsip_msg_find_hdr(event->body.rx_msg.rdata->msg_info.msg, PJSIP_H_CONTACT, NULL); - if (!contact_hdr) { + if (!contact_hdr || !contact_hdr->uri) { return; } -- cgit v1.2.3