Generate Security events in chan_sip using new Security Events Framework

Security Events Framework was added in 1.8 and support was added for AMI to generate
events at that time. This patch adds support for chan_sip to generate security events.

(closes issue ASTERISK-18264)
Reported by: Michael L. Young
Patches:
     security_events_chan_sip_v4.patch (license #5026) by Michael L. Young
Review: https://reviewboard.asterisk.org/r/1362/



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@337595 65c4cc65-6c06-0410-ace0-fbb531ad65f3
10-digiumphones
Jonathan Rose 14 years ago
parent 34ae017509
commit 857e4fdb14

@ -185,6 +185,7 @@ SIP Changes
-----------
* Add T38 support for REJECTED state where T.38 Negotiation is explicitly rejected.
* Add option encryption_taglen to set auth taglen only 32 and 80 are supported currently.
* SIP now generates security events using the Security Events Framework for REGISTER and INVITE.
Queue changes
-------------

File diff suppressed because it is too large Load Diff

@ -32,6 +32,7 @@
#include "asterisk/channel.h"
#include "asterisk/app.h"
#include "asterisk/astobj.h"
#include "asterisk/security_events.h"
#ifndef FALSE
#define FALSE 0
@ -41,7 +42,7 @@
#define TRUE 1
#endif
/* Arguments for find_peer */
/* Arguments for sip_find_peer */
#define FINDUSERS (1 << 0)
#define FINDPEERS (1 << 1)
#define FINDALLDEVICES (FINDUSERS | FINDPEERS)
@ -358,6 +359,8 @@
#define SIP_PAGE3_FLAGS_TO_COPY \
(SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32)
#define CHECK_AUTH_BUF_INITLEN 256
/*@}*/
/*----------------------------------------------------------*/
@ -380,6 +383,19 @@ enum sip_result {
AST_FAILURE = -1, /*!< Failure code */
};
/*! \brief The results from handling an invite request
*
* \note Start at these values so we do not conflict with
* check_auth_results values when returning from
* handle_request_invite. check_auth_results only returned during
* authentication routines
* */
enum inv_req_result {
INV_REQ_SUCCESS = 11, /*!< Success code */
INV_REQ_FAILED = 10, /*!< Failure code */
INV_REQ_ERROR = 9, /*!< Error code */
};
/*! \brief States for the INVITE transaction, not the dialog
* \note this is for the INVITE that sets up the dialog
*/
@ -471,7 +487,8 @@ enum check_auth_result {
AUTH_PEER_NOT_DYNAMIC = -6,
AUTH_ACL_FAILED = -7,
AUTH_BAD_TRANSPORT = -8,
AUTH_RTP_FAILED = 9,
AUTH_RTP_FAILED = -9,
AUTH_SESSION_LIMIT = -10,
};
/*! \brief States for outbound registrations (with register= lines in sip.conf */
@ -632,6 +649,13 @@ enum sip_tcptls_alert {
TCPTLS_ALERT_STOP, /*!< \brief A request to stop the tcp_handler thread */
};
enum digest_keys {
K_RESP,
K_URI,
K_USER,
K_NONCE,
K_LAST
};
/*----------------------------------------------------------*/
/*---- STRUCTS ----*/
@ -1794,4 +1818,22 @@ static const struct cfsip_options {
{ SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED, "tdialog" },
};
struct digestkeys {
const char *key;
const char *s;
};
AST_THREADSTORAGE(check_auth_buf);
/*----------------------------------------------------------*/
/*---- FUNCTIONS ----*/
/*----------------------------------------------------------*/
struct sip_peer *sip_find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport);
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader);
const char *sip_get_header(const struct sip_request *req, const char *name);
const char *sip_get_transport(enum sip_transport t);
void *sip_unref_peer(struct sip_peer *peer, char *tag);
struct sip_peer *sip_ref_peer(struct sip_peer *peer, char *tag);
#endif

@ -76,6 +76,7 @@
; verbose
; dtmf
; fax
; security
;
; Special filename "console" represents the system console
;
@ -104,6 +105,7 @@
; you are in the process of debugging a specific issue.
;
;debug => debug
;security => security
console => notice,warning,error
;console => notice,warning,error,debug
messages => notice,warning,error

