fwlogwatch-1.2/ 0000755 0000764 0000144 00000000000 11454326217 012061 5 ustar bw users fwlogwatch-1.2/Makefile 0000644 0000764 0000144 00000010164 11454321551 013517 0 ustar bw users # Copyright (C) 2000-2010 Boris Wesslowski
# $Id: Makefile 710 2010-10-10 11:28:41Z bw $
# You might want to add -DSHORT_NAMES to CFLAGS if you only intend to analyze
# log formats with short list/chain/branch/interface names like ipchains.
# You can also add -DLOGDOTS if your Cisco log host logs FQDNs and you only
# want the hostnames in the output.
# -DHAVE_IPV6 enables IPv6 support for the status web server.
# -DHAVE_ADNS enables support for asynchronous DNS lookups.
# Linux
CC = gcc
CFLAGS = -DHAVE_ZLIB -DHAVE_GETTEXT -pipe -O2 -Wall #-pedantic -Wpointer-arith #-g #-p
LDFLAGS = #-g #-static -p
LIBS = -lcrypt -lz #-ladns #-lc_p
# Solaris
#LIBS = -lnsl -lsocket -lcrypt -lz
#
#CC = gcc
#CFLAGS = -DSOLARIS -DHAVE_ZLIB -DHAVE_GETTEXT -pipe -O2 -Wall #-pedantic #-g
#LDFLAGS = #-g
#
#CC = cc
#CFLAGS = -DSOLARIS -DHAVE_ZLIB -DHAVE_GETTEXT -v -fast -xCC
# OpenBSD
#CC = gcc
#CFLAGS = -DHAVE_ZLIB -DHAVE_GETTEXT -pipe -O2 -Wall -I/usr/local/include
#LIBS = -L/usr/local/lib -lz -lintl
# FreeBSD
#CC = gcc
#CFLAGS = -DHAVE_ZLIB -DHAVE_GETTEXT -pipe -O2 -Wall -I/usr/local/include
#LIBS = -L/usr/local/lib -lcrypt -lz -lintl
LEX = flex
LFLAGS = -B --nounput #-f #-p -p -d
INSTALL = install
INSTALL_PROGRAM = $(INSTALL) -s -m 0755
INSTALL_SCRIPT = $(INSTALL) -m 0755
INSTALL_DATA = $(INSTALL) -m 0644
INSTALL_DIR = /usr/local
CONF_DIR = /etc
LOCALE_DIR = /usr
OBJS = cisco_ios.o cisco_pix.o compare.o ipchains.o ipfilter.o ipfw.o \
lancom.o main.o modes.o net.o netfilter.o netscreen.o output.o \
parser.o rcfile.o resolve.o response.o snort.o utils.o whois.o
all: fwlogwatch
cisco_ios.o: main.h utils.h
cisco_pix.o: main.h utils.h
compare.o: compare.h main.h output.h utils.h
ipchains.o: main.h utils.h
ipfilter.o: main.h utils.h
ipfw.o: main.h utils.h
lancom.o: main.h utils.h
main.o: main.h modes.h parser.h rcfile.h utils.h
modes.o: compare.h main.h net.h output.h parser.h rcfile.h \
resolve.h response.h utils.h whois.h
net.o: compare.h main.h output.h resolve.h response.h utils.h
netfilter.o: main.h utils.h
netscreen.o: main.h utils.h
output.o: main.h output.h resolve.h utils.h whois.h
parser.o: cisco_ios.h cisco_pix.h compare.h ipchains.h ipfilter.h \
ipfw.h main.h netfilter.h netscreen.h parser.h snort.h
rcfile.o: main.h parser.h rcfile.h utils.h
resolve.o: main.h resolve.h utils.h
response.o: main.h response.h utils.h
snort.o: main.h utils.h
utils.o: main.h
whois.o: main.h utils.h
fwlogwatch: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
install: all
$(INSTALL_PROGRAM) fwlogwatch $(INSTALL_DIR)/sbin/fwlogwatch
$(INSTALL_SCRIPT) contrib/fwlw_notify $(INSTALL_DIR)/sbin/fwlw_notify
$(INSTALL_SCRIPT) contrib/fwlw_respond $(INSTALL_DIR)/sbin/fwlw_respond
$(INSTALL_DATA) fwlogwatch.8 $(INSTALL_DIR)/share/man/man8/fwlogwatch.8
install-config:
$(INSTALL_DATA) fwlogwatch.config $(CONF_DIR)/fwlogwatch.config
install-i18n:
cd po; make
$(INSTALL_DATA) po/de.mo $(LOCALE_DIR)/share/locale/de/LC_MESSAGES/fwlogwatch.mo
$(INSTALL_DATA) po/ja.mo $(LOCALE_DIR)/share/locale/ja/LC_MESSAGES/fwlogwatch.mo
$(INSTALL_DATA) po/pt.mo $(LOCALE_DIR)/share/locale/pt/LC_MESSAGES/fwlogwatch.mo
$(INSTALL_DATA) po/sv.mo $(LOCALE_DIR)/share/locale/sv/LC_MESSAGES/fwlogwatch.mo
$(INSTALL_DATA) po/zh_CN.mo $(LOCALE_DIR)/share/locale/zh_CN/LC_MESSAGES/fwlogwatch.mo
$(INSTALL_DATA) po/zh_TW.mo $(LOCALE_DIR)/share/locale/zh_TW/LC_MESSAGES/fwlogwatch.mo
install-rhinit:
$(INSTALL_SCRIPT) contrib/fwlogwatch.init.redhat $(CONF_DIR)/rc.d/init.d/fwlogwatch
uninstall:
@rm -f $(INSTALL_DIR)/sbin/fwlogwatch \
$(INSTALL_DIR)/sbin/fwlw_notify \
$(INSTALL_DIR)/sbin/fwlw_respond \
$(INSTALL_DIR)/share/man/man8/fwlogwatch.8 \
$(LOCALE_DIR)/share/locale/de/LC_MESSAGES/fwlogwatch.mo \
$(LOCALE_DIR)/share/locale/ja/LC_MESSAGES/fwlogwatch.mo \
$(LOCALE_DIR)/share/locale/pt/LC_MESSAGES/fwlogwatch.mo \
$(LOCALE_DIR)/share/locale/sv/LC_MESSAGES/fwlogwatch.mo \
$(LOCALE_DIR)/share/locale/zh_CN/LC_MESSAGES/fwlogwatch.mo \
$(LOCALE_DIR)/share/locale/zh_TW/LC_MESSAGES/fwlogwatch.mo \
$(CONF_DIR)/fwlogwatch.config \
clean:
rm -f *.o *~ *.bak fwlogwatch
cd po; make clean
indent:
indent --k-and-r-style --indent-level 2 --line-length 180 *.c *.h
fwlogwatch-1.2/whois.c 0000644 0000764 0000144 00000014232 11453062534 013356 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: whois.c 706 2010-10-06 12:02:36Z bw $ */
#include
#include
#include
#include
#include
#include
#ifndef SOLARIS
#include
#else
#include
#endif
#include
#include
#include "main.h"
#include "utils.h"
#define QUAD2IP(a,b,c,d) ((a)<<24 | (b)<<16 | (c<<8) | (d))
#define PREFIX2MASK(n) (~0UL<<(32-(n)))
struct whois_entry *whois_first = NULL;
extern struct options opt;
int whois_get_type(char *type)
{
int cnt = 0, retval = -1;
char buffer[WHOISCMDLEN];
signed char c;
read(opt.whois_sock, &c, 1);
while ((c != '\n') && (c != EOF) && (cnt < WHOISCMDLEN)) {
buffer[cnt] = c;
cnt++;
read(opt.whois_sock, &c, 1);
}
buffer[cnt] = '\0';
switch (buffer[0]) {
case 'A':
*type = buffer[0];
retval = atoi(&buffer[1]);
break;
case 'C':
*type = buffer[0];
retval = 0;
break;
default:
*type = '\0';
}
return (retval);
}
void whois_read_socket(char *buf, int len)
{
int cnt = 0, retval;
bzero(buf, len);
while (cnt < len) {
retval = read(opt.whois_sock, (char *) (buf + cnt), (len - cnt));
cnt += retval;
}
*(buf + len) = '\0';
#ifdef WHOIS_DEBUG
fprintf(stderr, "--- WHOIS_DEBUG ---\n%s--- WHOIS_DEBUG ---\n", buf);
fflush(stdout);
#endif
}
char *whois_read_data()
{
int retval;
char type, *data = NULL;
while (1) {
retval = whois_get_type(&type);
if (type == 'A') {
data = xmalloc(retval + 1);
whois_read_socket(data, retval);
} else {
break;
}
}
return (data);
}
char *whois_get_from_as(int asn)
{
char cmdstr[WHOISCMDLEN], *data;
snprintf(cmdstr, WHOISCMDLEN, "!man,AS%d\n", asn);
write(opt.whois_sock, cmdstr, strlen(cmdstr));
data = whois_read_data();
return (data);
}
void whois_search_desc(struct whois_entry *we)
{
char *obj, *descs, *desce;
obj = whois_get_from_as(we->as_number);
if (obj != NULL) {
descs = strstr(obj, "descr:");
if (descs != NULL) {
descs += 6;
while ((*descs == ' ') || (*descs == '\t'))
descs++;
desce = strchr(descs, '\n');
if (desce != NULL)
*desce = '\0';
we->as_descr = xmalloc(strlen(descs) + 1);
xstrncpy(we->as_descr, descs, strlen(descs) + 1);
}
free(obj);
}
}
void whois_from_ip(struct in_addr ip, struct whois_entry *we)
{
char cmdstr[WHOISCMDLEN], *data, *descs, *desce;
we->as_number = 0;
we->ip_route = NULL;
we->ip_descr = NULL;
we->as_descr = NULL;
snprintf(cmdstr, WHOISCMDLEN, "!r%s/32,l\n", inet_ntoa(ip));
write(opt.whois_sock, cmdstr, strlen(cmdstr));
data = whois_read_data();
if (data != NULL) {
descs = desce = data;
while (*descs != '\0') {
if ((we->as_number == 0) && (strstr(descs, "origin:") == descs)) {
descs += 7;
while ((*descs == ' ') || (*descs == '\t'))
descs++;
descs += 2;
desce = strchr(descs, '\n');
if (desce != NULL)
*desce = '\0';
we->as_number = atoi(descs);
whois_search_desc(we);
descs = desce + 1;
} else if ((we->ip_route == NULL) && (strstr(descs, "route:") == descs)) {
descs += 6;
while ((*descs == ' ') || (*descs == '\t'))
descs++;
desce = strchr(descs, '\n');
if (desce != NULL)
*desce = '\0';
we->ip_route = xmalloc(strlen(descs) + 1);
xstrncpy(we->ip_route, descs, strlen(descs) + 1);
descs = desce + 1;
} else if ((we->ip_descr == NULL) && (strstr(descs, "descr:") == descs)) {
descs += 6;
while ((*descs == ' ') || (*descs == '\t'))
descs++;
desce = strchr(descs, '\n');
if (desce != NULL)
*desce = '\0';
we->ip_descr = xmalloc(strlen(descs) + 1);
xstrncpy(we->ip_descr, descs, strlen(descs) + 1);
descs = desce + 1;
} else {
descs++;
}
}
free(data);
}
if (we->as_number > 0) {
if (we->ip_route == NULL) {
we->ip_route = xmalloc(2);
xstrncpy(we->ip_route, "-", 2);
}
if (we->ip_descr == NULL) {
we->ip_descr = xmalloc(2);
xstrncpy(we->ip_descr, "-", 2);
}
if (we->as_descr == NULL) {
we->as_descr = xmalloc(2);
xstrncpy(we->as_descr, "-", 2);
}
}
}
struct whois_entry *whois(struct in_addr ip)
{
char adds[WHOISROUTELEN];
struct in_addr net, addr;
struct whois_entry *we;
unsigned long int tmp_ip;
if (opt.whois_sock == -1)
return NULL;
tmp_ip = ntohl(ip.s_addr);
if ((tmp_ip == QUAD2IP(0, 0, 0, 0))
|| ((tmp_ip & PREFIX2MASK(8)) == QUAD2IP(127, 0, 0, 0))
|| ((tmp_ip & PREFIX2MASK(8)) == QUAD2IP(10, 0, 0, 0))
|| ((tmp_ip & PREFIX2MASK(12)) == QUAD2IP(172, 16, 0, 0))
|| ((tmp_ip & PREFIX2MASK(16)) == QUAD2IP(192, 168, 0, 0))
|| (tmp_ip == QUAD2IP(255, 255, 255, 255)))
return NULL;
we = whois_first;
while (we != NULL) {
xstrncpy(adds, we->ip_route, WHOISROUTELEN);
net.s_addr = ip.s_addr & parse_cidr(adds);
convert_ip(adds, &addr);
if (addr.s_addr == net.s_addr) {
if (opt.verbose)
fprintf(stderr, _("Looking up whois info for %s from cache\n"), inet_ntoa(ip));
return (we);
}
we = we->next;
}
if (opt.verbose)
fprintf(stderr, _("Looking up whois info for %s\n"), inet_ntoa(ip));
we = xmalloc(sizeof(struct whois_entry));
whois_from_ip(ip, we);
if (we->as_number != 0) {
we->next = whois_first;
whois_first = we;
return (we);
} else {
return (NULL);
}
}
void whois_connect(const char *whois_server)
{
struct hostent *he;
struct sockaddr_in sin;
int sock, retval;
he = gethostbyname(whois_server);
if (he == NULL) {
fprintf(stderr, _("lookup failed: %s\n"), whois_server);
exit(EXIT_FAILURE);
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(WHOIS);
bcopy(he->h_addr, &sin.sin_addr, he->h_length);
retval = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
if (retval == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
write(sock, "!!\n", 3);
opt.whois_sock = sock;
}
void whois_close()
{
int retval;
write(opt.whois_sock, "q\n", 2);
retval = close(opt.whois_sock);
if (retval == -1)
perror("close");
opt.whois_sock = -1;
}
fwlogwatch-1.2/net.h 0000644 0000764 0000144 00000000327 11453062534 013020 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: net.h 706 2010-10-06 12:02:36Z bw $ */
#ifndef _NET_H
#define _NET_H
void prepare_socket(void);
void handshake(int linenum, int hitnum, int ignored);
#endif
fwlogwatch-1.2/AUTHORS 0000644 0000764 0000144 00000000125 11145337041 013121 0 ustar bw users $Id: AUTHORS 683 2009-02-13 18:38:25Z bw $
Boris Wesslowski
fwlogwatch-1.2/rcfile.c 0000644 0000764 0000144 00000031056 11453062534 013474 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: rcfile.c 706 2010-10-06 12:02:36Z bw $ */
#include
#include
#include
#include
#include
#include
#include "rcfile.h"
#include "main.h"
#include "parser.h"
#include "utils.h"
extern struct options opt;
char *get_one_parameter(char *string, unsigned char mode)
{
char *pnt;
while (*string == ' ' || *string == '\t' || *string == '=')
++string;
pnt = string;
while (*pnt != '\n' && *pnt != ' ' && *pnt != '\t' && *pnt != '\0' && (mode == HASH_IGNORE || *pnt != '#'))
++pnt;
*pnt = '\0';
return string;
}
char *get_parameter(char *string)
{
char *pnt;
while (*string == ' ' || *string == '\t' || *string == '=')
++string;
pnt = string;
while (*pnt != '\n' && *pnt != '#' && *pnt != '\0')
++pnt;
*pnt = '\0';
return string;
}
int get_num_parameter(char *string, char *rcfile, int linenum)
{
char *pnt;
while (*string == ' ' || *string == '\t' || *string == '=')
++string;
pnt = string;
while (*pnt != '\n' && *pnt != ' ' && *pnt != '#' && *pnt != '\t' && *pnt != '\0') {
if (!isdigit((int) *pnt))
fprintf(stderr, _("Error in configuration file '%s' line %d: not a number\n"), rcfile, linenum);
++pnt;
}
*pnt = '\0';
return atoi(string);
}
unsigned char get_yes_or_no(char *string, char *rcfile, int linenum)
{
char *pnt;
while (*string == ' ' || *string == '\t' || *string == '=')
++string;
pnt = string;
while (*pnt != '\n' && *pnt != ' ' && *pnt != '#' && *pnt != '\t' && *pnt != '\0')
++pnt;
*pnt = '\0';
if ((strncasecmp(string, "yes", 3) == 0)
|| (strncasecmp(string, "on", 2) == 0)
|| (strncasecmp(string, "true", 4) == 0)) {
return YES;
} else if ((strncasecmp(string, "no", 2) == 0)
|| (strncasecmp(string, "off", 3) == 0)
|| (strncasecmp(string, "false", 5) == 0)) {
return NO;
} else {
fprintf(stderr, _("Error in configuration file '%s' line %d, assuming 'true'\n"), rcfile, linenum);
return YES;
}
}
void parse_rcfile(char *input, char *rcfile, int linenum)
{
char *command;
while (*input == ' ' || *input == '\t')
++input;
if (*input == '#' || *input == '\n')
return;
command = strdup(input);
/* Include files */
if (strncasecmp(command, "include_file", 12) == 0) {
xstrncpy(opt.rcfile, get_one_parameter(command + 13, HASH_ENDS_INPUT), FILESIZE);
read_rcfile(opt.rcfile, MUST_EXIST);
}
/* Global options */
else if (strncasecmp(command, "verbose", 7) == 0) {
opt.verbose = opt.verbose + get_yes_or_no(command + 8, rcfile, linenum);
} else if (strncasecmp(command, "resolve_hosts", 13) == 0) {
opt.resolve = get_yes_or_no(command + 14, rcfile, linenum);
} else if (strncasecmp(command, "resolve_services", 16) == 0) {
opt.sresolve = get_yes_or_no(command + 17, rcfile, linenum);
} else if (strncasecmp(command, "input", 5) == 0) {
add_input_file(get_one_parameter(command + 6, HASH_ENDS_INPUT));
}
/* Evaluation options */
else if (strncasecmp(command, "parser", 6) == 0) {
xstrncpy(opt.format_sel, get_one_parameter(command + 7, HASH_ENDS_INPUT), SHORTLEN);
} else if (strncasecmp(command, "src_ip", 6) == 0) {
opt.src_ip = get_yes_or_no(command + 7, rcfile, linenum);
} else if (strncasecmp(command, "dst_ip", 6) == 0) {
opt.dst_ip = get_yes_or_no(command + 7, rcfile, linenum);
} else if (strncasecmp(command, "protocol", 8) == 0) {
opt.proto = get_yes_or_no(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "src_port", 8) == 0) {
opt.src_port = get_yes_or_no(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "dst_port", 8) == 0) {
opt.dst_port = get_yes_or_no(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "tcp_opts", 8) == 0) {
opt.opts = get_yes_or_no(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "exclude_src_host", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_HOST | PARSER_MODE_SRC | PARSER_MODE_NOT);
} else if (strncasecmp(command, "exclude_src_port", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_PORT | PARSER_MODE_SRC | PARSER_MODE_NOT);
} else if (strncasecmp(command, "exclude_dst_host", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_HOST | PARSER_MODE_NOT);
} else if (strncasecmp(command, "exclude_dst_port", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_PORT | PARSER_MODE_NOT);
} else if (strncasecmp(command, "include_src_host", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_HOST | PARSER_MODE_SRC);
} else if (strncasecmp(command, "include_src_port", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_PORT | PARSER_MODE_SRC);
} else if (strncasecmp(command, "include_dst_host", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_HOST);
} else if (strncasecmp(command, "include_dst_port", 16) == 0) {
add_exclude_hpb(get_one_parameter(command + 16, HASH_ENDS_INPUT), PARSER_MODE_PORT);
} else if (strncasecmp(command, "exclude_chain", 13) == 0) {
add_exclude_hpb(get_parameter(command + 14), PARSER_MODE_CHAIN | PARSER_MODE_NOT);
} else if (strncasecmp(command, "include_chain", 13) == 0) {
add_exclude_hpb(get_parameter(command + 14), PARSER_MODE_CHAIN);
} else if (strncasecmp(command, "exclude_branch", 14) == 0) {
add_exclude_hpb(get_parameter(command + 15), PARSER_MODE_BRANCH | PARSER_MODE_NOT);
} else if (strncasecmp(command, "include_branch", 14) == 0) {
add_exclude_hpb(get_parameter(command + 15), PARSER_MODE_BRANCH);
}
/* Sorting options */
else if (strncasecmp(command, "sort_order", 10) == 0) {
xstrncpy(opt.sort_order, get_one_parameter(command + 11, HASH_ENDS_INPUT), MAXSORTSIZE);
}
/* Output options */
else if (strncasecmp(command, "title", 5) == 0) {
xstrncpy(opt.title, get_parameter(command + 6), TITLESIZE);
} else if (strncasecmp(command, "stylesheet", 10) == 0) {
xstrncpy(opt.stylesheet, get_one_parameter(command + 11, HASH_ENDS_INPUT), CSSSIZE);
} else if (strncasecmp(command, "textcolor", 9) == 0) {
xstrncpy(opt.textcol, get_one_parameter(command + 10, HASH_IGNORE), COLORSIZE);
} else if (strncasecmp(command, "bgcolor", 7) == 0) {
xstrncpy(opt.bgcol, get_one_parameter(command + 8, HASH_IGNORE), COLORSIZE);
} else if (strncasecmp(command, "rowcolor1", 9) == 0) {
xstrncpy(opt.rowcol1, get_one_parameter(command + 10, HASH_IGNORE), COLORSIZE);
} else if (strncasecmp(command, "rowcolor2", 9) == 0) {
xstrncpy(opt.rowcol2, get_one_parameter(command + 10, HASH_IGNORE), COLORSIZE);
}
/* Log summary mode */
else if (strncasecmp(command, "data_amount", 11) == 0) {
opt.datalen = get_yes_or_no(command + 12, rcfile, linenum);
} else if (strncasecmp(command, "start_times", 11) == 0) {
opt.stimes = get_yes_or_no(command + 12, rcfile, linenum);
} else if (strncasecmp(command, "end_times", 9) == 0) {
opt.etimes = get_yes_or_no(command + 10, rcfile, linenum);
} else if (strncasecmp(command, "duration", 8) == 0) {
opt.duration = get_yes_or_no(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "html", 4) == 0) {
opt.html = get_yes_or_no(command + 5, rcfile, linenum);
} else if (strncasecmp(command, "output", 6) == 0) {
opt.use_out = 1;
xstrncpy(opt.outputfile, get_one_parameter(command + 7, HASH_ENDS_INPUT), FILESIZE);
} else if (strncasecmp(command, "recent", 6) == 0) {
opt.recent = parse_time(get_one_parameter(command + 7, HASH_ENDS_INPUT));
} else if (strncasecmp(command, "at_least", 8) == 0) {
opt.least = get_num_parameter(command + 9, rcfile, linenum);
} else if (strncasecmp(command, "maximum", 7) == 0) {
opt.max = get_num_parameter(command + 8, rcfile, linenum);
} else if (strncasecmp(command, "whois_lookup", 12) == 0) {
opt.whois_lookup = get_yes_or_no(command + 13, rcfile, linenum);
} else if (strncasecmp(command, "sender", 6) == 0) {
xstrncpy(opt.sender, get_parameter(command + 7), EMAILSIZE);
} else if (strncasecmp(command, "recipient", 9) == 0) {
xstrncpy(opt.recipient, get_parameter(command + 10), EMAILSIZE);
} else if (strncasecmp(command, "cc", 2) == 0) {
xstrncpy(opt.cc, get_parameter(command + 3), EMAILSIZE);
}
/* Realtime response mode */
else if (strncasecmp(command, "realtime_response", 17) == 0) {
if (get_yes_or_no(command + 18, rcfile, linenum) == YES) {
if ((opt.mode != LOG_SUMMARY) && (opt.mode != REALTIME_RESPONSE)) {
mode_error();
}
opt.mode = REALTIME_RESPONSE;
}
} else if (strncasecmp(command, "ipchains_check", 14) == 0) {
opt.ipchains_check = get_yes_or_no(command + 15, rcfile, linenum);
} else if (strncasecmp(command, "pidfile", 7) == 0) {
xstrncpy(opt.pidfile, get_one_parameter(command + 8, HASH_ENDS_INPUT), FILESIZE);
} else if (strncasecmp(command, "run_as", 6) == 0) {
xstrncpy(opt.run_as, get_one_parameter(command + 7, HASH_ENDS_INPUT), USERSIZE);
} else if (strncasecmp(command, "stateful_start", 14) == 0) {
opt.stateful_start = get_yes_or_no(command + 15, rcfile, linenum);
} else if (strncasecmp(command, "alert_threshold", 15) == 0) {
opt.threshold = get_num_parameter(command + 16, rcfile, linenum);
} else if (strncasecmp(command, "notify", 6) == 0) {
if (get_yes_or_no(command + 7, rcfile, linenum) == YES) {
opt.response = opt.response | OPT_NOTIFY;
} else {
opt.response = opt.response & ~OPT_NOTIFY;
}
} else if (strncasecmp(command, "respond", 7) == 0) {
if (get_yes_or_no(command + 8, rcfile, linenum) == YES) {
opt.response = opt.response | OPT_RESPOND;
} else {
opt.response = opt.response & ~OPT_RESPOND;
}
} else if (strncasecmp(command, "notification_script", 19) == 0) {
xstrncpy(opt.notify_script, get_one_parameter(command + 20, HASH_ENDS_INPUT), FILESIZE);
} else if (strncasecmp(command, "response_script", 15) == 0) {
xstrncpy(opt.respond_script, get_one_parameter(command + 16, HASH_ENDS_INPUT), FILESIZE);
} else if (strncasecmp(command, "known_host", 10) == 0) {
add_known_host(get_one_parameter(command + 11, HASH_ENDS_INPUT));
} else if (strncasecmp(command, "server_status", 13) == 0) {
opt.status = get_yes_or_no(command + 14, rcfile, linenum);
} else if (strncasecmp(command, "bind_to", 7) == 0) {
xstrncpy(opt.listenif, get_one_parameter(command + 8, HASH_ENDS_INPUT), IP6LEN);
} else if (strncasecmp(command, "listen_port", 11) == 0) {
opt.listenport = get_num_parameter(command + 12, rcfile, linenum);
} else if (strncasecmp(command, "listen_to", 9) == 0) {
xstrncpy(opt.listento, get_one_parameter(command + 10, HASH_ENDS_INPUT), IPLEN);
} else if (strncasecmp(command, "status_user", 11) == 0) {
xstrncpy(opt.user, get_one_parameter(command + 12, HASH_ENDS_INPUT), USERSIZE);
} else if (strncasecmp(command, "status_password", 15) == 0) {
xstrncpy(opt.password, get_one_parameter(command + 16, HASH_ENDS_INPUT), PASSWORDSIZE);
} else if (strncasecmp(command, "refresh", 7) == 0) {
opt.refresh = get_num_parameter(command + 8, rcfile, linenum);
}
/* Show log times mode */
else if (strncasecmp(command, "show_log_times", 14) == 0) {
if ((opt.mode != LOG_SUMMARY) && (opt.mode != SHOW_LOG_TIMES)) {
mode_error();
}
opt.mode = SHOW_LOG_TIMES;
} else {
fprintf(stderr, _("Unrecognized option in configuration file '%s' line %d\n"), rcfile, linenum);
exit(EXIT_FAILURE);
}
free(command);
}
unsigned char read_rcfile(char *rcfile, unsigned char must_exist)
{
char buf[BUFSIZE], *name;
FILE *fd;
int linenum = 1, retval;
struct stat info;
if (!must_exist) {
retval = stat(rcfile, &info);
if (retval == -1) {
return EXIT_FAILURE;
}
if (!S_ISREG(info.st_mode)) {
fprintf(stderr, _("%s is not a regular file, ignoring.\n"), rcfile);
return EXIT_FAILURE;
}
}
name = strdup(rcfile);
if (opt.verbose)
fprintf(stderr, _("Opening configuration file '%s'\n"), name);
fd = fopen(name, "r");
if (fd == NULL) {
fprintf(stderr, "fopen %s: %s\n", name, strerror(errno));
exit(EXIT_FAILURE);
}
while (fgets(buf, BUFSIZE, fd)) {
parse_rcfile(buf, name, linenum);
linenum++;
}
if (opt.verbose)
fprintf(stderr, _("Closing '%s'\n"), name);
xstrncpy(opt.rcfile, name, FILESIZE);
free(name);
retval = fclose(fd);
if (retval == EOF) {
perror("fclose");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
fwlogwatch-1.2/CREDITS 0000644 0000764 0000144 00000005770 11145337041 013104 0 ustar bw users $Id: CREDITS 683 2009-02-13 18:38:25Z bw $
This program was written by
Boris Wesslowski
Thanks go to the following persons:
Oliver Goebel
for looking after this program as a RUS-CERT project and some comments.
Florian Weimer
for a very nice code review.
Torkil Zachariassen
for comments on the first public release.
Shane Koster
for reporting a time calculation problem.
Diego M. Vadell
for reporting an ipchains log format difference in old kernels.
Didier Contis
for information and examples of the Cisco log file formats.
Werner Fleck /
for reporting ipchains parser omissions and building a first debian package.
Michael Reichardt
for reporting various problems.
Pekka Savola
for further examples of Cisco log formats.
Martin Hein
for contributing to ipfilter support.
sh00p
for reports about OpenBSD and ipfilter.
Neil McCalden
for a first version of port exclusion support.
Carl Wilhelm Soderstrom and
James Ralston
for improvements of the rpm spec file.
Tobias Hunger
for contributing to the improved response mode.
Diederick van Dijk
for contributing to Cisco PIX support.
Andreas Pfaller
for contributing to netfilter support and doing some debugging.
Alberto Gonzalez Iniesta
for maintaining the debian package.
Sherwood Herben
for contributing to realtime response mode.
Robert Malmgren and Dan Larsson
for contributing to FreeBSD support.
Ivan F. Martinez
for various suggestions and the Portuguese translation.
Oden Eriksson
for the Swedish translation.
Xiaojun Yang
for the simplified Chinese translation and doing a guided implementation
of the Windows XP and NetScreen parsers.
Ying-Chieh Liao
for the traditional Chinese translation.
Hugo van der Kooij
for various suggestions.
Peter Bray
for comments on the Makefile and the ipfilter parser.
Kimura Fuyuki
for FreeBSD portability fixes.
Kyle Amon
for contributing a first version of the PHP frontend.
Bram Vandoren
for contributing to output limiting.
Mirko Zeibig
for contributing to the Elsa Lancom parser.
Ronald Ruijgrok
for pushing me to extend CSS support.
Andrew Beresford
for suggesting fwsm support.
Robert Oschwald
for contributing a SuSE init script.
fwlogwatch-1.2/snort.l 0000644 0000764 0000144 00000011102 11453062534 013374 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: snort.l 706 2010-10-06 12:02:36Z bw $ */
%option prefix="snort"
%option outfile="snort.c"
%option noyywrap
%{
#define YY_NO_INPUT
#include
#include
#include
#include "main.h"
#include "utils.h"
extern struct options opt;
void snort_parse_date(char *input);
void snort_parse_branch(char *input);
void snort_parse_ip(char *input, unsigned char mode);
%}
MONTH "Jan"|"Feb"|"Mar"|"Apr"|"May"|"Jun"|"Jul"|"Aug"|"Sep"|"Oct"|"Nov"|"Dec"
STRING [a-zA-Z0-9._-]*
STRING2 [ -Z\\^-~]*
STRING3 [a-zA-Z(][ a-zA-Z0-9()/._-]*[a-zA-Z)]
LOGHOST [0-9.a-zA-Z()_:-]*
DIGIT [0-9]
NUMBER {DIGIT}+
OCTET {DIGIT}{1,3}
PORT {DIGIT}{1,5}
PROTO "TCP"|"UDP"|"ICMP"
%%
{MONTH}[ ]{1,2}{DIGIT}{1,2}[ ]{DIGIT}{2}:{DIGIT}{2}:{DIGIT}{2}[ ]{LOGHOST} snort_parse_date(snorttext);
"snort: " /* ignore */
"snort["{NUMBER}"]: " /* ignore */
"["{NUMBER}":"{NUMBER}":"{DIGIT}"]" /* ignore */
{STRING3} xstrncpy(opt.line->chainlabel, snorttext, SHORTLEN); opt.parser=opt.parser|SNORT_CHAIN;
"[Classification: "{STRING2}"]" snort_parse_branch(snorttext+17);
"[Priority: "{DIGIT}"]:" /* ignore */
"{"{PROTO}"}"[ ]{OCTET}"."{OCTET}"."{OCTET}"."{OCTET} snort_parse_ip(snorttext+1, SNORT_OPT_SRC);
"{"{PROTO}"}"[ ]{OCTET}"."{OCTET}"."{OCTET}"."{OCTET}":"{PORT} snort_parse_ip(snorttext+1, SNORT_OPT_SRC|SNORT_OPT_PORT);
"-> "{OCTET}"."{OCTET}"."{OCTET}"."{OCTET} snort_parse_ip(snorttext, SNORT_OPT_DST);
"-> "{OCTET}"."{OCTET}"."{OCTET}"."{OCTET}":"{PORT} snort_parse_ip(snorttext, SNORT_OPT_DST|SNORT_OPT_PORT);
"spp_portscan: ".* opt.parser=SNORT_NO_HIT;
"spp_stream4: ".* opt.parser=SNORT_NO_HIT;
[ ]+ /* ignore whitespace */
[\n] /* ignore */
{STRING} if(opt.verbose) fprintf(stderr, "Unrecognized token: %s\n", snorttext);
. if(opt.verbose) fprintf(stderr, "Unrecognized character: %s\n", snorttext);
%%
void snort_parse_date(char *input)
{
int retval, day, hour, minute, second;
char smonth[4];
retval = sscanf(input, "%3s %2d %2d:%2d:%2d %32s", smonth, &day, &hour, &minute, &second, opt.line->hostname);
if (retval != 6)
return;
build_time(smonth, day, hour, minute, second);
opt.parser = opt.parser | SNORT_DATE;
}
void snort_parse_branch(char *input)
{
char *ptr;
ptr = strchr(input, ']');
*ptr = '\0';
xstrncpy(opt.line->branchname, input, SHORTLEN);
opt.parser = opt.parser | SNORT_BRANCH;
}
void snort_parse_ip(char *input, unsigned char mode)
{
char ip[IPLEN];
int retval, host1, host2, host3, host4;
if ((mode & SNORT_OPT_SRC) != 0) {
char proto[8];
if ((mode & SNORT_OPT_PORT) != 0) {
retval = sscanf(input, "%8s %3d.%3d.%3d.%3d:%5d", proto, &host1, &host2, &host3, &host4, &opt.line->sport);
if (retval != 6)
return;
} else {
retval = sscanf(input, "%8s %3d.%3d.%3d.%3d", proto, &host1, &host2, &host3, &host4);
if (retval != 5)
return;
}
if (strncmp(proto, "TCP", 3) == 0)
opt.line->protocol = 6;
else if (strncmp(proto, "UDP", 3) == 0)
opt.line->protocol = 17;
else if (strncmp(proto, "ICMP", 4) == 0)
opt.line->protocol = 1;
if (opt.line->protocol != 0)
opt.parser = opt.parser | SNORT_PROTO;
} else if ((mode & SNORT_OPT_DST) != 0) {
if ((mode & SNORT_OPT_PORT) != 0) {
retval = sscanf(input, "-> %3d.%3d.%3d.%3d:%5d", &host1, &host2, &host3, &host4, &opt.line->sport);
if (retval != 5)
return;
} else {
retval = sscanf(input, "-> %3d.%3d.%3d.%3d", &host1, &host2, &host3, &host4);
if (retval != 4)
return;
}
} else {
return;
}
snprintf(ip, IPLEN, "%d.%d.%d.%d", host1, host2, host3, host4);
if ((mode & SNORT_OPT_SRC) != 0) {
if (convert_ip(ip, &opt.line->shost) == IN_ADDR_ERROR)
return;
opt.parser = opt.parser | SNORT_SRC;
} else if ((mode & SNORT_OPT_DST) != 0) {
if (convert_ip(ip, &opt.line->dhost) == IN_ADDR_ERROR)
return;
opt.parser = opt.parser | SNORT_DST;
}
}
unsigned char flex_snort(char *input, int linenum)
{
opt.parser = 0;
init_line();
snort_scan_string(input);
snortlex();
snort_delete_buffer(YY_CURRENT_BUFFER);
xstrncpy(opt.line->interface, "-", SHORTLEN);
opt.line->count = 1;
if (opt.parser & SNORT_NO_HIT)
return PARSE_NO_HIT;
if (opt.parser == (SNORT_DATE | SNORT_CHAIN | SNORT_BRANCH | SNORT_PROTO | SNORT_SRC | SNORT_DST)) {
return PARSE_OK;
} else {
if (opt.verbose)
fprintf(stderr, "snort parse error in line %d, ignoring.\n", linenum);
if (opt.verbose == 2)
fprintf(stderr, "input was: \"%s\"\n", input);
return PARSE_WRONG_FORMAT;
}
}
fwlogwatch-1.2/ChangeLog 0000644 0000764 0000144 00000015730 11454321551 013635 0 ustar bw users $Id: ChangeLog 710 2010-10-10 11:28:41Z bw $
Version 1.2 2010-10-10
- Extended netfilter and Cisco PIX/ASA parsers
- Removed interactive reporting mode
- Removed Windows XP firewall log parser
- Large amounts of fixes
Version 1.1 2006-04-17
- Several parser modifications triggered by log submissions
- Added GNU adns support
- Various small fixes
Version 1.0 2004-04-25
- Made status page interactive
- Added dynamic memory allocation and fixed memory leaks
- Added basic ipfw and fwsm support
- Added stateful start to realtime response mode
- Added command line option to set report title
- Added port number to -X option
- Added CIDR support for host inclusion/exclusion
- Created web page for submission of unrecognized entries
- Updated HTML DTD to XHTML 1.1
- Updated CSS and inverted the color scheme
- Small parser improvements
- Various small fixes
Version 0.9.3 2003-06-23
- Added inclusion/exclusion functions to the command line
- Added external stylesheet embedding in realtime response mode
- All html colors are done with css styles now
- Unified some output functions, small cleanups
- Small parser improvements
- Various small fixes
Version 0.9.2 2003-04-08
- Fixed problems with multiple input file support, whois resolver and
status web server page reload
Version 0.9.1 2003-03-22
- Added multiple input file support
- Various small fixes
Version 0.9 2002-08-20
- Added NetScreen support
- Added basic PIX version 6 support to Cisco PIX parser
- Added Elsa Lancom support contributed by Mirko Zeibig
- Added -M (maximum) option as suggested by Bram Vandoren
- Added php frontend (rewrite of a script by Kyle Amon)
- Added IPv6 support to status web server
- Various small fixes
Version 0.8.1 2002-05-15
- Modified several output functions to improve portability
Version 0.8 2002-05-08
- Added Snort support
- Added support for sending summaries by email (-T option)
- Made zlib and gettext support compile time options (-V shows options used)
- Changes in the parsers and CIDR code
- Various small fixes
Version 0.7.1 2002-04-04
was not officially released
Version 0.7 2002-03-27
- Several realtime response improvements
- Added support for configuration changes while running
- Added support for include files in configuration files
- Status page can be sorted and supports the at_least option
- SIGUSR1 reopens the log file, SIGHUP rereads the configuration file
- Documentation was updated
- HTML output now mostly uses inline CSS for colors and fonts
- Added support for external stylesheets and basic HTML color names
- The default configuration file is not parsed anymore if an alternative
configuration file is specified
- Rewrote parts of the ipfilter parser to support resolved IP addresses
in logs
- Various small fixes
Version 0.6 2002-02-24
- Added chain and branch selection/exclusion options
- Added Windows XP firewall log parser
- Added option to drop privileges when running as daemon
- Added traditional chinese translation (the existing is simplified chinese)
- Various small fixes
Version 0.5.2 2002-01-27
- Added 'title' option: The title of the summary and the realtime
response status page can be customized in the configuration file
- Added -e option: 'show end times', -t now only shows start times
- Added -N option: 'resolve service names' is a new option and off by
default now
- Added swedish translation
- I18n adjustments, small fixes
Version 0.5.1 2001-11-18
- Various fixes: whois code, mode selection, endianness problems, realtime
response with destination/port distinction, forward chain blocking for
iptables, international encoding, portability
- Added chinese and portuguese translations
Version 0.5 2001-10-11
- Added internationalization support with german as first language
- Added support for input from stdin in all modes
- Added options to specify paths for notifications and response scripts
- Made the check for correct ipchains rules a config file option
- Modified realtime response reaction behaviour when attacker insists
- Added display of selected parser options in realtime response status page
- Added automatic refresh of realtime response status page
- FreeBSD portablility fixes
- Various small fixes
Version 0.4 2001-08-19
- Added whois information lookup
- Added sorting by end time
- Changed pid file handling
- Renamed and introduced new listen_to option (bind_to)
- Implemented SIGHUP handling (e.g. for log rotation)
- Updated CGI scripts
- Added init script for redhat linux
- Various small fixes
Version 0.3.1 2001-05-25
- Rewrote netfilter prefix parsing code
- Made long list/chain/branch/interface names the default
- Fixed a sorting stability problem
- OpenBSD portability changes
- Various small fixes
Version 0.3 2001-04-08
- Rewrote realtime response mode to use external scripts for notifications
and responses
- Added a first version of Cisco PIX parser
- Added 'last message repeated' handling code
- Unrecognized text is now only displayed in verbose mode
Version 0.2.1 2001-03-09
- Added compressed input file support
- Added total packet length sum option
- Added support for long chain/branch/interface names
- Modified time output (summary shows times of packet log entries, log
times mode shows times of all entries)
- Various small fixes and cleanups
Version 0.2 2001-02-10
- Added ipfilter support
- Added host and port selection/exclusion support
- Added support for parser selection
- Realtime response mode is available also in non-ipchains and non-root
environments now
- Various small fixes
Version 0.1.3 2001-01-22
- Replaced the sorting algorithm with a stunningly fast linked list mergesort
- Added two more sorting modes
- Added PID file for realtime response mode
- Added CIDR notation support to known host feature
Version 0.1.2 2001-01-16
- Fixed some remaining problems in realtime response mode
Version 0.1.1 2001-01-12
- Various small fixes
Version 0.1 2001-01-07
- Rewrote IP Address handling code
- Small parser and output extensions
- Added mode collision detection
- Fixed time calculation problem and warp detection
Version 0.0.28 2000-12-26
- Rewrote ipchains parser (converted to flex)
- Added support for Cisco uptime log format
Version 0.0.27 2000-12-08
- Solaris portability patches
- Added at_least option
Version 0.0.26 2000-11-11
- Added basic Cisco support
- Various small fixes
Version 0.0.25 2000-11-06
- Added basic netfilter support
- Several internal optimizations
- Various small fixes
Version 0.0.24 2000-11-01
- Extended the man page and added some options to the command line that
were available only in the configuration file
- Various fixes and code cleanups
- Improved web interface
Version 0.0.23 2000-10-27
- Colors of the HTML output can be changed in the configuration file
- Multiple actions can be combined in realtime response mode
- Added mail notification option to realtime response mode
- Added sort order options
- Added daemon status display through own web server
Version 0.0.22 2000-10-23
- Better sample configuration
- Improved CGI demos
- Various small fixes
Version 0.0.21 2000-10-22
- Initial public release
fwlogwatch-1.2/netfilter.h 0000644 0000764 0000144 00000000320 11453062534 014217 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: netfilter.h 706 2010-10-06 12:02:36Z bw $ */
#ifndef _NETFILTER_H
#define _NETFILTER_H
unsigned char flex_netfilter(char *input, int linenum);
#endif
fwlogwatch-1.2/output.c 0000644 0000764 0000144 00000027411 11453062534 013570 0 ustar bw users /* Copyright (C) 2000-2010 Boris Wesslowski */
/* $Id: output.c 706 2010-10-06 12:02:36Z bw $ */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "output.h"
#include "resolve.h"
#include "utils.h"
#include "whois.h"
extern struct options opt;
extern struct conn_data *first;
void output_timediff(time_t start, time_t end, char *td)
{
time_t diff;
int part;
char tmp[4];
diff = end - start;
if (diff <= 0) {
snprintf(td, 2, "-");
return;
}
part = diff / 86400; /* days */
snprintf(td, TIMESIZE, "%02d:", part);
diff = diff % 86400;
part = diff / 3600; /* hours */
snprintf(tmp, 4, "%02d:", part);
strncat(td, tmp, 4);
diff = diff % 3600;
part = diff / 60; /* minutes */
snprintf(tmp, 4, "%02d:", part);
strncat(td, tmp, 4);
part = diff % 60; /* seconds */
snprintf(tmp, 3, "%02d", part);
strncat(td, tmp, 3);
}
void output_tcp_opts(struct conn_data *input, char *buf)
{
if ((input->flags & (TCP_ACK | TCP_FIN | TCP_RST | TCP_PSH | TCP_URG)) != 0) {
if (input->flags & TCP_SYN) {
strcpy(buf, "s");
} else {
strcpy(buf, "-");
}
if (input->flags & TCP_ACK) {
strcat(buf, "a");
} else {
strcat(buf, "-");
}
if (input->flags & TCP_FIN) {
strcat(buf, "f");
} else {
strcat(buf, "-");
}
if (input->flags & TCP_RST) {
strcat(buf, "r");
} else {
strcat(buf, "-");
}
if (input->flags & TCP_PSH) {
strcat(buf, "p");
} else {
strcat(buf, "-");
}
if (input->flags & TCP_URG) {
strcat(buf, "u");
} else {
strcat(buf, "-");
}
} else {
if (input->flags & TCP_SYN) {
strcpy(buf, "SYN");
} else {
strcpy(buf, "-");
}
}
}
void output_html_entry(struct conn_data *input, FILE * fd)
{
char *proto = NULL, time[TIMESIZE], buf[HOSTLEN];
if (opt.html == 2) {
fprintf(fd, "