[asterisk-commits] russell: branch group/security_events r192850 - in /team/group/security_event...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 6 16:26:51 CDT 2009


Author: russell
Date: Wed May  6 16:26:47 2009
New Revision: 192850

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=192850
Log:
Report failed ACL events in chan_sip, and finish most of the logger module, in theory

Modified:
    team/group/security_events/channels/chan_sip.c
    team/group/security_events/include/asterisk/security_events.h
    team/group/security_events/main/security_events.c
    team/group/security_events/res/res_security_log.c

Modified: team/group/security_events/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/channels/chan_sip.c?view=diff&rev=192850&r1=192849&r2=192850
==============================================================================
--- team/group/security_events/channels/chan_sip.c (original)
+++ team/group/security_events/channels/chan_sip.c Wed May  6 16:26:47 2009
@@ -272,6 +272,7 @@
 #include "asterisk/event.h"
 #include "asterisk/tcptls.h"
 #include "asterisk/stun.h"
+#include "asterisk/security_events.h"
 
 /*** DOCUMENTATION
 	<application name="SIPDtmfMode" language="en_US">
@@ -1780,7 +1781,8 @@
 	int hangupcause;			/*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */
 
 	struct sip_subscription_mwi *mwi;       /*!< If this is a subscription MWI dialog, to which subscription */
-}; 
+	struct timeval session_tv;		/*!< The time this dialog started */
+};
 
 
 /*! \brief
@@ -6884,6 +6886,8 @@
 	ast_string_field_set(p, engine, default_engine);
 
 	AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
+
+	p->session_tv = ast_tvnow();
 
 	/* Add to active dialog list */
 
@@ -11610,6 +11614,68 @@
 	return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
 }
 
+static enum ast_security_event_transport_type security_event_transport_type(
+		const enum sip_transport sip_transport)
+{
+	switch (sip_transport) {
+	case SIP_TRANSPORT_UDP:
+		return AST_SECURITY_EVENT_TRANSPORT_UDP;
+	case SIP_TRANSPORT_TCP:
+		return AST_SECURITY_EVENT_TRANSPORT_TCP;
+	case SIP_TRANSPORT_TLS:
+		return AST_SECURITY_EVENT_TRANSPORT_TLS;
+	}
+
+	ast_log(LOG_ERROR, "Unknown SIP transport type '%u'\n", sip_transport);
+
+	return 0;
+}
+
+static struct sockaddr_in *encode_sin_local(struct sockaddr_in *sin_local,
+		const struct sip_pvt *pvt)
+{
+	socklen_t sin_local_len;
+
+	if (pvt->socket.type == SIP_TRANSPORT_UDP) {
+		memcpy(sin_local, &bindaddr, sizeof(*sin_local));
+		return sin_local;
+	}
+
+	if (!pvt->socket.tcptls_session) {
+		ast_log(LOG_ERROR, "No TCP/TLS session on sip_pvt that isn't UDP\n");
+		return sin_local;
+	}
+
+	sin_local_len = sizeof(*sin_local);
+	if (getsockname(pvt->socket.tcptls_session->fd, sin_local, &sin_local_len)) {
+		ast_log(LOG_WARNING, "getsockname() failed: %s\n", strerror(errno));
+	}
+
+	return sin_local;
+}
+
+static void report_failed_acl(const struct sip_peer *peer, const struct sip_pvt *pvt,
+		const struct sockaddr_in *sin_remote, const char *acl_name)
+{
+	struct sockaddr_in sin_local = { 0, };
+	const 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    = "SIP",
+
+		.module     = AST_MODULE,
+		.account_id = peer->name,
+		.session_id = pvt->callid,
+		.acl_name   = acl_name,
+		.session_tv = &pvt->session_tv,
+		.sin_local  = encode_sin_local(&sin_local, pvt),
+		.sin_remote = sin_remote,
+		.transport  = security_event_transport_type(pvt->socket.type),
+	};
+
+	ast_security_event_report(
+			(struct ast_security_event_common *) &failed_acl_event);
+}
 
 /*! \brief Parse contact header and save registration (peer registration) */
 static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
