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
00035
00036
00037
00038
00039
00040
00041 #ifdef HAVE_CONFIG_H
00042 #include "config.h"
00043 #endif
00044
00045 #include <sys/types.h>
00046 #include <syslog.h>
00047 #include <stdlib.h>
00048 #ifdef HAVE_STRINGS_H
00049 #include <strings.h>
00050 #endif
00051
00052 #ifndef WIN32
00053 #include <sys/socket.h>
00054 #include <netinet/in.h>
00055 #include <arpa/inet.h>
00056 #endif
00057
00058 #include "decode.h"
00059 #include "event.h"
00060 #include "rules.h"
00061 #include "plugbase.h"
00062 #include "spo_plugbase.h"
00063 #include "debug.h"
00064 #include "parser.h"
00065 #include "mstring.h"
00066 #include "util.h"
00067
00068 #include "snort.h"
00069
00070 typedef struct _SyslogData
00071 {
00072 int facility;
00073 int priority;
00074 int options;
00075 } SyslogData;
00076
00077 void AlertSyslogInit(u_char *);
00078 SyslogData *ParseSyslogArgs(char *);
00079 void AlertSyslog(Packet *, char *, void *, Event *);
00080 void AlertSyslogCleanExit(int, void *);
00081 void AlertSyslogRestart(int, void *);
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 void AlertSyslogSetup(void)
00098 {
00099
00100
00101 RegisterOutputPlugin("alert_syslog", NT_OUTPUT_ALERT, AlertSyslogInit);
00102 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: Alert-Syslog is setup...\n"););
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 void AlertSyslogInit(u_char *args)
00118 {
00119 SyslogData *data;
00120 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: Alert-Syslog Initialized\n"););
00121
00122 pv.alert_plugin_active = 1;
00123
00124
00125 data = ParseSyslogArgs(args);
00126
00127 if (pv.daemon_flag)
00128 data->options |= LOG_PID;
00129
00130 openlog("snort", data->options, data->facility);
00131
00132 DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking syslog alert function to call list...\n"););
00133
00134
00135 AddFuncToOutputList(AlertSyslog, NT_OUTPUT_ALERT, data);
00136 AddFuncToCleanExitList(AlertSyslogCleanExit, data);
00137 AddFuncToRestartList(AlertSyslogRestart, data);
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 SyslogData *ParseSyslogArgs(char *args)
00156 {
00157 #ifdef WIN32
00158 char *DEFAULT_SYSLOG_HOST = "127.0.0.1";
00159 int DEFAULT_SYSLOG_PORT = 514;
00160 char **config_toks;
00161 char **host_toks;
00162 char *host_string = args;
00163 int num_config_toks, num_host_toks;
00164 #endif
00165 char **facility_toks;
00166 char *facility_string = args;
00167 int num_facility_toks = 0;
00168 int i = 0;
00169 SyslogData *data;
00170 char *tmp;
00171
00172 data = (SyslogData *)SnortAlloc(sizeof(SyslogData));
00173
00174
00175 data->options = 0;
00176 data->facility = LOG_AUTH;
00177 data->priority = LOG_INFO;
00178
00179 if(args == NULL)
00180 {
00181
00182 if(file_name != NULL)
00183 {
00184 LogMessage("%s(%d) => No arguments to alert_syslog preprocessor!\n",
00185 file_name, file_line);
00186 }
00187
00188 return data;
00189
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 #ifdef WIN32
00203
00204 config_toks = mSplit(args, ",", 2, &num_config_toks, '\\');
00205 switch( num_config_toks )
00206 {
00207 case 1:
00208 LogMessage("alert_syslog output processor is defaulting to syslog "
00209 "server on %s port %d!\n",
00210 DEFAULT_SYSLOG_HOST, DEFAULT_SYSLOG_PORT);
00211 strncpy(pv.syslog_server, DEFAULT_SYSLOG_HOST, STD_BUF-1);
00212 pv.syslog_server_port = DEFAULT_SYSLOG_PORT;
00213 facility_string = config_toks[0];
00214 break;
00215
00216 case 2:
00217 host_string = config_toks[0];
00218 facility_string = config_toks[1];
00219
00220 host_toks = mSplit(host_string, "=:", 3, &num_host_toks, 0);
00221 if(num_host_toks > 0 && strcmp(host_toks[0], "host") != 0 )
00222 {
00223 FatalError("%s(%d) => Badly formed alert_syslog 'host' "
00224 "argument ('%s')\n",
00225 file_name, file_line, host_string);
00226 }
00227
00228 if((num_host_toks >= 1 && strlen(host_toks[0]) == 0) ||
00229 (num_host_toks >= 2 && strlen(host_toks[1]) == 0) ||
00230 (num_host_toks >= 3 && strlen(host_toks[2]) == 0))
00231 {
00232 FatalError("%s(%d) => Badly formed alert_syslog 'host' "
00233 "argument ('%s')\n",
00234 file_name, file_line, host_string);
00235 }
00236 switch(num_host_toks)
00237 {
00238 case 2:
00239 strncpy(pv.syslog_server, host_toks[1], STD_BUF-1);
00240 pv.syslog_server_port = DEFAULT_SYSLOG_PORT;
00241 break;
00242
00243 case 3:
00244 strncpy(pv.syslog_server, host_toks[1], STD_BUF-1);
00245 pv.syslog_server_port = atoi(host_toks[2]);
00246 if( pv.syslog_server_port == 0 )
00247 {
00248 pv.syslog_server_port = DEFAULT_SYSLOG_PORT;
00249 LogMessage("WARNING %s(%d) => alert_syslog port "
00250 "appears to be non-numeric ('%s'). Defaulting "
00251 "to port %d!\n", file_name, file_line,
00252 host_toks[2], DEFAULT_SYSLOG_PORT);
00253
00254 }
00255 break;
00256
00257 default:
00258 FatalError("%s(%d) => Badly formed alert_syslog 'host' "
00259 "argument ('%s')\n",
00260 file_name, file_line, host_string);
00261 }
00262 mSplitFree(&host_toks, num_host_toks);
00263 break;
00264
00265 default:
00266 FatalError("%s(%d) => Badly formed alert_syslog arguments ('%s')\n",
00267 file_name, file_line, args);
00268 }
00269
00270 DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Logging alerts to syslog "
00271 "server %s on port %d\n", pv.syslog_server,
00272 pv.syslog_server_port););
00273 mSplitFree(&config_toks, num_facility_toks);
00274 #endif
00275
00276
00277
00278
00279 facility_toks = mSplit(facility_string, " |", 31, &num_facility_toks, '\\');
00280
00281 for(i = 0; i < num_facility_toks; i++)
00282 {
00283 if(*facility_toks[i] == '$')
00284 {
00285 if((tmp = VarGet(facility_toks[i]+1)) == NULL)
00286 {
00287 FatalError("%s(%d) => Undefined variable %s\n",
00288 file_name, file_line, facility_toks[i]);
00289 }
00290 }
00291 else
00292 {
00293 tmp = facility_toks[i];
00294 }
00295
00296
00297
00298 #ifdef LOG_CONS
00299 if(!strcasecmp("LOG_CONS", tmp))
00300 {
00301 data->options |= LOG_CONS;
00302 }
00303 else
00304 #endif
00305 #ifdef LOG_NDELAY
00306 if(!strcasecmp("LOG_NDELAY", tmp))
00307 {
00308 data->options |= LOG_NDELAY;
00309 }
00310 else
00311 #endif
00312 #ifdef LOG_PERROR
00313 if(!strcasecmp("LOG_PERROR", tmp))
00314 {
00315 data->options |= LOG_PERROR;
00316 }
00317 else
00318 #endif
00319 #ifdef LOG_PID
00320 if(!strcasecmp("LOG_PID", tmp))
00321 {
00322 data->options |= LOG_PID;
00323 }
00324 else
00325 #endif
00326 #ifdef LOG_NOWAIT
00327 if(!strcasecmp("LOG_NOWAIT", tmp))
00328 {
00329 data->options |= LOG_NOWAIT;
00330 }
00331 else
00332 #endif
00333
00334
00335 #ifdef LOG_AUTHPRIV
00336 if(!strcasecmp("LOG_AUTHPRIV", tmp))
00337 {
00338 data->facility = LOG_AUTHPRIV;
00339 }
00340 else
00341 #endif
00342 #ifdef LOG_AUTH
00343 if(!strcasecmp("LOG_AUTH", tmp))
00344 {
00345 data->facility = LOG_AUTH;
00346 }
00347 else
00348 #endif
00349 #ifdef LOG_DAEMON
00350 if(!strcasecmp("LOG_DAEMON", tmp))
00351 {
00352 data->facility = LOG_DAEMON;
00353 }
00354 else
00355 #endif
00356 #ifdef LOG_LOCAL0
00357 if(!strcasecmp("LOG_LOCAL0", tmp))
00358 {
00359 data->facility = LOG_LOCAL0;
00360 }
00361 else
00362 #endif
00363 #ifdef LOG_LOCAL1
00364 if(!strcasecmp("LOG_LOCAL1", tmp))
00365 {
00366 data->facility = LOG_LOCAL1;
00367 }
00368 else
00369 #endif
00370 #ifdef LOG_LOCAL2
00371 if(!strcasecmp("LOG_LOCAL2", tmp))
00372 {
00373 data->facility = LOG_LOCAL2;
00374 }
00375 else
00376 #endif
00377 #ifdef LOG_LOCAL3
00378 if(!strcasecmp("LOG_LOCAL3", tmp))
00379 {
00380 data->facility = LOG_LOCAL3;
00381 }
00382 else
00383 #endif
00384 #ifdef LOG_LOCAL4
00385 if(!strcasecmp("LOG_LOCAL4", tmp))
00386 {
00387 data->facility = LOG_LOCAL4;
00388 }
00389 else
00390 #endif
00391 #ifdef LOG_LOCAL5
00392 if(!strcasecmp("LOG_LOCAL5", tmp))
00393 {
00394 data->facility = LOG_LOCAL5;
00395 }
00396 else
00397 #endif
00398 #ifdef LOG_LOCAL6
00399 if(!strcasecmp("LOG_LOCAL6", tmp))
00400 {
00401 data->facility = LOG_LOCAL6;
00402 }
00403 else
00404 #endif
00405 #ifdef LOG_LOCAL7
00406 if(!strcasecmp("LOG_LOCAL7", tmp))
00407 {
00408 data->facility = LOG_LOCAL7;
00409 }
00410 else
00411 #endif
00412 #ifdef LOG_USER
00413 if(!strcasecmp("LOG_USER", tmp))
00414 {
00415 data->facility = LOG_USER;
00416 }
00417 else
00418 #endif
00419
00420
00421
00422 #ifdef LOG_EMERG
00423 if(!strcasecmp("LOG_EMERG", tmp))
00424 {
00425 data->priority = LOG_EMERG;
00426 }
00427 else
00428 #endif
00429 #ifdef LOG_ALERT
00430 if(!strcasecmp("LOG_ALERT", tmp))
00431 {
00432 data->priority = LOG_ALERT;
00433 }
00434 else
00435 #endif
00436 #ifdef LOG_CRIT
00437 if(!strcasecmp("LOG_CRIT", tmp))
00438 {
00439 data->priority = LOG_CRIT;
00440 }
00441 else
00442 #endif
00443 #ifdef LOG_ERR
00444 if(!strcasecmp("LOG_ERR", tmp))
00445 {
00446 data->priority = LOG_ERR;
00447 }
00448 else
00449 #endif
00450 #ifdef LOG_WARNING
00451 if(!strcasecmp("LOG_WARNING", tmp))
00452 {
00453 data->priority = LOG_WARNING;
00454 }
00455 else
00456 #endif
00457 #ifdef LOG_NOTICE
00458 if(!strcasecmp("LOG_NOTICE", tmp))
00459 {
00460 data->priority = LOG_NOTICE;
00461 }
00462 else
00463 #endif
00464 #ifdef LOG_INFO
00465 if(!strcasecmp("LOG_INFO", tmp))
00466 {
00467 data->priority = LOG_INFO;
00468 }
00469 else
00470 #endif
00471 #ifdef LOG_DEBUG
00472 if(!strcasecmp("LOG_DEBUG", tmp))
00473 {
00474 data->priority = LOG_DEBUG;
00475 }
00476 else
00477 #endif
00478 {
00479 LogMessage("WARNING %s (%d) => Unrecognized syslog "
00480 "facility/priority: %s\n",
00481 file_name, file_line, tmp);
00482 }
00483 }
00484 mSplitFree(&facility_toks, num_facility_toks);
00485
00486 return data;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 extern OptTreeNode *otn_tmp;
00504 void AlertSyslog(Packet *p, char *msg, void *arg, Event *event)
00505 {
00506 char sip[16];
00507 char dip[16];
00508 char pri_data[STD_BUF];
00509 char ip_data[STD_BUF];
00510 char event_data[STD_BUF];
00511 #define SYSLOG_BUF 1024
00512 char event_string[SYSLOG_BUF];
00513 SyslogData *data = (SyslogData *)arg;
00514
00515
00516 bzero(event_string, SYSLOG_BUF);
00517
00518 if(p && p->iph)
00519 {
00520
00521
00522
00523
00524 strlcpy(sip, inet_ntoa(p->iph->ip_src), 16);
00525 strlcpy(dip, inet_ntoa(p->iph->ip_dst), 16);
00526
00527 if(event != NULL)
00528 {
00529 snprintf(event_data, STD_BUF-1, "[%lu:%lu:%lu] ",
00530 (unsigned long) event->sig_generator,
00531 (unsigned long) event->sig_id,
00532 (unsigned long) event->sig_rev);
00533 strlcat(event_string, event_data, SYSLOG_BUF);
00534 }
00535
00536 if(msg != NULL)
00537 {
00538 strlcat(event_string, msg, SYSLOG_BUF);
00539 }
00540 else
00541 {
00542 strlcat(event_string, "ALERT", SYSLOG_BUF);
00543 }
00544
00545 if(otn_tmp != NULL)
00546 {
00547 if(otn_tmp->sigInfo.classType)
00548 {
00549 snprintf(pri_data, STD_BUF-1, " [Classification: %s] "
00550 "[Priority: %d]:", otn_tmp->sigInfo.classType->name,
00551 otn_tmp->sigInfo.priority);
00552 strlcat(event_string, pri_data, SYSLOG_BUF);
00553 }
00554 else if(otn_tmp->sigInfo.priority != 0)
00555 {
00556 snprintf(pri_data, STD_BUF-1, "[Priority: %d]:",
00557 otn_tmp->sigInfo.priority);
00558 strlcat(event_string, pri_data, SYSLOG_BUF);
00559 }
00560 }
00561
00562 if((p->iph->ip_proto != IPPROTO_TCP &&
00563 p->iph->ip_proto != IPPROTO_UDP) ||
00564 p->frag_flag)
00565 {
00566 if(!pv.alert_interface_flag)
00567 {
00568 snprintf(ip_data, STD_BUF-1, " {%s} %s -> %s",
00569 protocol_names[p->iph->ip_proto], sip, dip);
00570 }
00571 else
00572 {
00573 snprintf(ip_data, STD_BUF-1, " <%s> {%s} %s -> %s",
00574 PRINT_INTERFACE(pv.interface),
00575 protocol_names[p->iph->ip_proto],
00576 sip, dip);
00577 }
00578 }
00579 else
00580 {
00581 if(pv.alert_interface_flag)
00582 {
00583 snprintf(ip_data, STD_BUF-1, " <%s> {%s} %s:%i -> %s:%i",
00584 PRINT_INTERFACE(pv.interface),
00585 protocol_names[p->iph->ip_proto], sip,
00586 p->sp, dip, p->dp);
00587 }
00588 else
00589 {
00590 snprintf(ip_data, STD_BUF-1, " {%s} %s:%i -> %s:%i",
00591 protocol_names[p->iph->ip_proto], sip, p->sp,
00592 dip, p->dp);
00593 }
00594 }
00595
00596 strlcat(event_string, ip_data, SYSLOG_BUF);
00597
00598 syslog(data->priority, "%s", event_string);
00599
00600 }
00601 else
00602 {
00603 syslog(data->priority, "%s", msg == NULL ? "ALERT!" : msg);
00604 }
00605
00606 return;
00607
00608 }
00609
00610
00611 void AlertSyslogCleanExit(int signal, void *arg)
00612 {
00613 SyslogData *data = (SyslogData *)arg;
00614 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "AlertSyslogCleanExit\n"););
00615
00616 free(data);
00617 }
00618
00619 void AlertSyslogRestart(int signal, void *arg)
00620 {
00621 SyslogData *data = (SyslogData *)arg;
00622 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "AlertSyslogRestartFunc\n"););
00623
00624 free(data);
00625 }