X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fsyscheckd%2Fseechanges.c;h=7cf82215ebb1415345bbd93ef8289cbf04db8b89;hp=7bf2ee1920f78c719a7431c064474b07dacf6fd8;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/syscheckd/seechanges.c b/src/syscheckd/seechanges.c old mode 100755 new mode 100644 index 7bf2ee1..7cf8221 --- a/src/syscheckd/seechanges.c +++ b/src/syscheckd/seechanges.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/syscheckd/seechanges.c, 2011/09/08 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All rights reserved. * @@ -10,95 +7,114 @@ * Foundation */ - - #include "shared.h" #include "os_crypto/md5/md5_op.h" +#include "syscheck.h" + +/* Prototypes */ +static char *gen_diff_alert(const char *filename, time_t alert_diff_time) __attribute__((nonnull)); +static int seechanges_dupfile(const char *old, const char *current) __attribute__((nonnull)); +static int seechanges_createpath(const char *filename) __attribute__((nonnull)); #ifdef USE_MAGIC #include + +/* Global variables */ extern magic_t magic_cookie; -int is_text(magic_t cookie, const void* buf, size_t len) + +int is_text(magic_t cookie, const void *buf, size_t len) { - const char* magic = magic_buffer(cookie, buf, len); + const char *magic = magic_buffer(cookie, buf, len); - if(!magic) - { - const char* err = magic_error(cookie); + if (!magic) { + const char *err = magic_error(cookie); merror("%s: ERROR: magic_buffer: %s", ARGV0, err ? err : "unknown"); - return(1); // TODO default to true? - } - else - { - if(strncmp(magic, "text/", 5) == 0) return(1); + return (1); // TODO default to true? + } else { + if (strncmp(magic, "text/", 5) == 0) { + return (1); + } } - return(0); + return (0); } #endif -/* Generate diffs alerts. */ -char *gen_diff_alert(char *filename, int alert_diff_time) +/* Return TRUE if the file name match one of the ``nodiff`` entries. + Return FALSE otherwise */ +int is_nodiff(const char *filename){ + if (syscheck.nodiff){ + int i; + for (i = 0; syscheck.nodiff[i] != NULL; i++){ + if (strncasecmp(syscheck.nodiff[i], filename, + strlen(syscheck.nodiff[i])) == 0) { + return (TRUE); + } + } + } + if (syscheck.nodiff_regex) { + int i; + for (i = 0; syscheck.nodiff_regex[i] != NULL; i++) { + if (OSMatch_Execute(filename, strlen(filename), + syscheck.nodiff_regex[i])) { + return (TRUE); + } + } + } + return (FALSE); +} + +/* Generate diffs alerts */ +static char *gen_diff_alert(const char *filename, time_t alert_diff_time) { - int n = 0; + size_t n = 0; FILE *fp; char *tmp_str; - char buf[OS_MAXSTR +1]; - char diff_alert[OS_MAXSTR +1]; + char buf[OS_MAXSTR + 1]; + char diff_alert[OS_MAXSTR + 1]; buf[OS_MAXSTR] = '\0'; diff_alert[OS_MAXSTR] = '\0'; snprintf(buf, OS_MAXSTR, "%s/local/%s/diff.%d", - DIFF_DIR_PATH, filename, alert_diff_time); + DIFF_DIR_PATH, filename, (int)alert_diff_time); fp = fopen(buf, "r"); - if(!fp) - { + if (!fp) { merror("%s: ERROR: Unable to generate diff alert.", ARGV0); - return(NULL); + return (NULL); } - n = fread(buf, 1, 4096 -1, fp); - if(n <= 0) - { + n = fread(buf, 1, 4096 - 1, fp); + if (n <= 0) { merror("%s: ERROR: Unable to generate diff alert (fread).", ARGV0); fclose(fp); - return(NULL); - } - else if(n >= 4000) - { - /* We need to clear the last new line. */ + return (NULL); + } else if (n >= 4000) { + /* Clear the last newline */ buf[n] = '\0'; tmp_str = strrchr(buf, '\n'); - if(tmp_str) + if (tmp_str) { *tmp_str = '\0'; - else - { - /* Weird diff with only one large line. */ + } else { + /* Weird diff with only one large line */ buf[256] = '\0'; } - } - else - { + } else { buf[n] = '\0'; } n = 0; - - /* Getting up to 20 line changes. */ + /* Get up to 20 line changes */ tmp_str = buf; - - while(tmp_str && (*tmp_str != '\0')) - { + while (tmp_str && (*tmp_str != '\0')) { tmp_str = strchr(tmp_str, '\n'); - if(!tmp_str) + if (!tmp_str) { break; - else if(n >= 19) - { + } else if (n >= 19) { *tmp_str = '\0'; break; } @@ -106,105 +122,94 @@ char *gen_diff_alert(char *filename, int alert_diff_time) tmp_str++; } - - /* Creating alert. */ - snprintf(diff_alert, 4096 -1, "%s%s", - buf, n>=19? - "\nMore changes..": + /* Create alert */ + snprintf(diff_alert, 4096 - 1, "%s%s", + buf, n >= 19 ? + "\nMore changes.." : ""); - fclose(fp); - return(strdup(diff_alert)); + return (strdup(diff_alert)); } - -int seechanges_dupfile(char *old, char *new) +static int seechanges_dupfile(const char *old, const char *current) { - int n; + size_t n; FILE *fpr; FILE *fpw; - unsigned char buf[2048 +1]; + unsigned char buf[2048 + 1]; buf[2048] = '\0'; - fpr = fopen(old,"r"); - fpw = fopen(new,"w"); + fpr = fopen(old, "r"); + if (!fpr) { + return (0); + } - if(!fpr || !fpw) - { - return(0); + fpw = fopen(current, "w"); + if (!fpw) { + fclose(fpr); + return (0); } n = fread(buf, 1, 2048, fpr); - #ifdef USE_MAGIC - if(is_text(magic_cookie, buf, n) == 0) - { +#ifdef USE_MAGIC + if (is_text(magic_cookie, buf, n) == 0) { goto cleanup; } - #endif +#endif - do - { + do { buf[n] = '\0'; fwrite(buf, n, 1, fpw); - } - while((n = fread(buf, 1, 2048, fpr)) > 0); + } while ((n = fread(buf, 1, 2048, fpr)) > 0); #ifdef USE_MAGIC cleanup: #endif fclose(fpr); fclose(fpw); - return(1); + return (1); } - -int seechanges_createpath(char *filename) +static int seechanges_createpath(const char *filename) { char *buffer = NULL; char *tmpstr = NULL; char *newdir = NULL; - os_strdup(filename, buffer); newdir = buffer; - tmpstr = strchr(buffer +1, '/'); - if(!tmpstr) - { + tmpstr = strchr(buffer + 1, '/'); + if (!tmpstr) { merror("%s: ERROR: Invalid path name: '%s'", ARGV0, filename); free(buffer); - return(0); + return (0); } *tmpstr = '\0'; tmpstr++; - - while(1) - { - if(IsDir(newdir) != 0) - { - #ifndef WIN32 - if(mkdir(newdir, 0770) == -1) - #else - if(mkdir(newdir) == -1) - #endif + while (1) { + if (IsDir(newdir) != 0) { +#ifndef WIN32 + if (mkdir(newdir, 0770) == -1) +#else + if (mkdir(newdir) == -1) +#endif { - merror(MKDIR_ERROR, ARGV0, newdir); + merror(MKDIR_ERROR, ARGV0, newdir, errno, strerror(errno)); free(buffer); - return(0); + return (0); } } - if(*tmpstr == '\0') - { + if (*tmpstr == '\0') { break; } tmpstr[-1] = '/'; tmpstr = strchr(tmpstr, '/'); - if(!tmpstr) - { + if (!tmpstr) { break; } *tmpstr = '\0'; @@ -212,30 +217,25 @@ int seechanges_createpath(char *filename) } free(buffer); - return(1); + return (1); } - -/* Checks if the file has changed */ -char *seechanges_addfile(char *filename) +/* Check if the file has changed */ +char *seechanges_addfile(const char *filename) { time_t old_date_of_change; time_t new_date_of_change; - - char old_location[OS_MAXSTR +1]; - char tmp_location[OS_MAXSTR +1]; + char old_location[OS_MAXSTR + 1]; + char tmp_location[OS_MAXSTR + 1]; char diff_location[OS_MAXSTR + 1]; char old_tmp[OS_MAXSTR + 1]; char new_tmp[OS_MAXSTR + 1]; char diff_tmp[OS_MAXSTR + 1]; - - char diff_cmd[OS_MAXSTR +1]; - + char diff_cmd[OS_MAXSTR + 1]; os_md5 md5sum_old; os_md5 md5sum_new; int status = -1; - old_location[OS_MAXSTR] = '\0'; tmp_location[OS_MAXSTR] = '\0'; diff_location[OS_MAXSTR] = '\0'; @@ -246,7 +246,6 @@ char *seechanges_addfile(char *filename) md5sum_new[0] = '\0'; md5sum_old[0] = '\0'; - snprintf( old_location, OS_MAXSTR, @@ -256,41 +255,43 @@ char *seechanges_addfile(char *filename) DIFF_LAST_FILE ); - - /* If the file is not there, rename new location to last location. */ - if(OS_MD5_File(old_location, md5sum_old) != 0) - { + /* If the file is not there, rename new location to last location */ + if (OS_MD5_File(old_location, md5sum_old, OS_BINARY) != 0) { seechanges_createpath(old_location); - if(seechanges_dupfile(filename, old_location) != 1) - { - merror(RENAME_ERROR, ARGV0, filename); + if (seechanges_dupfile(filename, old_location) != 1) { + merror(RENAME_ERROR, ARGV0, filename, old_location, errno, strerror(errno)); } - return(NULL); + return (NULL); } - - /* Get md5sum of the new file. */ - if(OS_MD5_File(filename, md5sum_new) != 0) - { - //merror("%s: ERROR: Invalid internal state (missing '%s').", - // ARGV0, filename); - return(NULL); + /* Get md5sum of the new file */ + if (OS_MD5_File(filename, md5sum_new, OS_BINARY) != 0) { + return (NULL); } - - /* If they match, keep the old file and remove the new. */ - if(strcmp(md5sum_new, md5sum_old) == 0) - { - return(NULL); + /* If they match, keep the old file and remove the new */ + if (strcmp(md5sum_new, md5sum_old) == 0) { + return (NULL); } + /* Save the old file at timestamp and rename new to last */ + old_date_of_change = File_DateofChange(old_location); + + snprintf( + tmp_location, + OS_MAXSTR, + "%s/local/%s/state.%d", + DIFF_DIR_PATH, + filename + 1, + (int)old_date_of_change + ); /* Saving the old file at timestamp and renaming new to last. */ old_date_of_change = File_DateofChange(old_location); snprintf( tmp_location, - OS_MAXSTR, + sizeof(tmp_location), "%s/local/%s/state.%d", DIFF_DIR_PATH, filename + 1, @@ -298,13 +299,19 @@ char *seechanges_addfile(char *filename) ); - rename(old_location, tmp_location); + if((rename(old_location, tmp_location)) < 0) { + merror("%s: ERROR rename of %s failed: %s", ARGV0, old_location, strerror(errno)); + } if(seechanges_dupfile(filename, old_location) != 1) { merror("%s: ERROR: Unable to create snapshot for %s",ARGV0, filename); return(NULL); } + if (seechanges_dupfile(filename, old_location) != 1) { + merror("%s: ERROR: Unable to create snapshot for %s", ARGV0, filename); + return (NULL); + } new_date_of_change = File_DateofChange(old_location); @@ -340,7 +347,6 @@ char *seechanges_addfile(char *filename) md5sum_new, (int)new_date_of_change ); - /* Create diff location */ snprintf( diff_location, @@ -367,28 +373,38 @@ char *seechanges_addfile(char *filename) goto cleanup; } + if (is_nodiff((filename))) { + /* Dont leak sensible data with a diff hanging around */ + FILE *fdiff; + char* nodiff_message = ""; + fdiff = fopen(diff_location, "w"); + if (!fdiff){ + merror("%s: ERROR: Unable to open file for writing `%s`", ARGV0, diff_location); + goto cleanup; + } + fwrite(nodiff_message, strlen(nodiff_message) + 1, 1, fdiff); + fclose(fdiff); + /* Success */ + status = 0; + } else { + /* OK, run diff */ + snprintf( + diff_cmd, + 2048, + "diff \"%s\" \"%s\" > \"%s\" 2> /dev/null", + new_tmp, + old_tmp, + diff_tmp + ); + + if (system(diff_cmd) != 256) { + merror("%s: ERROR: Unable to run `%s`", ARGV0, diff_cmd); + goto cleanup; + } - - /* Run diff. */ - snprintf( - diff_cmd, - 2048, - "diff \"%s\" \"%s\" > \"%s\" 2> /dev/null", - new_tmp, - old_tmp, - diff_tmp - ); - - - - if(system(diff_cmd) != 256) { - merror("%s: ERROR: Unable to run diff for %s", ARGV0, filename); - goto cleanup; - - } - - /* Success */ - status = 0; + /* Success */ + status = 0; + }; cleanup: unlink(old_tmp); @@ -398,10 +414,6 @@ cleanup: if (status == -1) return (NULL); - /* Generate alert. */ + /* Generate alert */ return (gen_diff_alert(filename, new_date_of_change)); } - - - -/* EOF */