@@ -11724,11 +11790,16 @@
 		return PARSE_REGISTER_FAILED;
 	}
 	memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr));
+	testsin.sin_port = htons(port);
 	if (ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW ||
 			ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
+		report_failed_acl(peer, pvt, &testsin, "ContactACL");
+
 		ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", host);
+
 		ast_string_field_set(peer, fullcontact, "");
 		ast_string_field_set(pvt, our_contact, "");
+
 		return PARSE_REGISTER_FAILED;
 	}
 
@@ -12348,6 +12419,8 @@
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		/* Peer fails ACL check */
 		if (peer) {
+			report_failed_acl(peer, p, sin, "PeerACL");
+
 			unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
 			peer = NULL;
 			res = AUTH_ACL_FAILED;

Modified: team/group/security_events/include/asterisk/security_events.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/include/asterisk/security_events.h?view=diff&rev=192850&r1=192849&r2=192850
==============================================================================
--- team/group/security_events/include/asterisk/security_events.h (original)
+++ team/group/security_events/include/asterisk/security_events.h Wed May  6 16:26:47 2009
@@ -43,6 +43,7 @@
 enum ast_security_event_transport_type {
 	AST_SECURITY_EVENT_TRANSPORT_UDP,
 	AST_SECURITY_EVENT_TRANSPORT_TCP,
+	AST_SECURITY_EVENT_TRANSPORT_TLS,
 };
 
 /*!
@@ -70,14 +71,20 @@
 	/*! \brief required */
 	const struct sockaddr_in *sin_local;
 	/*! \brief required */
-	enum ast_security_event_transport_type local_transport;
-	/*! \brief required */
 	const struct sockaddr_in *sin_remote;
 	/*! \brief required */
-	enum ast_security_event_transport_type remote_transport;
+	enum ast_security_event_transport_type transport;
 };
 
 int ast_security_event_report(const struct ast_security_event_common *sec);
+
+const enum ast_event_ie_type *ast_security_event_get_required_ies(
+		const enum ast_security_event_type event_type);
+
+const enum ast_event_ie_type *ast_security_event_get_optional_ies(
+		const enum ast_security_event_type event_type);
+
+const char *ast_security_event_get_name(const enum ast_security_event_type event_type);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/group/security_events/main/security_events.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/main/security_events.c?view=diff&rev=192850&r1=192849&r2=192850
==============================================================================
--- team/group/security_events/main/security_events.c (original)
+++ team/group/security_events/main/security_events.c Wed May  6 16:26:47 2009
@@ -37,16 +37,75 @@
 
 static int handle_failed_acl(const struct ast_security_event_common *sec);
 
