X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fsyscheckd%2Fcreate_db.c;h=91875cffb947c0b6b490e8defed530de4dd0db3b;hb=refs%2Fheads%2Fupstream;hp=63610ba6ffeabdff13be19ef37fa36576277c2f8;hpb=914feba5d54f979cd5d7e69c349c3d01f630042a;p=ossec-hids.git diff --git a/src/syscheckd/create_db.c b/src/syscheckd/create_db.c index 63610ba..91875cf 100755 --- a/src/syscheckd/create_db.c +++ b/src/syscheckd/create_db.c @@ -1,14 +1,15 @@ -/* @(#) $Id: create_db.c,v 1.28 2009/10/02 19:28:34 dcid Exp $ */ +/* @(#) $Id: ./src/syscheckd/create_db.c, 2011/11/02 dcid Exp $ + */ /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public - * License (version 3) as published by the FSF - Free Software + * License (version 2) as published by the FSF - Free Software * Foundation * - * License details at the LICENSE file included with OSSEC or + * License details at the LICENSE file included with OSSEC or * online at: http://www.ossec.net/en/licensing.html */ @@ -20,14 +21,11 @@ #include "os_crypto/md5_sha1/md5_sha1_op.h" -/* flags for read_dir and read_file */ -#define CREATE_DB 1 -#define CHECK_DB 2 int __counter = 0; /** Prototypes **/ -int read_dir(char *dir_name, int opts, int flag); +int read_dir(char *dir_name, int opts, OSMatch *restriction); /* int check_file(char *file_name) @@ -35,42 +33,14 @@ int read_dir(char *dir_name, int opts, int flag); */ int check_file(char *file_name) { - char buf[MAX_LINE +2]; - buf[MAX_LINE +1] = '\0'; - - while(fgets(buf, MAX_LINE, syscheck.fp) != NULL) + if(OSHash_Get(syscheck.fp, file_name)) { - if((buf[0] != '#') && (buf[0] != ' ') && (buf[0] != '\n')) - { - char *n_buf; - - /* Removing the new line */ - n_buf = strchr(buf,'\n'); - if(n_buf == NULL) - continue; - - *n_buf = '\0'; - - - /* First 6 characters are for internal use */ - n_buf = buf; - n_buf+=6; - - n_buf = strchr(n_buf, ' '); - if(n_buf) - { - n_buf++; - - /* Checking if name matches */ - if(strcmp(n_buf, file_name) == 0) - return(1); - } - } + return(1); } /* New file */ sleep(1); - + debug2("%s: DEBUG: new file '%s'.", ARGV0, file_name); return(0); } @@ -80,21 +50,23 @@ int check_file(char *file_name) /* int read_file(char *file_name, int opts, int flag) * Reads and generates the integrity data of a file. */ -int read_file(char *file_name, int opts, int flag) +int read_file(char *file_name, int opts, OSMatch *restriction) { - int check_file_new = 0; + char *buf; + char sha1s = '+'; struct stat statbuf; - + + /* Checking if file is to be ignored */ if(syscheck.ignore) { int i = 0; while(syscheck.ignore[i] != NULL) { - if(strncasecmp(syscheck.ignore[i], file_name, + if(strncasecmp(syscheck.ignore[i], file_name, strlen(syscheck.ignore[i])) == 0) { - return(0); + return(0); } i++; @@ -107,7 +79,7 @@ int read_file(char *file_name, int opts, int flag) int i = 0; while(syscheck.ignore_regex[i] != NULL) { - if(OSMatch_Execute(file_name, strlen(file_name), + if(OSMatch_Execute(file_name, strlen(file_name), syscheck.ignore_regex[i])) { return(0); @@ -127,59 +99,46 @@ int read_file(char *file_name, int opts, int flag) merror("%s: Error accessing '%s'.",ARGV0, file_name); return(-1); } - + if(S_ISDIR(statbuf.st_mode)) { #ifdef DEBUG verbose("%s: Reading dir: %s\n",ARGV0, file_name); #endif - return(read_dir(file_name, opts, flag)); + return(read_dir(file_name, opts, restriction)); + } + + + /* restricting file types. */ + if(restriction) + { + if(!OSMatch_Execute(file_name, strlen(file_name), + restriction)) + { + return(0); + } } - - + + /* No S_ISLNK on windows */ #ifdef WIN32 - else if(S_ISREG(statbuf.st_mode)) + if(S_ISREG(statbuf.st_mode)) #else - else if(S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) - #endif + if(S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) + #endif { os_md5 mf_sum; os_sha1 sf_sum; - - - /* If check_db, we just need to verify that the file is - * already present. If not, we add it. - */ - if(flag == CHECK_DB) - { - /* File in the database already */ - fseek(syscheck.fp, 0, SEEK_SET); - if(check_file(file_name)) - { - /* Sleeping in here too */ - #ifndef WIN32 - if(__counter >= (3 * syscheck.sleep_after)) - #else - if(__counter >= (syscheck.sleep_after)) - #endif - { - sleep(syscheck.tsleep); - __counter = 0; - } - __counter++; - - return(0); - } - fseek(syscheck.fp, 0, SEEK_END); - check_file_new = 1; - } + os_sha1 sf_sum2; + os_sha1 sf_sum3; /* Cleaning sums */ strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); + strncpy(sf_sum2, "xxx", 4); + strncpy(sf_sum3, "xxx", 4); /* Generating checksums. */ @@ -194,7 +153,7 @@ int read_file(char *file_name, int opts, int flag) { if(S_ISREG(statbuf_lnk.st_mode)) { - if(OS_MD5_SHA1_File(file_name, mf_sum, sf_sum) < 0) + if(OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum) < 0) { strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); @@ -202,44 +161,73 @@ int read_file(char *file_name, int opts, int flag) } } } - else if(OS_MD5_SHA1_File(file_name, mf_sum, sf_sum) < 0) + else if(OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum) < 0) #else - if(OS_MD5_SHA1_File(file_name, mf_sum, sf_sum) < 0) + if(OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum) < 0) #endif - + { strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); + } + + if(opts & CHECK_SEECHANGES) + { + sha1s = 's'; + } + } + else + { + if(opts & CHECK_SEECHANGES) + sha1s = 'n'; + else + sha1s = '-'; } - - - /* Adding file */ - fprintf(syscheck.fp,"%c%c%c%c%c%c%d:%d:%d:%d:%s:%s %s\n", + + + buf = OSHash_Get(syscheck.fp, file_name); + if(!buf) + { + char alert_msg[912 +1]; + + alert_msg[912] = '\0'; + + if(opts & CHECK_SEECHANGES) + { + char *alertdump = seechanges_addfile(file_name); + if(alertdump) + { + free(alertdump); + alertdump = NULL; + } + } + + + snprintf(alert_msg, 912, "%c%c%c%c%c%c%d:%d:%d:%d:%s:%s", opts & CHECK_SIZE?'+':'-', opts & CHECK_PERM?'+':'-', opts & CHECK_OWNER?'+':'-', opts & CHECK_GROUP?'+':'-', opts & CHECK_MD5SUM?'+':'-', - opts & CHECK_SHA1SUM?'+':'-', + sha1s, opts & CHECK_SIZE?(int)statbuf.st_size:0, opts & CHECK_PERM?(int)statbuf.st_mode:0, opts & CHECK_OWNER?(int)statbuf.st_uid:0, opts & CHECK_GROUP?(int)statbuf.st_gid:0, opts & CHECK_MD5SUM?mf_sum:"xxx", - opts & CHECK_SHA1SUM?sf_sum:"xxx", - file_name); + opts & CHECK_SHA1SUM?sf_sum:"xxx"); + if(OSHash_Add(syscheck.fp, strdup(file_name), strdup(alert_msg)) <= 0) + { + merror("%s: ERROR: Unable to add file to db: %s", ARGV0, file_name); + } - /* Send new file */ - if(check_file_new) - { - char alert_msg[912 +2]; /* Sending the new checksum to the analysis server */ - alert_msg[912 +1] = '\0'; - snprintf(alert_msg, 912, "%d:%d:%d:%d:%s:%s %s", + alert_msg[912] = '\0'; + snprintf(alert_msg, 912, "%d:%d:%d:%d:%s:%s %s", opts & CHECK_SIZE?(int)statbuf.st_size:0, opts & CHECK_PERM?(int)statbuf.st_mode:0, opts & CHECK_OWNER?(int)statbuf.st_uid:0, @@ -249,14 +237,50 @@ int read_file(char *file_name, int opts, int flag) file_name); send_syscheck_msg(alert_msg); } - - + else + { + char alert_msg[OS_MAXSTR +1]; + char c_sum[256 +2]; + + c_sum[0] = '\0'; + c_sum[256] = '\0'; + alert_msg[0] = '\0'; + alert_msg[OS_MAXSTR] = '\0'; + + /* If it returns < 0, we will already have alerted. */ + if(c_read_file(file_name, buf, c_sum) < 0) + return(0); + + if(strcmp(c_sum, buf+6) != 0) + { + /* Sending the new checksum to the analysis server */ + char *fullalert = NULL; + alert_msg[OS_MAXSTR] = '\0'; + if(buf[5] == 's' || buf[5] == 'n') + { + fullalert = seechanges_addfile(file_name); + if(fullalert) + { + snprintf(alert_msg, OS_MAXSTR, "%s %s\n%s", c_sum, file_name, fullalert); + free(fullalert); + fullalert = NULL; + } + else + { + snprintf(alert_msg, 912, "%s %s", c_sum, file_name); + } + } + else + { + snprintf(alert_msg, 912, "%s %s", c_sum, file_name); + } + send_syscheck_msg(alert_msg); + } + } + + /* Sleeping in here too */ - #ifndef WIN32 - if(__counter >= (3 * syscheck.sleep_after)) - #else - if(__counter >= (2 * syscheck.sleep_after)) - #endif + if(__counter >= (syscheck.sleep_after)) { sleep(syscheck.tsleep); __counter = 0; @@ -264,7 +288,7 @@ int read_file(char *file_name, int opts, int flag) __counter++; - #ifdef DEBUG + #ifdef DEBUG verbose("%s: file '%s %s'",ARGV0, file_name, mf_sum); #endif } @@ -282,14 +306,14 @@ int read_file(char *file_name, int opts, int flag) /* read_dir v0.1 * */ -int read_dir(char *dir_name, int opts, int flag) +int read_dir(char *dir_name, int opts, OSMatch *restriction) { int dir_size; - - char f_name[PATH_MAX +2]; + + char f_name[PATH_MAX +2]; DIR *dp; - - struct dirent *entry; + + struct dirent *entry; f_name[PATH_MAX +1] = '\0'; @@ -297,28 +321,25 @@ int read_dir(char *dir_name, int opts, int flag) /* Directory should be valid */ if((dir_name == NULL)||((dir_size = strlen(dir_name)) > PATH_MAX)) { - if(flag == CREATE_DB) - merror(NULL_ERROR, ARGV0); - + merror(NULL_ERROR, ARGV0); + return(-1); } - - + + /* Opening the directory given */ dp = opendir(dir_name); - if(!dp) + if(!dp) { if(errno == ENOTDIR) { - if(read_file(dir_name, opts, flag) == 0) + if(read_file(dir_name, opts, restriction) == 0) return(0); } - - if(flag == CREATE_DB) - { - #ifdef WIN32 - int di = 0; - char *(defaultfilesn[])= { + + #ifdef WIN32 + int di = 0; + char *(defaultfilesn[])= { "C:\\autoexec.bat", "C:\\config.sys", "C:\\WINDOWS/System32/eventcreate.exe", @@ -327,33 +348,32 @@ int read_dir(char *dir_name, int opts, int flag) "C:\\WINDOWS/System32/Tasks", NULL }; - while(defaultfilesn[di] != NULL) + while(defaultfilesn[di] != NULL) + { + if(strcmp(defaultfilesn[di], dir_name) == 0) { - if(strcmp(defaultfilesn[di], dir_name) == 0) - { - break; - } - di++; + break; } + di++; + } - if(defaultfilesn[di] == NULL) - { - merror("%s: WARN: Error opening directory: '%s': %s ", - ARGV0, dir_name, strerror(errno)); - } - - #else - + if(defaultfilesn[di] == NULL) + { merror("%s: WARN: Error opening directory: '%s': %s ", - ARGV0, - dir_name, - strerror(errno)); - #endif + ARGV0, dir_name, strerror(errno)); } - + + #else + + merror("%s: WARN: Error opening directory: '%s': %s ", + ARGV0, + dir_name, + strerror(errno)); + #endif + return(-1); } - + /* Checking for real time flag. */ if(opts & CHECK_REALTIME) @@ -367,27 +387,29 @@ int read_dir(char *dir_name, int opts, int flag) while((entry = readdir(dp)) != NULL) { char *s_name; - + /* Just ignore . and .. */ if((strcmp(entry->d_name,".") == 0) || - (strcmp(entry->d_name,"..") == 0)) + (strcmp(entry->d_name,"..") == 0)) continue; - + strncpy(f_name, dir_name, PATH_MAX); - + s_name = f_name; - + s_name += dir_size; /* checking if the file name is already null terminated */ if(*(s_name-1) != '/') *s_name++ = '/'; - + *s_name = '\0'; - + strncpy(s_name, entry->d_name, PATH_MAX - dir_size -2); - read_file(f_name, opts, flag); + + /* Check integrity of the file */ + read_file(f_name, opts, restriction); } closedir(dp); @@ -395,56 +417,52 @@ int read_dir(char *dir_name, int opts, int flag) } -/* int check_db() - * Checks database for new files. - */ -int check_db() +/* int run_dbcheck */ +int run_dbcheck() { int i = 0; - /* Read all available directories */ __counter = 0; - do + while(syscheck.dir[i] != NULL) { - read_dir(syscheck.dir[i], syscheck.opts[i], CHECK_DB); + read_dir(syscheck.dir[i], syscheck.opts[i], syscheck.filerestrict[i]); i++; - }while(syscheck.dir[i] != NULL); + } return(0); } - /* int create_db * Creates the file database. */ -int create_db(int delete_db) +int create_db() { int i = 0; - - syscheck.fp = fopen(syscheck.db, "w+"); /* Read and write */ + + /* Creating store data */ + syscheck.fp = OSHash_Create(); if(!syscheck.fp) { - ErrorExit("%s: Unable to create syscheck database " - "at '%s'. Exiting.",ARGV0,syscheck.db); - return(0); + ErrorExit("%s: Unable to create syscheck database." + ". Exiting.",ARGV0); + return(0); } - - /* Creating a local fp only */ - if(delete_db) + if(!OSHash_setSize(syscheck.fp, 2048)) { - unlink(syscheck.db); + merror(LIST_ERROR, ARGV0); + return(0); } - + /* dir_name can't be null */ if((syscheck.dir == NULL) || (syscheck.dir[0] == NULL)) { merror("%s: No directories to check.",ARGV0); return(-1); } - + merror("%s: INFO: Starting syscheck database (pre-scan).", ARGV0); @@ -453,7 +471,7 @@ int create_db(int delete_db) __counter = 0; do { - if(read_dir(syscheck.dir[i], syscheck.opts[i], CREATE_DB) == 0) + if(read_dir(syscheck.dir[i], syscheck.opts[i], syscheck.filerestrict[i]) == 0) { #ifdef WIN32 if(syscheck.opts[i] & CHECK_REALTIME) @@ -465,7 +483,11 @@ int create_db(int delete_db) i++; }while(syscheck.dir[i] != NULL); - + #if defined (USEINOTIFY) || defined (WIN32) + if(syscheck.realtime && (syscheck.realtime->fd >= 0)) + verbose("%s: INFO: Real time file monitoring started.", ARGV0); + #endif + merror("%s: INFO: Finished creating syscheck database (pre-scan " "completed).", ARGV0); return(0);