]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add list support for which vars/api to expand in httapi
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 9 Jan 2012 18:47:47 +0000 (12:47 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 9 Jan 2012 18:47:47 +0000 (12:47 -0600)
src/include/switch_channel.h
src/include/switch_event.h
src/mod/applications/mod_httapi/httapi.conf.xml
src/mod/applications/mod_httapi/mod_httapi.c
src/mod/applications/mod_httapi/mod_httapi_doc.txt
src/switch_channel.c
src/switch_event.c

index 94eb9e571d05680cd6bdf5254b6661f96950aae8..844013361e25b225172986aab851a392291e8909 100644 (file)
@@ -591,7 +591,10 @@ SWITCH_DECLARE(void) switch_channel_event_set_extended_data(_In_ switch_channel_
   \return the original string if no expansion takes place otherwise a new string that must be freed
   \note it's necessary to test if the return val is the same as the input and free the string if it is not.
 */
-SWITCH_DECLARE(char *) switch_channel_expand_variables(_In_ switch_channel_t *channel, _In_ const char *in);
+SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *channel, const char *in, switch_event_t *var_list, switch_event_t *api_list);
+#define switch_channel_expand_variables(_channel, _in) switch_channel_expand_variables_check(_channel, _in, NULL, NULL)
+
+
 SWITCH_DECLARE(char *) switch_channel_build_param_string(_In_ switch_channel_t *channel, _In_opt_ switch_caller_profile_t *caller_profile,
                                                                                                                 _In_opt_ const char *prefix);
 SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(_In_ switch_channel_t *channel);
index 23cd0825b5275c6e1d1446d8acaff52c44edfb69..c77e4aebb4a58fbfad75aa3c4f71547ff9cc9c94 100644 (file)
@@ -104,7 +104,8 @@ struct switch_event {
 
 typedef enum {
        EF_UNIQ_HEADERS = (1 << 0),
-       EF_NO_CHAT_EXEC = (1 << 1)
+       EF_NO_CHAT_EXEC = (1 << 1),
+       EF_DEFAULT_ALLOW = (1 << 2)
 } switch_event_flag_t;
 
 
@@ -329,7 +330,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_body(switch_event_t *event, con
 
 SWITCH_DECLARE(switch_status_t) switch_event_set_body(switch_event_t *event, const char *body);
 
-SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *in);
+SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list);
+#define switch_event_expand_headers(_event, _in) switch_event_expand_headers_check(_event, _in, NULL, NULL)
 
 SWITCH_DECLARE(switch_status_t) switch_event_create_pres_in_detailed(_In_z_ char *file, _In_z_ char *func, _In_ int line,
                                                                                                                                         _In_z_ const char *proto, _In_z_ const char *login,
@@ -399,7 +401,7 @@ SWITCH_DECLARE(void) switch_event_deliver(switch_event_t **event);
 #define switch_event_fire_data(event, data) switch_event_fire_detailed(__FILE__, (const char * )__SWITCH_FUNC__, __LINE__, event, data)
 
 SWITCH_DECLARE(char *) switch_event_build_param_string(switch_event_t *event, const char *prefix, switch_hash_t *vars_map);
-
+SWITCH_DECLARE(int) switch_event_check_permission_list(switch_event_t *list, const char *name);
 ///\}
 
 SWITCH_END_EXTERN_C
index dfd7d692fb4b99e19a87108446e1f3664491ee98..c2fe584a02d9eda8ba21ca75600ce40da31f470b 100644 (file)
        <!-- <permission name="all" value="true"/> -->
        <!--<permission name="none" value="true"/> -->
        <permission name="set-params" value="true"/>
-       <permission name="set-vars" value="false"/>
+       <permission name="set-vars" value="false">
+         <!-- default to "deny" or "allow" -->
+         <!-- type attr can be "deny" or "allow" nothing defaults to opposite of the list default so allow in this case -->
+         <!-- 
+         <variable-list default="deny">
+           <variable name="caller_id_name"/>
+           <variable name="hangup"/> 
+         </variable-list>
+         -->
+       </permission>
+       <permission name="get-vars" value="false">
+         <!-- default to "deny" or "allow" -->
+         <!-- type attr can be "deny" or "allow" nothing defaults to opposite of the list default so allow in this case -->
+         <!-- 
+         <variable-list default="deny">
+           <variable name="caller_id_name"/>
+           <variable name="hangup"/> 
+         </variable-list>
+         -->
+       </permission>
        <permission name="extended-data" value="false"/>
        <permission name="execute-apps" value="true">
          <!-- default to "deny" or "allow" -->
            <application name="hangup"/>
          </application-list>
        </permission>
-       <permission name="expand-vars-in-tag-body" value="false"/>
+       <permission name="expand-vars-in-tag-body" value="false">
+         <!-- default to "deny" or "allow" -->
+         <!-- type attr can be "deny" or "allow" nothing defaults to opposite of the list default so allow in this case -->
+         <!-- 
+         <variable-list default="deny">
+           <variable name="caller_id_name"/>
+           <variable name="hangup"/> 
+         </variable-list>
+
+         <api-list default="deny">
+           <api name="expr"/>
+           <api name="lua"/> 
+         </api-list>
+         -->
+       </permission>
        <permission name="dial" value="true"/>
        <permission name="dial-set-context" value="false"/>
        <permission name="dial-set-dialplan" value="false"/>
index 4465eb6162ff224d8014247897ef5db0402c8c09..6392167ec567d6671b4329a5604ac4d3ecab7df3 100644 (file)
@@ -38,6 +38,7 @@ SWITCH_MODULE_DEFINITION(mod_httapi, mod_httapi_load, mod_httapi_shutdown, NULL)
 typedef struct profile_perms_s {
        switch_byte_t set_params;
        switch_byte_t set_vars;
+       switch_byte_t get_vars;
        switch_byte_t extended_data;
        switch_byte_t execute_apps;
        switch_byte_t expand_vars;
@@ -99,6 +100,14 @@ typedef struct client_profile_s {
                int default_allow;
        } dial_params;
 
+       struct {
+               switch_event_t *expand_var_list;
+               switch_event_t *set_var_list;
+               switch_event_t *get_var_list;
+               switch_event_t *api_list;
+               int default_allow;
+       } var_params;
+
 } client_profile_t;
 
 #define HTTAPI_MAX_API_BYTES 1024 * 1024
@@ -259,6 +268,26 @@ static void console_clean_log(const char *level_str, const char *msg)
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, level, "%s", switch_str_nil(msg));
 }
 