-struct {
-	enum ast_security_event_type event_type;
+static const struct {
+	const char *name;
 	uint32_t version;
 	int (*handler)(const struct ast_security_event_common *);
+#define MAX_SECURITY_IES 6
+	enum ast_event_ie_type required_ies[MAX_SECURITY_IES];
+	enum ast_event_ie_type optional_ies[MAX_SECURITY_IES];
+#undef MAX_SECURITY_IES
 } sec_events[AST_SECURITY_EVENT_NUM_TYPES] = {
 	[AST_SECURITY_EVENT_FAILED_ACL] = {
-		.version    = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
-		.handler    = handle_failed_acl,
+		.name    = "FailedACL",
+		.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
+		.handler = handle_failed_acl,
+		.required_ies = {
+			AST_EVENT_IE_EVENT_VERSION,
+			AST_EVENT_IE_ACCOUNT_ID,
+			AST_EVENT_IE_SESSION_ID,
+			AST_EVENT_IE_LOCAL_ADDR,
+			AST_EVENT_IE_REMOTE_ADDR,
+			AST_EVENT_IE_END
+		},
+		.optional_ies = {
+			AST_EVENT_IE_MODULE,
+			AST_EVENT_IE_ACL_NAME,
+			AST_EVENT_IE_SESSION_TV,
+			AST_EVENT_IE_END
+		},
+
 	},
 };
+
+static int check_event_type(const enum ast_security_event_type event_type)
+{
+	if (event_type < 0 || event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
+		ast_log(LOG_ERROR, "Invalid security event type %u\n", event_type);
+		return -1;
+	}
+
+	return 0;
+}
+
+const char *ast_security_event_get_name(const enum ast_security_event_type event_type)
+{
+	if (check_event_type(event_type)) {
+		return NULL;
+	}
+
+	return sec_events[event_type].name;
+}
+
+const enum ast_event_ie_type *ast_security_event_get_required_ies(
+		const enum ast_security_event_type event_type)
+{
+	if (check_event_type(event_type)) {
+		return NULL;
+	}
+
+	return sec_events[event_type].required_ies;
+}
+
+const enum ast_event_ie_type *ast_security_event_get_optional_ies(
+		const enum ast_security_event_type event_type)
+{
+	if (check_event_type(event_type)) {
+		return NULL;
+	}
+
+	return sec_events[event_type].optional_ies;
+}
 
 static void encode_timestamp(struct ast_str **str, const struct timeval *tv)
 {
@@ -121,6 +180,9 @@
 	case AST_SECURITY_EVENT_TRANSPORT_TCP:
 		ast_str_append(&str, 0, "TCP/");
 		break;
+	case AST_SECURITY_EVENT_TRANSPORT_TLS:
+		ast_str_append(&str, 0, "TLS/");
+		break;
 	}
 
 	ast_str_append(&str, 0, "%s/%hu",
@@ -158,9 +220,9 @@
 	}
 
 	add_ipv4_ie(&event, AST_EVENT_IE_LOCAL_ADDR,
-			failed_acl->sin_local, failed_acl->local_transport);
+			failed_acl->sin_local, failed_acl->transport);
 	add_ipv4_ie(&event, AST_EVENT_IE_REMOTE_ADDR,
-			failed_acl->sin_remote, failed_acl->remote_transport);
+			failed_acl->sin_remote, failed_acl->transport);
 
 	return 0;
 }

Modified: team/group/security_events/res/res_security_log.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/res/res_security_log.c?view=diff&rev=192850&r1=192849&r2=192850
==============================================================================
--- team/group/security_events/res/res_security_log.c (original)
+++ team/group/security_events/res/res_security_log.c Wed May  6 16:26:47 2009
@@ -21,7 +21,7 @@
  *
  * \author Russell Bryant <russell at digium.com>
  *
- * \brief Security Logging
+ * \brief Security Event Logging
  */
 
 #include "asterisk.h"
@@ -31,53 +31,94 @@
 #include "asterisk/module.h"
 #include "asterisk/logger.h"
 #include "asterisk/event.h"
+#include "asterisk/threadstorage.h"
+#include "asterisk/strings.h"
 #include "asterisk/security_events.h"
 
 static struct ast_event_sub *security_event_sub;
 