@ -283,8 +283,13 @@ enum ast_event_ie_type {
AST_EVENT_IE_CHALLENGE = 0x0032,
AST_EVENT_IE_RESPONSE = 0x0033,
AST_EVENT_IE_EXPECTED_RESPONSE = 0x0034,
AST_EVENT_IE_RECEIVED_CHALLENGE = 0x0035,
AST_EVENT_IE_RECEIVED_HASH = 0x0036,
AST_EVENT_IE_USING_PASSWORD = 0x0037,
AST_EVENT_IE_ATTEMPTED_TRANSPORT = 0x0038,
/*! \brief Must be the last IE value +1 */
AST_EVENT_IE_TOTAL = 0x0035,
AST_EVENT_IE_TOTAL = 0x0039,
};
/*!

@ -111,7 +111,17 @@ enum ast_security_event_type {
* \brief An attempt at basic password authentication failed
*/
AST_SECURITY_EVENT_INVAL_PASSWORD,
/* \brief This _must_ stay at the end. */
/*!
* \brief Challenge was sent out, informational
*/
AST_SECURITY_EVENT_CHAL_SENT,
/*!
* \brief An attempt to contact a peer on an invalid transport.
*/
AST_SECURITY_EVENT_INVAL_TRANSPORT,
/*!
* \brief This _must_ stay at the end.
*/
AST_SECURITY_EVENT_NUM_TYPES
};
@ -393,6 +403,11 @@ struct ast_security_event_successful_auth {
* \note Account ID required
*/
struct ast_security_event_common common;
/*!
* \brief Using password - if a password was used or not
* \note required, 0 = no, 1 = yes
*/
uint32_t *using_password;
};
/*!
@ -455,12 +470,69 @@ struct ast_security_event_inval_password {
* \brief Event descriptor version
* \note This _must_ be changed if this event descriptor is changed.
*/
#define AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION 1
#define AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION 2
/*!
* \brief Common security event descriptor elements
* \note Account ID required
*/
struct ast_security_event_common common;
/*!
* \brief Challenge provided
* \note required
*/
const char *challenge;
/*!
* \brief Challenge received
* \note required
*/
const char *received_challenge;
/*!
* \brief Hash received
* \note required
*/
const char *received_hash;
};
/*!
* \brief A challenge was sent out
*/
struct ast_security_event_chal_sent {
/*!
* \brief Event descriptor version
* \note This _must_ be changed if this event descriptor is changed.
*/
#define AST_SECURITY_EVENT_CHAL_SENT_VERSION 1
/*!
* \brief Common security event descriptor elements
* \note Account ID required
*/
struct ast_security_event_common common;
/*!
* \brief Challenge sent
* \note required
*/
const char *challenge;
};
/*!
* \brief Attempt to contact peer on invalid transport
*/
struct ast_security_event_inval_transport {
/*!
* \brief Event descriptor version
* \note This _must_ be changed if this event descriptor is changed.
*/
#define AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION 1
/*!
* \brief Common security event descriptor elements
* \note Account ID required
*/
struct ast_security_event_common common;
/*!
* \brief Attempted transport
* \note required
*/
const char *transport;
};
#if defined(__cplusplus) || defined(c_plusplus)

@ -264,6 +264,10 @@ static const struct ie_map {
[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" },
[AST_EVENT_IE_RECEIVED_CHALLENGE] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedChallenge" },
[AST_EVENT_IE_RECEIVED_HASH] = { AST_EVENT_IE_PLTYPE_STR, "ReceivedHash" },
[AST_EVENT_IE_USING_PASSWORD] = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" },
};
const char *ast_event_get_type_name(const struct ast_event *event)

@ -265,6 +265,7 @@ static const struct {
{ AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
{ AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
{ AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
{ AST_EVENT_IE_USING_PASSWORD, SEC_EVT_FIELD(successful_auth, using_password) },
{ AST_EVENT_IE_END, 0 }
},
.optional_ies = {
@ -335,6 +336,55 @@ static const struct {
{ AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
{ AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
{ AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
{ AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(inval_password, challenge) },
{ AST_EVENT_IE_RECEIVED_CHALLENGE, SEC_EVT_FIELD(inval_password, received_challenge) },
{ AST_EVENT_IE_RECEIVED_HASH, SEC_EVT_FIELD(inval_password, received_hash) },
{ AST_EVENT_IE_END, 0 }
},
.optional_ies = {
{ AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
{ AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
{ AST_EVENT_IE_END, 0 }
},
},
[AST_SECURITY_EVENT_CHAL_SENT] = {
.name = "ChallengeSent",
.version = AST_SECURITY_EVENT_CHAL_SENT_VERSION,
.severity = AST_SECURITY_EVENT_SEVERITY_INFO,
.required_ies = {
{ AST_EVENT_IE_EVENT_TV, 0 },
{ AST_EVENT_IE_SEVERITY, 0 },
{ AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
{ AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
{ AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
{ AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
{ AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
{ AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
{ AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(chal_sent, challenge) },
{ AST_EVENT_IE_END, 0 }
},
.optional_ies = {
{ AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
{ AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
{ AST_EVENT_IE_END, 0 }
},
},
[AST_SECURITY_EVENT_INVAL_TRANSPORT] = {
.name = "InvalidTransport",
.version = AST_SECURITY_EVENT_INVAL_TRANSPORT_VERSION,
.severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
.required_ies = {
{ AST_EVENT_IE_EVENT_TV, 0 },
{ AST_EVENT_IE_SEVERITY, 0 },
{ AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
{ AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
{ AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
{ AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
{ AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
{ AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
{ AST_EVENT_IE_ATTEMPTED_TRANSPORT, SEC_EVT_FIELD(inval_transport, transport) },
{ AST_EVENT_IE_END, 0 }
},
.optional_ies = {
@ -500,6 +550,9 @@ static int add_ie(struct ast_event **event, const struct ast_security_event_comm
case AST_EVENT_IE_CHALLENGE:
case AST_EVENT_IE_RESPONSE:
case AST_EVENT_IE_EXPECTED_RESPONSE:
case AST_EVENT_IE_RECEIVED_CHALLENGE:
case AST_EVENT_IE_RECEIVED_HASH:
case AST_EVENT_IE_ATTEMPTED_TRANSPORT:
{
const char *str;
@ -519,6 +572,7 @@ static int add_ie(struct ast_event **event, const struct ast_security_event_comm
break;
}
case AST_EVENT_IE_EVENT_VERSION:
case AST_EVENT_IE_USING_PASSWORD:
{
uint32_t val;
val = *((const uint32_t *)(((const char *) sec) + ie_type->offset));

Loading…
Cancel
Save