1 /* @(#) $Id: ./src/os_csyslogd/alert.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
12 * License details at the LICENSE file included with OSSEC or
13 * online at: http://www.ossec.net/en/licensing.html
18 #include "config/config.h"
19 #include "os_net/os_net.h"
21 /** int OS_Alert_SendSyslog
22 * Sends an alert via syslog.
23 * Returns 1 on success or 0 on error.
25 int OS_Alert_SendSyslog(alert_data *al_data, SyslogConfig *syslog_config)
28 char syslog_msg[OS_SIZE_2048];
30 /* These will be Malloc'd, so no need to predeclare size, just remember to free! */
31 char *json_safe_comment;
32 char *json_safe_message;
38 if(syslog_config->socket < 0)
44 /* Clearing the memory before insert */
45 memset(syslog_msg, '\0', OS_SIZE_2048);
48 /* Looking if location is set */
49 if(syslog_config->location)
51 if(!OSMatch_Execute(al_data->location,
52 strlen(al_data->location),
53 syslog_config->location))
60 /* Looking for the level */
61 if(syslog_config->level)
63 if(al_data->level < syslog_config->level)
70 /* Looking for rule id */
71 if(syslog_config->rule_id)
74 while(syslog_config->rule_id[id_i] != 0)
76 if(syslog_config->rule_id[id_i] == al_data->rule)
84 /* If we found, id is going to be a valid rule */
85 if(!syslog_config->rule_id[id_i])
92 /* Looking for the group */
93 if(syslog_config->group)
95 if(!OSMatch_Execute(al_data->group,
96 strlen(al_data->group),
97 syslog_config->group))
104 /* Fixing the timestamp to be syslog compatible.
105 * We have 2008 Jul 10 10:11:23
106 * Should be: Jul 10 10:11:23
108 tstamp = al_data->date;
109 if(strlen(al_data->date) > 14)
113 /* Fixing first digit if the day is < 10 */
119 /* Remove the double quotes from "dangerous" fields */
120 if( (json_safe_comment = os_strip_char(al_data->comment, '"')) == NULL ) {
123 if( (json_safe_message = os_strip_char(al_data->log[0], '"')) == NULL ) {
128 if(syslog_config->format == DEFAULT_CSYSLOG)
130 /* Building syslog message. */
131 snprintf(syslog_msg, OS_SIZE_2048,
132 "<%d>%s %s ossec: Alert Level: %d; Rule: %d - %s; Location: %s;",
133 syslog_config->priority, tstamp, __shost,
135 al_data->rule, al_data->comment,
138 field_add_string(syslog_msg, OS_SIZE_2048, " srcip: %s;", al_data->srcip );
140 field_add_string(syslog_msg, OS_SIZE_2048, " srccity: %s;", al_data->geoipdatasrc );
141 field_add_string(syslog_msg, OS_SIZE_2048, " dstcity: %s;", al_data->geoipdatadst );
143 field_add_string(syslog_msg, OS_SIZE_2048, " dstip: %s;", al_data->dstip );
144 field_add_string(syslog_msg, OS_SIZE_2048, " user: %s;", al_data->user );
145 field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s;", al_data->old_md5 );
146 field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s;", al_data->new_md5 );
147 field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s;", al_data->old_sha1 );
148 field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s;", al_data->new_sha1 );
149 field_add_truncated(syslog_msg, OS_SIZE_2048, " %s", al_data->log[0], 2 );
151 else if(syslog_config->format == CEF_CSYSLOG)
153 snprintf(syslog_msg, OS_SIZE_2048,
155 "<%d>%s CEF:0|%s|%s|%s|%d|%s|%d|dvc=%s cs2=%s cs2Label=Location",
156 syslog_config->priority,
163 (al_data->level > 10) ? 10 : al_data->level,
164 __shost, al_data->location);
166 field_add_string(syslog_msg, OS_SIZE_2048, " src=%s", al_data->srcip );
168 field_add_string(syslog_msg, OS_SIZE_2048, " cs3Label=SrcCity cs3=%s", al_data->geoipdatasrc );
169 field_add_string(syslog_msg, OS_SIZE_2048, " cs4Label=DstCity cs4=%s", al_data->geoipdatadst );
171 field_add_string(syslog_msg, OS_SIZE_2048, " suser=%s", al_data->user );
172 field_add_string(syslog_msg, OS_SIZE_2048, " dst=%s", al_data->dstip );
173 field_add_truncated(syslog_msg, OS_SIZE_2048, " msg=%s", al_data->log[0], 2 );
174 if (al_data->new_md5 && al_data->new_sha1) {
175 field_add_string(syslog_msg, OS_SIZE_2048, " Previous MD5: %s", al_data->old_md5 );
176 field_add_string(syslog_msg, OS_SIZE_2048, " Current MD5: %s", al_data->new_md5 );
177 field_add_string(syslog_msg, OS_SIZE_2048, " Previous SHA1: %s", al_data->old_sha1 );
178 field_add_string(syslog_msg, OS_SIZE_2048, " Current SHA1: %s", al_data->new_sha1 );
181 else if(syslog_config->format == JSON_CSYSLOG)
183 // Padding is two to make sure we can fit closign bracket
185 /* Build a JSON Object for logging */
186 snprintf(syslog_msg, OS_SIZE_2048 - padding,
187 "<%d>%s %s ossec: { \"crit\": %d, \"id\": %d, \"description\": \"%s\", \"component\": \"%s\",",
190 syslog_config->priority, tstamp, __shost,
193 al_data->level, al_data->rule, json_safe_comment,
196 /* Event specifics */
197 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"classification\": \"%s\",", al_data->group );
199 if( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_ip\": \"%s\",", al_data->srcip ) > 0 )
200 field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"src_port\": %d,", al_data->srcport );
203 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"src_city\": \"%s\",", al_data->geoipdatasrc );
204 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_city\": \"%s\",", al_data->geoipdatadst );
207 if ( field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"dst_ip\": \"%s\",", al_data->dstip ) > 0 )
208 field_add_int(syslog_msg, OS_SIZE_2048 - padding, " \"dst_port\": %d,", al_data->dstport );
210 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"file\": \"%s\",", al_data->filename );
211 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"acct\": \"%s\",", al_data->user );
212 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_old\": \"%s\",", al_data->old_md5 );
213 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"md5_new\": \"%s\",", al_data->new_md5 );
214 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_old\": \"%s\",", al_data->old_sha1 );
215 field_add_string(syslog_msg, OS_SIZE_2048 - padding, " \"sha1_new\": \"%s\",", al_data->new_sha1 );
217 field_add_truncated(syslog_msg, OS_SIZE_2048 - padding, " \"message\": \"%s\"", json_safe_message, 2 );
219 field_add_string(syslog_msg, OS_SIZE_2048, " }", "" );
221 else if(syslog_config->format == SPLUNK_CSYSLOG)
223 /* Build a Splunk Style Key/Value string for logging */
224 snprintf(syslog_msg, OS_SIZE_2048,
225 "<%d>%s %s ossec: crit=%d id=%d description=\"%s\" component=\"%s\",",
228 syslog_config->priority, tstamp, __shost,
231 al_data->level, al_data->rule, json_safe_comment,
234 /* Event specifics */
235 field_add_string(syslog_msg, OS_SIZE_2048, " classification=\"%s\",", al_data->group );
237 if( field_add_string(syslog_msg, OS_SIZE_2048, " src_ip=\"%s\",", al_data->srcip ) > 0 )
238 field_add_int(syslog_msg, OS_SIZE_2048, " src_port=%d,", al_data->srcport );
241 field_add_string(syslog_msg, OS_SIZE_2048, " src_city=\"%s\",", al_data->geoipdatasrc );
242 field_add_string(syslog_msg, OS_SIZE_2048, " dst_city=\"%s\",", al_data->geoipdatadst );
245 if( field_add_string(syslog_msg, OS_SIZE_2048, " dst_ip=\"%s\",", al_data->dstip ) > 0 )
246 field_add_int(syslog_msg, OS_SIZE_2048, " dst_port=%d,", al_data->dstport );
248 field_add_string(syslog_msg, OS_SIZE_2048, " file=\"%s\",", al_data->filename );
249 field_add_string(syslog_msg, OS_SIZE_2048, " acct=\"%s\",", al_data->user );
250 field_add_string(syslog_msg, OS_SIZE_2048, " md5_old=\"%s\",", al_data->old_md5 );
251 field_add_string(syslog_msg, OS_SIZE_2048, " md5_new=\"%s\",", al_data->new_md5 );
252 field_add_string(syslog_msg, OS_SIZE_2048, " sha1_old=\"%s\",", al_data->old_sha1 );
253 field_add_string(syslog_msg, OS_SIZE_2048, " sha1_new=\"%s\",", al_data->new_sha1 );
255 field_add_truncated(syslog_msg, OS_SIZE_2048, " message=\"%s\"", json_safe_message, 2 );
259 OS_SendUDPbySize(syslog_config->socket, strlen(syslog_msg), syslog_msg);
260 /* Free the malloc'd variables */
261 free(json_safe_comment);
262 free(json_safe_message);