2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2009, Digium, Inc.
6 * Russell Bryant <russell@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
22 * \brief Security Event Reporting Helpers
24 * \author Russell Bryant <russell@digium.com>
29 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31 #include "asterisk/utils.h"
32 #include "asterisk/strings.h"
33 #include "asterisk/network.h"
34 #include "asterisk/security_events.h"
36 static const size_t TIMESTAMP_STR_LEN = 32;
41 enum ast_security_event_severity severity;
42 #define MAX_SECURITY_IES 12
43 struct ast_security_event_ie_type required_ies[MAX_SECURITY_IES];
44 struct ast_security_event_ie_type optional_ies[MAX_SECURITY_IES];
45 #undef MAX_SECURITY_IES
46 } sec_events[AST_SECURITY_EVENT_NUM_TYPES] = {
48 #define SEC_EVT_FIELD(e, field) (offsetof(struct ast_security_event_##e, field))
50 [AST_SECURITY_EVENT_FAILED_ACL] = {
52 .version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
53 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
55 { AST_EVENT_IE_EVENT_TV, 0 },
56 { AST_EVENT_IE_SEVERITY, 0 },
57 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
58 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
59 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
60 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
61 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
62 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
63 { AST_EVENT_IE_END, 0 }
66 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
67 { AST_EVENT_IE_ACL_NAME, SEC_EVT_FIELD(failed_acl, acl_name) },
68 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
69 { AST_EVENT_IE_END, 0 }
73 [AST_SECURITY_EVENT_INVAL_ACCT_ID] = {
74 .name = "InvalidAccountID",
75 .version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
76 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
78 { AST_EVENT_IE_EVENT_TV, 0 },
79 { AST_EVENT_IE_SEVERITY, 0 },
80 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
81 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
82 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
83 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
84 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
85 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
86 { AST_EVENT_IE_END, 0 }
89 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
90 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
91 { AST_EVENT_IE_END, 0 }
95 [AST_SECURITY_EVENT_SESSION_LIMIT] = {
96 .name = "SessionLimit",
97 .version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
98 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
100 { AST_EVENT_IE_EVENT_TV, 0 },
101 { AST_EVENT_IE_SEVERITY, 0 },
102 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
103 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
104 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
105 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
106 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
107 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
108 { AST_EVENT_IE_END, 0 }
111 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
112 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
113 { AST_EVENT_IE_END, 0 }
117 [AST_SECURITY_EVENT_MEM_LIMIT] = {
118 .name = "MemoryLimit",
119 .version = AST_SECURITY_EVENT_MEM_LIMIT_VERSION,
120 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
122 { AST_EVENT_IE_EVENT_TV, 0 },
123 { AST_EVENT_IE_SEVERITY, 0 },
124 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
125 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
126 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
127 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
128 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
129 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
130 { AST_EVENT_IE_END, 0 }
133 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
134 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
135 { AST_EVENT_IE_END, 0 }
139 [AST_SECURITY_EVENT_LOAD_AVG] = {
140 .name = "LoadAverageLimit",
141 .version = AST_SECURITY_EVENT_LOAD_AVG_VERSION,
142 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
144 { AST_EVENT_IE_EVENT_TV, 0 },
145 { AST_EVENT_IE_SEVERITY, 0 },
146 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
147 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
148 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
149 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
150 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
151 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
152 { AST_EVENT_IE_END, 0 }
155 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
156 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
157 { AST_EVENT_IE_END, 0 }
161 [AST_SECURITY_EVENT_REQ_NO_SUPPORT] = {
162 .name = "RequestNotSupported",
163 .version = AST_SECURITY_EVENT_REQ_NO_SUPPORT_VERSION,
164 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
166 { AST_EVENT_IE_EVENT_TV, 0 },
167 { AST_EVENT_IE_SEVERITY, 0 },
168 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
169 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
170 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
171 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
172 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
173 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
174 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_no_support, request_type) },
175 { AST_EVENT_IE_END, 0 }
178 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
179 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
180 { AST_EVENT_IE_END, 0 }
184 [AST_SECURITY_EVENT_REQ_NOT_ALLOWED] = {
185 .name = "RequestNotAllowed",
186 .version = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
187 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
189 { AST_EVENT_IE_EVENT_TV, 0 },
190 { AST_EVENT_IE_SEVERITY, 0 },
191 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
192 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
193 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
194 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
195 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
196 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
197 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_not_allowed, request_type) },
198 { AST_EVENT_IE_END, 0 }
201 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
202 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
203 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_not_allowed, request_params) },
204 { AST_EVENT_IE_END, 0 }
208 [AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED] = {
209 .name = "AuthMethodNotAllowed",
210 .version = AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED_VERSION,
211 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
213 { AST_EVENT_IE_EVENT_TV, 0 },
214 { AST_EVENT_IE_SEVERITY, 0 },
215 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
216 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
217 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
218 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
219 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
220 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
221 { AST_EVENT_IE_AUTH_METHOD, SEC_EVT_FIELD(auth_method_not_allowed, auth_method) },
222 { AST_EVENT_IE_END, 0 }
225 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
226 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
227 { AST_EVENT_IE_END, 0 }
231 [AST_SECURITY_EVENT_REQ_BAD_FORMAT] = {
232 .name = "RequestBadFormat",
233 .version = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
234 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
236 { AST_EVENT_IE_EVENT_TV, 0 },
237 { AST_EVENT_IE_SEVERITY, 0 },
238 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
239 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
240 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
241 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
242 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
243 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_bad_format, request_type) },
244 { AST_EVENT_IE_END, 0 }
247 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
248 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
249 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
250 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_bad_format, request_params) },
251 { AST_EVENT_IE_END, 0 }
255 [AST_SECURITY_EVENT_SUCCESSFUL_AUTH] = {
256 .name = "SuccessfulAuth",
257 .version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
258 .severity = AST_SECURITY_EVENT_SEVERITY_INFO,
260 { AST_EVENT_IE_EVENT_TV, 0 },
261 { AST_EVENT_IE_SEVERITY, 0 },
262 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
263 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
264 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
265 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
266 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
267 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
268 { AST_EVENT_IE_END, 0 }
271 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
272 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
273 { AST_EVENT_IE_END, 0 }
277 [AST_SECURITY_EVENT_UNEXPECTED_ADDR] = {
278 .name = "UnexpectedAddress",
279 .version = AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION,
280 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
282 { AST_EVENT_IE_EVENT_TV, 0 },
283 { AST_EVENT_IE_SEVERITY, 0 },
284 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
285 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
286 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
287 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
288 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
289 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
290 { AST_EVENT_IE_EXPECTED_ADDR, SEC_EVT_FIELD(unexpected_addr, expected_addr) },
291 { AST_EVENT_IE_END, 0 }
294 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
295 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
296 { AST_EVENT_IE_END, 0 }
300 [AST_SECURITY_EVENT_CHAL_RESP_FAILED] = {
301 .name = "ChallengeResponseFailed",
302 .version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
303 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
305 { AST_EVENT_IE_EVENT_TV, 0 },
306 { AST_EVENT_IE_SEVERITY, 0 },
307 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
308 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
309 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
310 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
311 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
312 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
313 { AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(chal_resp_failed, challenge) },
314 { AST_EVENT_IE_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, response) },
315 { AST_EVENT_IE_EXPECTED_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, expected_response) },
316 { AST_EVENT_IE_END, 0 }
319 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
320 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
321 { AST_EVENT_IE_END, 0 }
325 [AST_SECURITY_EVENT_INVAL_PASSWORD] = {
326 .name = "InvalidPassword",
327 .version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
328 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
330 { AST_EVENT_IE_EVENT_TV, 0 },
331 { AST_EVENT_IE_SEVERITY, 0 },
332 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
333 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
334 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
335 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
336 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
337 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
338 { AST_EVENT_IE_END, 0 }
341 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
342 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
343 { AST_EVENT_IE_END, 0 }
351 static const struct {
352 enum ast_security_event_severity severity;
355 { AST_SECURITY_EVENT_SEVERITY_INFO, "Informational" },
356 { AST_SECURITY_EVENT_SEVERITY_ERROR, "Error" },
359 const char *ast_security_event_severity_get_name(
360 const enum ast_security_event_severity severity)
364 for (i = 0; i < ARRAY_LEN(severities); i++) {
365 if (severities[i].severity == severity) {
366 return severities[i].str;
373 static int check_event_type(const enum ast_security_event_type event_type)
375 if (event_type < 0 || event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
376 ast_log(LOG_ERROR, "Invalid security event type %u\n", event_type);
383 const char *ast_security_event_get_name(const enum ast_security_event_type event_type)
385 if (check_event_type(event_type)) {
389 return sec_events[event_type].name;
392 const struct ast_security_event_ie_type *ast_security_event_get_required_ies(
393 const enum ast_security_event_type event_type)
395 if (check_event_type(event_type)) {
399 return sec_events[event_type].required_ies;
402 const struct ast_security_event_ie_type *ast_security_event_get_optional_ies(
403 const enum ast_security_event_type event_type)
405 if (check_event_type(event_type)) {
409 return sec_events[event_type].optional_ies;
412 static void encode_timestamp(struct ast_str **str, const struct timeval *tv)
414 ast_str_set(str, 0, "%u-%u",
415 (unsigned int) tv->tv_sec,
416 (unsigned int) tv->tv_usec);
419 static struct ast_event *alloc_event(const struct ast_security_event_common *sec)
421 struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
422 struct timeval tv = ast_tvnow();
423 const char *severity_str;
425 if (check_event_type(sec->event_type)) {
429 encode_timestamp(&str, &tv);
432 ast_security_event_severity_get_name(sec_events[sec->event_type].severity),
436 return ast_event_new(AST_EVENT_SECURITY,
437 AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type,
438 AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version,
439 AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, str->str,
440 AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service,
441 AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str,
445 static int add_timeval_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
446 const struct timeval *tv)
448 struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
450 encode_timestamp(&str, tv);
452 return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
455 static int add_ipv4_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
456 const struct ast_security_event_ipv4_addr *addr)
458 struct ast_str *str = ast_str_alloca(64);
460 ast_str_set(&str, 0, "IPV4/");
462 switch (addr->transport) {
463 case AST_SECURITY_EVENT_TRANSPORT_UDP:
464 ast_str_append(&str, 0, "UDP/");
466 case AST_SECURITY_EVENT_TRANSPORT_TCP:
467 ast_str_append(&str, 0, "TCP/");
469 case AST_SECURITY_EVENT_TRANSPORT_TLS:
470 ast_str_append(&str, 0, "TLS/");
474 ast_str_append(&str, 0, "%s/%hu",
475 ast_inet_ntoa(addr->sin->sin_addr),
476 ntohs(addr->sin->sin_port));
478 return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
486 static int add_ie(struct ast_event **event, const struct ast_security_event_common *sec,
487 const struct ast_security_event_ie_type *ie_type, enum ie_required req)
491 switch (ie_type->ie_type) {
492 case AST_EVENT_IE_SERVICE:
493 case AST_EVENT_IE_ACCOUNT_ID:
494 case AST_EVENT_IE_SESSION_ID:
495 case AST_EVENT_IE_MODULE:
496 case AST_EVENT_IE_ACL_NAME:
497 case AST_EVENT_IE_REQUEST_TYPE:
498 case AST_EVENT_IE_REQUEST_PARAMS:
499 case AST_EVENT_IE_AUTH_METHOD:
500 case AST_EVENT_IE_CHALLENGE:
501 case AST_EVENT_IE_RESPONSE:
502 case AST_EVENT_IE_EXPECTED_RESPONSE:
506 str = *((const char **)(((const char *) sec) + ie_type->offset));
509 ast_log(LOG_WARNING, "Required IE '%d' for security event "
510 "type '%d' not present\n", ie_type->ie_type,
516 res = ast_event_append_ie_str(event, ie_type->ie_type, str);
521 case AST_EVENT_IE_EVENT_VERSION:
524 val = *((const uint32_t *)(((const char *) sec) + ie_type->offset));
525 res = ast_event_append_ie_uint(event, ie_type->ie_type, val);
528 case AST_EVENT_IE_LOCAL_ADDR:
529 case AST_EVENT_IE_REMOTE_ADDR:
530 case AST_EVENT_IE_EXPECTED_ADDR:
532 const struct ast_security_event_ipv4_addr *addr;
534 addr = (const struct ast_security_event_ipv4_addr *)(((const char *) sec) + ie_type->offset);
536 if (req && !addr->sin) {
537 ast_log(LOG_WARNING, "Required IE '%d' for security event "
538 "type '%d' not present\n", ie_type->ie_type,
544 res = add_ipv4_ie(event, ie_type->ie_type, addr);
548 case AST_EVENT_IE_SESSION_TV:
550 const struct timeval *tval;
552 tval = *((const struct timeval **)(((const char *) sec) + ie_type->offset));
555 ast_log(LOG_WARNING, "Required IE '%d' for security event "
556 "type '%d' not present\n", ie_type->ie_type,
562 add_timeval_ie(event, ie_type->ie_type, tval);
567 case AST_EVENT_IE_EVENT_TV:
568 case AST_EVENT_IE_SEVERITY:
569 /* Added automatically, nothing to do here. */
572 ast_log(LOG_WARNING, "Unhandled IE type '%d', this security event "
573 "will be missing data.\n", ie_type->ie_type);
580 static int handle_security_event(const struct ast_security_event_common *sec)
582 struct ast_event *event;
583 const struct ast_security_event_ie_type *ies;
586 if (!(event = alloc_event(sec))) {
590 for (ies = ast_security_event_get_required_ies(sec->event_type), i = 0;
591 ies[i].ie_type != AST_EVENT_IE_END;
593 if (add_ie(&event, sec, ies + i, REQUIRED)) {
598 for (ies = ast_security_event_get_optional_ies(sec->event_type), i = 0;
599 ies[i].ie_type != AST_EVENT_IE_END;
601 if (add_ie(&event, sec, ies + i, NOT_REQUIRED)) {
607 if (ast_event_queue(event)) {
615 ast_event_destroy(event);
621 int ast_security_event_report(const struct ast_security_event_common *sec)
625 if (sec->event_type < 0 || sec->event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
626 ast_log(LOG_ERROR, "Invalid security event type\n");
630 if (!sec_events[sec->event_type].name) {
631 ast_log(LOG_WARNING, "Security event type %u not handled\n",
636 if (sec->version != sec_events[sec->event_type].version) {
637 ast_log(LOG_WARNING, "Security event %u version mismatch\n",
642 res = handle_security_event(sec);