[svn-commits] russell: trunk r206021 - in /trunk: doc/tex/ include/asterisk/ main/ res/ tests/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sat Jul 11 14:15:07 CDT 2009


Author: russell
Date: Sat Jul 11 14:15:03 2009
New Revision: 206021

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=206021
Log:
Add an API for reporting security events, and a security event logging module.

This commit introduces the security events API.  This API is to be used by
Asterisk components to report events that have security implications.
A simple example is when a connection is made but fails authentication.  These
events can be used by external tools manipulate firewall rules or something
similar after detecting unusual activity based on security events.

Inside of Asterisk, the events go through the ast_event API.  This means that
they have a binary encoding, and it is easy to write code to subscribe to these
events and do something with them.

One module is provided that is a subscriber to these events - res_security_log.
This module turns security events into a parseable text format and sends them
to the "security" logger level.  Using logger.conf, these log entries may be
sent to a file, or to syslog.

One service, AMI, has been fully updated for reporting security events.
AMI was chosen as it was a fairly straight forward service to convert.
The next target will be chan_sip.  That will be more complicated and will
be done as its own project as the next phase of security events work.

For more information on the security events framework, see the documentation
generated from doc/tex/.  "make asterisk.pdf"

https://reviewboard.asterisk.org/r/273/

Added:
    trunk/doc/tex/security-events.tex
      - copied unchanged from r206020, team/group/security_events/doc/tex/security-events.tex
    trunk/include/asterisk/security_events.h
      - copied unchanged from r206020, team/group/security_events/include/asterisk/security_events.h
    trunk/include/asterisk/security_events_defs.h
      - copied unchanged from r206020, team/group/security_events/include/asterisk/security_events_defs.h
    trunk/main/security_events.c
      - copied unchanged from r206020, team/group/security_events/main/security_events.c
    trunk/res/res_security_log.c
      - copied unchanged from r206020, team/group/security_events/res/res_security_log.c
    trunk/tests/test_ami_security_events.sh
      - copied unchanged from r206020, team/group/security_events/tests/test_ami_security_events.sh
    trunk/tests/test_security_events.c
      - copied unchanged from r206020, team/group/security_events/tests/test_security_events.c
Modified:
    trunk/doc/tex/asterisk.tex
    trunk/include/asterisk/event_defs.h
    trunk/main/event.c
    trunk/main/manager.c

Modified: trunk/doc/tex/asterisk.tex
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/doc/tex/asterisk.tex?view=diff&rev=206021&r1=206020&r2=206021
==============================================================================
--- trunk/doc/tex/asterisk.tex (original)
+++ trunk/doc/tex/asterisk.tex Sat Jul 11 14:15:03 2009
@@ -144,6 +144,9 @@
 \chapter{Calendaring}
   \input{calendaring.tex}
 
+\chapter{Security Framework}
+  \input{security-events.tex}
+
 \chapter{Development}
   \section{Backtrace}
   \input{backtrace.tex}

Modified: trunk/include/asterisk/event_defs.h
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/include/asterisk/event_defs.h?view=diff&rev=206021&r1=206020&r2=206021
==============================================================================
--- trunk/include/asterisk/event_defs.h (original)
+++ trunk/include/asterisk/event_defs.h Sat Jul 11 14:15:03 2009
@@ -49,58 +49,60 @@
 	 *  directly, in general.  Use AST_EVENT_DEVICE_STATE instead. */
 	AST_EVENT_DEVICE_STATE_CHANGE = 0x06,
 	/*! Channel Event Logging events */
-	AST_EVENT_CEL = 0x07,
+	AST_EVENT_CEL                 = 0x07,
+	/*! A report of a security related event (see security_events.h) */
+	AST_EVENT_SECURITY            = 0x08,
 	/*! Number of event types.  This should be the last event type + 1 */
