res_pjsip: Validate that contact uris start with sip: or sips:
authorGeorge Joseph <george.joseph@fairview5.com>
Thu, 23 Apr 2015 14:16:45 +0000 (08:16 -0600)
committerGeorge Joseph <george.joseph@fairview5.com>
Thu, 23 Apr 2015 16:54:59 +0000 (11:54 -0500)
Currently we use pjsip_parse_hdr to validate contact uris but it
appears that it allows uris without a scheme if there's a port
supplied.  I.E myexample.com will fail but myexample.com:5060 will
pass even though it has no scheme.  This causes SEGVs later on
whenever the uri is used.

To prevent this, permanent_contact_validate has been updated to check
that the scheme is either 'sip' or 'sips'.

2 uses of possibly-null endpoint have also been fixed in
create_out_of_dialog_request.

ASTERISK-24999

Change-Id: Ifc17d16a4923e1045d37fe51e43bbe29fa556ca2
Reported-by: Brad Latus

res/res_pjsip.c
res/res_pjsip/location.c

index 2bc5abd..a613bcc 100644 (file)
@@ -2723,7 +2723,8 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s
        if (sip_dialog_create_from(pool, &from, endpoint ? endpoint->fromuser : NULL,
                                endpoint ? endpoint->fromdomain : NULL, &remote_uri, &selector)) {
                ast_log(LOG_ERROR, "Unable to create From header for %.*s request to endpoint %s\n",
-                               (int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint));
+                               (int) pj_strlen(&method->name), pj_strbuf(&method->name),
+                               endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
                pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
                return -1;
        }
@@ -2731,7 +2732,8 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s
        if (pjsip_endpt_create_request(ast_sip_get_pjsip_endpoint(), method, &remote_uri,
                        &from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
                ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s\n",
-                               (int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint));
+                               (int) pj_strlen(&method->name), pj_strbuf(&method->name),
+                               endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
                pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
                return -1;
        }
index 2165041..45370dd 100644 (file)
@@ -290,6 +290,8 @@ static int permanent_contact_validate(void *data)
        pj_pool_t *pool;
        pj_str_t contact_uri;
        static const pj_str_t HCONTACT = { "Contact", 7 };
+       pjsip_contact_hdr *contact_hdr;
+       int rc = 0;
 
        pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Permanent Contact Validation", 256, 256);
        if (!pool) {
@@ -297,13 +299,14 @@ static int permanent_contact_validate(void *data)
        }
 
        pj_strdup2_with_null(pool, &contact_uri, value);
-       if (!pjsip_parse_hdr(pool, &HCONTACT, contact_uri.ptr, contact_uri.slen, NULL)) {
-               pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
-               return -1;
+       if (!(contact_hdr = pjsip_parse_hdr(pool, &HCONTACT, contact_uri.ptr, contact_uri.slen, NULL))
+               || !(PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri)
+                       || PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri))) {
+               rc = -1;
        }
 
        pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
-       return 0;
+       return rc;
 }
 
 static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)