diff --git a/ChangeLog b/ChangeLog index be15d01..e5eced4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-05-20 Hannes von Haugwitz + * Print checksums of databases in verbose level 2 or higher (closes + feature request 1502032) + * Added new 'database_attrs' option + 2013-05-18 Hannes von Haugwitz * configure.in: removed check for 'libcrypt' * Renamed 'detailed_init_report' option to 'report_detailed_init' diff --git a/NEWS b/NEWS index aa971f9..4aeed98 100644 --- a/NEWS +++ b/NEWS @@ -2,11 +2,13 @@ Version 0.16 (NOT_YET_RELEASED) * Enabled summarize_changes by default * Compare database entries just once * Added new root_prefix option + * Added new database_attrs option * Added new report_detailed_init option * Added new report_base16 option * Wrap attribute values instead of cut them off * Side-by-side output of acl and xattrs values * Use '|' to separate the old value from the new one + * Print checksums of databases in verbose level 2 or higher * Print added or removed attributes of changed entries if forced via report_attributes * Print details about added and removed entries in verbose level 7 diff --git a/doc/aide.conf.5.in b/doc/aide.conf.5.in index f3629df..a68d18b 100644 --- a/doc/aide.conf.5.in +++ b/doc/aide.conf.5.in @@ -38,6 +38,14 @@ first is used. The default value is "@prefix@/etc/aide.db.new". .IP "database_new" The url from which the other database for \-\-compare is read. There is no default for this one. +.IP "database_attrs" +The attributes of the (uncompressed) database files which are to be added to +the final report in verbose level 2 or higher. Only checksum attributes are +supported. To disable set +.I database_attrs +to +.RB ' E '. +By default all compiled in checksums are added to the report. .IP "verbose" The level of messages that is output. This value can be 0-255 inclusive. This parameter can only be given once. Value from the first diff --git a/include/db.h b/include/db.h index 077c38f..8c684f1 100644 --- a/include/db.h +++ b/include/db.h @@ -1,7 +1,7 @@ /* aide, Advanced Intrusion Detection Environment * - * Copyright (C) 1999-2002,2004,2005 Rami Lehti, Pablo Virolainen, - * Richard van den Berg + * Copyright (C) 1999-2002,2004,2005,2013 Rami Lehti, Pablo Virolainen, + * Richard van den Berg, Hannes von Haugwitz * $Header$ * * This program is free software; you can redistribute it and/or @@ -33,7 +33,7 @@ int db_writespec(db_config*); int db_writeline(db_line*,db_config*); -int db_close(db_config*); +void db_close(); void free_db_line(db_line* dl); diff --git a/include/db_config.h b/include/db_config.h index 4de8732..79a2ae6 100644 --- a/include/db_config.h +++ b/include/db_config.h @@ -1,6 +1,6 @@ /* aide, Advanced Intrusion Detection Environment * - * Copyright (C) 1999-2002,2004-2006,2010-2012 Rami Lehti, Pablo Virolainen, + * Copyright (C) 1999-2002,2004-2006,2010-2013 Rami Lehti, Pablo Virolainen, * Richard van den Berg, Hannes von Haugwitz * $Header$ * @@ -252,6 +252,52 @@ extern const int db_aliasvalue[db_alias_size]; #include "seltree.h" +typedef struct db_line { + byte* md5; + byte* sha1; + byte* rmd160; + byte* tiger; + + byte* sha256; + byte* sha512; + + byte* crc32; /* MHASH only */ + byte* haval; + byte* gost; + byte* crc32b; + byte* whirlpool; + + acl_type* acl; + /* Something here.. */ + + mode_t perm; + mode_t perm_o; /* Permission for tree traverse */ + uid_t uid; + gid_t gid; + time_t atime; + time_t ctime; + time_t mtime; + AIDE_INO_TYPE inode; + nlink_t nlink; + + AIDE_OFF_TYPE size; + AIDE_OFF_TYPE size_o; /* ... */ + AIDE_BLKCNT_TYPE bcount; + char* filename; + char* fullpath; + char* linkname; + + char *cntx; + + xattrs_type* xattrs; + + unsigned long e2fsattrs; + + /* Attributes .... */ + DB_ATTR_TYPE attr; + +} db_line; + typedef struct db_config { url_t* db_in_url; @@ -265,6 +311,14 @@ typedef struct db_config { int config_check; + struct md_container *mdc_in; + struct md_container *mdc_out; + + struct db_line *line_db_in; + struct db_line *line_db_out; + + DB_ATTR_TYPE db_attrs; + #ifdef WITH_ZLIB gzFile db_gzin; gzFile db_gznew; @@ -360,52 +414,6 @@ typedef struct db_config { } db_config; -typedef struct db_line { - byte* md5; - byte* sha1; - byte* rmd160; - byte* tiger; - - byte* sha256; - byte* sha512; - - byte* crc32; /* MHASH only */ - byte* haval; - byte* gost; - byte* crc32b; - byte* whirlpool; - - acl_type* acl; - /* Something here.. */ - - mode_t perm; - mode_t perm_o; /* Permission for tree traverse */ - uid_t uid; - gid_t gid; - time_t atime; - time_t ctime; - time_t mtime; - AIDE_INO_TYPE inode; - nlink_t nlink; - - AIDE_OFF_TYPE size; - AIDE_OFF_TYPE size_o; /* ... */ - AIDE_BLKCNT_TYPE bcount; - char* filename; - char* fullpath; - char* linkname; - - char *cntx; - - xattrs_type* xattrs; - - unsigned long e2fsattrs; - - /* Attributes .... */ - DB_ATTR_TYPE attr; - -} db_line; - #ifdef WITH_PSQL #include "libpq-fe.h" diff --git a/src/aide.c b/src/aide.c index e5316c1..c32be69 100644 --- a/src/aide.c +++ b/src/aide.c @@ -1,6 +1,6 @@ /* aide, Advanced Intrusion Detection Environment * - * Copyright (C) 1999-2006,2010-2012 Rami Lehti, Pablo Virolainen, Mike + * Copyright (C) 1999-2006,2010-2013 Rami Lehti, Pablo Virolainen, Mike * Markley, Richard van den Berg, Hannes von Haugwitz * $Header$ * @@ -316,6 +316,23 @@ static void setdefaults_before_config() conf->db_new=NULL; conf->db_out_url=NULL; conf->db_out=NULL; + + conf->mdc_in=NULL; + conf->mdc_out=NULL; + + conf->line_db_in=NULL; + conf->line_db_out=NULL; + + conf->db_attrs = 0; +#if defined(WITH_MHASH) || defined(WITH_GCRYPT) + conf->db_attrs |= DB_MD5|DB_TIGER|DB_HAVAL|DB_CRC32|DB_SHA1|DB_RMD160|DB_SHA256|DB_SHA512; +#ifdef WITH_MHASH + conf->db_attrs |= DB_GOST; +#ifdef HAVE_MHASH_WHIRLPOOL + conf->db_attrs |= DB_WHIRLPOOL; +#endif +#endif +#endif #ifdef WITH_ZLIB conf->db_gzin=0; @@ -584,7 +601,7 @@ int main(int argc,char**argv) } populate_tree(conf->tree); - db_close(conf); + db_close(); exit(gen_report(conf->tree)); diff --git a/src/commandconf.c b/src/commandconf.c index 2a2a65b..b40f4a6 100644 --- a/src/commandconf.c +++ b/src/commandconf.c @@ -34,6 +34,7 @@ #include "db_config.h" #include "gen_list.h" #include "symboltable.h" +#include "md.h" #include "util.h" #include "base64.h" /*for locale support*/ @@ -239,6 +240,7 @@ int db_input_wrapper(char* buf, int max_size, int db) #ifdef WITH_ZLIB gzFile* db_gzp=NULL; #endif + struct md_container *mdc; switch(db) { case DB_OLD: { #ifdef WITH_CURL @@ -282,6 +284,9 @@ int db_input_wrapper(char* buf, int max_size, int db) case url_https: case url_ftp: { retval=url_fread(buf,1,max_size,(URL_FILE *)*db_filep); + if ((mdc = (db == DB_OLD ? conf->mdc_in : conf->mdc_out))) { + update_md(mdc, buf, retval); + } break; } default: @@ -354,6 +359,10 @@ int db_input_wrapper(char* buf, int max_size, int db) #endif /* WITH_MHASH */ #endif /* WITH_ZLIB */ + if ((mdc = (db == DB_OLD ? conf->mdc_in : conf->mdc_out))) { + update_md(mdc, buf, retval); + } + #ifdef WITH_MHASH if(*domd){ if(!*md){ diff --git a/src/compare_db.c b/src/compare_db.c index caf0c5f..db67a15 100644 --- a/src/compare_db.c +++ b/src/compare_db.c @@ -302,6 +302,7 @@ static char* get_file_type_string(mode_t mode) { #ifdef S_IFDOOR case S_IFDOOR: return _("Door"); #endif + case 0: return NULL; default: return _("Unknown file type"); } } @@ -461,7 +462,12 @@ static void print_dbline_attributes(db_line* oline, db_line* nline, DB_ATTR_TYPE int length = sizeof(details_attributes)/sizeof(DB_ATTR_TYPE); int p = (width_details-(width_details%2?13:14))/2; DB_ATTR_TYPE attrs; - error(2,"\n%s: %s\n",get_file_type_string((nline==NULL?oline:nline)->perm),(nline==NULL?oline:nline)->filename); + error(2,"\n"); + char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm); + if (file_type) { + error(2,"%s: ", file_type); + } + error(2,"%s\n", (nline==NULL?oline:nline)->filename); attrs=(~(ignored_attrs))&(report_attrs|changed_attrs)&((oline==NULL?0:oline->attr)|(nline==NULL?0:nline->attr)); for (j=0; j < length; ++j) { if (details_attributes[j]&attrs) { @@ -618,13 +624,25 @@ static void print_report_header() { } } +static void print_report_databases() { + if (conf->verbose_level>=2 && (conf->line_db_in || conf->line_db_out)) { + error(2,(char*)report_top_format,_("The attributes of the (uncompressed) database(s)")); + if (conf->line_db_in) { + print_attributes_removed_node(conf->line_db_in); + } + if (conf->line_db_out) { + print_attributes_removed_node(conf->line_db_out); + } + } +} + static void print_report_footer() { char *time = malloc(time_string_len * sizeof (char)); int run_time = (int) difftime(conf->end_time, conf->start_time); strftime(time, time_string_len, time_format, localtime(&(conf->end_time))); - error(2,_("\nEnd timestamp: %s (run time: %dm %ds)\n"), time, run_time/60, run_time%60); + error(2,_("\n\nEnd timestamp: %s (run time: %dm %ds)\n"), time, run_time/60, run_time%60); free(time); time=NULL; } @@ -691,6 +709,7 @@ int gen_report(seltree* node) { print_report_details(node); } } + print_report_databases(); conf->end_time=time(&(conf->end_time)); print_report_footer(); diff --git a/src/conf_lex.l b/src/conf_lex.l index 34c596a..229415f 100644 --- a/src/conf_lex.l +++ b/src/conf_lex.l @@ -15,7 +15,7 @@ EX [" "\t]* #define YYDEBUG /* - * Copyright (C) 1999-2002,2004-2006,2010-2012 Rami Lehti, Pablo + * Copyright (C) 1999-2002,2004-2006,2010-2013 Rami Lehti, Pablo * Virolainen, Richard van den Berg, Hannes von Haugwitz * $Header$ * This program is free software; you can redistribute it and/or @@ -307,6 +307,12 @@ int var_in_conflval=0; return (TDATABASE_NEW); } +^[\t\ ]*"database_attrs"{E} { + error(230,"%li:database_attrs =\n",conf_lineno); + BEGIN EXPR; + return (TDATABASE_ATTRS); +} + ^[\t\ ]*"warn_dead_symlinks"{E} { error(230,"%li:warn_dead_symlinks =\n",conf_lineno); BEGIN CONFVALHUNT; diff --git a/src/conf_yacc.y b/src/conf_yacc.y index 1e8a1bf..f7d2874 100644 --- a/src/conf_yacc.y +++ b/src/conf_yacc.y @@ -1,7 +1,7 @@ %{ /* - * Copyright (C) 1999-2006,2010-2012 Rami Lehti, Pablo Virolainen, + * Copyright (C) 1999-2006,2010-2013 Rami Lehti, Pablo Virolainen, * Richard van den Berg, Hannes von Haugwitz * $Header$ * This program is free software; you can redistribute it and/or @@ -81,6 +81,7 @@ extern long conf_lineno; %token TDATABASE %token TDATABASE_OUT %token TDATABASE_NEW +%token TDATABASE_ATTRS %token TREPORT_URL %token TGZIPDBOUT %token TROOT_PREFIX @@ -152,7 +153,7 @@ lines : lines line | ; line : rule | equrule | negrule | definestmt | undefstmt | ifdefstmt | ifndefstmt | ifhoststmt | ifnhoststmt - | groupdef | db_in | db_out | db_new | verbose | report_detailed_init | config_version + | groupdef | db_in | db_out | db_new | db_attrs | verbose | report_detailed_init | config_version | report | gzipdbout | root_prefix | report_base16 | recursion_stopper | warn_dead_symlinks | grouped | summarize_changes | acl_no_symlink_follow | beginconfigstmt | endconfigstmt | TEOF { @@ -268,6 +269,15 @@ verbose : TVERBOSE TSTRING { do_verbdef($2); }; report : TREPORT_URL TSTRING { do_repurldef($2); } ; +db_attrs : TDATABASE_ATTRS expr { + DB_ATTR_TYPE attr; + if((attr = $2&(~DB_HASHES))){ + error(0, "%li: invalid attribute(s) in database_attrs: %llx\n", conf_lineno-1, attr); + YYABORT; + } + conf->db_attrs=$2; +} ; + beginconfigstmt : TBEGIN_CONFIG TSTRING { #ifdef WITH_MHASH conf->do_configmd=1; diff --git a/src/db.c b/src/db.c index 1cbb54f..dd133d4 100644 --- a/src/db.c +++ b/src/db.c @@ -26,6 +26,7 @@ #include "db.h" #include "db_file.h" #include "db_disk.h" +#include "md.h" #ifdef WITH_PSQL #include "db_sql.h" @@ -131,6 +132,47 @@ const char* db_namealias[db_alias_size] = { const int db_aliasvalue[db_alias_size] = { db_lnkcount } ; /* "count", */ +static struct md_container *init_db_attrs(URL_TYPE type) { + struct md_container *mdc = NULL; + if (conf->db_attrs) { + switch (type) { + case url_stdout: + case url_stderr: + case url_fd: + case url_file: + #ifdef WITH_CURL + case url_http: + case url_https: + case url_ftp: + #endif /* WITH CURL */ + mdc = malloc(sizeof(struct md_container)); /* freed in close_db_attrs */ + mdc->todo_attr = conf->db_attrs; + init_md(mdc); + break; + #ifdef WITH_PSQL + case url_sql: + break; + #endif /* WITH_PSQL */ + default : + error(200,_("init_db_attrs(): Unknown url type.\n")); + } + } + return mdc; +} + +static db_line *close_db_attrs (struct md_container *mdc, char *url_value) { + db_line *line = NULL; + if (mdc != NULL) { + close_md(mdc); + line = malloc(sizeof(struct db_line)); + line->filename = url_value; + line->perm = 0; + line->attr = conf->db_attrs; + md2line(mdc, line); + free(mdc); + } + return line; +} int db_init(int db) { @@ -149,6 +191,7 @@ int db_init(int db) case DB_OLD: { + conf->mdc_in = init_db_attrs((conf->db_in_url)->type); rv=be_init(1,conf->db_in_url,0); if(rv==NULL) { error(200,_("db_in is null\n")); @@ -160,6 +203,7 @@ int db_init(int db) } case DB_WRITE: { #ifdef WITH_ZLIB + conf->mdc_out = init_db_attrs((conf->db_out_url)->type); if(conf->gzip_dbout){ rv=be_init(0,conf->db_out_url,conf->gzip_dbout); conf->db_gzout=rv; @@ -180,6 +224,7 @@ int db_init(int db) return RETOK; } case DB_NEW: { + conf->mdc_out = init_db_attrs((conf->db_new_url)->type); rv=be_init(1,conf->db_new_url,0); if(rv==NULL) { error(200,_("db_new is null\n")); @@ -760,25 +805,19 @@ int db_writeline(db_line* line,db_config* dbconf){ return RETFAIL; } -int db_close(db_config* dbconf) -{ - if (dbconf==NULL) return RETOK; - - switch (dbconf->db_out_url->type) { +void db_close() { + switch (conf->db_out_url->type) { case url_stdout: case url_stderr: case url_fd: case url_file: { if ( #ifdef WITH_ZLIB - (dbconf->gzip_dbout && dbconf->db_gzout) || + (conf->gzip_dbout && conf->db_gzout) || #endif - (dbconf->db_out!=NULL)) { - if (db_close_file(dbconf)==RETOK) { - return RETOK; - } + (conf->db_out!=NULL)) { + db_close_file(conf); } - return RETFAIL; break; } #ifdef WITH_CURL @@ -786,31 +825,27 @@ int db_close(db_config* dbconf) case url_https: case url_ftp: { - if (dbconf->db_out!=NULL) { - url_fclose(dbconf->db_out); + if (conf->db_out!=NULL) { + url_fclose(conf->db_out); } break; } #endif /* WITH CURL */ #ifdef WITH_PSQL case url_sql: { - if (dbconf->db_out!=NULL) { - if (db_close_sql(dbconf->db_out)==RETOK) { - return RETOK; - } else { - return RETFAIL; - } + if (conf->db_out!=NULL) { + db_close_sql(conf->db_out); } - return RETOK; break; } #endif default : { error(0,_("db_close():Unknown output in db out.\n")); - return RETFAIL; } } - return RETFAIL; + conf->line_db_in = close_db_attrs(conf->mdc_in, (conf->db_in_url)->value); + conf->line_db_out = close_db_attrs(conf->mdc_out, (conf->action&DO_DIFF + ? conf->db_new_url : conf->db_out_url)->value); } void free_db_line(db_line* dl) diff --git a/src/db_file.c b/src/db_file.c index 0b714b0..f9fff4d 100644 --- a/src/db_file.c +++ b/src/db_file.c @@ -142,6 +142,10 @@ int dofprintf( const char* s,...) retval=vsnprintf(temp,retval+1,s,ap); va_end(ap); + if (conf->mdc_out) { + update_md(conf->mdc_out,temp ,retval); + } + #ifdef WITH_MHASH if(conf->do_dbnewmd) mhash(conf->dbnewmd,(void*)temp,retval);