00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "asterisk.h"
00035
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 398102 $");
00037
00038 #include "asterisk/module.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/event.h"
00041 #include "asterisk/threadstorage.h"
00042 #include "asterisk/strings.h"
00043 #include "asterisk/security_events.h"
00044
00045 static const char LOG_SECURITY_NAME[] = "SECURITY";
00046
00047 static int LOG_SECURITY;
00048
00049 static struct ast_event_sub *security_event_sub;
00050
00051 AST_THREADSTORAGE(security_event_buf);
00052 static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
00053
00054 enum ie_required {
00055 NOT_REQUIRED,
00056 REQUIRED
00057 };
00058
00059 static int ie_is_present(const struct ast_event *event,
00060 const enum ast_event_ie_type ie_type)
00061 {
00062 return (ast_event_get_ie_raw(event, ie_type) != NULL);
00063 }
00064
00065 static void append_ie(struct ast_str **str, const struct ast_event *event,
00066 const enum ast_event_ie_type ie_type, enum ie_required required)
00067 {
00068 if (!required && !ie_is_present(event, ie_type)) {
00069
00070 return;
00071 }
00072
00073
00074 ast_assert(ie_is_present(event, ie_type));
00075
00076 switch (ast_event_get_ie_pltype(ie_type)) {
00077 case AST_EVENT_IE_PLTYPE_UINT:
00078 ast_str_append(str, 0, ",%s=\"%u\"",
00079 ast_event_get_ie_type_name(ie_type),
00080 ast_event_get_ie_uint(event, ie_type));
00081 break;
00082 case AST_EVENT_IE_PLTYPE_STR:
00083 ast_str_append(str, 0, ",%s=\"%s\"",
00084 ast_event_get_ie_type_name(ie_type),
00085 ast_event_get_ie_str(event, ie_type));
00086 break;
00087 case AST_EVENT_IE_PLTYPE_BITFLAGS:
00088 ast_str_append(str, 0, ",%s=\"%u\"",
00089 ast_event_get_ie_type_name(ie_type),
00090 ast_event_get_ie_bitflags(event, ie_type));
00091 break;
00092 case AST_EVENT_IE_PLTYPE_UNKNOWN:
00093 case AST_EVENT_IE_PLTYPE_EXISTS:
00094 case AST_EVENT_IE_PLTYPE_RAW:
00095 ast_log(LOG_WARNING, "Unexpected payload type for IE '%s'\n",
00096 ast_event_get_ie_type_name(ie_type));
00097 break;
00098 }
00099 }
00100
00101 static void append_ies(struct ast_str **str, const struct ast_event *event,
00102 const struct ast_security_event_ie_type *ies, enum ie_required required)
00103 {
00104 unsigned int i;
00105
00106 for (i = 0; ies[i].ie_type != AST_EVENT_IE_END; i++) {
00107 append_ie(str, event, ies[i].ie_type, required);
00108 }
00109 }
00110
00111 static void security_event_cb(const struct ast_event *event, void *data)
00112 {
00113 struct ast_str *str;
00114 enum ast_security_event_type event_type;
00115
00116 if (!(str = ast_str_thread_get(&security_event_buf,
00117 SECURITY_EVENT_BUF_INIT_LEN))) {
00118 return;
00119 }
00120
00121
00122 event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT);
00123 ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
00124
00125 ast_str_set(&str, 0, "%s=\"%s\"",
00126 ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
00127 ast_security_event_get_name(event_type));
00128
00129 append_ies(&str, event,
00130 ast_security_event_get_required_ies(event_type), REQUIRED);
00131 append_ies(&str, event,
00132 ast_security_event_get_optional_ies(event_type), NOT_REQUIRED);
00133
00134 ast_log_dynamic_level(LOG_SECURITY, "%s\n", ast_str_buffer(str));
00135 }
00136
00137 static int load_module(void)
00138 {
00139 if ((LOG_SECURITY = ast_logger_register_level(LOG_SECURITY_NAME)) == -1) {
00140 return AST_MODULE_LOAD_DECLINE;
00141 }
00142
00143 if (!(security_event_sub = ast_event_subscribe(AST_EVENT_SECURITY,
00144 security_event_cb, "Security Event Logger",
00145 NULL, AST_EVENT_IE_END))) {
00146 ast_logger_unregister_level(LOG_SECURITY_NAME);
00147 LOG_SECURITY = -1;
00148 return AST_MODULE_LOAD_DECLINE;
00149 }
00150
00151 ast_verb(3, "Security Logging Enabled\n");
00152
00153 return AST_MODULE_LOAD_SUCCESS;
00154 }
00155
00156 static int unload_module(void)
00157 {
00158 if (security_event_sub) {
00159 security_event_sub = ast_event_unsubscribe(security_event_sub);
00160 }
00161
00162 ast_logger_unregister_level(LOG_SECURITY_NAME);
00163
00164 ast_verb(3, "Security Logging Disabled\n");
00165
00166 return 0;
00167 }
00168
00169 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Security Event Logging");