+static switch_status_t parse_get_var(const char *tag_name, client_t *client, switch_xml_t tag, const char *body)
+{
+       const char *var = switch_xml_attr(tag, "name");
+       const char *perm = switch_xml_attr(tag, "permanent");
+
+
+       if (switch_event_check_permission_list(client->profile->var_params.get_var_list, var)) {
+               const char *vval = switch_channel_get_variable(client->channel, var);
+               if (vval) {
+                       switch_event_add_header_string(perm ? client->params : client->one_time_params, SWITCH_STACK_BOTTOM, var, vval);
+               }
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "variable %s permission denied!\n", var);
+               return SWITCH_STATUS_FALSE;
+       }
+
+       return SWITCH_STATUS_SUCCESS;
+       
+}
+
 static switch_status_t parse_continue(const char *tag_name, client_t *client, switch_xml_t tag, const char *body)
 {
        
@@ -648,29 +677,11 @@ static switch_status_t parse_sms(const char *tag_name, client_t *client, switch_
 
 static int check_app_perm(client_t *client, const char *app_name)
 {
-       const char *v;
-       int r = 0;
-
        if (!client->profile->perms.execute_apps) {
                return 0;
        }
 
-       if (!client->profile->dial_params.app_list) {
-               return 1;
-       }
-
-       if ((v = switch_event_get_header(client->profile->dial_params.app_list, app_name))) {
-               if (*v == 'd') {
-                       r = 0;
-               } else {
-                       r = 1;
-               }
-       } else {
-               r = client->profile->dial_params.default_allow;
-       }
-       
-
-       return r;
+       return switch_event_check_permission_list(client->profile->dial_params.app_list, app_name);
 }
 
 static switch_status_t parse_execute(const char *tag_name, client_t *client, switch_xml_t tag, const char *body)
@@ -997,7 +1008,11 @@ static switch_status_t parse_xml(client_t *client)
                                                        if (zstr(val)) {
                                                                val = NULL;
                                                        }
-                                                       switch_channel_set_variable(client->channel, tag->name, val);
+                                                       if (switch_event_check_permission_list(client->profile->var_params.set_var_list, tag->name)) {
+                                                               switch_channel_set_variable(client->channel, tag->name, val);
+                                                       } else {
+                                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "variable %s permission denied!\n", tag->name);
+                                                       }
                                                }
                                                tag = tag->sibling;
                                        }
