From 0ae89e7b7e52453b080e945817fe310dc0586b62 Mon Sep 17 00:00:00 2001 From: Joshua Colp Date: Fri, 3 Jan 2014 17:27:08 +0000 Subject: res_pjsip: Ensure more URI validation happens in pj threads. ........ Merged revisions 404737 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@404738 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/res_pjsip/location.c | 25 +++++++++++++------ res/res_pjsip/pjsip_configuration.c | 48 +++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 3bd4dea10..31eaeeee4 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -225,11 +225,10 @@ static int expiration_struct2str(const void *obj, const intptr_t *args, char **b return (ast_asprintf(buf, "%lu", contact->expiration_time.tv_sec) < 0) ? -1 : 0; } -/*! \brief Custom handler for permanent URIs */ -static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) +/*! \brief Helper function which validates a permanent contact */ +static int permanent_contact_validate(void *data) { - struct ast_sip_aor *aor = obj; - RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup); + const char *value = data; pj_pool_t *pool; pj_str_t contact_uri; static const pj_str_t HCONTACT = { "Contact", 7 }; @@ -239,15 +238,27 @@ static int permanent_uri_handler(const struct aco_option *opt, struct ast_variab return -1; } - pj_strdup2_with_null(pool, &contact_uri, var->value); + pj_strdup2_with_null(pool, &contact_uri, value); if (!pjsip_parse_hdr(pool, &HCONTACT, contact_uri.ptr, contact_uri.slen, NULL)) { - ast_log(LOG_ERROR, "Permanent URI on aor '%s' with contact '%s' failed to parse\n", - ast_sorcery_object_get_id(aor), var->value); pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); return -1; } pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); + return 0; +} + +/*! \brief Custom handler for permanent URIs */ +static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) +{ + struct ast_sip_aor *aor = obj; + RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup); + + if (ast_sip_push_task_synchronous(NULL, permanent_contact_validate, (char*)var->value)) { + ast_log(LOG_ERROR, "Permanent URI on aor '%s' with contact '%s' failed to parse\n", + ast_sorcery_object_get_id(aor), var->value); + return -1; + } if ((!aor->permanent_contacts && !(aor->permanent_contacts = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) || !(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", NULL))) { diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 3a1edab60..e5604380e 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -835,6 +835,29 @@ static struct ast_endpoint *persistent_endpoint_find_or_create(const struct ast_ return persistent->endpoint; } +/*! \brief Helper function which validates an outbound proxy */ +static int outbound_proxy_validate(void *data) +{ + const char *proxy = data; + pj_pool_t *pool; + pj_str_t tmp; + static const pj_str_t ROUTE_HNAME = { "Route", 5 }; + + pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Outbound Proxy Validation", 256, 256); + if (!pool) { + return -1; + } + + pj_strdup2_with_null(pool, &tmp, proxy); + if (!pjsip_parse_hdr(pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL)) { + pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); + return -1; + } + + pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); + return 0; +} + /*! \brief Callback function for when an object is finalized */ static int sip_endpoint_apply_handler(const struct ast_sorcery *sorcery, void *obj) { @@ -844,26 +867,11 @@ static int sip_endpoint_apply_handler(const struct ast_sorcery *sorcery, void *o return -1; } - if (!ast_strlen_zero(endpoint->outbound_proxy)) { - pj_pool_t *pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Outbound Proxy Validation", 256, 256); - static const pj_str_t ROUTE_HNAME = { "Route", 5 }; - pj_str_t tmp; - - if (!pool) { - ast_log(LOG_ERROR, "Could not allocate pool for outbound proxy validation on '%s'\n", - ast_sorcery_object_get_id(endpoint)); - return -1; - } - - pj_strdup2_with_null(pool, &tmp, endpoint->outbound_proxy); - if (!pjsip_parse_hdr(pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL)) { - ast_log(LOG_ERROR, "Invalid outbound proxy '%s' specified on endpoint '%s'\n", - endpoint->outbound_proxy, ast_sorcery_object_get_id(endpoint)); - pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); - return -1; - } - - pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool); + if (!ast_strlen_zero(endpoint->outbound_proxy) && + ast_sip_push_task_synchronous(NULL, outbound_proxy_validate, (char*)endpoint->outbound_proxy)) { + ast_log(LOG_ERROR, "Invalid outbound proxy '%s' specified on endpoint '%s'\n", + endpoint->outbound_proxy, ast_sorcery_object_get_id(endpoint)); + return -1; } return 0; -- cgit v1.2.3