-	AST_EVENT_TOTAL        = 0x08,
+	AST_EVENT_TOTAL               = 0x09,
 };
 
 /*! \brief Event Information Element types */
 enum ast_event_ie_type {
 	/*! Used to terminate the arguments to event functions */
-	AST_EVENT_IE_END       = -1,
+	AST_EVENT_IE_END                 = -1,
 
 	/*! 
 	 * \brief Number of new messages
 	 * Used by: AST_EVENT_MWI 
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_NEWMSGS   = 0x01,
+	AST_EVENT_IE_NEWMSGS             = 0x0001,
 	/*! 
 	 * \brief Number of
 	 * Used by: AST_EVENT_MWI 
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_OLDMSGS   = 0x02,
+	AST_EVENT_IE_OLDMSGS             = 0x0002,
 	/*! 
 	 * \brief Mailbox name \verbatim (mailbox[@context]) \endverbatim
 	 * Used by: AST_EVENT_MWI 
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_MAILBOX   = 0x03,
+	AST_EVENT_IE_MAILBOX             = 0x0003,
 	/*! 
 	 * \brief Unique ID
 	 * Used by: AST_EVENT_SUB, AST_EVENT_UNSUB
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_UNIQUEID  = 0x04,
+	AST_EVENT_IE_UNIQUEID            = 0x0004,
 	/*! 
 	 * \brief Event type 
 	 * Used by: AST_EVENT_SUB, AST_EVENT_UNSUB
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_EVENTTYPE = 0x05,
+	AST_EVENT_IE_EVENTTYPE           = 0x0005,
 	/*!
 	 * \brief Hint that someone cares that an IE exists
 	 * Used by: AST_EVENT_SUB
 	 * Payload type: UINT (ast_event_ie_type)
 	 */
-	AST_EVENT_IE_EXISTS    = 0x6,
+	AST_EVENT_IE_EXISTS              = 0x0006,
 	/*!
 	 * \brief Device Name
 	 * Used by AST_EVENT_DEVICE_STATE_CHANGE
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_DEVICE    = 0x07,
+	AST_EVENT_IE_DEVICE              = 0x0007,
 	/*!
 	 * \brief Generic State IE
 	 * Used by AST_EVENT_DEVICE_STATE_CHANGE
@@ -108,161 +110,180 @@
 	 * The actual state values depend on the event which
 	 * this IE is a part of.
 	 */
-	 AST_EVENT_IE_STATE    = 0x08,
+	 AST_EVENT_IE_STATE              = 0x0008,
 	 /*!
 	  * \brief Context IE
 	  * Used by AST_EVENT_MWI
 	  * Payload type: str
 	  */
-	 AST_EVENT_IE_CONTEXT  = 0x09,
+	 AST_EVENT_IE_CONTEXT            = 0x0009,
 	/*! 
 	 * \brief Channel Event Type
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_CEL_EVENT_TYPE = 0x0a,
+	AST_EVENT_IE_CEL_EVENT_TYPE      = 0x000a,
 	/*! 
 	 * \brief Channel Event Time (seconds)
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_CEL_EVENT_TIME = 0x0b,
+	AST_EVENT_IE_CEL_EVENT_TIME      = 0x000b,
 	/*! 
 	 * \brief Channel Event Time (micro-seconds)
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_CEL_EVENT_TIME_USEC = 0x0c,
+	AST_EVENT_IE_CEL_EVENT_TIME_USEC = 0x000c,
 	/*! 
 	 * \brief Channel Event User Event Name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_USEREVENT_NAME = 0x0d,
+	AST_EVENT_IE_CEL_USEREVENT_NAME  = 0x000d,
 	/*! 
 	 * \brief Channel Event CID name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CIDNAME = 0x0e,
+	AST_EVENT_IE_CEL_CIDNAME         = 0x000e,
 	/*! 
 	 * \brief Channel Event CID num
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CIDNUM = 0x0f,
+	AST_EVENT_IE_CEL_CIDNUM          = 0x000f,
 	/*! 
 	 * \brief Channel Event extension name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_EXTEN = 0x10,
+	AST_EVENT_IE_CEL_EXTEN           = 0x0010,
 	/*! 
 	 * \brief Channel Event context name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CONTEXT = 0x11,
+	AST_EVENT_IE_CEL_CONTEXT         = 0x0011,
 	/*! 
 	 * \brief Channel Event channel name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CHANNAME = 0x12,
+	AST_EVENT_IE_CEL_CHANNAME        = 0x0012,
 	/*! 
 	 * \brief Channel Event app name
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_APPNAME = 0x13,
+	AST_EVENT_IE_CEL_APPNAME         = 0x0013,
 	/*! 
 	 * \brief Channel Event app args/data
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_APPDATA = 0x14,
+	AST_EVENT_IE_CEL_APPDATA         = 0x0014,
 	/*! 
 	 * \brief Channel Event AMA flags
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: UINT
 	 */
-	AST_EVENT_IE_CEL_AMAFLAGS = 0x15,
+	AST_EVENT_IE_CEL_AMAFLAGS        = 0x0015,
 	/*! 
 	 * \brief Channel Event AccountCode
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_ACCTCODE = 0x16,
+	AST_EVENT_IE_CEL_ACCTCODE        = 0x0016,
 	/*! 
 	 * \brief Channel Event UniqueID
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_UNIQUEID = 0x17,
+	AST_EVENT_IE_CEL_UNIQUEID        = 0x0017,
 	/*! 
 	 * \brief Channel Event Userfield
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_USERFIELD = 0x18,
+	AST_EVENT_IE_CEL_USERFIELD       = 0x0018,
 	/*! 
 	 * \brief Channel Event CID ANI field
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CIDANI = 0x19,
+	AST_EVENT_IE_CEL_CIDANI          = 0x0019,
 	/*! 
 	 * \brief Channel Event CID RDNIS field
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CIDRDNIS = 0x1a,
+	AST_EVENT_IE_CEL_CIDRDNIS        = 0x001a,
 	/*! 
 	 * \brief Channel Event CID dnid
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_CIDDNID = 0x1b,
+	AST_EVENT_IE_CEL_CIDDNID         = 0x001b,
 	/*! 
 	 * \brief Channel Event Peer -- for Things involving multiple channels, like BRIDGE
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_PEER = 0x1c,
+	AST_EVENT_IE_CEL_PEER            = 0x001c,
 	/*! 
 	 * \brief Channel Event LinkedID
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_LINKEDID = 0x1d,
+	AST_EVENT_IE_CEL_LINKEDID        = 0x001d,
 	/*! 
 	 * \brief Channel Event peeraccount
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_PEERACCT = 0x1e,
+	AST_EVENT_IE_CEL_PEERACCT        = 0x001e,
 	/*! 
 	 * \brief Channel Event extra data
 	 * Used by: AST_EVENT_CEL
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_CEL_EXTRA = 0x1f,
+	AST_EVENT_IE_CEL_EXTRA           = 0x001f,
 	/*!
 	 * \brief Description
 	 * Used by: AST_EVENT_SUB, AST_EVENT_UNSUB
 	 * Payload type: STR
 	 */
-	AST_EVENT_IE_DESCRIPTION = 0x20,
+	AST_EVENT_IE_DESCRIPTION         = 0x0020,
 	/*!
 	 * \brief Entity ID
 	 * Used by All events
 	 * Payload type: RAW
 	 * This IE indicates which server the event originated from
 	 */
-	AST_EVENT_IE_EID      = 0x21,
-};
-
-#define AST_EVENT_IE_MAX AST_EVENT_IE_EID
+	AST_EVENT_IE_EID                 = 0x0021,
+	AST_EVENT_IE_SECURITY_EVENT      = 0x0022,
+	AST_EVENT_IE_EVENT_VERSION       = 0x0023,
+	AST_EVENT_IE_SERVICE             = 0x0024,
+	AST_EVENT_IE_MODULE              = 0x0025,
+	AST_EVENT_IE_ACCOUNT_ID          = 0x0026,
+	AST_EVENT_IE_SESSION_ID          = 0x0027,
+	AST_EVENT_IE_SESSION_TV          = 0x0028,
+	AST_EVENT_IE_ACL_NAME            = 0x0029,
+	AST_EVENT_IE_LOCAL_ADDR          = 0x002a,
+	AST_EVENT_IE_REMOTE_ADDR         = 0x002b,
+	AST_EVENT_IE_EVENT_TV            = 0x002c,
+	AST_EVENT_IE_REQUEST_TYPE        = 0x002d,
+	AST_EVENT_IE_REQUEST_PARAMS      = 0x002e,
+	AST_EVENT_IE_AUTH_METHOD         = 0x002f,
+	AST_EVENT_IE_SEVERITY            = 0x0030,
+	AST_EVENT_IE_EXPECTED_ADDR       = 0x0031,
+	AST_EVENT_IE_CHALLENGE           = 0x0032,
+	AST_EVENT_IE_RESPONSE            = 0x0033,
+	AST_EVENT_IE_EXPECTED_RESPONSE   = 0x0034,
+	/*! \brief Must be the last IE value +1 */
+	AST_EVENT_IE_TOTAL               = 0x0035,
+};
 
 /*!
  * \brief Payload types for event information elements

Modified: trunk/main/event.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/main/event.c?view=diff&rev=206021&r1=206020&r2=206021
==============================================================================
--- trunk/main/event.c (original)
+++ trunk/main/event.c Sat Jul 11 14:15:03 2009
@@ -183,63 +183,77 @@
 };
 
 /*!
- * The index of each entry _must_ match the event type number!
+ * \brief Event Names
  */
