X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Fsyscheckd%2Fseechanges.c;h=7bf2ee1920f78c719a7431c064474b07dacf6fd8;hb=789cbc8e52da68eba3517b920ef22e000cf3c9fd;hp=15496c85b6e111db1cdc930edb3c6242d272b155;hpb=ef70704f0b31b59bb719b884d6a99cb9e3e2044a;p=ossec-hids.git diff --git a/src/syscheckd/seechanges.c b/src/syscheckd/seechanges.c index 15496c8..7bf2ee1 100755 --- a/src/syscheckd/seechanges.c +++ b/src/syscheckd/seechanges.c @@ -15,7 +15,28 @@ #include "shared.h" #include "os_crypto/md5/md5_op.h" +#ifdef USE_MAGIC +#include +extern magic_t magic_cookie; +int is_text(magic_t cookie, const void* buf, size_t len) +{ + const char* magic = magic_buffer(cookie, buf, len); + + 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(0); +} +#endif /* Generate diffs alerts. */ char *gen_diff_alert(char *filename, int alert_diff_time) @@ -115,13 +136,24 @@ int seechanges_dupfile(char *old, char *new) return(0); } - while((n = fread(buf, 1, 2048, fpr)) > 0) + n = fread(buf, 1, 2048, fpr); + #ifdef USE_MAGIC + if(is_text(magic_cookie, buf, n) == 0) + { + goto cleanup; + } + #endif + + do { buf[n] = '\0'; fwrite(buf, n, 1, fpw); - } + while((n = fread(buf, 1, 2048, fpr)) > 0); +#ifdef USE_MAGIC +cleanup: +#endif fclose(fpr); fclose(fpw); return(1); @@ -187,23 +219,42 @@ int seechanges_createpath(char *filename) /* Checks if the file has changed */ char *seechanges_addfile(char *filename) { - int date_of_change; + 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 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]; 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'; + old_tmp[OS_MAXSTR] = '\0'; + new_tmp[OS_MAXSTR] = '\0'; + diff_tmp[OS_MAXSTR] = '\0'; diff_cmd[OS_MAXSTR] = '\0'; md5sum_new[0] = '\0'; md5sum_old[0] = '\0'; - snprintf(old_location, OS_MAXSTR, "%s/local/%s/%s", DIFF_DIR_PATH, filename +1, - DIFF_LAST_FILE); + snprintf( + old_location, + OS_MAXSTR, + "%s/local/%s/%s", + DIFF_DIR_PATH, + filename + 1, + DIFF_LAST_FILE + ); /* If the file is not there, rename new location to last location. */ @@ -235,9 +286,18 @@ char *seechanges_addfile(char *filename) /* Saving the old file at timestamp and renaming new to last. */ - date_of_change = File_DateofChange(old_location); - snprintf(tmp_location, OS_MAXSTR, "%s/local/%s/state.%d", DIFF_DIR_PATH, filename +1, - date_of_change); + 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 + ); + + rename(old_location, tmp_location); if(seechanges_dupfile(filename, old_location) != 1) { @@ -246,25 +306,100 @@ char *seechanges_addfile(char *filename) } + new_date_of_change = File_DateofChange(old_location); + + /* Create file names */ + snprintf( + old_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_old, + (int)old_date_of_change + ); + + snprintf( + new_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_new, + (int)new_date_of_change + ); + + snprintf( + diff_tmp, + OS_MAXSTR, + "%s/%s/syscheck-changes-%s-%d-%s-%d", + DEFAULTDIR, + TMP_DIR, + md5sum_old, + (int)old_date_of_change, + md5sum_new, + (int)new_date_of_change + ); + + /* Create diff location */ + snprintf( + diff_location, + OS_MAXSTR, + "%s/local/%s/diff.%d", + DIFF_DIR_PATH, + filename + 1, + (int)new_date_of_change + ); + + /* Create symlinks */ + if (symlink(old_location, old_tmp) == -1) { + merror(LINK_ERROR, ARGV0, old_location, old_tmp, errno, strerror(errno)); + goto cleanup; + } + + if (symlink(tmp_location, new_tmp) == -1) { + merror(LINK_ERROR, ARGV0, tmp_location, new_tmp, errno, strerror(errno)); + goto cleanup; + } + + if (symlink(diff_location, diff_tmp) == -1) { + merror(LINK_ERROR, ARGV0, diff_location, diff_tmp, errno, strerror(errno)); + goto cleanup; + } + + + /* Run diff. */ - date_of_change = File_DateofChange(old_location); - snprintf(diff_cmd, 2048, "diff \"%s\" \"%s\" > \"%s/local/%s/diff.%d\" " - "2>/dev/null", - tmp_location, old_location, - DIFF_DIR_PATH, filename +1, date_of_change); - if(system(diff_cmd) != 256) - { - merror("%s: ERROR: Unable to run diff for %s", - ARGV0, filename); - return(NULL); + 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; - /* Generate alert. */ - return(gen_diff_alert(filename, date_of_change)); +cleanup: + unlink(old_tmp); + unlink(new_tmp); + unlink(diff_tmp); + if (status == -1) + return (NULL); - return(NULL); + /* Generate alert. */ + return (gen_diff_alert(filename, new_date_of_change)); }