Mon Jun 27 16:50:56 2011

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 #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       /* Added automatically, nothing to do here. */
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 

Generated on Mon Jun 27 16:50:56 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7