@@ -1019,7 +1034,8 @@ static switch_status_t parse_xml(client_t *client)
                                                        if (tag->txt && client->profile->perms.expand_vars) {
                                                                switch_channel_get_variables(client->channel, &templ_data);
                                                                switch_event_merge(templ_data, client->params);
-                                                               expanded = switch_event_expand_headers(templ_data, tag->txt);
+                                                               expanded = switch_event_expand_headers_check(templ_data, tag->txt, 
+                                                                                                                                                        client->profile->var_params.expand_var_list, client->profile->var_params.api_list);
                                                                switch_event_destroy(&templ_data);
                                                        }
 
@@ -1639,6 +1655,60 @@ static switch_status_t do_config(void)
                                        profile->perms.set_params = switch_true(val);
                                } else if (!strcasecmp(var, "set-vars")) {
                                        profile->perms.set_vars = switch_true(val);
+
+                                       if (profile->perms.set_vars) {
+                                               switch_xml_t x_list, x_var;
+                                               if ((x_list = switch_xml_child(param, "variable-list"))) {
+                                                       char *var = (char *) switch_xml_attr_soft(param, "default");
+                                                       
+                                                       profile->var_params.default_allow = (var && !strcasecmp(var, "allow"));
+                                                       switch_event_create(&profile->var_params.set_var_list, SWITCH_EVENT_CLONE);
+                                                       profile->var_params.set_var_list->flags |= EF_UNIQ_HEADERS;
+                                                       if (profile->var_params.default_allow) {
+                                                               profile->var_params.set_var_list->flags |= EF_DEFAULT_ALLOW;
+                                                       }
+
+
+                                                       for (x_var = switch_xml_child(x_list, "variable"); x_var; x_var = x_var->next) {
+                                                               const char *name = switch_xml_attr(x_var, "name");
+                                                               const char *type = switch_xml_attr(x_var, "type");
+
+                                                               if (zstr(type)) type = profile->var_params.default_allow ? "deny" : "allow";
+
+                                                               if (name) {
+                                                                       switch_event_add_header_string(profile->var_params.set_var_list, SWITCH_STACK_BOTTOM, name, type);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               } else if (!strcasecmp(var, "get-vars")) {
+                                       profile->perms.get_vars = switch_true(val);
+
+                                       if (profile->perms.get_vars) {
+                                               switch_xml_t x_list, x_var;
+                                               if ((x_list = switch_xml_child(param, "variable-list"))) {
+                                                       char *var = (char *) switch_xml_attr_soft(param, "default");
+                                                       
+                                                       profile->var_params.default_allow = (var && !strcasecmp(var, "allow"));
+                                                       switch_event_create(&profile->var_params.get_var_list, SWITCH_EVENT_CLONE);
+                                                       profile->var_params.get_var_list->flags |= EF_UNIQ_HEADERS;
+                                                       if (profile->var_params.default_allow) {
+                                                               profile->var_params.get_var_list->flags |= EF_DEFAULT_ALLOW;
+                                                       }
+
+
+                                                       for (x_var = switch_xml_child(x_list, "variable"); x_var; x_var = x_var->next) {
+                                                               const char *name = switch_xml_attr(x_var, "name");
+                                                               const char *type = switch_xml_attr(x_var, "type");
+
+                                                               if (zstr(type)) type = profile->var_params.default_allow ? "deny" : "allow";
+
+                                                               if (name) {
+                                                                       switch_event_add_header_string(profile->var_params.get_var_list, SWITCH_STACK_BOTTOM, name, type);
+                                                               }
+                                                       }
+                                               }
+                                       }
                                } else if (!strcasecmp(var, "extended-data")) {
                                        profile->perms.extended_data = switch_true(val);
                                } else if (!strcasecmp(var, "execute-apps")) {
@@ -1652,6 +1722,10 @@ static switch_status_t do_config(void)
                                                        profile->dial_params.default_allow = (var && !strcasecmp(var, "allow"));
                                                        switch_event_create(&profile->dial_params.app_list, SWITCH_EVENT_CLONE);
                                                        profile->dial_params.app_list->flags |= EF_UNIQ_HEADERS;
+                                                       if (profile->dial_params.default_allow) {
+                                                               profile->dial_params.app_list->flags |= EF_DEFAULT_ALLOW;
+                                                       }
+
 
                                                        for (x_app = switch_xml_child(x_list, "application"); x_app; x_app = x_app->next) {
                                                                const char *name = switch_xml_attr(x_app, "name");
@@ -1668,6 +1742,56 @@ static switch_status_t do_config(void)
                                        
                                } else if (!strcasecmp(var, "expand-vars")) {
                                        profile->perms.expand_vars = switch_true(val);
+
+                                       if (profile->perms.expand_vars) {
+                                               switch_xml_t x_list, x_var, x_api;
+                                               if ((x_list = switch_xml_child(param, "variable-list"))) {
+                                                       char *var = (char *) switch_xml_attr_soft(param, "default");
+                                                       
+                                                       profile->var_params.default_allow = (var && !strcasecmp(var, "allow"));
+                                                       switch_event_create(&profile->var_params.expand_var_list, SWITCH_EVENT_CLONE);
+                                                       profile->var_params.expand_var_list->flags |= EF_UNIQ_HEADERS;
+                                                       if (profile->var_params.default_allow) {
+                                                               profile->var_params.expand_var_list->flags |= EF_DEFAULT_ALLOW;
+                                                       }
+
+
+                                                       for (x_var = switch_xml_child(x_list, "variable"); x_var; x_var = x_var->next) {
+                                                               const char *name = switch_xml_attr(x_var, "name");
+                                                               const char *type = switch_xml_attr(x_var, "type");
+
+                                                               if (zstr(type)) type = profile->var_params.default_allow ? "deny" : "allow";
+
+                                                               if (name) {
+                                                                       switch_event_add_header_string(profile->var_params.expand_var_list, SWITCH_STACK_BOTTOM, name, type);
+                                                               }
+                                                       }
+                                               }
+
+                                               if ((x_list = switch_xml_child(param, "api-list"))) {
+                                                       char *api = (char *) switch_xml_attr_soft(param, "default");
+                                                       
+                                                       profile->var_params.default_allow = (api && !strcasecmp(api, "allow"));
+                                                       switch_event_create(&profile->var_params.api_list, SWITCH_EVENT_CLONE);
+                                                       profile->var_params.api_list->flags |= EF_UNIQ_HEADERS;
+                                                       if (profile->var_params.default_allow) {
+                                                               profile->var_params.api_list->flags |= EF_DEFAULT_ALLOW;
+                                                       }
+
+
+                                                       for (x_api = switch_xml_child(x_list, "api"); x_api; x_api = x_api->next) {
+                                                               const char *name = switch_xml_attr(x_api, "name");
+                                                               const char *type = switch_xml_attr(x_api, "type");
+
+                                                               if (zstr(type)) type = profile->var_params.default_allow ? "deny" : "allow";
+
+                                                               if (name) {
+                                                                       switch_event_add_header_string(profile->var_params.api_list, SWITCH_STACK_BOTTOM, name, type);
+                                                               }
+                                                       }
+                                               }
+                                       }
+
                                } else if (!strcasecmp(var, "dial")) {
                                        profile->perms.dial.enabled = switch_true(val);
                                } else if (!strcasecmp(var, "dial-set-context")) {
@@ -2465,6 +2589,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load)
        bind_parser("break", parse_break);
        bind_parser("log", parse_log);
        bind_parser("continue", parse_continue);
+       bind_parser("setVar", parse_get_var);
 
        if (do_config() != SWITCH_STATUS_SUCCESS) {
                return SWITCH_STATUS_FALSE;
@@ -2498,6 +2623,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_httapi_shutdown)
                switch_hash_this(hi, &vvar, NULL, &val);
                profile = (client_profile_t *) val;
                switch_event_destroy(&profile->dial_params.app_list);
+               switch_event_destroy(&profile->var_params.expand_var_list);
+               switch_event_destroy(&profile->var_params.set_var_list);
+               switch_event_destroy(&profile->var_params.get_var_list);
        }
 
 
index e86520968252687d435308a868264f72486495de..c8121379bc79c3706d88e9cf98e04b2dc69bb596 100644 (file)
@@ -249,6 +249,15 @@ action                 : Change url to submit to.
 temp-action        : Change url to submit to. just for the next loop.
 
 
+<getVar action temp-action permanent/>
+                    : Get a Channel variable (depends on permissions)
+
+ATTRS:
+action             : Change url to submit to.
+temp-action        : Change url to submit to. just for the next loop.
+permanent          : Add as a permanent param or just once.
+
+
 
 
 
index 56206810272ad4d846949761e44e44b28c3cc974..435c2a3929cc63ed98ba44c7e4085d1a74e8c43a 100644 (file)
@@ -151,6 +151,9 @@ struct switch_channel {
        opaque_channel_flag_t opaque_flags;
        switch_originator_type_t last_profile_type;
        switch_caller_extension_t *queued_extension;
+       switch_event_t *app_list;
+       switch_event_t *api_list;
+       switch_event_t *var_list;
 };
 
 
@@ -578,6 +581,9 @@ SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel)
        }
        switch_mutex_lock(channel->profile_mutex);
        switch_event_destroy(&channel->variables);
+       switch_event_destroy(&channel->api_list);
+       switch_event_destroy(&channel->var_list);
+       switch_event_destroy(&channel->app_list);
        switch_mutex_unlock(channel->profile_mutex);
 }
 
@@ -3287,7 +3293,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
        memset(c, 0, olen - cpos);\
        }}                           \
 
