[asterisk-commits] markm: trunk r326267 - in /trunk: CHANGES main/manager.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 5 11:46:20 CDT 2011
Author: markm
Date: Tue Jul 5 11:46:17 2011
New Revision: 326267
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=326267
Log:
New feature: AMI Action FilterAdd
This adds a new action, FilterAdd to the manager interface that allows control over event filters for the current session
(closes issue ASTERISK-16795)
Reported by: kobaz
Tested by: kobaz,loloski
Modified:
trunk/CHANGES
trunk/main/manager.c
Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=326267&r1=326266&r2=326267
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Tue Jul 5 11:46:17 2011
@@ -41,6 +41,9 @@
Description field that is set by 'description' in the channel configuration
file.
* Added Uniqueid header to UserEvent.
+ * Added new action FilterAdd to control event filters for the current session.
+ This requires the system permission and uses the same filter syntax as
+ filters that can be defined in manager.conf
Asterisk HTTP Server
--------------------------
Modified: trunk/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/manager.c?view=diff&rev=326267&r1=326266&r2=326267
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Tue Jul 5 11:46:17 2011
@@ -812,6 +812,52 @@
<para>Generates an AOC-D or AOC-E message on a channel.</para>
</description>
</manager>
+ <manager name="Filter" language="en_US">
+ <synopsis>
+ Dynamically add filters for the current manager session.
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Operation">
+ <enumlist>
+ <enum name="Add">
+ <para>Add a filter.</para>
+ </enum>
+ </enumlist>
+ </parameter>
+ <parameter name="Filter">
+ <para>Filters can be whitelist or blacklist</para>
+ <para>Example whitelist filter: "Event: Newchannel"</para>
+ <para>Example blacklist filter: "!Channel: DAHDI.*"</para>
+ <para>This filter option is used to whitelist or blacklist events per user to be
+ reported with regular expressions and are allowed if both the regex matches
+ and the user has read access as defined in manager.conf. Filters are assumed to be for whitelisting
+ unless preceeded by an exclamation point, which marks it as being black.
+ Evaluation of the filters is as follows:</para>
+ <para>- If no filters are configured all events are reported as normal.</para>
+ <para>- If there are white filters only: implied black all filter processed first, then white filters.</para>
+ <para>- If there are black filters only: implied white all filter processed first, then black filters.</para>
+ <para>- If there are both white and black filters: implied black all filter processed first, then white
+ filters, and lastly black filters.</para>
+ </parameter>
+ </syntax>
+ <description>
+ <para>The filters added are only used for the current session.
+ Once the connection is closed the filters are removed.</para>
+ <para>This comand requires the system permission because
+ this command can be used to create filters that may bypass
+ filters defined in manager.conf</para>
+ </description>
+ </manager>
+ <manager name="FilterList" language="en_US">
+ <synopsis>
+ Show current event filters for this session
+ </synopsis>
+ <description>
+ <para>The filters displayed are for the current session. Only those filters defined in
+ manager.conf will be present upon starting a new session.</para>
+ </description>
+ </manager>
***/
enum error_type {
@@ -828,6 +874,11 @@
FAILURE_APPEND
};
+enum add_filter_result {
+ FILTER_SUCCESS,
+ FILTER_ALLOC_FAILED,
+ FILTER_COMPILE_FAIL,
+};
/*!
* Linked list of events.
@@ -1019,6 +1070,8 @@
static void free_channelvars(void);
+static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters);
+
/*! \brief Add a custom hook to be called when an event is fired */
void ast_manager_register_hook(struct manager_custom_hook *hook)
{
@@ -4122,6 +4175,88 @@
return 0;
}
+/*
+ * \brief Manager command to add an event filter to a manager session
+ * \see For more details look at manager_add_filter
+ */
+static int action_filter(struct mansession *s, const struct message *m)
+{
+ const char *filter = astman_get_header(m, "Filter");
+ const char *operation = astman_get_header(m, "Operation");
+ int res;
+
+ if (!strcasecmp(operation, "Add")) {
+ res = manager_add_filter(filter, s->session->whitefilters, s->session->blackfilters);
+
+ if (res != FILTER_SUCCESS) {
+ if (res == FILTER_ALLOC_FAILED) {
+ astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
+ return 0;
+ } else if (res == FILTER_COMPILE_FAIL) {
+ astman_send_error(s, m, "Filter did not compile. Check the syntax of the filter given.");
+ return 0;
+ } else {
+ astman_send_error(s, m, "Internal Error. Failed adding filter.");
+ return 0;
+ }
+ }
+
+ astman_send_ack(s, m, "Success");
+ return 0;
+ }
+
+ astman_send_error(s, m, "Unknown operation");
+ return 0;
+}
+
+/*
+ * \brief Add an event filter to a manager session
+ *
+ * \param s manager session to modify filters on
+ * \param filter_pattern Filter syntax to add, see below for syntax
+ *
+ * \return FILTER_ALLOC_FAILED Memory allocation failure
+ * \return FILTER_COMPILE_FAIL If the filter did not compile
+ * \return FILTER_SUCCESS Success
+ *
+ * Filter will be used to match against each line of a manager event
+ * Filter can be any valid regular expression
+ * Filter can be a valid regular expression prefixed with !, which will add the filter as a black filter
+ *
+ * \example filter_pattern = "Event: Newchannel"
+ * \example filter_pattern = "Event: New.*"
+ * \example filter_pattern = "!Channel: DAHDI.*"
+ *
+ */
+static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters) {
+ regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
+ int is_blackfilter;
+
+ if (!new_filter) {
+ return FILTER_ALLOC_FAILED;
+ }
+
+ if (filter_pattern[0] == '!') {
+ is_blackfilter = 1;
+ filter_pattern++;
+ } else {
+ is_blackfilter = 0;
+ }
+
+ if (regcomp(new_filter, filter_pattern, 0)) {
+ ao2_t_ref(new_filter, -1, "failed to make regx");
+ return FILTER_COMPILE_FAIL;
+ }
+
+ if (is_blackfilter) {
+ ao2_t_link(blackfilters, new_filter, "link new filter into black user container");
+ } else {
+ ao2_t_link(whitefilters, new_filter, "link new filter into white user container");
+ }
+
+ return FILTER_SUCCESS;
+}
+
static int match_filter(struct mansession *s, char *eventdata)
{
int result = 0;
@@ -6284,6 +6419,7 @@
ast_manager_register_xml("ModuleLoad", EVENT_FLAG_SYSTEM, manager_moduleload);
ast_manager_register_xml("ModuleCheck", EVENT_FLAG_SYSTEM, manager_modulecheck);
ast_manager_register_xml("AOCMessage", EVENT_FLAG_AOC, action_aocmessage);
+ ast_manager_register_xml("Filter", EVENT_FLAG_SYSTEM, action_filter);
ast_cli_register_multiple(cli_manager, ARRAY_LEN(cli_manager));
ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
@@ -6563,25 +6699,7 @@
}
} else if (!strcasecmp(var->name, "eventfilter")) {
const char *value = var->value;
- regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
- if (new_filter) {
- int is_blackfilter;
- if (value[0] == '!') {
- is_blackfilter = 1;
- value++;
- } else {
- is_blackfilter = 0;
- }
- if (regcomp(new_filter, value, 0)) {
- ao2_t_ref(new_filter, -1, "failed to make regx");
- } else {
- if (is_blackfilter) {
- ao2_t_link(user->blackfilters, new_filter, "link new filter into black user container");
- } else {
- ao2_t_link(user->whitefilters, new_filter, "link new filter into white user container");
- }
- }
- }
+ manager_add_filter(value, user->whitefilters, user->blackfilters);
} else {
ast_debug(1, "%s is an unknown option.\n", var->name);
}
More information about the asterisk-commits
mailing list