#include "shared.h"
#include "os_crypto/md5/md5_op.h"
+#ifdef USE_MAGIC
+#include <magic.h>
+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)
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);
/* 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. */
/* 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)
{
}
+ 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));
}