Tue Aug 20 16:34:38 2013

Asterisk developer's documentation


security_events.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2009, Digium, Inc.
00005  *
00006  * Russell Bryant <russell@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*!
00020  * \file
00021  *
00022  * \brief Security Event Reporting Helpers
00023  *
00024  * \author Russell Bryant <russell@digium.com>
00025  */
00026 
00027 /*** MODULEINFO
00028    <support_level>core</support_level>
00029  ***/
00030 
00031 #include "asterisk.h"
00032 
00033 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 376469 $")
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, ast_str_buffer(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       /* Added automatically, nothing to do here. */
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 

Generated on 20 Aug 2013 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1