security_events: Push out security events over AMI events

Security Events will now be written to any listener of the new 'security' class

Review: https://reviewboard.asterisk.org/r/2998/
........

Merged revisions 402584 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@402585 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/97/197/1
Jonathan Rose 12 years ago
parent 518f091a1a
commit bf5492abd2

@ -579,6 +579,9 @@ AMI (Asterisk Manager Interface)
They contain information about the transfer that just completed, including They contain information about the transfer that just completed, including
the location of the transfered channel. 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) CDR (Call Detail Records)
------------------ ------------------
* Significant changes have been made to the behavior of CDRs. The CDR engine * Significant changes have been made to the behavior of CDRs. The CDR engine

@ -147,6 +147,7 @@ bindaddr = 0.0.0.0
; test - Ability to read TestEvent notifications sent to the Asterisk Test ; test - Ability to read TestEvent notifications sent to the Asterisk Test
; Suite. Note that this is only enabled when the TEST_FRAMEWORK ; Suite. Note that this is only enabled when the TEST_FRAMEWORK
; compiler flag is defined. ; compiler flag is defined.
; security - Security Events. Read-only.
; message - Permissions to send out of call messages. Write-only ; message - Permissions to send out of call messages. Write-only
; ;
;read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan ;read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan

@ -68,26 +68,27 @@
/*! \name Manager event classes */ /*! \name Manager event classes */
/*@{ */ /*@{ */
#define EVENT_FLAG_SYSTEM (1 << 0) /* System events such as module load/unload */ #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_CALL (1 << 1) /* Call event, such as state change, etc */
#define EVENT_FLAG_LOG (1 << 2) /* Log events */ #define EVENT_FLAG_LOG (1 << 2) /* Log events */
#define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */ #define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */
#define EVENT_FLAG_COMMAND (1 << 4) /* Ability to read/set commands */ #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_AGENT (1 << 5) /* Ability to read/set agent info */
#define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user 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_CONFIG (1 << 7) /* Ability to modify configurations */
#define EVENT_FLAG_DTMF (1 << 8) /* Ability to read DTMF events */ #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_REPORTING (1 << 9) /* Reporting events such as rtcp sent */
#define EVENT_FLAG_CDR (1 << 10) /* CDR events */ #define EVENT_FLAG_CDR (1 << 10) /* CDR events */
#define EVENT_FLAG_DIALPLAN (1 << 11) /* Dialplan events (VarSet, NewExten) */ #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_ORIGINATE (1 << 12) /* Originate a call to an extension */
#define EVENT_FLAG_AGI (1 << 13) /* AGI events */ #define EVENT_FLAG_AGI (1 << 13) /* AGI events */
#define EVENT_FLAG_HOOKRESPONSE (1 << 14) /* Hook Response */ #define EVENT_FLAG_HOOKRESPONSE (1 << 14) /* Hook Response */
#define EVENT_FLAG_CC (1 << 15) /* Call Completion events */ #define EVENT_FLAG_CC (1 << 15) /* Call Completion events */
#define EVENT_FLAG_AOC (1 << 16) /* Advice Of Charge 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_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 */ /*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 */ /*! \brief Export manager structures */

@ -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 */ /*! \brief The \ref stasis_subscription for forwarding the RTP topic to the AMI topic */
static struct stasis_forward *rtp_topic_forwarder; 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 MGR_SHOW_TERMINAL_WIDTH 80
#define MAX_VARS 128 #define MAX_VARS 128
@ -1593,6 +1596,7 @@ static const struct permalias {
{ EVENT_FLAG_CC, "cc" }, { EVENT_FLAG_CC, "cc" },
{ EVENT_FLAG_AOC, "aoc" }, { EVENT_FLAG_AOC, "aoc" },
{ EVENT_FLAG_TEST, "test" }, { EVENT_FLAG_TEST, "test" },
{ EVENT_FLAG_SECURITY, "security" },
{ EVENT_FLAG_MESSAGE, "message" }, { EVENT_FLAG_MESSAGE, "message" },
{ INT_MAX, "all" }, { INT_MAX, "all" },
{ 0, "none" }, { 0, "none" },
@ -7774,6 +7778,8 @@ static void manager_shutdown(void)
} }
stasis_forward_cancel(rtp_topic_forwarder); stasis_forward_cancel(rtp_topic_forwarder);
rtp_topic_forwarder = NULL; rtp_topic_forwarder = NULL;
stasis_forward_cancel(security_topic_forwarder);
security_topic_forwarder = NULL;
ao2_cleanup(manager_topic); ao2_cleanup(manager_topic);
manager_topic = NULL; manager_topic = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(ast_manager_get_generic_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_manager_get_generic_type);
@ -7817,6 +7823,11 @@ static int manager_subscriptions_init(void)
return -1; 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); stasis_router = stasis_message_router_create(manager_topic);
if (!stasis_router) { if (!stasis_router) {
return -1; return -1;

@ -42,6 +42,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj2.h" #include "asterisk/astobj2.h"
static const size_t TIMESTAMP_STR_LEN = 32; static const size_t TIMESTAMP_STR_LEN = 32;
static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
/*! \brief Security Topic */ /*! \brief Security Topic */
static struct stasis_topic *security_topic; static struct stasis_topic *security_topic;
@ -51,8 +52,81 @@ struct stasis_topic *ast_security_topic(void)
return security_topic; 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 */ /*! \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) static void security_stasis_cleanup(void)
{ {

Loading…
Cancel
Save