00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "asterisk.h"
00032
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $")
00034
00035 #include "asterisk/utils.h"
00036 #include "asterisk/strings.h"
00037 #include "asterisk/network.h"
00038 #include "asterisk/security_events.h"
00039
00040 static const size_t TIMESTAMP_STR_LEN = 32;
00041
00042 static const struct {
00043 const char *name;
00044 uint32_t version;
00045 enum ast_security_event_severity severity;
00046 #define MAX_SECURITY_IES 12
00047 struct ast_security_event_ie_type required_ies[MAX_SECURITY_IES];
00048 struct ast_security_event_ie_type optional_ies[MAX_SECURITY_IES];
00049 #undef MAX_SECURITY_IES
00050 } sec_events[AST_SECURITY_EVENT_NUM_TYPES] = {
00051
00052 #define SEC_EVT_FIELD(e, field) (offsetof(struct ast_security_event_##e, field))
00053
00054 [AST_SECURITY_EVENT_FAILED_ACL] = {
00055 .name = "FailedACL",
00056 .version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
00057 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00058 .required_ies = {
00059 { AST_EVENT_IE_EVENT_TV, 0 },
00060 { AST_EVENT_IE_SEVERITY, 0 },
00061 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00062 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00063 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00064 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00065 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00066 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00067 { AST_EVENT_IE_END, 0 }
00068 },
00069 .optional_ies = {
00070 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00071 { AST_EVENT_IE_ACL_NAME, SEC_EVT_FIELD(failed_acl, acl_name) },
00072 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00073 { AST_EVENT_IE_END, 0 }
00074 },
00075 },
00076
00077 [AST_SECURITY_EVENT_INVAL_ACCT_ID] = {
00078 .name = "InvalidAccountID",
00079 .version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
00080 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00081 .required_ies = {
00082 { AST_EVENT_IE_EVENT_TV, 0 },
00083 { AST_EVENT_IE_SEVERITY, 0 },
00084 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00085 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00086 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00087 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00088 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00089 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00090 { AST_EVENT_IE_END, 0 }
00091 },
00092 .optional_ies = {
00093 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00094 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00095 { AST_EVENT_IE_END, 0 }
00096 },
00097 },
00098
00099 [AST_SECURITY_EVENT_SESSION_LIMIT] = {
00100 .name = "SessionLimit",
00101 .version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
00102 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00103 .required_ies = {
00104 { AST_EVENT_IE_EVENT_TV, 0 },
00105 { AST_EVENT_IE_SEVERITY, 0 },
00106 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00107 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00108 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00109 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00110 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00111 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00112 { AST_EVENT_IE_END, 0 }
00113 },
00114 .optional_ies = {
00115 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00116 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00117 { AST_EVENT_IE_END, 0 }
00118 },
00119 },
00120
00121 [AST_SECURITY_EVENT_MEM_LIMIT] = {
00122 .name = "MemoryLimit",
00123 .version = AST_SECURITY_EVENT_MEM_LIMIT_VERSION,
00124 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00125 .required_ies = {
00126 { AST_EVENT_IE_EVENT_TV, 0 },
00127 { AST_EVENT_IE_SEVERITY, 0 },
00128 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00129 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00130 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00131 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00132 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00133 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00134 { AST_EVENT_IE_END, 0 }
00135 },
00136 .optional_ies = {
00137 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00138 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00139 { AST_EVENT_IE_END, 0 }
00140 },
00141 },
00142
00143 [AST_SECURITY_EVENT_LOAD_AVG] = {
00144 .name = "LoadAverageLimit",
00145 .version = AST_SECURITY_EVENT_LOAD_AVG_VERSION,
00146 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00147 .required_ies = {
00148 { AST_EVENT_IE_EVENT_TV, 0 },
00149 { AST_EVENT_IE_SEVERITY, 0 },
00150 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00151 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00152 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00153 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00154 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00155 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00156 { AST_EVENT_IE_END, 0 }
00157 },
00158 .optional_ies = {
00159 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00160 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00161 { AST_EVENT_IE_END, 0 }
00162 },
00163 },
00164
00165 [AST_SECURITY_EVENT_REQ_NO_SUPPORT] = {
00166 .name = "RequestNotSupported",
00167 .version = AST_SECURITY_EVENT_REQ_NO_SUPPORT_VERSION,
00168 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00169 .required_ies = {
00170 { AST_EVENT_IE_EVENT_TV, 0 },
00171 { AST_EVENT_IE_SEVERITY, 0 },
00172 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00173 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00174 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00175 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00176 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00177 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00178 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_no_support, request_type) },
00179 { AST_EVENT_IE_END, 0 }
00180 },
00181 .optional_ies = {
00182 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00183 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00184 { AST_EVENT_IE_END, 0 }
00185 },
00186 },
00187
00188 [AST_SECURITY_EVENT_REQ_NOT_ALLOWED] = {
00189 .name = "RequestNotAllowed",
00190 .version = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
00191 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00192 .required_ies = {
00193 { AST_EVENT_IE_EVENT_TV, 0 },
00194 { AST_EVENT_IE_SEVERITY, 0 },
00195 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00196 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00197 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00198 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00199 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00200 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00201 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_not_allowed, request_type) },
00202 { AST_EVENT_IE_END, 0 }
00203 },
00204 .optional_ies = {
00205 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00206 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00207 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_not_allowed, request_params) },
00208 { AST_EVENT_IE_END, 0 }
00209 },
00210 },
00211
00212 [AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED] = {
00213 .name = "AuthMethodNotAllowed",
00214 .version = AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED_VERSION,
00215 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00216 .required_ies = {
00217 { AST_EVENT_IE_EVENT_TV, 0 },
00218 { AST_EVENT_IE_SEVERITY, 0 },
00219 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00220 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00221 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00222 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00223 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00224 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00225 { AST_EVENT_IE_AUTH_METHOD, SEC_EVT_FIELD(auth_method_not_allowed, auth_method) },
00226 { AST_EVENT_IE_END, 0 }
00227 },
00228 .optional_ies = {
00229 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00230 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00231 { AST_EVENT_IE_END, 0 }
00232 },
00233 },
00234
00235 [AST_SECURITY_EVENT_REQ_BAD_FORMAT] = {
00236 .name = "RequestBadFormat",
00237 .version = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
00238 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00239 .required_ies = {
00240 { AST_EVENT_IE_EVENT_TV, 0 },
00241 { AST_EVENT_IE_SEVERITY, 0 },
00242 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00243 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00244 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00245 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00246 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00247 { AST_EVENT_IE_REQUEST_TYPE, SEC_EVT_FIELD(req_bad_format, request_type) },
00248 { AST_EVENT_IE_END, 0 }
00249 },
00250 .optional_ies = {
00251 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00252 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00253 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00254 { AST_EVENT_IE_REQUEST_PARAMS, SEC_EVT_FIELD(req_bad_format, request_params) },
00255 { AST_EVENT_IE_END, 0 }
00256 },
00257 },
00258
00259 [AST_SECURITY_EVENT_SUCCESSFUL_AUTH] = {
00260 .name = "SuccessfulAuth",
00261 .version = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
00262 .severity = AST_SECURITY_EVENT_SEVERITY_INFO,
00263 .required_ies = {
00264 { AST_EVENT_IE_EVENT_TV, 0 },
00265 { AST_EVENT_IE_SEVERITY, 0 },
00266 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00267 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00268 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00269 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00270 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00271 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00272 { AST_EVENT_IE_END, 0 }
00273 },
00274 .optional_ies = {
00275 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00276 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00277 { AST_EVENT_IE_END, 0 }
00278 },
00279 },
00280
00281 [AST_SECURITY_EVENT_UNEXPECTED_ADDR] = {
00282 .name = "UnexpectedAddress",
00283 .version = AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION,
00284 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00285 .required_ies = {
00286 { AST_EVENT_IE_EVENT_TV, 0 },
00287 { AST_EVENT_IE_SEVERITY, 0 },
00288 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00289 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00290 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00291 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00292 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00293 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00294 { AST_EVENT_IE_EXPECTED_ADDR, SEC_EVT_FIELD(unexpected_addr, expected_addr) },
00295 { AST_EVENT_IE_END, 0 }
00296 },
00297 .optional_ies = {
00298 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00299 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00300 { AST_EVENT_IE_END, 0 }
00301 },
00302 },
00303
00304 [AST_SECURITY_EVENT_CHAL_RESP_FAILED] = {
00305 .name = "ChallengeResponseFailed",
00306 .version = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
00307 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00308 .required_ies = {
00309 { AST_EVENT_IE_EVENT_TV, 0 },
00310 { AST_EVENT_IE_SEVERITY, 0 },
00311 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00312 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00313 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00314 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00315 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00316 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00317 { AST_EVENT_IE_CHALLENGE, SEC_EVT_FIELD(chal_resp_failed, challenge) },
00318 { AST_EVENT_IE_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, response) },
00319 { AST_EVENT_IE_EXPECTED_RESPONSE, SEC_EVT_FIELD(chal_resp_failed, expected_response) },
00320 { AST_EVENT_IE_END, 0 }
00321 },
00322 .optional_ies = {
00323 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00324 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00325 { AST_EVENT_IE_END, 0 }
00326 },
00327 },
00328
00329 [AST_SECURITY_EVENT_INVAL_PASSWORD] = {
00330 .name = "InvalidPassword",
00331 .version = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
00332 .severity = AST_SECURITY_EVENT_SEVERITY_ERROR,
00333 .required_ies = {
00334 { AST_EVENT_IE_EVENT_TV, 0 },
00335 { AST_EVENT_IE_SEVERITY, 0 },
00336 { AST_EVENT_IE_SERVICE, SEC_EVT_FIELD(common, service) },
00337 { AST_EVENT_IE_EVENT_VERSION, SEC_EVT_FIELD(common, version) },
00338 { AST_EVENT_IE_ACCOUNT_ID, SEC_EVT_FIELD(common, account_id) },
00339 { AST_EVENT_IE_SESSION_ID, SEC_EVT_FIELD(common, session_id) },
00340 { AST_EVENT_IE_LOCAL_ADDR, SEC_EVT_FIELD(common, local_addr) },
00341 { AST_EVENT_IE_REMOTE_ADDR, SEC_EVT_FIELD(common, remote_addr) },
00342 { AST_EVENT_IE_END, 0 }
00343 },
00344 .optional_ies = {
00345 { AST_EVENT_IE_MODULE, SEC_EVT_FIELD(common, module) },
00346 { AST_EVENT_IE_SESSION_TV, SEC_EVT_FIELD(common, session_tv) },
00347 { AST_EVENT_IE_END, 0 }
00348 },
00349 },
00350
00351 #undef SEC_EVT_FIELD
00352
00353 };
00354
00355 static const struct {
00356 enum ast_security_event_severity severity;
00357 const char *str;
00358 } severities[] = {
00359 { AST_SECURITY_EVENT_SEVERITY_INFO, "Informational" },
00360 { AST_SECURITY_EVENT_SEVERITY_ERROR, "Error" },
00361 };
00362
00363 const char *ast_security_event_severity_get_name(
00364 const enum ast_security_event_severity severity)
00365 {
00366 unsigned int i;
00367
00368 for (i = 0; i < ARRAY_LEN(severities); i++) {
00369 if (severities[i].severity == severity) {
00370 return severities[i].str;
00371 }
00372 }
00373
00374 return NULL;
00375 }
00376
00377 static int check_event_type(const enum ast_security_event_type event_type)
00378 {
00379 if (event_type < 0 || event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
00380 ast_log(LOG_ERROR, "Invalid security event type %u\n", event_type);
00381 return -1;
00382 }
00383
00384 return 0;
00385 }
00386
00387 const char *ast_security_event_get_name(const enum ast_security_event_type event_type)
00388 {
00389 if (check_event_type(event_type)) {
00390 return NULL;
00391 }
00392
00393 return sec_events[event_type].name;
00394 }
00395
00396 const struct ast_security_event_ie_type *ast_security_event_get_required_ies(
00397 const enum ast_security_event_type event_type)
00398 {
00399 if (check_event_type(event_type)) {
00400 return NULL;
00401 }
00402
00403 return sec_events[event_type].required_ies;
00404 }
00405
00406 const struct ast_security_event_ie_type *ast_security_event_get_optional_ies(
00407 const enum ast_security_event_type event_type)
00408 {
00409 if (check_event_type(event_type)) {
00410 return NULL;
00411 }
00412
00413 return sec_events[event_type].optional_ies;
00414 }
00415
00416 static void encode_timestamp(struct ast_str **str, const struct timeval *tv)
00417 {
00418 ast_str_set(str, 0, "%u-%u",
00419 (unsigned int) tv->tv_sec,
00420 (unsigned int) tv->tv_usec);
00421 }
00422
00423 static struct ast_event *alloc_event(const struct ast_security_event_common *sec)
00424 {
00425 struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
00426 struct timeval tv = ast_tvnow();
00427 const char *severity_str;
00428
00429 if (check_event_type(sec->event_type)) {
00430 return NULL;
00431 }
00432
00433 encode_timestamp(&str, &tv);
00434
00435 severity_str = S_OR(
00436 ast_security_event_severity_get_name(sec_events[sec->event_type].severity),
00437 "Unknown"
00438 );
00439
00440 return ast_event_new(AST_EVENT_SECURITY,
00441 AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type,
00442 AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version,
00443 AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, str->str,
00444 AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service,
00445 AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str,
00446 AST_EVENT_IE_END);
00447 }
00448
00449 static int add_timeval_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
00450 const struct timeval *tv)
00451 {
00452 struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
00453
00454 encode_timestamp(&str, tv);
00455
00456 return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
00457 }
00458
00459 static int add_ipv4_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
00460 const struct ast_security_event_ipv4_addr *addr)
00461 {
00462 struct ast_str *str = ast_str_alloca(64);
00463
00464 ast_str_set(&str, 0, "IPV4/");
00465
00466 switch (addr->transport) {
00467 case AST_SECURITY_EVENT_TRANSPORT_UDP:
00468 ast_str_append(&str, 0, "UDP/");
00469 break;
00470 case AST_SECURITY_EVENT_TRANSPORT_TCP:
00471 ast_str_append(&str, 0, "TCP/");
00472 break;
00473 case AST_SECURITY_EVENT_TRANSPORT_TLS:
00474 ast_str_append(&str, 0, "TLS/");
00475 break;
00476 }
00477
00478 ast_str_append(&str, 0, "%s/%hu",
00479 ast_inet_ntoa(addr->sin->sin_addr),
00480 ntohs(addr->sin->sin_port));
00481
00482 return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
00483 }
00484
00485 enum ie_required {
00486 NOT_REQUIRED,
00487 REQUIRED
00488 };
00489
00490 static int add_ie(struct ast_event **event, const struct ast_security_event_common *sec,
00491 const struct ast_security_event_ie_type *ie_type, enum ie_required req)
00492 {
00493 int res = 0;
00494
00495 switch (ie_type->ie_type) {
00496 case AST_EVENT_IE_SERVICE:
00497 case AST_EVENT_IE_ACCOUNT_ID:
00498 case AST_EVENT_IE_SESSION_ID:
00499 case AST_EVENT_IE_MODULE:
00500 case AST_EVENT_IE_ACL_NAME:
00501 case AST_EVENT_IE_REQUEST_TYPE:
00502 case AST_EVENT_IE_REQUEST_PARAMS:
00503 case AST_EVENT_IE_AUTH_METHOD:
00504 case AST_EVENT_IE_CHALLENGE:
00505 case AST_EVENT_IE_RESPONSE:
00506 case AST_EVENT_IE_EXPECTED_RESPONSE:
00507 {
00508 const char *str;
00509
00510 str = *((const char **)(((const char *) sec) + ie_type->offset));
00511
00512 if (req && !str) {
00513 ast_log(LOG_WARNING, "Required IE '%d' for security event "
00514 "type '%d' not present\n", ie_type->ie_type,
00515 sec->event_type);
00516 res = -1;
00517 }
00518
00519 if (str) {
00520 res = ast_event_append_ie_str(event, ie_type->ie_type, str);
00521 }
00522
00523 break;
00524 }
00525 case AST_EVENT_IE_EVENT_VERSION:
00526 {
00527 uint32_t val;
00528 val = *((const uint32_t *)(((const char *) sec) + ie_type->offset));
00529 res = ast_event_append_ie_uint(event, ie_type->ie_type, val);
00530 break;
00531 }
00532 case AST_EVENT_IE_LOCAL_ADDR:
00533 case AST_EVENT_IE_REMOTE_ADDR:
00534 case AST_EVENT_IE_EXPECTED_ADDR:
00535 {
00536 const struct ast_security_event_ipv4_addr *addr;
00537
00538 addr = (const struct ast_security_event_ipv4_addr *)(((const char *) sec) + ie_type->offset);
00539
00540 if (req && !addr->sin) {
00541 ast_log(LOG_WARNING, "Required IE '%d' for security event "
00542 "type '%d' not present\n", ie_type->ie_type,
00543 sec->event_type);
00544 res = -1;
00545 }
00546
00547 if (addr->sin) {
00548 res = add_ipv4_ie(event, ie_type->ie_type, addr);
00549 }
00550 break;
00551 }
00552 case AST_EVENT_IE_SESSION_TV:
00553 {
00554 const struct timeval *tval;
00555
00556 tval = *((const struct timeval **)(((const char *) sec) + ie_type->offset));
00557
00558 if (req && !tval) {
00559 ast_log(LOG_WARNING, "Required IE '%d' for security event "
00560 "type '%d' not present\n", ie_type->ie_type,
00561 sec->event_type);
00562 res = -1;
00563 }
00564
00565 if (tval) {
00566 add_timeval_ie(event, ie_type->ie_type, tval);
00567 }
00568
00569 break;
00570 }
00571 case AST_EVENT_IE_EVENT_TV:
00572 case AST_EVENT_IE_SEVERITY:
00573
00574 break;
00575 default:
00576 ast_log(LOG_WARNING, "Unhandled IE type '%d', this security event "
00577 "will be missing data.\n", ie_type->ie_type);
00578 break;
00579 }
00580
00581 return res;
00582 }
00583
00584 static int handle_security_event(const struct ast_security_event_common *sec)
00585 {
00586 struct ast_event *event;
00587 const struct ast_security_event_ie_type *ies;
00588 unsigned int i;
00589
00590 if (!(event = alloc_event(sec))) {
00591 return -1;
00592 }
00593
00594 for (ies = ast_security_event_get_required_ies(sec->event_type), i = 0;
00595 ies[i].ie_type != AST_EVENT_IE_END;
00596 i++) {
00597 if (add_ie(&event, sec, ies + i, REQUIRED)) {
00598 goto return_error;
00599 }
00600 }
00601
00602 for (ies = ast_security_event_get_optional_ies(sec->event_type), i = 0;
00603 ies[i].ie_type != AST_EVENT_IE_END;
00604 i++) {
00605 if (add_ie(&event, sec, ies + i, NOT_REQUIRED)) {
00606 goto return_error;
00607 }
00608 }
00609
00610
00611 if (ast_event_queue(event)) {
00612 goto return_error;
00613 }
00614
00615 return 0;
00616
00617 return_error:
00618 if (event) {
00619 ast_event_destroy(event);
00620 }
00621
00622 return -1;
00623 }
00624
00625 int ast_security_event_report(const struct ast_security_event_common *sec)
00626 {
00627 int res;
00628
00629 if (sec->event_type < 0 || sec->event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
00630 ast_log(LOG_ERROR, "Invalid security event type\n");
00631 return -1;
00632 }
00633
00634 if (!sec_events[sec->event_type].name) {
00635 ast_log(LOG_WARNING, "Security event type %u not handled\n",
00636 sec->event_type);
00637 return -1;
00638 }
00639
00640 if (sec->version != sec_events[sec->event_type].version) {
00641 ast_log(LOG_WARNING, "Security event %u version mismatch\n",
00642 sec->event_type);
00643 return -1;
00644 }
00645
00646 res = handle_security_event(sec);
00647
00648 return res;
00649 }
00650
00651