-static const struct {
-	uint32_t version;
-#define MAX_SECURITY_IES 4
-	const enum ast_event_ie_type required_ies[MAX_SECURITY_IES];
-	const enum ast_event_ie_type optional_ies[MAX_SECURITY_IES];
-#undef MAX_SECURITY_IES
-} event_handlers[AST_SECURITY_EVENT_NUM_TYPES] = {
-	[AST_SECURITY_EVENT_FAILED_ACL] = {
-		.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
-		.required_ies = {
-			AST_EVENT_IE_ACCOUNT_ID,
-			AST_EVENT_IE_SESSION_ID,
-			AST_EVENT_IE_LOCAL_ADDR,
-			AST_EVENT_IE_REMOTE_ADDR,
-		},
-		.optional_ies = {
-			AST_EVENT_IE_MODULE,
-			AST_EVENT_IE_ACL_NAME,
-			AST_EVENT_IE_SESSION_TV,
-		},
-	},
+AST_THREADSTORAGE(security_event_buf);
+static const size_t security_event_buf_init_len = 256;
+
+enum ie_required {
+	NOT_REQUIRED,
+	REQUIRED
 };
+
+static int ie_is_present(const struct ast_event *event,
+		const enum ast_event_ie_type ie_type)
+{
+	return (ast_event_get_ie_raw(event, ie_type) != NULL);
+}
+
+static void append_ie(struct ast_str **str, const struct ast_event *event,
+		const enum ast_event_ie_type ie_type, enum ie_required required)
+{
+	if (!required && !ie_is_present(event, ie_type)) {
+		/* Optional IE isn't present.  Ignore. */
+		return;
+	}
+
+	/* At this point, it _better_ be there! */
+	ast_assert(ie_is_present(event, ie_type));
+
+	switch (ast_event_get_ie_pltype(ie_type)) {
+	case AST_EVENT_IE_PLTYPE_UINT:
+		ast_str_append(str, 0, ",%s=\"%u\"",
+				ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
+				ast_event_get_ie_uint(event, ie_type));
+		break;
+	case AST_EVENT_IE_PLTYPE_STR:
+		ast_str_append(str, 0, ",%s=\"%s\"",
+				ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
+				ast_event_get_ie_str(event, ie_type));
+		break;
+	case AST_EVENT_IE_PLTYPE_BITFLAGS:
+		ast_str_append(str, 0, ",%s=\"%u\"",
+				ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
+				ast_event_get_ie_bitflags(event, ie_type));
+		break;
+	case AST_EVENT_IE_PLTYPE_UNKNOWN:
+	case AST_EVENT_IE_PLTYPE_EXISTS:
+	case AST_EVENT_IE_PLTYPE_RAW:
+		ast_log(LOG_WARNING, "Unexpected payload type for IE '%s'\n",
+				ast_event_get_ie_type_name(ie_type));
+		break;
+	}
+}
 
 static void security_event_cb(const struct ast_event *event, void *data)
 {
+	struct ast_str *str;
 	enum ast_security_event_type event_type;
-	uint32_t version;
+	const enum ast_event_ie_type *ies;
 
-	event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT);
-
-	if (event_type < 0 || event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
-		ast_log(LOG_ERROR, "Invalid security event type %u\n", event_type);
+	if (!(str = ast_str_thread_get(&security_event_buf,
+			security_event_buf_init_len))) {
 		return;
 	}
 
-	version = ast_event_get_ie_uint(event, AST_EVENT_IE_EVENT_VERSION);
+	/* Note that the event type is guaranteed to be valid here. */
+	event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT);
+	ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
 
-	if (version != event_handlers[event_type].version) {
-		ast_log(LOG_WARNING, "Version skew for event type %u\n", event_type);
-		return;
+	ast_str_set(&str, 0, "%s=\"%s\"",
+			ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
+			ast_security_event_get_name(event_type));
+
+	for (ies = ast_security_event_get_required_ies(event_type);
+			*ies != AST_EVENT_IE_END;
+			ies++) {
+		append_ie(&str, event, *ies, REQUIRED);
 	}
 
-	/* XXX */
+	for (ies = ast_security_event_get_optional_ies(event_type);
+			*ies != AST_EVENT_IE_END;
+			ies++) {
+		append_ie(&str, event, *ies, NOT_REQUIRED);
+	}
+
+	ast_log(LOG_SECURITY, "%s\n", ast_str_buffer(str));
 }
 
 static int load_module(void)
@@ -103,4 +144,4 @@
 	return 0;
 }
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Security Logging");
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Security Event Logging");




More information about the asterisk-commits mailing list