Sat Apr 26 2014 22:01:41

Asterisk developer's documentation


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