]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip: Ensure more URI validation happens in pj threads.
authorJoshua Colp <jcolp@digium.com>
Fri, 3 Jan 2014 17:27:08 +0000 (17:27 +0000)
committerJoshua Colp <jcolp@digium.com>
Fri, 3 Jan 2014 17:27:08 +0000 (17:27 +0000)
........

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
res/res_pjsip/pjsip_configuration.c

index 3bd4dea104e7dae4cd49c46062fe4a81a11d4c11..31eaeeee468dd033472908c94d400d9a45c36f70 100644 (file)
@@ -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))) {
index 3a1edab607bb2f237dd013012b15044ea44c228e..e5604380eaddea6a0d8a0373f890bef501fe61d0 100644 (file)
@@ -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;