From 3768d802279291a851291c22ed5722761aab5782 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 6 Jan 2012 15:10:37 -0600 Subject: [PATCH] add app lists to white or blacklist apps in the execute tag --- conf/autoload_configs/httapi.conf.xml | 9 +- src/mod/applications/mod_httapi/apps.cgi | 34 +++++++ .../applications/mod_httapi/httapi.conf.xml | 13 ++- src/mod/applications/mod_httapi/mod_httapi.c | 90 +++++++++++++++++-- .../mod_httapi/mod_httapi_doc.txt | 2 +- 5 files changed, 137 insertions(+), 11 deletions(-) create mode 100755 src/mod/applications/mod_httapi/apps.cgi diff --git a/conf/autoload_configs/httapi.conf.xml b/conf/autoload_configs/httapi.conf.xml index d82e6b2eef..dfd7d692fb 100644 --- a/conf/autoload_configs/httapi.conf.xml +++ b/conf/autoload_configs/httapi.conf.xml @@ -28,7 +28,14 @@ - + + + + + + + + diff --git a/src/mod/applications/mod_httapi/apps.cgi b/src/mod/applications/mod_httapi/apps.cgi new file mode 100755 index 0000000000..90414b810e --- /dev/null +++ b/src/mod/applications/mod_httapi/apps.cgi @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +# Object initialization: +use XML::Simple; +use CGI; +use Data::Dumper; +use XML::Writer; + +my $q = CGI->new; +my $exiting = $q->param("exiting"); + +if ($exiting) { + print $q->header(-type => "text/plain"); + print "OK"; + exit(); +} + +print $q->header(-type => "text/xml"); + + +my $writer = new XML::Writer(OUTPUT => STDOUT, DATA_MODE => 1); + +$writer->startTag('document', type => 'xml/freeswitch-httapi'); + +$writer->startTag('work'); +$writer->emptyTag('pause', milliseconds => "500"); +$writer->emptyTag('execute', application => "info"); +$writer->dataElement('execute', "user_busy", application => "hangup"); +$writer->endTag('work'); + + +$writer->endTag('document'); +$writer->end(); + diff --git a/src/mod/applications/mod_httapi/httapi.conf.xml b/src/mod/applications/mod_httapi/httapi.conf.xml index 05b321e11b..dfd7d692fb 100644 --- a/src/mod/applications/mod_httapi/httapi.conf.xml +++ b/src/mod/applications/mod_httapi/httapi.conf.xml @@ -1,8 +1,8 @@ - + - + @@ -28,7 +28,14 @@ - + + + + + + + + diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index ae87ad5c40..17454b32f0 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -40,7 +40,7 @@ typedef struct profile_perms_s { switch_byte_t set_vars; switch_byte_t extended_data; switch_byte_t execute_apps; - switch_byte_t expand_vars_in_tag_body; + switch_byte_t expand_vars; struct { switch_byte_t enabled; switch_byte_t set_context; @@ -95,6 +95,8 @@ typedef struct client_profile_s { struct { char *context; char *dp; + switch_event_t *app_list; + int default_allow; } dial_params; } client_profile_t; @@ -627,11 +629,41 @@ static switch_status_t parse_sms(const char *tag_name, client_t *client, switch_ return SWITCH_STATUS_SUCCESS; } +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; +} + static switch_status_t parse_execute(const char *tag_name, client_t *client, switch_xml_t tag, const char *body) { const char *app_name = switch_xml_attr(tag, "application"); + const char *data = switch_xml_attr(tag, "data"); - if (!client->profile->perms.execute_apps) { + if (zstr(data)) data = body; + + if (!check_app_perm(client, app_name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Permission Denied!\n"); switch_channel_hangup(client->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return SWITCH_STATUS_FALSE; @@ -642,7 +674,19 @@ static switch_status_t parse_execute(const char *tag_name, client_t *client, swi switch_channel_hangup(client->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return SWITCH_STATUS_FALSE; } else { - switch_core_session_execute_application(client->session, app_name, body); + if (!client->profile->perms.expand_vars) { + const char *p; + + for(p = data; p && *p; p++) { + if (*p == '$') { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Expand Variables: Permission Denied!\n"); + switch_channel_hangup(client->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + return SWITCH_STATUS_FALSE; + } + } + } + + switch_core_session_execute_application(client->session, app_name, data); } return SWITCH_STATUS_SUCCESS; @@ -928,7 +972,7 @@ static switch_status_t parse_xml(client_t *client) char *expanded = tag->txt; switch_event_t *templ_data; - if (tag->txt && client->profile->perms.expand_vars_in_tag_body) { + 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); @@ -1525,8 +1569,31 @@ static switch_status_t do_config(void) profile->perms.extended_data = switch_true(val); } else if (!strcasecmp(var, "execute-apps")) { profile->perms.execute_apps = switch_true(val); - } else if (!strcasecmp(var, "expand-vars-in-tag-body")) { - profile->perms.expand_vars_in_tag_body = switch_true(val); + + if (profile->perms.execute_apps) { + switch_xml_t x_list, x_app; + if ((x_list = switch_xml_child(param, "application-list"))) { + char *var = (char *) switch_xml_attr_soft(param, "default"); + + 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; + + 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"); + const char *type = switch_xml_attr(x_app, "type"); + + if (zstr(type)) type = profile->dial_params.default_allow ? "deny" : "allow"; + + if (name) { + switch_event_add_header_string(profile->dial_params.app_list, SWITCH_STACK_BOTTOM, name, type); + } + } + } + } + + } else if (!strcasecmp(var, "expand-vars")) { + profile->perms.expand_vars = switch_true(val); } else if (!strcasecmp(var, "dial")) { profile->perms.dial.enabled = switch_true(val); } else if (!strcasecmp(var, "dial-set-context")) { @@ -2240,6 +2307,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_httapi_shutdown) { hash_node_t *ptr = NULL; + client_profile_t *profile; + switch_hash_index_t *hi; + void *val; + const void *vvar; + + for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + profile = (client_profile_t *) val; + switch_event_destroy(&profile->dial_params.app_list); + } + switch_core_hash_destroy(&globals.profile_hash); switch_core_hash_destroy(&globals.parse_hash); diff --git a/src/mod/applications/mod_httapi/mod_httapi_doc.txt b/src/mod/applications/mod_httapi/mod_httapi_doc.txt index 8359d1278c..f6c94e6fd4 100644 --- a/src/mod/applications/mod_httapi/mod_httapi_doc.txt +++ b/src/mod/applications/mod_httapi/mod_httapi_doc.txt @@ -266,7 +266,7 @@ default-profile : default Profile set-vars : tag can be parsed to set channel vars. extended-data : Extended data is sent like full channel event data. execute-apps : tag is enabled to execute apps. -expand-vars-in-tag-body : body content of tags are run trough variable expansion. +expand-vars : Allow expansion of FS ${variables}. (this opens up all FSAPI calls) *dial : tag is enabled allowing outbound dialing. dial-set-context : context attribute is permitted. dial-set-dialplan : dialplan attribute is permitted.