-SWITCH_DECLARE(char *) switch_channel_expand_variables(switch_channel_t *channel, const char *in)
+SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *channel, const char *in, switch_event_t *var_list, switch_event_t *api_list)
 {
        char *p, *c = NULL;
        char *data, *indup, *endof_indup;
@@ -3425,7 +3431,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables(switch_channel_t *channel
                                        char *ptr;
                                        int idx = -1;
 
-                                       if ((expanded = switch_channel_expand_variables(channel, (char *) vname)) == vname) {
+                                       if ((expanded = switch_channel_expand_variables_check(channel, (char *) vname, var_list, api_list)) == vname) {
                                                expanded = NULL;
                                        } else {
                                                vname = expanded;
@@ -3446,6 +3452,10 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables(switch_channel_t *channel
                                        }
                                        
                                        if ((sub_val = (char *) switch_channel_get_variable_dup(channel, vname, SWITCH_TRUE, idx))) {
+                                               if (var_list && !switch_event_check_permission_list(var_list, vname)) {
+                                                       sub_val = "INVALID";
+                                               }
+
                                                if (offset || ooffset) {
                                                        cloned_sub_val = strdup(sub_val);
                                                        switch_assert(cloned_sub_val);
@@ -3478,24 +3488,29 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables(switch_channel_t *channel
 
                                        if (stream.data) {
                                                char *expanded_vname = NULL;
-
-                                               if ((expanded_vname = switch_channel_expand_variables(channel, (char *) vname)) == vname) {
+                                               
+                                               if ((expanded_vname = switch_channel_expand_variables_check(channel, (char *) vname, var_list, api_list)) == vname) {
                                                        expanded_vname = NULL;
                                                } else {
                                                        vname = expanded_vname;
                                                }
 
-                                               if ((expanded = switch_channel_expand_variables(channel, vval)) == vval) {
+                                               if ((expanded = switch_channel_expand_variables_check(channel, vval, var_list, api_list)) == vval) {
                                                        expanded = NULL;
                                                } else {
                                                        vval = expanded;
                                                }
 
-                                               if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) {
-                                                       func_val = stream.data;
-                                                       sub_val = func_val;
+                                               if (api_list && !switch_event_check_permission_list(api_list, vname)) {
+                                                       func_val = "INVALID";
+                                                       sub_val = "INVALID";
                                                } else {
-                                                       free(stream.data);
+                                                       if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) {
+                                                               func_val = stream.data;
+                                                               sub_val = func_val;
+                                                       } else {
+                                                               free(stream.data);
+                                                       }
                                                }
 
                                                switch_safe_free(expanded);
index fcb913f2a5ad10d00d6d995484cf2e7b9320298e..f17ec08e5cfd3c65dfe2e39eb3483d5fae9ae2d1 100644 (file)
@@ -1981,7 +1981,7 @@ if ((dp = realloc(data, olen))) {\
     memset(c, 0, olen - cpos);\
  }}                           \
 
-SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const char *in)
+SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list)
 {
        char *p, *c = NULL;
        char *data, *indup, *endof_indup;
@@ -2121,7 +2121,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const
                                        char *ptr;
                                        int idx = -1;
                                        
-                                       if ((expanded = switch_event_expand_headers(event, (char *) vname)) == vname) {
+                                       if ((expanded = switch_event_expand_headers_check(event, (char *) vname, var_list, api_list)) == vname) {
                                                expanded = NULL;
                                        } else {
                                                vname = expanded;
@@ -2145,6 +2145,11 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const
                                                if ((gvar = switch_core_get_variable_dup(vname))) {
                                                        sub_val = gvar;
                                                }
+
+                                               if (var_list && !switch_event_check_permission_list(var_list, vname)) {
+                                                       sub_val = "INVALID";
+                                               }
+
                                        }
 
                                        if (offset || ooffset) {
@@ -2175,23 +2180,28 @@ SWITCH_DECLARE(char *) switch_event_expand_headers(switch_event_t *event, const
                                        if (stream.data) {
                                                char *expanded_vname = NULL;
 
-                                               if ((expanded_vname = switch_event_expand_headers(event, (char *) vname)) == vname) {
+                                               if ((expanded_vname = switch_event_expand_headers_check(event, (char *) vname, var_list, api_list)) == vname) {
                                                        expanded_vname = NULL;
                                                } else {
                                                        vname = expanded_vname;
                                                }
 
-                                               if ((expanded = switch_event_expand_headers(event, vval)) == vval) {
+                                               if ((expanded = switch_event_expand_headers_check(event, vval, var_list, api_list)) == vval) {
                                                        expanded = NULL;
                                                } else {
                                                        vval = expanded;
                                                }
 
-                                               if (switch_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
-                                                       func_val = stream.data;
-                                                       sub_val = func_val;
+                                               if (api_list && !switch_event_check_permission_list(api_list, vname)) {
+                                                       func_val = "INVALID";
+                                                       sub_val = "INVALID";
                                                } else {
-                                                       free(stream.data);
+                                                       if (switch_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
+                                                               func_val = stream.data;
+                                                               sub_val = func_val;
+                                                       } else {
+                                                               free(stream.data);
+                                                       }
                                                }
 
                                                switch_safe_free(expanded);
@@ -2330,6 +2340,32 @@ SWITCH_DECLARE(char *) switch_event_build_param_string(switch_event_t *event, co
        return stream.data;
 }
 
+SWITCH_DECLARE(int) switch_event_check_permission_list(switch_event_t *list, const char *name)
+{
+       const char *v;
+       int r = 0;
+       int default_allow = switch_test_flag(list, EF_DEFAULT_ALLOW);
+
+       if (!list->headers) {
+               return default_allow;
+       }
+
+       if ((v = switch_event_get_header(list, name))) {
+               if (*v == 'd') {
+                       r = 0;
+               } else {
+                       r = 1;
+               }
+       } else {
+               r = default_allow;
+       }
+
+       return r;       
+}
+
+
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c