summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--configs/manager.conf.sample1
-rw-r--r--include/asterisk/manager.h39
-rw-r--r--main/manager.c11
-rw-r--r--main/security_events.c76
5 files changed, 110 insertions, 20 deletions
diff --git a/CHANGES b/CHANGES
index 423ffb640..381de61bb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -579,6 +579,9 @@ AMI (Asterisk Manager Interface)
They contain information about the transfer that just completed, including
the location of the transfered channel.
+ * Added a 'security' class to AMI which outputs the required fields for
+ security messages similar to the log messages from res_security_log
+
CDR (Call Detail Records)
------------------
* Significant changes have been made to the behavior of CDRs. The CDR engine
diff --git a/configs/manager.conf.sample b/configs/manager.conf.sample
index 54f6928c8..13076ce8d 100644
--- a/configs/manager.conf.sample
+++ b/configs/manager.conf.sample
@@ -147,6 +147,7 @@ bindaddr = 0.0.0.0
; test - Ability to read TestEvent notifications sent to the Asterisk Test
; Suite. Note that this is only enabled when the TEST_FRAMEWORK
; compiler flag is defined.
+; security - Security Events. Read-only.
; message - Permissions to send out of call messages. Write-only
;
;read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index dad7c4917..6d0be4c0d 100644
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -68,26 +68,27 @@
/*! \name Manager event classes */
/*@{ */
-#define EVENT_FLAG_SYSTEM (1 << 0) /* System events such as module load/unload */
-#define EVENT_FLAG_CALL (1 << 1) /* Call event, such as state change, etc */
-#define EVENT_FLAG_LOG (1 << 2) /* Log events */
-#define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */
-#define EVENT_FLAG_COMMAND (1 << 4) /* Ability to read/set commands */
-#define EVENT_FLAG_AGENT (1 << 5) /* Ability to read/set agent info */
-#define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user info */
-#define EVENT_FLAG_CONFIG (1 << 7) /* Ability to modify configurations */
-#define EVENT_FLAG_DTMF (1 << 8) /* Ability to read DTMF events */
-#define EVENT_FLAG_REPORTING (1 << 9) /* Reporting events such as rtcp sent */
-#define EVENT_FLAG_CDR (1 << 10) /* CDR events */
-#define EVENT_FLAG_DIALPLAN (1 << 11) /* Dialplan events (VarSet, NewExten) */
-#define EVENT_FLAG_ORIGINATE (1 << 12) /* Originate a call to an extension */
-#define EVENT_FLAG_AGI (1 << 13) /* AGI events */
-#define EVENT_FLAG_HOOKRESPONSE (1 << 14) /* Hook Response */
-#define EVENT_FLAG_CC (1 << 15) /* Call Completion events */
-#define EVENT_FLAG_AOC (1 << 16) /* Advice Of Charge events */
-#define EVENT_FLAG_TEST (1 << 17) /* Test event used to signal the Asterisk Test Suite */
+#define EVENT_FLAG_SYSTEM (1 << 0) /* System events such as module load/unload */
+#define EVENT_FLAG_CALL (1 << 1) /* Call event, such as state change, etc */
+#define EVENT_FLAG_LOG (1 << 2) /* Log events */
+#define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */
+#define EVENT_FLAG_COMMAND (1 << 4) /* Ability to read/set commands */
+#define EVENT_FLAG_AGENT (1 << 5) /* Ability to read/set agent info */
+#define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user info */
+#define EVENT_FLAG_CONFIG (1 << 7) /* Ability to modify configurations */
+#define EVENT_FLAG_DTMF (1 << 8) /* Ability to read DTMF events */
+#define EVENT_FLAG_REPORTING (1 << 9) /* Reporting events such as rtcp sent */
+#define EVENT_FLAG_CDR (1 << 10) /* CDR events */
+#define EVENT_FLAG_DIALPLAN (1 << 11) /* Dialplan events (VarSet, NewExten) */
+#define EVENT_FLAG_ORIGINATE (1 << 12) /* Originate a call to an extension */
+#define EVENT_FLAG_AGI (1 << 13) /* AGI events */
+#define EVENT_FLAG_HOOKRESPONSE (1 << 14) /* Hook Response */
+#define EVENT_FLAG_CC (1 << 15) /* Call Completion events */
+#define EVENT_FLAG_AOC (1 << 16) /* Advice Of Charge events */
+#define EVENT_FLAG_TEST (1 << 17) /* Test event used to signal the Asterisk Test Suite */
+#define EVENT_FLAG_SECURITY (1 << 18) /* Security Message as AMI Event */
/*XXX Why shifted by 30? XXX */
-#define EVENT_FLAG_MESSAGE (1 << 30) /* MESSAGE events. */
+#define EVENT_FLAG_MESSAGE (1 << 30) /* MESSAGE events. */
/*@} */
/*! \brief Export manager structures */
diff --git a/main/manager.c b/main/manager.c
index 01cc75474..f2590b1bb 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -1129,6 +1129,9 @@ static struct stasis_message_router *stasis_router;
/*! \brief The \ref stasis_subscription for forwarding the RTP topic to the AMI topic */
static struct stasis_forward *rtp_topic_forwarder;
+/*! \brief The \ref stasis_subscription for forwarding the Security topic to the AMI topic */
+static struct stasis_forward *security_topic_forwarder;
+
#define MGR_SHOW_TERMINAL_WIDTH 80
#define MAX_VARS 128
@@ -1593,6 +1596,7 @@ static const struct permalias {
{ EVENT_FLAG_CC, "cc" },
{ EVENT_FLAG_AOC, "aoc" },
{ EVENT_FLAG_TEST, "test" },
+ { EVENT_FLAG_SECURITY, "security" },
{ EVENT_FLAG_MESSAGE, "message" },
{ INT_MAX, "all" },
{ 0, "none" },
@@ -7774,6 +7778,8 @@ static void manager_shutdown(void)
}
stasis_forward_cancel(rtp_topic_forwarder);
rtp_topic_forwarder = NULL;
+ stasis_forward_cancel(security_topic_forwarder);
+ security_topic_forwarder = NULL;
ao2_cleanup(manager_topic);
manager_topic = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(ast_manager_get_generic_type);
@@ -7817,6 +7823,11 @@ static int manager_subscriptions_init(void)
return -1;
}
+ security_topic_forwarder = stasis_forward_all(ast_security_topic(), manager_topic);
+ if (!security_topic_forwarder) {
+ return -1;
+ }
+
stasis_router = stasis_message_router_create(manager_topic);
if (!stasis_router) {
return -1;
diff --git a/main/security_events.c b/main/security_events.c
index d10338984..42ebc59fe 100644
--- a/main/security_events.c
+++ b/main/security_events.c
@@ -42,6 +42,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj2.h"
static const size_t TIMESTAMP_STR_LEN = 32;
+static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
/*! \brief Security Topic */
static struct stasis_topic *security_topic;
@@ -51,8 +52,81 @@ struct stasis_topic *ast_security_topic(void)
return security_topic;
}
+static int append_event_str_single(struct ast_str **str, struct ast_json *json,
+ const enum ast_event_ie_type ie_type)
+{
+ const char *ie_type_key = ast_event_get_ie_type_name(ie_type);
+ struct ast_json *json_string = ast_json_object_get(json, ie_type_key);
+
+ ast_assert(json_string != NULL);
+
+ if (ast_str_append(str, 0, "%s: %s\r\n", ie_type_key, ast_json_string_get(json_string)) == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int append_event_str_from_json(struct ast_str **str, struct ast_json *json,
+ const struct ast_security_event_ie_type *ies)
+{
+ unsigned int i;
+
+ for (i = 0; ies[i].ie_type != AST_EVENT_IE_END; i++) {
+ if (append_event_str_single(str, json, ies[i].ie_type)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static struct ast_manager_event_blob *security_event_to_ami_blob(struct ast_json *json)
+{
+ RAII_VAR(struct ast_str *, str, NULL, ast_free);
+ struct ast_json *event_type_json;
+ enum ast_security_event_type event_type;
+
+ event_type_json = ast_json_object_get(json, "SecurityEvent");
+ event_type = ast_json_integer_get(event_type_json);
+
+ ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
+
+ if (!(str = ast_str_create(SECURITY_EVENT_BUF_INIT_LEN))) {
+ return NULL;
+ }
+
+ if (append_event_str_from_json(&str, json,
+ ast_security_event_get_required_ies(event_type))) {
+ ast_log(LOG_ERROR, "Failed to issue a security event to AMI.\n");
+ return NULL;
+ }
+
+ return ast_manager_event_blob_create(EVENT_FLAG_SECURITY,
+ ast_security_event_get_name(event_type),
+ "%s",
+ ast_str_buffer(str));
+}
+
+static struct ast_manager_event_blob *security_event_to_ami(struct stasis_message *message)
+{
+ struct ast_json_payload *payload = stasis_message_data(message);
+
+ if (stasis_message_type(message) != ast_security_event_type()) {
+ return NULL;
+ }
+
+ if (!payload) {
+ return NULL;
+ }
+
+ return security_event_to_ami_blob(payload->json);
+}
+
/*! \brief Message type for security events */
-STASIS_MESSAGE_TYPE_DEFN(ast_security_event_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_security_event_type,
+ .to_ami = security_event_to_ami,
+ );
static void security_stasis_cleanup(void)
{