-static struct event_name {
-	enum ast_event_type type;
-	const char *name;
-} event_names[] = {
-	{ 0, "" },
-	{ AST_EVENT_CUSTOM,              "Custom" },
-	{ AST_EVENT_MWI,                 "MWI" },
-	{ AST_EVENT_SUB,                 "Subscription" },
-	{ AST_EVENT_UNSUB,               "Unsubscription" },
-	{ AST_EVENT_DEVICE_STATE,        "DeviceState" },
-	{ AST_EVENT_DEVICE_STATE_CHANGE, "DeviceStateChange" },
-	{ AST_EVENT_CEL, "CEL" },
+static const char * const event_names[AST_EVENT_TOTAL] = {
+	[AST_EVENT_CUSTOM]              = "Custom",
+	[AST_EVENT_MWI]                 = "MWI",
+	[AST_EVENT_SUB]                 = "Subscription",
+	[AST_EVENT_UNSUB]               = "Unsubscription",
+	[AST_EVENT_DEVICE_STATE]        = "DeviceState",
+	[AST_EVENT_DEVICE_STATE_CHANGE] = "DeviceStateChange",
+	[AST_EVENT_CEL]                 = "CEL",
+	[AST_EVENT_SECURITY]            = "Security",
 };
 
 /*!
- * The index of each entry _must_ match the event ie number!
+ * \brief IE payload types and names
  */
-static struct ie_map {
-	enum ast_event_ie_type ie_type;
+static const struct ie_map {
 	enum ast_event_ie_pltype ie_pltype;
 	const char *name;
-} ie_maps[] = {
-	{ 0, 0, "" },
-	{ AST_EVENT_IE_NEWMSGS,              AST_EVENT_IE_PLTYPE_UINT, "NewMessages" },
-	{ AST_EVENT_IE_OLDMSGS,              AST_EVENT_IE_PLTYPE_UINT, "OldMessages" },
-	{ AST_EVENT_IE_MAILBOX,              AST_EVENT_IE_PLTYPE_STR,  "Mailbox" },
-	{ AST_EVENT_IE_UNIQUEID,             AST_EVENT_IE_PLTYPE_UINT, "UniqueID" },
-	{ AST_EVENT_IE_EVENTTYPE,            AST_EVENT_IE_PLTYPE_UINT, "EventType" },
-	{ AST_EVENT_IE_EXISTS,               AST_EVENT_IE_PLTYPE_UINT, "Exists" },
-	{ AST_EVENT_IE_DEVICE,               AST_EVENT_IE_PLTYPE_STR,  "Device" },
-	{ AST_EVENT_IE_STATE,                AST_EVENT_IE_PLTYPE_UINT, "State" },
-	{ AST_EVENT_IE_CONTEXT,              AST_EVENT_IE_PLTYPE_STR,  "Context" },
-	{ AST_EVENT_IE_EID,                  AST_EVENT_IE_PLTYPE_RAW,  "EntityID" },
-	{ AST_EVENT_IE_CEL_EVENT_TYPE,       AST_EVENT_IE_PLTYPE_UINT,  "CELEventType" },
-	{ AST_EVENT_IE_CEL_EVENT_TIME,       AST_EVENT_IE_PLTYPE_UINT,  "CELEventTime" },
-	{ AST_EVENT_IE_CEL_EVENT_TIME_USEC,  AST_EVENT_IE_PLTYPE_UINT,  "CELEventTimeUSec" },
-	{ AST_EVENT_IE_CEL_USEREVENT_NAME,   AST_EVENT_IE_PLTYPE_UINT,  "CELUserEventName" },
-	{ AST_EVENT_IE_CEL_CIDNAME,          AST_EVENT_IE_PLTYPE_STR,  "CELCIDName" },
-	{ AST_EVENT_IE_CEL_CIDNUM,           AST_EVENT_IE_PLTYPE_STR,  "CELCIDNum" },
-	{ AST_EVENT_IE_CEL_EXTEN,            AST_EVENT_IE_PLTYPE_STR,  "CELExten" },
-	{ AST_EVENT_IE_CEL_CONTEXT,          AST_EVENT_IE_PLTYPE_STR,  "CELContext" },
-	{ AST_EVENT_IE_CEL_CHANNAME,         AST_EVENT_IE_PLTYPE_STR,  "CELChanName" },
-	{ AST_EVENT_IE_CEL_APPNAME,          AST_EVENT_IE_PLTYPE_STR,  "CELAppName" },
-	{ AST_EVENT_IE_CEL_APPDATA,          AST_EVENT_IE_PLTYPE_STR,  "CELAppData" },
-	{ AST_EVENT_IE_CEL_AMAFLAGS,         AST_EVENT_IE_PLTYPE_STR,  "CELAMAFlags" },
-	{ AST_EVENT_IE_CEL_ACCTCODE,         AST_EVENT_IE_PLTYPE_UINT,  "CELAcctCode" },
-	{ AST_EVENT_IE_CEL_UNIQUEID,         AST_EVENT_IE_PLTYPE_STR,  "CELUniqueID" },
-	{ AST_EVENT_IE_CEL_USERFIELD,        AST_EVENT_IE_PLTYPE_STR,  "CELUserField" },
-	{ AST_EVENT_IE_CEL_CIDANI,           AST_EVENT_IE_PLTYPE_STR,  "CELCIDani" },
-	{ AST_EVENT_IE_CEL_CIDRDNIS,         AST_EVENT_IE_PLTYPE_STR,  "CELCIDrdnis" },
-	{ AST_EVENT_IE_CEL_CIDDNID,          AST_EVENT_IE_PLTYPE_STR,  "CELCIDdnid" },
-	{ AST_EVENT_IE_CEL_PEER,             AST_EVENT_IE_PLTYPE_STR,  "CELPeer" },
-	{ AST_EVENT_IE_CEL_LINKEDID,         AST_EVENT_IE_PLTYPE_STR,  "CELLinkedID" },
-	{ AST_EVENT_IE_CEL_PEERACCT,         AST_EVENT_IE_PLTYPE_STR,  "CELPeerAcct" },
-	{ AST_EVENT_IE_CEL_EXTRA,            AST_EVENT_IE_PLTYPE_STR,  "CELExtra" },
+} ie_maps[AST_EVENT_IE_TOTAL] = {
+	[AST_EVENT_IE_NEWMSGS]             = { AST_EVENT_IE_PLTYPE_UINT, "NewMessages" },
+	[AST_EVENT_IE_OLDMSGS]             = { AST_EVENT_IE_PLTYPE_UINT, "OldMessages" },
+	[AST_EVENT_IE_MAILBOX]             = { AST_EVENT_IE_PLTYPE_STR,  "Mailbox" },
+	[AST_EVENT_IE_UNIQUEID]            = { AST_EVENT_IE_PLTYPE_UINT, "UniqueID" },
+	[AST_EVENT_IE_EVENTTYPE]           = { AST_EVENT_IE_PLTYPE_UINT, "EventType" },
+	[AST_EVENT_IE_EXISTS]              = { AST_EVENT_IE_PLTYPE_UINT, "Exists" },
+	[AST_EVENT_IE_DEVICE]              = { AST_EVENT_IE_PLTYPE_STR,  "Device" },
+	[AST_EVENT_IE_STATE]               = { AST_EVENT_IE_PLTYPE_UINT, "State" },
+	[AST_EVENT_IE_CONTEXT]             = { AST_EVENT_IE_PLTYPE_STR,  "Context" },
+	[AST_EVENT_IE_EID]                 = { AST_EVENT_IE_PLTYPE_RAW,  "EntityID" },
+	[AST_EVENT_IE_CEL_EVENT_TYPE]      = { AST_EVENT_IE_PLTYPE_UINT, "CELEventType" },
+	[AST_EVENT_IE_CEL_EVENT_TIME]      = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTime" },
+	[AST_EVENT_IE_CEL_EVENT_TIME_USEC] = { AST_EVENT_IE_PLTYPE_UINT, "CELEventTimeUSec" },
+	[AST_EVENT_IE_CEL_USEREVENT_NAME]  = { AST_EVENT_IE_PLTYPE_UINT, "CELUserEventName" },
+	[AST_EVENT_IE_CEL_CIDNAME]         = { AST_EVENT_IE_PLTYPE_STR,  "CELCIDName" },
+	[AST_EVENT_IE_CEL_CIDNUM]          = { AST_EVENT_IE_PLTYPE_STR,  "CELCIDNum" },
+	[AST_EVENT_IE_CEL_EXTEN]           = { AST_EVENT_IE_PLTYPE_STR,  "CELExten" },
+	[AST_EVENT_IE_CEL_CONTEXT]         = { AST_EVENT_IE_PLTYPE_STR,  "CELContext" },
+	[AST_EVENT_IE_CEL_CHANNAME]        = { AST_EVENT_IE_PLTYPE_STR,  "CELChanName" },
+	[AST_EVENT_IE_CEL_APPNAME]         = { AST_EVENT_IE_PLTYPE_STR,  "CELAppName" },
+	[AST_EVENT_IE_CEL_APPDATA]         = { AST_EVENT_IE_PLTYPE_STR,  "CELAppData" },
+	[AST_EVENT_IE_CEL_AMAFLAGS]        = { AST_EVENT_IE_PLTYPE_STR,  "CELAMAFlags" },
+	[AST_EVENT_IE_CEL_ACCTCODE]        = { AST_EVENT_IE_PLTYPE_UINT, "CELAcctCode" },
+	[AST_EVENT_IE_CEL_UNIQUEID]        = { AST_EVENT_IE_PLTYPE_STR,  "CELUniqueID" },
+	[AST_EVENT_IE_CEL_USERFIELD]       = { AST_EVENT_IE_PLTYPE_STR,  "CELUserField" },
+	[AST_EVENT_IE_CEL_CIDANI]          = { AST_EVENT_IE_PLTYPE_STR,  "CELCIDani" },
+	[AST_EVENT_IE_CEL_CIDRDNIS]        = { AST_EVENT_IE_PLTYPE_STR,  "CELCIDrdnis" },
+	[AST_EVENT_IE_CEL_CIDDNID]         = { AST_EVENT_IE_PLTYPE_STR,  "CELCIDdnid" },
+	[AST_EVENT_IE_CEL_PEER]            = { AST_EVENT_IE_PLTYPE_STR,  "CELPeer" },
+	[AST_EVENT_IE_CEL_LINKEDID]        = { AST_EVENT_IE_PLTYPE_STR,  "CELLinkedID" },
+	[AST_EVENT_IE_CEL_PEERACCT]        = { AST_EVENT_IE_PLTYPE_STR,  "CELPeerAcct" },
+	[AST_EVENT_IE_CEL_EXTRA]           = { AST_EVENT_IE_PLTYPE_STR,  "CELExtra" },
+	[AST_EVENT_IE_SECURITY_EVENT]      = { AST_EVENT_IE_PLTYPE_STR,  "SecurityEvent" },
+	[AST_EVENT_IE_EVENT_VERSION]       = { AST_EVENT_IE_PLTYPE_UINT, "EventVersion" },
+	[AST_EVENT_IE_SERVICE]             = { AST_EVENT_IE_PLTYPE_STR,  "Service" },
+	[AST_EVENT_IE_MODULE]              = { AST_EVENT_IE_PLTYPE_STR,  "Module" },
+	[AST_EVENT_IE_ACCOUNT_ID]          = { AST_EVENT_IE_PLTYPE_STR,  "AccountID" },
+	[AST_EVENT_IE_SESSION_ID]          = { AST_EVENT_IE_PLTYPE_STR,  "SessionID" },
+	[AST_EVENT_IE_SESSION_TV]          = { AST_EVENT_IE_PLTYPE_STR,  "SessionTV" },
+	[AST_EVENT_IE_ACL_NAME]            = { AST_EVENT_IE_PLTYPE_STR,  "ACLName" },
+	[AST_EVENT_IE_LOCAL_ADDR]          = { AST_EVENT_IE_PLTYPE_STR,  "LocalAddress" },
+	[AST_EVENT_IE_REMOTE_ADDR]         = { AST_EVENT_IE_PLTYPE_STR,  "RemoteAddress" },
+	[AST_EVENT_IE_EVENT_TV]            = { AST_EVENT_IE_PLTYPE_STR,  "EventTV" },
+	[AST_EVENT_IE_REQUEST_TYPE]        = { AST_EVENT_IE_PLTYPE_STR,  "RequestType" },
+	[AST_EVENT_IE_REQUEST_PARAMS]      = { AST_EVENT_IE_PLTYPE_STR,  "RequestParams" },
+	[AST_EVENT_IE_AUTH_METHOD]         = { AST_EVENT_IE_PLTYPE_STR,  "AuthMethod" },
+	[AST_EVENT_IE_SEVERITY]            = { AST_EVENT_IE_PLTYPE_STR,  "Severity" },
+	[AST_EVENT_IE_EXPECTED_ADDR]       = { AST_EVENT_IE_PLTYPE_STR,  "ExpectedAddress" },
+	[AST_EVENT_IE_CHALLENGE]           = { AST_EVENT_IE_PLTYPE_STR,  "Challenge" },
+	[AST_EVENT_IE_RESPONSE]            = { AST_EVENT_IE_PLTYPE_STR,  "Response" },
+	[AST_EVENT_IE_EXPECTED_RESPONSE]   = { AST_EVENT_IE_PLTYPE_STR,  "ExpectedResponse" },
 };
 
 const char *ast_event_get_type_name(const struct ast_event *event)
@@ -248,12 +262,12 @@
 
 	type = ast_event_get_type(event);
 
-	if (type >= AST_EVENT_TOTAL || type < 0) {
+	if (type < 0 || type >= ARRAY_LEN(event_names)) {
 		ast_log(LOG_ERROR, "Invalid event type - '%d'\n", type);
 		return "";
 	}
 
-	return event_names[type].name;
+	return event_names[type];
 }
 
 int ast_event_str_to_event_type(const char *str, enum ast_event_type *event_type)
@@ -261,10 +275,11 @@
 	int i;
 
 	for (i = 0; i < ARRAY_LEN(event_names); i++) {
-		if (strcasecmp(event_names[i].name, str))
+		if (strcasecmp(event_names[i], str)) {
 			continue;
-
-		*event_type = event_names[i].type;
+		}
+
+		*event_type = i;
 		return 0;
 	}
 
@@ -273,31 +288,21 @@
 
 const char *ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
 {
-	if (ie_type <= 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
 		ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
 		return "";
 	}
 
-	if (ie_maps[ie_type].ie_type != ie_type) {
-		ast_log(LOG_ERROR, "The ie type passed in does not match the ie type defined in the ie table.\n");
-		return "";
-	}
-
 	return ie_maps[ie_type].name;
 }
 
 enum ast_event_ie_pltype ast_event_get_ie_pltype(enum ast_event_ie_type ie_type)
 {
-	if (ie_type <= 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= ARRAY_LEN(ie_maps)) {
 		ast_log(LOG_ERROR, "Invalid IE type - '%d'\n", ie_type);
 		return AST_EVENT_IE_PLTYPE_UNKNOWN;
 	}
 
-	if (ie_maps[ie_type].ie_type != ie_type) {
-		ast_log(LOG_ERROR, "The ie type passed in does not match the ie type defined in the ie table.\n");
-		return AST_EVENT_IE_PLTYPE_UNKNOWN;
-	}
-
 	return ie_maps[ie_type].ie_pltype;
 }
 
@@ -306,10 +311,11 @@
 	int i;
 
 	for (i = 0; i < ARRAY_LEN(ie_maps); i++) {
-		if (strcasecmp(ie_maps[i].name, str))
+		if (strcasecmp(ie_maps[i].name, str)) {
 			continue;
-
-		*ie_type = ie_maps[i].ie_type;
+		}
+
+		*ie_type = i;
 		return 0;
 	}
 
@@ -661,7 +667,7 @@
 {
 	struct ast_event_ie_val *ie_val;
 
-	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
 		return -1;
 	}
 
@@ -683,11 +689,13 @@
 {
 	struct ast_event_ie_val *ie_val;
 
-	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX)
-		return -1;
-
-	if (!(ie_val = ast_calloc(1, sizeof(*ie_val))))
-		return -1;
+	if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
+		return -1;
+	}
+
+	if (!(ie_val = ast_calloc(1, sizeof(*ie_val)))) {
+		return -1;
+	}
 
 	ie_val->ie_type = ie_type;
 	ie_val->payload.uint = flags;
@@ -703,7 +711,7 @@
 {
 	struct ast_event_ie_val *ie_val;
 
-	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
 		return -1;
 	}
 
@@ -724,7 +732,7 @@
 {
 	struct ast_event_ie_val *ie_val;
 
-	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
 		return -1;
 	}
 
@@ -752,7 +760,7 @@
 {
 	struct ast_event_ie_val *ie_val;
 
-	if (ie_type < 0 || ie_type > AST_EVENT_IE_MAX) {
+	if (ie_type <= 0 || ie_type >= AST_EVENT_IE_TOTAL) {
 		return -1;
 	}
 

Modified: trunk/main/manager.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/main/manager.c?view=diff&rev=206021&r1=206020&r2=206021
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Sat Jul 11 14:15:03 2009
@@ -74,6 +74,7 @@
 #include "asterisk/term.h"
 #include "asterisk/astobj2.h"
 #include "asterisk/features.h"
+#include "asterisk/security_events.h"
 
 /*** DOCUMENTATION
 	<manager name="Ping" language="en_US">
@@ -807,6 +808,7 @@
 	pthread_t waiting_thread;	/*!< Sleeping thread using this descriptor */
 	uint32_t managerid;	/*!< Unique manager identifier, 0 for AMI sessions */
 	time_t sessionstart;    /*!< Session start time */
+	struct timeval sessionstart_tv; /*!< Session start time */
 	time_t sessiontimeout;	/*!< Session timeout if HTTP */
 	char username[80];	/*!< Logged in username */
 	char challenge[10];	/*!< Authentication challenge */
@@ -834,6 +836,7 @@
  */
 struct mansession {
 	struct mansession_session *session;
+	struct ast_tcptls_session_instance *tcptls_session;
 	FILE *f;
 	int fd;
 	ast_mutex_t lock;
@@ -1735,6 +1738,241 @@
 	return maskint;
 }
 
+static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
+{
+	return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS :
+			AST_SECURITY_EVENT_TRANSPORT_TCP;
+}
+
+static struct sockaddr_in *mansession_encode_sin_local(const struct mansession *s,
+		struct sockaddr_in *sin_local)
+{
+	*sin_local = s->tcptls_session->parent->local_address;
+
+	return sin_local;
+}
+
+static void report_invalid_user(const struct mansession *s, const char *username)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_inval_acct_id inval_acct_id = {
+		.common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
+		.common.version    = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s);
+
+	ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
+}
+
+static void report_failed_acl(const struct mansession *s, const char *username)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_failed_acl failed_acl_event = {
+		.common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
+		.common.version    = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+
+	ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
+}
+
+static void report_inval_password(const struct mansession *s, const char *username)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_inval_password inval_password = {
+		.common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
+		.common.version    = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+
+	ast_security_event_report(AST_SEC_EVT(&inval_password));
+}
+
+static void report_auth_success(const struct mansession *s)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_successful_auth successful_auth = {
+		.common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
+		.common.version    = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = s->session->username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+
+	ast_security_event_report(AST_SEC_EVT(&successful_auth));
+}
+
+static void report_req_not_allowed(const struct mansession *s, const char *action)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	char request_type[64];
+	struct ast_security_event_req_not_allowed req_not_allowed = {
+		.common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED,
+		.common.version    = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = s->session->username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+
+		.request_type      = request_type,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+	snprintf(request_type, sizeof(request_type), "Action: %s", action);
+
+	ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
+}
+
+static void report_req_bad_format(const struct mansession *s, const char *action)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	char request_type[64];
+	struct ast_security_event_req_bad_format req_bad_format = {
+		.common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT,
+		.common.version    = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = s->session->username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+
+		.request_type      = request_type,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+	snprintf(request_type, sizeof(request_type), "Action: %s", action);
+
+	ast_security_event_report(AST_SEC_EVT(&req_bad_format));
+}
+
+static void report_failed_challenge_response(const struct mansession *s,
+		const char *response, const char *expected_response)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_chal_resp_failed chal_resp_failed = {
+		.common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
+		.common.version    = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = s->session->username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+
+		.challenge         = s->session->challenge,
+		.response          = response,
+		.expected_response = expected_response,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+
+	ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
+}
+
+static void report_session_limit(const struct mansession *s)
+{
+	struct sockaddr_in sin_local;
+	char session_id[32];
+	struct ast_security_event_session_limit session_limit = {
+		.common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
+		.common.version    = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
+		.common.service    = "AMI",
+		.common.account_id = s->session->username,
+		.common.session_tv = &s->session->sessionstart_tv,
+		.common.local_addr = {
+			.sin       = mansession_encode_sin_local(s, &sin_local),
+			.transport = mansession_get_transport(s),
+		},
+		.common.remote_addr = {
+			.sin       = &s->session->sin,
+			.transport = mansession_get_transport(s),
+		},
+		.common.session_id = session_id,
+	};
+
+	snprintf(session_id, sizeof(session_id), "%p", s->session);
+
+	ast_security_event_report(AST_SEC_EVT(&session_limit));
+}
+
 /*
  * Here we start with action_ handlers for AMI actions,
  * and the internal functions used by them.
@@ -1757,8 +1995,10 @@
 	AST_RWLIST_WRLOCK(&users);
 
 	if (!(user = get_manager_by_name_locked(username))) {
+		report_invalid_user(s, username);
 		ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
 	} else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
+		report_failed_acl(s, username);
 		ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
 	} else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
 		const char *key = astman_get_header(m, "Key");
@@ -1777,13 +2017,19 @@
 				len += sprintf(md5key + len, "%2.2x", digest[x]);
 			if (!strcmp(md5key, key)) {
 				error = 0;
+			} else {
+				report_failed_challenge_response(s, key, md5key);
 			}
 		} else {
 			ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n",
 				S_OR(s->session->challenge, ""));
 		}
-	} else if (password && user->secret && !strcmp(password, user->secret)) {
-		error = 0;
+	} else if (user->secret) {
+		if (!strcmp(password, user->secret)) {
+			error = 0;
+		} else {
+			report_inval_password(s, username);
+		}
 	}
 
 	if (error) {
@@ -1799,7 +2045,10 @@
 	s->session->writeperm = user->writeperm;
 	s->session->writetimeout = user->writetimeout;
 	s->session->sessionstart = time(NULL);
+	s->session->sessionstart_tv = ast_tvnow();
 	set_eventmask(s, astman_get_header(m, "Events"));
+
+	report_auth_success(s);
 
 	AST_RWLIST_UNLOCK(&users);
 	return 0;
@@ -3550,6 +3799,7 @@
 	ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action));
 
 	if (ast_strlen_zero(action)) {
+		report_req_bad_format(s, "NONE");
 		mansession_lock(s);
 		astman_send_error(s, m, "Missing action in request");
 		mansession_unlock(s);
@@ -3557,6 +3807,9 @@
 	}
 
 	if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
+		if (!s->session->authenticated) {
+			report_req_not_allowed(s, action);
+		}
 		mansession_lock(s);
 		astman_send_error(s, m, "Permission denied");
 		mansession_unlock(s);
@@ -3566,6 +3819,7 @@
 	if (!allowmultiplelogin && !s->session->authenticated && user &&
 		(!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
 		if (check_manager_session_inuse(user)) {
+			report_session_limit(s);
 			sleep(1);
 			mansession_lock(s);
 			astman_send_error(s, m, "Login Already In Use");
@@ -3583,7 +3837,7 @@
 			call_func = tmp->func;
 		} else {
 			astman_send_error(s, m, "Permission denied");
-			tmp = NULL;
+			report_req_not_allowed(s, action);
 		}
 		break;
 	}
@@ -3595,6 +3849,9 @@
 		ret = call_func(s, m);
 	} else {
 		char buf[512];
+		if (!tmp) {
+			report_req_bad_format(s, action);
+		}
 		snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
 		mansession_lock(s);
 		astman_send_error(s, m, buf);
@@ -3733,7 +3990,9 @@
 {
 	struct ast_tcptls_session_instance *ser = data;
 	struct mansession_session *session = build_mansession(ser->remote_address);
-	struct mansession s = { NULL, };
+	struct mansession s = {
+		.tcptls_session = data,
+	};
 	int flags;
 	int res;
 




More information about the svn-commits mailing list