add app lists to white or blacklist apps in the execute tag

This commit is contained in:
Anthony Minessale 2012-01-06 15:10:37 -06:00
parent 27a3f1ccf2
commit 3768d80227
5 changed files with 137 additions and 11 deletions

View File

@ -28,7 +28,14 @@
<permission name="set-params" value="true"/>
<permission name="set-vars" value="false"/>
<permission name="extended-data" value="false"/>
<permission name="execute-apps" value="false"/>
<permission name="execute-apps" value="true">
<!-- default to "deny" or "allow" -->
<application-list default="deny">
<!-- type attr can be "deny" or "allow" nothing defaults to opposite of the list default so allow in this case -->
<application name="info"/>
<application name="hangup"/>
</application-list>
</permission>
<permission name="expand-vars-in-tag-body" value="false"/>
<permission name="dial" value="true"/>
<permission name="dial-set-context" value="false"/>

View File

@ -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();

View File

@ -1,8 +1,8 @@
<configuration name="httapi.conf" description="HT-TAPI Hypertext Telephony API">
<settings>
<!-- print xml on the console -->
<!-- print xml on the consol -->
<param name="debug" value="true"/>
<!-- time to keep audio files when discovered they were deleted from the http server -->
<!-- time to keep audio files when discoverd they were deleted from the http server -->
<param name="file-not-found-expires" value="300"/>
<!-- how often to re-check the server to make sure the remote file has not changed -->
<param name="file-cache-ttl" value="300"/>
@ -28,7 +28,14 @@
<permission name="set-params" value="true"/>
<permission name="set-vars" value="false"/>
<permission name="extended-data" value="false"/>
<permission name="execute-apps" value="false"/>
<permission name="execute-apps" value="true">
<!-- default to "deny" or "allow" -->
<application-list default="deny">
<!-- type attr can be "deny" or "allow" nothing defaults to opposite of the list default so allow in this case -->
<application name="info"/>
<application name="hangup"/>
</application-list>
</permission>
<permission name="expand-vars-in-tag-body" value="false"/>
<permission name="dial" value="true"/>
<permission name="dial-set-context" value="false"/>

View File

@ -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);

View File

@ -266,7 +266,7 @@ default-profile : <string> default Profile
set-vars : <variables> tag can be parsed to set channel vars.
extended-data : Extended data is sent like full channel event data.
execute-apps : <execute> 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 : <dial> tag is enabled allowing outbound dialing.
dial-set-context : <dial context=""> context attribute is permitted.
dial-set-dialplan : <dial dialplan=""> dialplan attribute is permitted.