/*
* logtool - a logfile parsing/monitoring/manipulation utility
*
* Copyright (C) Y2K (2000) A.L.Lambert
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* yee ole' includes */
#include "includes.h"
/* A regex function to match paterns */
int lt_match(const char *string, char *pattern) /* This means "what you want to search", "what you want to search for" */
{
int status;
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
return(FALSE); /* report error */
}
status = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
if (status != 0) {
return(FALSE); /* report error */
}
return(TRUE);
}
/* a function to match against pre-compiled regex's */
int lt_match_re(const char *string, regex_t re) {
int status;
status = regexec(&re, string, (size_t) 0, NULL, 0);
if (status != 0) {
return FALSE;
} else {
return TRUE;
}
}
int lt_filelen(FILE *file) {
int retval = 0;
/* find out how long the file is */
fseek(file, 0, SEEK_END); /* seek end of file */
retval = ftell(file); /* get byte value */
fseek(file, 0, SEEK_SET); /* return to begin */
return retval; /* return size of file */
}
short int lt_load_regex(char *file, char **dest, regex_t *re) {
char line[LSIZE];
char tmp[LSIZE];
char count = 1;
FILE *fileptr;
short int retval;
DIR *dir;
struct stat *stbuf;
char *fname;
struct dirent *de;
stbuf=malloc(sizeof(struct stat));
if(stat(file, stbuf)<0) {
/* Could not stat, so, back out */
if(cf.debug) fprintf(stderr, "Could not stat %s\n", file);
return FALSE;
}
if(S_ISDIR(stbuf->st_mode)) {
dir=opendir(file);
if( ! dir ) {
if(cf.debug) fprintf(stderr, "Could not opendir %s\n", file);
return FALSE;
}
while((de=readdir(dir))) {
if(!strncmp(de->d_name, ".", 1)) continue;
fname=malloc(strlen(file)+strlen(de->d_name)+2);
sprintf(fname, "%s/%s", file, de->d_name);
if(!lt_load_regex(fname, dest, re)) {
if(cf.debug) fprintf(stderr,
"error occured, bailing out\n");
free(fname);
return FALSE;
}
free(fname);
}
return TRUE;
}
fileptr = fopen(file, "r");
if( ! fileptr ) {
if(cf.debug) fprintf(stderr, "unable to open file: %s\n", file);
/* oopsie; no such file; abort this loading, and return FALSE */
return FALSE;
}
/* we malloc enough space for 2 of these files just to be safe we don't
* overflow as we add |'s and such to build the regexec string */
*dest = malloc(lt_filelen(fileptr) * 2);
*dest[0] = '\0';
/* while we read the file, and don't have comments */
while(fgets(line, LSIZE, fileptr) != NULL) {
if(lt_match(line, "^#|^$") == 0) {
sscanf(line, "%[^\n]", tmp);
if(count == 1) {
strncat(*dest, tmp, strlen(tmp) + 1);
count = 2;
} else {
strncat(*dest, "|", 2);
strncat(*dest, tmp, strlen(tmp) + 1);
}
}
}
/* close off yee ole file pointer */
fclose(fileptr);
/* if we got no valid regex's, then return false */
if(*dest[0] == '\0') {
/* we had no strings, nevermind */
retval = FALSE;
} else {
retval = TRUE; /* assume those strings are valid */
/* see if we can compile the patern into a regex */
if (regcomp(re, *dest, REG_EXTENDED|REG_NOSUB) != 0) {
/* oops; wouldn't compile.. nevermind */
return(FALSE); /* report error */
}
}
if(cf.debug) fprintf(stderr, "opened file: %s and got strings >%s<\n", file, *dest);
return (retval);
}
void lt_loadstrings() {
/* for all the regex's we want to load, hit em up here */
/* if you're adding one of these, see logtool.h, readconf.c and regex.c */
/* I need to get off my butt and init this in lt_set_regfile() in readconf.c instead of here, :) */
reg.include_check = lt_load_regex(reg.include_file, ®.include_strs, ®.include_reg);
reg.exclude_check = lt_load_regex(reg.exclude_file, ®.exclude_strs, ®.exclude_reg);
reg.green_check = lt_load_regex(reg.green_file, ®.green_strs, ®.green_reg);
reg.brightgreen_check = lt_load_regex(reg.brightgreen_file, ®.brightgreen_strs, ®.brightgreen_reg);
reg.yellow_check = lt_load_regex(reg.yellow_file, ®.yellow_strs, ®.yellow_reg);
reg.brightyellow_check =lt_load_regex(reg.brightyellow_file, ®.brightyellow_strs, ®.brightyellow_reg);
reg.blue_check = lt_load_regex(reg.blue_file, ®.blue_strs, ®.blue_reg);
reg.brightblue_check = lt_load_regex(reg.brightblue_file, ®.brightblue_strs, ®.brightblue_reg);
reg.cyan_check = lt_load_regex(reg.cyan_file, ®.cyan_strs, ®.cyan_reg);
reg.brightcyan_check = lt_load_regex(reg.brightcyan_file, ®.brightcyan_strs, ®.brightcyan_reg);
reg.magenta_check = lt_load_regex(reg.magenta_file, ®.magenta_strs, ®.magenta_reg);
reg.brightmagenta_check = lt_load_regex(reg.brightmagenta_file, ®.brightmagenta_strs, ®.brightmagenta_reg);
reg.brightred_check = lt_load_regex(reg.brightred_file, ®.brightred_strs, ®.brightred_reg);
}
/* our different event types defined: for EVENT_*. They are (currently) SYSLOG, SNORT, and IPTABLES */
/* Laurent Jacquot: I have got some lines not matching ^[A-Z] ... */
char syslog_format[256] = "^[A-Za-z][a-z][a-z] .[0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] .* .* .*$";
char snort_format[256] = "^[A-Za-z][a-z][a-z] .[0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] .* snort.*: .*[0-9] -> .*[0-9].*$";
char iptables_format[256] = "^[A-Za-z][a-z][a-z] .[0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] .*IN=.* OUT=.* SRC=.* DST=.* .*$";
regex_t syslog_freg;
regex_t snort_freg;
regex_t iptables_freg;
void lt_regexinit() {
regcomp(&syslog_freg, syslog_format, REG_EXTENDED|REG_NOSUB);
regcomp(&snort_freg, snort_format, REG_EXTENDED|REG_NOSUB);
regcomp(&iptables_freg, iptables_format, REG_EXTENDED|REG_NOSUB);
lt_loadstrings();
}
/* currently known event types: SNORT SYSLOG UNKNOWN */
short int lt_fmtcheck(char *tmp) {
short int retval = -1;
if(lt_match_re(tmp, syslog_freg) == TRUE) {
retval = EVENT_SYSLOG;
}
if(lt_match_re(tmp, snort_freg) == TRUE) {
retval = EVENT_SNORT;
}
if(lt_match_re(tmp, iptables_freg) == TRUE) {
retval = EVENT_IPTABLES;
}
if(retval == -1) {
retval = EVENT_UNKNOWN;
}
return retval;
}
syntax highlighted by Code2HTML, v. 0.9.1