[Feature] Add --exclude option to hashdeep
Converted from SourceForge issue 3305389, submitted by jkeller1ca
I'm using hashdeep to verify that no files have been changed on my filesystem before every boot and I'd like to keep the list of known hashes on that filesystem. This implies some sort of special handling for the known hash file. I'd like to be able to pass an '--exclude=known_hashes.txt' option to hashdeep. This would skip this file for auditing or creation of the known hashes. Granted, I'd have to verify the known_hashes.txt file some other way, but at least this way, I'd get most of the filesystem.
Submitted by jessekornblum
Instead of excluding any particular file, just don't pass it in as a command line argument. You may need to put known_hashes.txt in it's own directory, but that shouldn't be too difficult. For example, instead of putting known_hashes.txt in /home/jkeller1ca/known_hashes.txt, it might have to go in /known or some other newly created and then skipped directory.
Submitted by jkeller1ca
I see what you are saying. I could write: hashdeep -a -r -k /known_hashes.txt -o f /bin /etc /home /lib /lib32 /lib64 /opt /root /sbin /usr
What I was proposing allows me to write: hashdeep -a -r -k /known_hashes.txt -o f -N -N /known_hashes.txt -N /known_hashes.txt -N "/var_" -N "/tmp_" /
Here's a patch that implements the -N functionality. I don't have a windows box, so cannot test that code, but here you go.
diff -ur md5deep-3.9.orig/common/dig.c md5deep-3.9/common/dig.c --- md5deep-3.9.orig/common/dig.c2010-12-21 06:29:25.000000000 -0800 +++ md5deep-3.9/common/dig.c2011-05-23 12:14:59.204137001 -0700 @@ -601,6 +601,9 @@ s->timestamp = 0;
type = file_type(s,fn); +
- if(!check_excludes(s,fn))
- return FALSE;
if (s->mode & mode_expert) return (should_hash_expert(s,fn,type)); diff -ur md5deep-3.9.orig/common/helpers.c md5deep-3.9/common/helpers.c --- md5deep-3.9.orig/common/helpers.c2011-03-22 17:09:43.000000000 -0700 +++ md5deep-3.9/common/helpers.c2011-05-25 09:20:11.523782307 -0700 @@ -13,6 +13,9 @@ // $Id: helpers.c 250 2010-12-15 19:12:06Z jessekornblum $
#include "main.h" +#if !defined(_WIN32) +#include <fnmatch.h> +#endif
void setup_expert_mode(state *s, char *arg) { @@ -41,6 +44,49 @@ } }
+int add_exclude_pattern(state *s,const char *optarg) +{
- int count=1;
- TCHAR ** pattern_pointer=s->exclude_patterns;
- TCHAR ** new_exclude_patterns=NULL;
- while( *pattern_pointer ) {
-
count++; -
pattern_pointer++; -
} - MD5DEEP_ALLOC(TCHAR*,new_exclude_patterns,count+1);
- memcpy(new_exclude_patterns,s->exclude_patterns,(count-1)sizeof(TCHAR));
- new_exclude_patterns[count-1]=strdup(optarg);
- free(s->exclude_patterns);
- s->exclude_patterns=new_exclude_patterns;
- return STATUS_OK; +}
+#if defined(_WIN32) +int check_excludes(state *s,TCHAR *fn) +{
- TCHAR ** pattern_pointer=s->exclude_patterns;
- while( *pattern_pointer ) {
- if(PathMatchSpecEx(fn,*pattern_pointer,PMSF_NORMAL) == S_OK)
-
return FALSE; - pattern_pointer++;
- } +} +#else +int check_excludes(state *s,TCHAR *fn) +{
- TCHAR ** pattern_pointer=s->exclude_patterns;
- while(*pattern_pointer) {
- if(!fnmatch(*pattern_pointer,fn,0))
-
return FALSE; - pattern_pointer++;
- }
- return TRUE; +} +#endif
uint64_t find_block_size(state *s, char *input_str) { diff -ur md5deep-3.9.orig/hashdeep/main.c md5deep-3.9/hashdeep/main.c --- md5deep-3.9.orig/hashdeep/main.c2011-04-21 05:47:23.000000000 -0700 +++ md5deep-3.9/hashdeep/main.c2011-05-23 10:59:24.914136805 -0700 @@ -28,6 +28,7 @@ fprintf(stdout,"%s%s",s->hashes[i]->name,(i+1<NUM_ALGORITHMS)?",":NEWLINE);
print_status("-a - audit mode. Validates FILES against known hashes. Requires -k");
- print_status("-N - Do not include files matching pattern; may be specified multiple times"); print_status("-m - matching mode. Requires -k"); print_status("-x - negative matching mode. Requires -k"); print_status("-w - in -m mode, displays which known file was matched"); @@ -256,7 +257,7 @@ { int i;
- while ((i=getopt(argc,argv,"o:I:i:c:MmXxtablk:resp:wvVh")) != -1)
- while ((i=getopt(argc,argv,"o:I:i:c:MmN:Xxtablk:resp:wvVh")) != -1) { switch (i) { @@ -356,6 +357,9 @@ s->mode |= mode_verbose; break;
- case 'N':
-
add_exclude_pattern(s,optarg); -
case 'V': print_status("%s", VERSION); exit(EXIT_SUCCESS); @@ -389,6 +393,7 @@ MD5DEEP_ALLOC(TCHAR,s->short_name,PATH_MAX); MD5DEEP_ALLOC(TCHAR,s->msg,PATH_MAX); MD5DEEP_ALLOC(unsigned char,s->buffer,MD5DEEP_IDEAL_BLOCK_SIZE);break; - MD5DEEP_ALLOC(TCHAR*,s->exclude_patterns,1);
s->known = NULL; s->last = NULL; diff -ur md5deep-3.9.orig/hashdeep/main.h md5deep-3.9/hashdeep/main.h --- md5deep-3.9.orig/hashdeep/main.h2010-12-21 06:29:24.000000000 -0800 +++ md5deep-3.9/hashdeep/main.h2011-05-23 10:59:59.084136806 -0700 @@ -225,6 +225,8 @@ /* For audit mode, the number of each type of file */ uint64_t match_exact, match_expect, match_partial, match_moved, match_unused, match_unknown, match_total; +
- TCHAR ** exclude_patterns;
};
#include "ui.h" diff -ur md5deep-3.9.orig/include/common.h md5deep-3.9/include/common.h --- md5deep-3.9.orig/include/common.h2010-12-21 06:29:25.000000000 -0800 +++ md5deep-3.9/include/common.h2011-05-25 09:21:06.943782309 -0700 @@ -362,6 +362,10 @@ // Return the size, in bytes of an open file stream. On error, return -1 off_t find_file_size(FILE *f);
+// Functions to manage the exclude_patterns member of the state structures. +int check_excludes(state *s,TCHAR *fn); +int add_exclude_pattern(state *s,const char *optarg); +
// ------------------------------------------------------------------ // MAIN PROCESSING diff -ur md5deep-3.9.orig/md5deep/main.c md5deep-3.9/md5deep/main.c --- md5deep-3.9.orig/md5deep/main.c2011-03-22 17:12:45.000000000 -0700 +++ md5deep-3.9/md5deep/main.c2011-05-23 10:54:15.514136792 -0700 @@ -44,6 +44,7 @@ print_status("-M and -X are the same as -m and -x but also print hashes of each file"); print_status("-w - displays which known file generated a match"); print_status("-n - displays known hashes that did not match any input files");
- print_status("-N - Do not include files matching pattern; may be specified multiple times"); print_status("-a and -A add a single hash to the positive or negative matching set"); print_status("-b - prints only the bare name of files; all path information is omitted"); print_status("-l - print relative paths for filenames"); @@ -111,7 +112,7 @@
while ((i = getopt(argc, argv,
-
"f:I:i:M:X:x:m:o:A:a:tnwczsSp:erhvV0lbkqZ")) != -1) { -
"f:I:i:M:X:x:m:n:o:A:a:tnwczsSp:erhvV0lbkqZ")) != -1) {switch (i) {
case 'f': @@ -251,6 +252,10 @@ usage(); exit (STATUS_OK);
-
case 'N':
-
add_exclude_pattern(s,optarg); -
break;case 'v': print_status("%s",VERSION); exit (STATUS_OK); @@ -284,6 +289,7 @@ MD5DEEP_ALLOC(unsigned char,s->hash_sum,PATH_MAX); MD5DEEP_ALLOC(char,s->hash_result,PATH_MAX); MD5DEEP_ALLOC(char,s->known_fn,PATH_MAX);
-
MD5DEEP_ALLOC(TCHAR*,s->exclude_patterns,1);
s->mode = mode_none; s->hashes_loaded = FALSE; diff -ur md5deep-3.9.orig/md5deep/main.h md5deep-3.9/md5deep/main.h --- md5deep-3.9.orig/md5deep/main.h2010-12-21 06:29:25.000000000 -0800 +++ md5deep-3.9/md5deep/main.h2011-05-23 10:32:20.064136735 -0700 @@ -119,6 +119,9 @@ // Used in matching operations char * known_fn;
- //
- TCHAR ** exclude_patterns;
} _state;
Submitted by jessekornblum
Wow! Thanks for the patch! Unfortunately I have to table this issue for now and I've locked the code base for a rewrite. But I'm leaving the feature request open. You can see the new code as it's being built in the SVN tree under branches/version4.