1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
12 #include "config/config.h"
13 #include "os_net/os_net.h"
16 /* Send an alert via syslog
17 * Returns 1 on success or 0 on error
19 int OS_Alert_SendSyslog(alert_data *al_data, const SyslogConfig *syslog_config)
23 char syslog_msg[OS_SIZE_2048];
26 if (syslog_config->socket < 0) {
30 /* Clear the memory before insert */
31 memset(syslog_msg, '\0', OS_SIZE_2048);
33 /* Look if location is set */
34 if (syslog_config->location) {
35 if (!OSMatch_Execute(al_data->location,
36 strlen(al_data->location),
37 syslog_config->location)) {
42 /* Look for the level */
43 if (syslog_config->level) {
44 if (al_data->level < syslog_config->level) {
49 /* Look for rule id */
50 if (syslog_config->rule_id) {
52 while (syslog_config->rule_id[id_i] != 0) {
53 if (syslog_config->rule_id[id_i] == al_data->rule) {
59 /* If we found, id is going to be a valid rule */
60 if (!syslog_config->rule_id[id_i]) {
65 /* Look for the group */
66 if (syslog_config->group) {
67 if (!OSMatch_Execute(al_data->group,
68 strlen(al_data->group),
69 syslog_config->group)) {
74 /* Fix the timestamp to be syslog compatible
75 * We have 2008 Jul 10 10:11:23
76 * Should be: Jul 10 10:11:23
78 tstamp = al_data->date;
79 if (strlen(al_data->date) > 14) {
82 /* Fix first digit if the day is < 10 */
83 if (tstamp[4] == '0') {
88 if (syslog_config->use_fqdn) {
89 hostname = __shost_long;
95 if (syslog_config->format == DEFAULT_CSYSLOG) {
96 /* Build syslog message */
97 snprintf(syslog_msg, OS_SIZE_2048,
98 "<%u>%s %s ossec: Alert Level: %u; Rule: %u - %s; Location: %s;",
99 syslog_config->priority, tstamp, hostname,
101 al_data->rule, al_data->comment,
104 field_add_string(syslog_msg, OS_SIZE_2048, " classification: %s;", al_data->group );
105 field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip );
106 #ifdef LIBGEOIP_ENABLED
107 field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->srcgeoip );
108 field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->dstgeoip );
110 field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip );
111 field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user );
112 field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 );
113 field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 );
114 field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 );
115 field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 );
116 /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */
117 field_add_string(syslog_msg, OS_SIZE_2048, " Size changed: from %s;", al_data->file_size );
118 field_add_string(syslog_msg, OS_SIZE_2048, " User ownership: was %s;", al_data->owner_chg );
119 field_add_string(syslog_msg, OS_SIZE_2048, " Group ownership: was %s;", al_data->group_chg );
120 field_add_string(syslog_msg, OS_SIZE_2048, " Permissions changed: from %s;", al_data->perm_chg );
121 /* "9/19/2016 - Sivakumar Nellurandi - parsing additions" */
122 field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 );
123 } else if (syslog_config->format == CEF_CSYSLOG) {
124 snprintf(syslog_msg, OS_SIZE_2048,
125 "<%u>%s CEF:0|%s|%s|%s|%u|%s|%u|dvc=%s cs1=%s cs1Label=Location",
126 syslog_config->priority,
133 (al_data->level > 10) ? 10 : al_data->level,
134 hostname, al_data->location);
135 field_add_string(syslog_msg, OS_SIZE_2048, " classification=%s", al_data->group );
136 field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip );
137 field_add_int(syslog_msg, OS_SIZE_2048, " dpt=%d", al_data->dstport );
138 field_add_int(syslog_msg, OS_SIZE_2048, " spt=%d", al_data->srcport );
139 field_add_string(syslog_msg, OS_SIZE_2048, " fname=%s", al_data->filename );
140 field_add_string(syslog_msg, OS_SIZE_2048, " dhost=%s", al_data->dstip );
141 field_add_string(syslog_msg, OS_SIZE_2048, " shost=%s", al_data->srcip );
142 field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
143 field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
144 #ifdef LIBGEOIP_ENABLED
145 field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=SrcCity cs4=%s", al_data->srcgeoip );
146 field_add_string(syslog_msg, OS_SIZE_2048, " cs5Label=DstCity cs5=%s", al_data->dstgeoip );
148 field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
149 field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
150 field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 );
151 if (al_data->new_md5 && al_data->new_sha1) {
152 field_add_string(syslog_msg, OS_SIZE_2048, " cs2Label=OldMD5 cs2=%s", al_data->old_md5);
153 field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=NewMD5 cs3=%s", al_data->new_md5);
154 field_add_string(syslog_msg, OS_SIZE_2048, " oldFileHash=%s", al_data->old_sha1 );
155 field_add_string(syslog_msg, OS_SIZE_2048, " fhash=%s", al_data->new_sha1 );
156 field_add_string(syslog_msg, OS_SIZE_2048, " fileHash=%s", al_data->new_sha1 );
158 } else if (syslog_config->format == JSON_CSYSLOG) {
159 /* Build a JSON Object for logging */
162 root = cJSON_CreateObject();
164 /* Data guaranteed to be there */
165 cJSON_AddNumberToObject(root, "crit", al_data->level);
166 cJSON_AddNumberToObject(root, "id", al_data->rule);
167 cJSON_AddStringToObject(root, "component", al_data->location);
170 if (al_data->group) {
171 cJSON_AddStringToObject(root, "classification", al_data->group);
173 if (al_data->comment) {
174 cJSON_AddStringToObject(root, "description", al_data->comment);
177 /* Raw log message generating event */
178 if (al_data->log && al_data->log[0]) {
179 cJSON_AddStringToObject(root, "message", al_data->log[0]);
182 /* Add data if it exists */
184 cJSON_AddStringToObject(root, "acct", al_data->user);
186 if (al_data->srcip) {
187 cJSON_AddStringToObject(root, "src_ip", al_data->srcip);
189 if (al_data->srcport) {
190 cJSON_AddNumberToObject(root, "src_port", al_data->srcport);
192 if (al_data->dstip) {
193 cJSON_AddStringToObject(root, "dst_ip", al_data->dstip);
195 if (al_data->dstport) {
196 cJSON_AddNumberToObject(root, "dst_port", al_data->dstport);
198 if (al_data->filename) {
199 cJSON_AddStringToObject(root, "file", al_data->filename);
201 if (al_data->old_md5) {
202 cJSON_AddStringToObject(root, "md5_old", al_data->old_md5);
204 if (al_data->new_md5) {
205 cJSON_AddStringToObject(root, "md5_new", al_data->new_md5);
207 if (al_data->old_sha1) {
208 cJSON_AddStringToObject(root, "sha1_old", al_data->old_sha1);
210 if (al_data->new_sha1) {
211 cJSON_AddStringToObject(root, "sha1_new", al_data->new_sha1);
213 #ifdef LIBGEOIP_ENABLED
214 if (al_data->srcgeoip) {
215 cJSON_AddStringToObject(root, "src_city", al_data->srcgeoip);
217 if (al_data->dstgeoip) {
218 cJSON_AddStringToObject(root, "dst_city", al_data->dstgeoip);
222 /* Create the JSON string */
223 json_string = cJSON_PrintUnformatted(root);
225 /* Create the syslog message */
226 snprintf(syslog_msg, OS_SIZE_2048,
227 "<%u>%s %s ossec: %s",
230 syslog_config->priority, tstamp, hostname,
232 /* JSON Encoded Data */
235 /* Clean up the memory for the JSON structure */
238 } else if (syslog_config->format == SPLUNK_CSYSLOG) {
239 /* Build a Splunk Style Key/Value string for logging */
240 snprintf(syslog_msg, OS_SIZE_2048,
241 "<%u>%s %s ossec: crit=%u id=%u description=\"%s\" component=\"%s\",",
244 syslog_config->priority, tstamp, hostname,
247 al_data->level, al_data->rule, al_data->comment,
250 /* Event specifics */
251 field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group );
253 if ( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 ) {
254 field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport );
257 #ifdef LIBGEOIP_ENABLED
258 field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->srcgeoip );
259 field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->dstgeoip );
262 if ( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 ) {
263 field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport );
266 field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename );
267 field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user );
268 field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 );
269 field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 );
270 field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 );
271 field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 );
273 field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", al_data->log[0], 2 );
276 OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);