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