diff --git a/.aide.metadata b/.aide.metadata index a8e59ce..c6500fa 100644 --- a/.aide.metadata +++ b/.aide.metadata @@ -1 +1 @@ -b97f65bb12701a42baa2cce45b41ed6367a70734 SOURCES/aide-0.16.tar.gz +c699190eba9fcaa29ee362f57fb1a05dd74d947a SOURCES/aide-0.18.6.tar.gz diff --git a/.gitignore b/.gitignore index f8be39e..58a533c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/aide-0.16.tar.gz +SOURCES/aide-0.18.6.tar.gz diff --git a/SOURCES/aide-0.15-syslog-format.patch b/SOURCES/aide-0.15-syslog-format.patch deleted file mode 100644 index 0361434..0000000 --- a/SOURCES/aide-0.15-syslog-format.patch +++ /dev/null @@ -1,496 +0,0 @@ -diff -up ./doc/aide.conf.5.in.syslog_format ./doc/aide.conf.5.in ---- ./doc/aide.conf.5.in.syslog_format 2016-07-25 22:58:12.000000000 +0200 -+++ ./doc/aide.conf.5.in 2018-09-27 19:09:09.697371212 +0200 -@@ -57,6 +57,25 @@ inclusive. This parameter can only be gi - occurrence is used. If \-\-verbose or \-V is used then the value from that - is used. The default is 5. If verbosity is 20 then additional report - output is written when doing \-\-check, \-\-update or \-\-compare. -+.IP "syslog_format" -+Valid values are yes,true,no and false. This option enables new syslog format -+which is suitable for logging. Every change is logged as one simple line. This option -+changes verbose level to 0 and prints everything that was changed. It is suggested -+to use this option with "report_url=syslog:...". Default value is "false/no". -+Maximum size of message is 1KB which is limitation of syslog call. If message is -+greater than limit, message will be truncated. -+Option summarize_changes has no impact for this format. -+.nf -+.eo -+ -+Output always starts with: -+"AIDE found differences between database and filesystem!!" -+And it is followed by summary: -+summary;total_number_of_files=1000;added_files=0;removed_files=0;changed_files=1 -+And finally there are logs about changes: -+dir=/usr/sbin;Mtime_old=0000-00-00 00:00:00;Mtime_new=0000-00-00 00:00:00;... -+.ec -+.fi - .IP "report_url" - The url that the output is written to. There can be multiple instances - of this parameter. Output is written to all of them. The default is -diff -up ./include/db_config.h.syslog_format ./include/db_config.h ---- ./include/db_config.h.syslog_format 2016-07-25 22:56:55.000000000 +0200 -+++ ./include/db_config.h 2018-09-27 19:09:09.697371212 +0200 -@@ -311,6 +311,7 @@ typedef struct db_config { - FILE* db_out; - - int config_check; -+ int syslog_format; - - struct md_container *mdc_in; - struct md_container *mdc_out; -diff -up ./src/aide.c.syslog_format ./src/aide.c ---- ./src/aide.c.syslog_format 2018-09-27 19:09:09.695371197 +0200 -+++ ./src/aide.c 2018-09-27 19:09:09.698371220 +0200 -@@ -283,6 +283,7 @@ static void setdefaults_before_config() - } - - /* Setting some defaults */ -+ conf->syslog_format=0; - conf->report_db=0; - conf->tree=NULL; - conf->config_check=0; -@@ -495,6 +496,10 @@ static void setdefaults_after_config() - if(conf->verbose_level==-1){ - conf->verbose_level=5; - } -+ if(conf->syslog_format==1){ -+ conf->verbose_level=0; -+ } -+ - } - - -diff -up ./src/compare_db.c.syslog_format ./src/compare_db.c ---- ./src/compare_db.c.syslog_format 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/compare_db.c 2018-09-27 19:09:09.698371220 +0200 -@@ -110,7 +110,7 @@ const DB_ATTR_TYPE details_attributes[] - #endif - }; - --const char* details_string[] = { _("File type") , _("Lname"), _("Size"), _("Size (>)"), _("Bcount"), _("Perm"), _("Uid"), _("Gid"), _("Atime"), _("Mtime"), _("Ctime"), _("Inode"), _("Linkcount"), _("MD5"), _("SHA1"), _("RMD160"), _("TIGER"), _("SHA256"), _("SHA512") -+const char* details_string[] = { _("File type") , _("Lname"), _("Size"), _("Size"), _("Bcount"), _("Perm"), _("Uid"), _("Gid"), _("Atime"), _("Mtime"), _("Ctime"), _("Inode"), _("Linkcount"), _("MD5"), _("SHA1"), _("RMD160"), _("TIGER"), _("SHA256"), _("SHA512") - #ifdef WITH_MHASH - , _("CRC32"), _("HAVAL"), _("GOST"), _("CRC32B"), _("WHIRLPOOL") - #endif -@@ -269,12 +269,19 @@ static int xattrs2array(xattrs_type* xat - if ((len == xattrs->ents[num - 1].vsz) || ((len == (xattrs->ents[num - 1].vsz - 1)) && !val[len])) { - length = 8 + width + strlen(xattrs->ents[num - 1].key) + strlen(val); - (*values)[num]=malloc(length *sizeof(char)); -- snprintf((*values)[num], length , "[%.*zd] %s = %s", width, num, xattrs->ents[num - 1].key, val); -+ -+ char * fmt = "[%.*zd] %s = %s"; -+ if (conf->syslog_format) fmt = "[%.*zd]%s=%s"; // its smaller so it has to be enough space allocated. -+ snprintf((*values)[num], length , fmt, width, num, xattrs->ents[num - 1].key, val); -+ - } else { - val = encode_base64(xattrs->ents[num - 1].val, xattrs->ents[num - 1].vsz); - length = 10 + width + strlen(xattrs->ents[num - 1].key) + strlen(val); - (*values)[num]=malloc( length *sizeof(char)); -- snprintf((*values)[num], length , "[%.*zd] %s <=> %s", width, num, xattrs->ents[num - 1].key, val); -+ -+ char * fmt = "[%.*zd] %s <=> %s"; -+ if (conf->syslog_format) fmt = "[%.*zd]%s<=>%s"; // its smaller so it has to be enough space allocated. -+ snprintf((*values)[num], length , fmt, width, num, xattrs->ents[num - 1].key, val); - free(val); - } - } -@@ -302,6 +309,26 @@ static int acl2array(acl_type* acl, char - } - if (acl->acl_a || acl->acl_d) { - int j, k, i; -+ if (conf->syslog_format) { -+ *values = malloc(2 * sizeof(char*)); -+ -+ char *A, *D = ""; -+ -+ if (acl->acl_a) { A = acl->acl_a; } -+ if (acl->acl_d) { D = acl->acl_d; } -+ -+ (*values)[0] = (char*) malloc(strlen(A) + 3); // "A:" and \0 -+ snprintf((*values)[0], strlen(A) + 3, "A:%s", A); -+ -+ (*values)[1] = (char*) malloc(strlen(D) + 3); // "D:" and \0 -+ snprintf((*values)[1], strlen(D) + 3, "D:%s", D); -+ -+ i = 0; while ( (*values)[0][i] ) { if ( (*values)[0][i]=='\n') { (*values)[0][i] = ' '; } i++; } -+ i = 0; while ( (*values)[1][i] ) { if ( (*values)[1][i]=='\n') { (*values)[1][i] = ' '; } i++; } -+ -+ return 2; -+ } -+ - if (acl->acl_a) { i = 0; while (acl->acl_a[i]) { if (acl->acl_a[i++]=='\n') { n++; } } } - if (acl->acl_d) { i = 0; while (acl->acl_d[i]) { if (acl->acl_d[i++]=='\n') { n++; } } } - *values = malloc(n * sizeof(char*)); -@@ -338,25 +365,25 @@ static char* e2fsattrs2string(unsigned l - - static char* get_file_type_string(mode_t mode) { - switch (mode & S_IFMT) { -- case S_IFREG: return _("File"); -- case S_IFDIR: return _("Directory"); -+ case S_IFREG: return conf->syslog_format ? "file" : _("File"); -+ case S_IFDIR: return conf->syslog_format ? "dir" : _("Directory"); - #ifdef S_IFIFO -- case S_IFIFO: return _("FIFO"); -+ case S_IFIFO: return conf->syslog_format ? "fifo" : _("FIFO"); - #endif -- case S_IFLNK: return _("Link"); -- case S_IFBLK: return _("Block device"); -- case S_IFCHR: return _("Character device"); -+ case S_IFLNK: return conf->syslog_format ? "link" : _("Link"); -+ case S_IFBLK: return conf->syslog_format ? "blockd" : _("Block device"); -+ case S_IFCHR: return conf->syslog_format ? "chard" : _("Character device"); - #ifdef S_IFSOCK -- case S_IFSOCK: return _("Socket"); -+ case S_IFSOCK: return conf->syslog_format ? "socket" : _("Socket"); - #endif - #ifdef S_IFDOOR -- case S_IFDOOR: return _("Door"); -+ case S_IFDOOR: return conf->syslog_format ? "door" : _("Door"); - #endif - #ifdef S_IFPORT -- case S_IFPORT: return _("Port"); -+ case S_IFPORT: return conf->syslog_format ? "port" : _("Port"); - #endif - case 0: return NULL; -- default: return _("Unknown file type"); -+ default: return conf->syslog_format ? "unknown" : _("Unknown file type"); - } - } - -@@ -554,6 +581,51 @@ static void print_dbline_attributes(db_l - } - } - -+ -+static void print_dbline_attributes_syslog(db_line* oline, db_line* nline, DB_ATTR_TYPE -+ changed_attrs, DB_ATTR_TYPE force_attrs) { -+ char **ovalue, **nvalue; -+ int onumber, nnumber, i, j; -+ int length = sizeof(details_attributes)/sizeof(DB_ATTR_TYPE); -+ DB_ATTR_TYPE attrs; -+ char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm); -+ if (file_type) { -+ error(0,"%s=", file_type); -+ } -+ error(0,"%s", (nline==NULL?oline:nline)->filename); -+ attrs=force_attrs|(~(ignored_changed_attrs)&changed_attrs); -+ for (j=0; j < length; ++j) { -+ if (details_attributes[j]&attrs) { -+ onumber=get_attribute_values(details_attributes[j], oline, &ovalue); -+ nnumber=get_attribute_values(details_attributes[j], nline, &nvalue); -+ -+ if (details_attributes[j] == DB_ACL || details_attributes[j] == DB_XATTRS) { -+ -+ error(0, ";%s_old=|", details_string[j]); -+ -+ for (i = 0 ; i < onumber ; i++) { -+ error(0, "%s|", ovalue[i]); -+ } -+ -+ error(0, ";%s_new=|", details_string[j]); -+ -+ for (i = 0 ; i < nnumber ; i++) { -+ error(0, "%s|", nvalue[i]); -+ } -+ -+ } else { -+ -+ error(0, ";%s_old=%s;%s_new=%s", details_string[j], *ovalue, details_string[j], *nvalue); -+ -+ } -+ -+ for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL; -+ for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL; -+ } -+ } -+ error(0, "\n"); -+} -+ - static void print_attributes_added_node(db_line* line) { - print_dbline_attributes(NULL, line, 0, line->attr); - } -@@ -562,6 +634,26 @@ static void print_attributes_removed_nod - print_dbline_attributes(line, NULL, 0, line->attr); - } - -+static void print_attributes_added_node_syslog(db_line* line) { -+ -+ char *file_type = get_file_type_string(line->perm); -+ if (file_type) { -+ error(0,"%s=", file_type); -+ } -+ error(0,"%s; added\n", line->filename); -+ -+} -+ -+static void print_attributes_removed_node_syslog(db_line* line) { -+ -+ char *file_type = get_file_type_string(line->perm); -+ if (file_type) { -+ error(0,"%s=", file_type); -+ } -+ error(0,"%s; removed\n", line->filename); -+ -+} -+ - static void terse_report(seltree* node) { - list* r=NULL; - if ((node->checked&(DB_OLD|DB_NEW)) != 0) { -@@ -626,6 +718,26 @@ static void print_report_details(seltree - } - } - -+static void print_syslog_format(seltree* node) { -+ list* r=NULL; -+ -+ if (node->checked&NODE_CHANGED) { -+ print_dbline_attributes_syslog(node->old_data, node->new_data, node->changed_attrs, forced_attrs); -+ } -+ -+ if (node->checked&NODE_ADDED) { -+ print_attributes_added_node_syslog(node->new_data); -+ } -+ -+ if (node->checked&NODE_REMOVED) { -+ print_attributes_removed_node_syslog(node->old_data); -+ } -+ -+ for(r=node->childs;r;r=r->next){ -+ print_syslog_format((seltree*)r->data); -+ } -+} -+ - static void print_report_header() { - char *time; - int first = 1; -@@ -747,39 +859,53 @@ int gen_report(seltree* node) { - send_audit_report(); - #endif - if ((nadd|nrem|nchg) > 0 || conf->report_quiet == 0) { -- print_report_header(); -- if(conf->action&(DO_COMPARE|DO_DIFF) || (conf->action&DO_INIT && conf->report_detailed_init) ) { -- if (conf->grouped) { -- if (nadd) { -- error(2,(char*)report_top_format,_("Added entries")); -- print_report_list(node, NODE_ADDED); -- } -- if (nrem) { -- error(2,(char*)report_top_format,_("Removed entries")); -- print_report_list(node, NODE_REMOVED); -- } -- if (nchg) { -- error(2,(char*)report_top_format,_("Changed entries")); -- print_report_list(node, NODE_CHANGED); -- } -- } else if (nadd || nrem || nchg) { -- if (nadd && nrem && nchg) { error(2,(char*)report_top_format,_("Added, removed and changed entries")); } -- else if (nadd && nrem) { error(2,(char*)report_top_format,_("Added and removed entries")); } -- else if (nadd && nchg) { error(2,(char*)report_top_format,_("Added and changed entries")); } -- else if (nrem && nchg) { error(2,(char*)report_top_format,_("Removed and changed entries")); } -- else if (nadd) { error(2,(char*)report_top_format,_("Added entries")); } -- else if (nrem) { error(2,(char*)report_top_format,_("Removed entries")); } -- else if (nchg) { error(2,(char*)report_top_format,_("Changed entries")); } -- print_report_list(node, NODE_ADDED|NODE_REMOVED|NODE_CHANGED); -- } -- if (nadd || nrem || nchg) { -- error(nchg?5:7,(char*)report_top_format,_("Detailed information about changes")); -- print_report_details(node); -- } -- } -- print_report_databases(); -- conf->end_time=time(&(conf->end_time)); -- print_report_footer(); -+ -+ if (!conf->syslog_format) { -+ print_report_header(); -+ } -+ -+ if(conf->action&(DO_COMPARE|DO_DIFF) || (conf->action&DO_INIT && conf->report_detailed_init) ) { -+ if (!conf->syslog_format && conf->grouped) { -+ if (nadd) { -+ error(2,(char*)report_top_format,_("Added entries")); -+ print_report_list(node, NODE_ADDED); -+ } -+ if (nrem) { -+ error(2,(char*)report_top_format,_("Removed entries")); -+ print_report_list(node, NODE_REMOVED); -+ } -+ if (nchg) { -+ error(2,(char*)report_top_format,_("Changed entries")); -+ print_report_list(node, NODE_CHANGED); -+ } -+ } else if (!conf->syslog_format && ( nadd || nrem || nchg ) ) { -+ if (nadd && nrem && nchg) { error(2,(char*)report_top_format,_("Added, removed and changed entries")); } -+ else if (nadd && nrem) { error(2,(char*)report_top_format,_("Added and removed entries")); } -+ else if (nadd && nchg) { error(2,(char*)report_top_format,_("Added and changed entries")); } -+ else if (nrem && nchg) { error(2,(char*)report_top_format,_("Removed and changed entries")); } -+ else if (nadd) { error(2,(char*)report_top_format,_("Added entries")); } -+ else if (nrem) { error(2,(char*)report_top_format,_("Removed entries")); } -+ else if (nchg) { error(2,(char*)report_top_format,_("Changed entries")); } -+ print_report_list(node, NODE_ADDED|NODE_REMOVED|NODE_CHANGED); -+ } -+ if (nadd || nrem || nchg) { -+ if (!conf->syslog_format) { -+ error(nchg?5:7,(char*)report_top_format,_("Detailed information about changes")); -+ print_report_details(node); -+ } else { -+ /* Syslog Format */ -+ error(0, "AIDE found differences between database and filesystem!!\n"); -+ error(0, "summary;total_number_of_files=%ld;added_files=%ld;" -+ "removed_files=%ld;changed_files=%ld\n",ntotal,nadd,nrem,nchg); -+ print_syslog_format(node); -+ } -+ } -+ } -+ if (!conf->syslog_format) { -+ print_report_databases(); -+ conf->end_time=time(&(conf->end_time)); -+ print_report_footer(); -+ } - } - - return conf->action&(DO_COMPARE|DO_DIFF) ? (nadd!=0)*1+(nrem!=0)*2+(nchg!=0)*4 : 0; -diff -up ./src/conf_lex.l.syslog_format ./src/conf_lex.l ---- ./src/conf_lex.l.syslog_format 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/conf_lex.l 2018-09-27 19:09:09.698371220 +0200 -@@ -401,6 +401,12 @@ int var_in_conflval=0; - return (TROOT_PREFIX); - } - -+^[\t\ ]*"syslog_format"{E} { -+ error(230,"%li:syslog_format =\n",conf_lineno); -+ BEGIN CONFVALHUNT; -+ return (SYSLOG_FORMAT); -+} -+ - ^[\t\ ]*"recstop"{E} { - error(230,"%li:recstop =\n",conf_lineno); - BEGIN CONFVALHUNT; -diff -up ./src/conf_yacc.y.syslog_format ./src/conf_yacc.y ---- ./src/conf_yacc.y.syslog_format 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/conf_yacc.y 2018-09-27 19:09:09.699371228 +0200 -@@ -89,6 +89,7 @@ extern long conf_lineno; - %token TREPORT_URL - %token TGZIPDBOUT - %token TROOT_PREFIX -+%token SYSLOG_FORMAT - %token TUMASK - %token TTRUE - %token TFALSE -@@ -160,7 +161,7 @@ line : rule | equrule | negrule | define - | ifdefstmt | ifndefstmt | ifhoststmt | ifnhoststmt - | groupdef | db_in | db_out | db_new | db_attrs | verbose | report_detailed_init | config_version - | database_add_metadata | report | gzipdbout | root_prefix | report_base16 | report_quiet -- | report_ignore_e2fsattrs | recursion_stopper | warn_dead_symlinks | grouped -+ | report_ignore_e2fsattrs | syslogformat | recursion_stopper | warn_dead_symlinks | grouped - | summarize_changes | acl_no_symlink_follow | beginconfigstmt | endconfigstmt - | TEOF { - newlinelastinconfig=1; -@@ -408,6 +409,15 @@ conf->gzip_dbout=0; - #endif - } ; - -+syslogformat : SYSLOG_FORMAT TTRUE { -+conf->syslog_format=1; -+} | -+ SYSLOG_FORMAT TFALSE { -+conf->syslog_format=0; -+} ; -+ -+ -+ - recursion_stopper : TRECSTOP TSTRING { - /* FIXME implement me */ - -diff -up ./src/error.c.syslog_format ./src/error.c ---- ./src/error.c.syslog_format 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/error.c 2018-09-27 19:13:40.312416750 +0200 -@@ -38,6 +38,9 @@ - /*for locale support*/ - #include "util.h" - -+#define MAX_BUFFER_SIZE 1024 -+static char syslog_buffer[MAX_BUFFER_SIZE+1]; -+ - int cmp_url(url_t* url1,url_t* url2){ - - return ((url1->type==url2->type)&&(strcmp(url1->value,url2->value)==0)); -@@ -48,7 +51,9 @@ int error_init(url_t* url,int initial) - { - list* r=NULL; - FILE* fh=NULL; -- int sfac; -+ int sfac; -+ -+ memset(syslog_buffer, 0, MAX_BUFFER_SIZE+1); - - if (url->type==url_database) { - conf->report_db++; -@@ -163,13 +168,24 @@ void error(int errorlevel,char* error_ms - } - #ifdef HAVE_SYSLOG - if(conf->initial_report_url->type==url_syslog){ --#ifdef HAVE_VSYSLOG -- vsyslog(SYSLOG_PRIORITY,error_msg,ap); --#else -- char buf[1024]; -- vsnprintf(buf,1024,error_msg,ap); -- syslog(SYSLOG_PRIORITY,"%s",buf); --#endif -+ -+ char buff[MAX_BUFFER_SIZE+1]; -+ vsnprintf(buff,MAX_BUFFER_SIZE,error_msg,ap); -+ size_t buff_len = strlen(buff); -+ -+ char result_buff[MAX_BUFFER_SIZE+1]; -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wformat-truncation" -+ snprintf(result_buff, MAX_BUFFER_SIZE, "%s%s", syslog_buffer, buff); -+#pragma GCC diagnostic pop -+ -+ if(buff[buff_len-1] == '\n'){ -+ syslog(SYSLOG_PRIORITY,"%s",result_buff); -+ memset(syslog_buffer, 0, MAX_BUFFER_SIZE+1); -+ } else { -+ memcpy(syslog_buffer, result_buff, MAX_BUFFER_SIZE); -+ } -+ - va_end(ap); - return; - } -@@ -181,17 +197,25 @@ void error(int errorlevel,char* error_ms - - #ifdef HAVE_SYSLOG - if (conf->report_syslog!=0) { --#ifdef HAVE_VSYSLOG -- va_start(ap,error_msg); -- vsyslog(SYSLOG_PRIORITY,error_msg,ap); -- va_end(ap); --#else -- char buf[1024]; -- va_start(ap,error_msg); -- vsnprintf(buf,1024,error_msg,ap); -+ va_start(ap, error_msg); -+ -+ char buff[MAX_BUFFER_SIZE+1]; -+ vsnprintf(buff,MAX_BUFFER_SIZE,error_msg,ap); -+ size_t buff_len = strlen(buff); -+ -+ char result_buff[MAX_BUFFER_SIZE+1]; -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wformat-truncation" -+ snprintf(result_buff, MAX_BUFFER_SIZE, "%s%s", syslog_buffer, buff); -+#pragma GCC diagnostic pop -+ -+ if(buff[buff_len-1] == '\n'){ -+ syslog(SYSLOG_PRIORITY,"%s",result_buff); -+ memset(syslog_buffer, 0, MAX_BUFFER_SIZE+1); -+ } else { -+ memcpy(syslog_buffer, result_buff, MAX_BUFFER_SIZE); -+ } - va_end(ap); -- syslog(SYSLOG_PRIORITY,"%s",buf); --#endif - } - #endif - diff --git a/SOURCES/aide-0.16-CVE-2021-45417.patch b/SOURCES/aide-0.16-CVE-2021-45417.patch deleted file mode 100644 index 1752df3..0000000 --- a/SOURCES/aide-0.16-CVE-2021-45417.patch +++ /dev/null @@ -1,123 +0,0 @@ -diff --git a/include/base64.h b/include/base64.h -index 0ff7116..381ef5d 100644 ---- a/include/base64.h -+++ b/include/base64.h -@@ -36,7 +36,6 @@ - #include - #include "types.h" - --#define B64_BUF 16384 - #define FAIL -1 - #define SKIP -2 - -diff --git a/src/base64.c b/src/base64.c -index fd01bac..1b0f301 100644 ---- a/src/base64.c -+++ b/src/base64.c -@@ -85,11 +85,9 @@ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL - }; - - /* Returns NULL on error */ --/* FIXME Possible buffer overflow on outputs larger than B64_BUF */ - char* encode_base64(byte* src,size_t ssize) - { - char* outbuf; -- char* retbuf; - int pos; - int i, l, left; - unsigned long triple; -@@ -101,7 +99,10 @@ char* encode_base64(byte* src,size_t ssize) - error(240,"\n"); - return NULL; - } -- outbuf = (char *)malloc(sizeof(char)*B64_BUF); -+ -+ /* length of encoded base64 string (padded) */ -+ size_t length = sizeof(char)* ((ssize + 2) / 3) * 4; -+ outbuf = (char *)malloc(length + 1); - - /* Initialize working pointers */ - inb = src; -@@ -162,20 +163,14 @@ char* encode_base64(byte* src,size_t ssize) - inb++; - } - -- /* outbuf is not completely used so we use retbuf */ -- retbuf=(char*)malloc(sizeof(char)*(pos+1)); -- memcpy(retbuf,outbuf,pos); -- retbuf[pos]='\0'; -- free(outbuf); -+ outbuf[pos]='\0'; - -- return retbuf; -+ return outbuf; - } - --/* FIXME Possible buffer overflow on outputs larger than B64_BUF */ - byte* decode_base64(char* src,size_t ssize, size_t *ret_len) - { - byte* outbuf; -- byte* retbuf; - char* inb; - int i; - int l; -@@ -188,10 +183,18 @@ byte* decode_base64(char* src,size_t ssize, size_t *ret_len) - if (!ssize||src==NULL) - return NULL; - -+ /* exit on unpadded input */ -+ if (ssize % 4) { -+ error(3, "decode_base64: '%s' has invalid length (missing padding characters?)", src); -+ return NULL; -+ } -+ -+ /* calculate length of decoded string, substract padding chars if any (ssize is >= 4) */ -+ size_t length = sizeof(byte) * ((ssize / 4) * 3)- (src[ssize-1] == '=') - (src[ssize-2] == '='); - - /* Initialize working pointers */ - inb = src; -- outbuf = (byte *)malloc(sizeof(byte)*B64_BUF); -+ outbuf = (byte *)malloc(length + 1); - - l = 0; - triple = 0; -@@ -243,15 +246,11 @@ byte* decode_base64(char* src,size_t ssize, size_t *ret_len) - inb++; - } - -- retbuf=(byte*)malloc(sizeof(byte)*(pos+1)); -- memcpy(retbuf,outbuf,pos); -- retbuf[pos]='\0'; -- -- free(outbuf); -+ outbuf[pos]='\0'; - - if (ret_len) *ret_len = pos; - -- return retbuf; -+ return outbuf; - } - - size_t length_base64(char* src,size_t ssize) -diff --git a/src/db.c b/src/db.c -index 858240d..62c4faa 100644 ---- a/src/db.c -+++ b/src/db.c -@@ -664,13 +664,15 @@ db_line* db_char2line(char** ss,int db){ - - time_t base64totime_t(char* s){ - -+ if(strcmp(s,"0")==0){ -+ return 0; -+ } - byte* b=decode_base64(s,strlen(s),NULL); - char* endp; - -- if (b==NULL||strcmp(s,"0")==0) { -+ if (b==NULL) { - - /* Should we print error here? */ -- free(b); - - return 0; - } else { diff --git a/SOURCES/aide-0.16-CVE-2025-54389-part2.patch b/SOURCES/aide-0.16-CVE-2025-54389-part2.patch deleted file mode 100644 index 3fed87e..0000000 --- a/SOURCES/aide-0.16-CVE-2025-54389-part2.patch +++ /dev/null @@ -1,220 +0,0 @@ -diff -up aide-0.16/src/db_disk.c.orig aide-0.16/src/db_disk.c ---- aide-0.16/src/db_disk.c.orig 2025-08-21 09:58:21.271581589 +0200 -+++ aide-0.16/src/db_disk.c 2025-08-21 10:01:26.310573141 +0200 -@@ -139,7 +139,11 @@ void add_child (db_line * fil) - int i; - struct seltree *new_r; - -- error (255, "Adding child %s\n", fil->filename); -+ { -+ char *fname_safe = stresc(fil->filename); -+ error (255, "Adding child %s\n", fname_safe); -+ free(fname_safe); -+ } - - new_r = get_seltree_node (r, fil->filename); - if (new_r != NULL) { -@@ -182,9 +186,13 @@ static int get_file_status(char *filenam - if(sres == -1){ - char* er = strerror(errno); - if (er == NULL) { -- error(0,"get_file_status: lstat() failed for %s. strerror() failed for %i\n", filename, errno); -+ char *filename_safe = stresc(filename); -+ error(0,"get_file_status: lstat() failed for %s. strerror() failed for %i\n", filename_safe, errno); -+ free(filename_safe); - } else { -- error(0,"get_file_status: lstat() failed for %s: %s\n", filename, er); -+ char *filename_safe = stresc(filename); -+ error(0,"get_file_status: lstat() failed for %s: %s\n", filename_safe, er); -+ free(filename_safe); - } - } - return sres; -@@ -220,7 +228,11 @@ db_line *db_readline_disk () - error (240, "%s attr=%llu\n", &fullname[conf->root_prefix_length], attr); - - if (fil != NULL) { -- error (240, "%s attr=%llu\n", fil->filename, fil->attr); -+ { -+ char *fname_safe = stresc(fil->filename); -+ error (240, "%s attr=%llu\n", fname_safe, fil->attr); -+ free(fname_safe); -+ } - return fil; - } - } -@@ -269,7 +281,11 @@ recursion: - error (240, "%s attr=%llu\n", &fullname[conf->root_prefix_length], attr); - - if (fil != NULL) { -- error (240, "%s attr=%llu\n", fil->filename, fil->attr); -+ { -+ char *fname_safe = stresc(fil->filename); -+ error (240, "%s attr=%llu\n", fname_safe, fil->attr); -+ free(fname_safe); -+ } - } else { - /* - Something went wrong during read process -> -diff -up aide-0.16/src/gen_list.c.orig aide-0.16/src/gen_list.c ---- aide-0.16/src/gen_list.c.orig 2025-08-21 09:58:21.273581610 +0200 -+++ aide-0.16/src/gen_list.c 2025-08-21 10:04:29.190502666 +0200 -@@ -37,6 +37,7 @@ - #include "list.h" - #include "gen_list.h" - #include "seltree.h" -+#include "util.h" - #include "db.h" - #include "db_config.h" - #include "commandconf.h" -@@ -993,16 +994,28 @@ int check_rxtree(char* filename,seltree* - if(conf->limit!=NULL) { - retval=pcre_exec(conf->limit_crx, NULL, filename, strlen(filename), 0, PCRE_PARTIAL_SOFT, NULL, 0); - if (retval >= 0) { -- error(220, "check_rxtree: %s does match limit: %s\n", filename, conf->limit); -+ char *fname_safe = stresc(filename); -+ char *limit_safe = conf->limit?stresc(conf->limit):NULL; -+ error(220, "check_rxtree: %s does match limit: %s\n", fname_safe, limit_safe?limit_safe:""); -+ free(fname_safe); -+ free(limit_safe); - } else if (retval == PCRE_ERROR_PARTIAL) { -- error(220, "check_rxtree: %s does PARTIAL match limit: %s\n", filename, conf->limit); -+ char *fname_safe = stresc(filename); -+ char *limit_safe = conf->limit?stresc(conf->limit):NULL; -+ error(220, "check_rxtree: %s does PARTIAL match limit: %s\n", fname_safe, limit_safe?limit_safe:""); - if(S_ISDIR(perm) && get_seltree_node(tree,filename)==NULL){ -- error(220, "check_rxtree: creating new seltree node for '%s'\n", filename); -+ error(220, "check_rxtree: creating new seltree node for '%s'\n", fname_safe); - new_seltree_node(tree,filename,0,NULL); - } -+ free(fname_safe); -+ free(limit_safe); - return -1; - } else { -- error(220, "check_rxtree: %s does NOT match limit: %s\n", filename, conf->limit); -+ char *fname_safe = stresc(filename); -+ char *limit_safe = conf->limit?stresc(conf->limit):NULL; -+ error(220, "check_rxtree: %s does NOT match limit: %s\n", fname_safe, limit_safe?limit_safe:""); -+ free(fname_safe); -+ free(limit_safe); - return -2; - } - } -@@ -1039,13 +1052,25 @@ db_line* get_file_attrs(char* filename,D - } else { - - if(fs->st_atime>cur_time){ -- error(CLOCK_SKEW,_("%s atime in future\n"),filename); -+ { -+ char *fname_safe = stresc(filename); -+ error(CLOCK_SKEW,_("%s atime in future\n"),fname_safe); -+ free(fname_safe); -+ } - } - if(fs->st_mtime>cur_time){ -- error(CLOCK_SKEW,_("%s mtime in future\n"),filename); -+ { -+ char *fname_safe = stresc(filename); -+ error(CLOCK_SKEW,_("%s mtime in future\n"),fname_safe); -+ free(fname_safe); -+ } - } - if(fs->st_ctime>cur_time){ -- error(CLOCK_SKEW,_("%s ctime in future\n"),filename); -+ { -+ char *fname_safe = stresc(filename); -+ error(CLOCK_SKEW,_("%s ctime in future\n"),fname_safe); -+ free(fname_safe); -+ } - } - } - -@@ -1220,7 +1245,11 @@ void hsymlnk(db_line* line) { - int sres; - sres=AIDE_STAT_FUNC(line->fullpath,&fs); - if (sres!=0 && sres!=EACCES) { -- error(4,"Dead symlink detected at %s\n",line->fullpath); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(4,"Dead symlink detected at %s\n",fp_safe); -+ free(fp_safe); -+ } - } - if(!(line->attr&DB_RDEV)) - fs.st_rdev=0; -diff -up aide-0.16/src/util.c.orig aide-0.16/src/util.c ---- aide-0.16/src/util.c.orig 2025-08-21 09:58:21.272581600 +0200 -+++ aide-0.16/src/util.c 2025-08-21 10:07:50.157894133 +0200 -@@ -104,9 +104,11 @@ url_t* parse_url(char* val) - r+=2; - for(i=0;r[0]!='/'&&r[0]!='\0';r++,i++); - if(r[0]=='\0'){ -- error(0,"Invalid file-URL,no path after hostname: file:%s\n",t); -+ char *t_safe = stresc(t); -+ error(0,"Invalid file-URL,no path after hostname: file:%s\n",t_safe); -+ free(t_safe); - free(hostname); -- return NULL; -+ return NULL; - } - u->value=strdup(r); - r[0]='\0'; -@@ -118,9 +120,11 @@ url_t* parse_url(char* val) - free(hostname); - break; - } else { -- error(0,"Invalid file-URL, cannot use hostname other than localhost or %s: file:%s\n",hostname,u->value); -- free(hostname); -- return NULL; -+ char *value_safe = stresc(u->value); -+ error(0,"Invalid file-URL, cannot use hostname other than localhost or %s: file:%s\n",hostname,value_safe); -+ free(value_safe); -+ free(hostname); -+ return NULL; - } - - break; -@@ -150,6 +154,43 @@ url_t* parse_url(char* val) - return u; - } - -+static size_t escape_str(const char *unescaped_str, char *str, size_t s) { -+ size_t n = 0; -+ size_t i = 0; -+ char c; -+ while (i < s && (c = unescaped_str[i])) { -+ if ((c >= 0 && (c < 0x1f || c == 0x7f)) || -+ (c == '\\' && isdigit(unescaped_str[i+1]) -+ && isdigit(unescaped_str[i+2]) -+ && isdigit(unescaped_str[i+3]))) { -+ if (str) { snprintf(&str[n], 5, "\\%03o", c); } -+ n += 4; -+ } else { -+ if (str) { str[n] = c; } -+ n++; -+ } -+ i++; -+ } -+ if (str) { str[n] = '\0'; } -+ n++; -+ return n; -+} -+ -+char *strnesc(const char *unescaped_str, size_t s) { -+ int n = escape_str(unescaped_str, NULL, s); -+ char *str = malloc(n); -+ if (str == NULL) { -+ error(0, "malloc: failed to allocate %d bytes of memory\n", n); -+ exit(1); -+ } -+ escape_str(unescaped_str, str, s); -+ return str; -+} -+ -+char *stresc(const char *unescaped_str) { -+ return strnesc(unescaped_str, strlen(unescaped_str)); -+} -+ - /* Returns 1 if the string contains unsafe characters, 0 otherwise. */ - int contains_unsafe (const char *s) - { diff --git a/SOURCES/aide-0.16-CVE-2025-54389.patch b/SOURCES/aide-0.16-CVE-2025-54389.patch deleted file mode 100644 index 706c219..0000000 --- a/SOURCES/aide-0.16-CVE-2025-54389.patch +++ /dev/null @@ -1,1053 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index 263c438f4a2a38edc45f91c0d5a216112a8fa38c..5d286a8e07d0b3235f97272223175a1dd85848b2 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,27 +1,30 @@ -+2025-08-07 Hannes von Haugwitz -+ * Escape control characters in report and log output (CVE-2025-54389) -+ - 2016-07-25 Hannes von Haugwitz -- * Release version 0.16 -+ * Release version 0.16 - - 2016-07-11 Hannes von Haugwitz - * Fix example aide.conf (xattr -> xattrs) - * aide.conf.5: update "SELECTION LINES" section - * Released version 0.16rc1 - - 2016-07-10 Hannes von Haugwitz - * Fix compilation with latest libaudit - * Use AC_PROG_CC_C99 instead of AC_PROG_CC - * Add AM_PROG_CC_C_O - * aide.conf.in: logfile -> file - * Update README - * Update manual pages (aide.1 and aide.conf.5) - - 2016-07-07 Hannes von Haugwitz - * Adapt manual to version 0.16 - - 2016-06-08 Hannes von Haugwitz - * Add missing break statements - - 2016-04-15 Hannes von Haugwitz - * Released version 0.16b1 - - 2016-04-13 Hannes von Haugwitz - * Fix spelling errors -diff --git a/doc/aide.1.in b/doc/aide.1.in -index 932810eebd2eda353c2f30ce89a042e5f9d69a51..e932b8d0273e9144b09b3e1f8cf61cba2be12155 100644 ---- a/doc/aide.1.in -+++ b/doc/aide.1.in -@@ -71,51 +71,61 @@ output. See aide.conf (5) section URLS for available values. - Prints out the standard help message. - .PP - .SH DIAGNOSTICS - Normally, the exit status is 0 if no errors occurred. Except when the - .BR --check , - .BR --compare " or" - .B --update - command was requested, in which case the exit status is defined as: - .IP "1 * (new files detected?) +" - .IP "2 * (removed files detected?) +" - .IP "4 * (changed files detected?)" - .PP - Additionally, the following exit codes are defined for generic error - conditions: - .IP "14 Error writing error" - .IP "15 Invalid argument error" - .IP "16 Unimplemented function error" - .IP "17 Invalid configureline error" - .IP "18 IO error" - .IP "19 Version mismatch error" - .PP - .SH NOTES - Please note that due to mmap issues, aide cannot be terminated with - SIGTERM. Use SIGKILL to terminate. - -+.IP "Checksum encoding" -+ - The checksums in the database and in the output are by default base64 - encoded (see also report_base16 option). - To decode them you can use the following shell command: - - echo | base64 \-d | hexdump \-v \-e '32/1 "%02x" "\\n"' - -+.IP "Control characters" -+ -+Control characters (00-31 and 127) are always escaped in log and plain report -+output. They are escaped by a literal backslash (\\) followed by exactly 3 -+digits representing the character in octal notation (e.g. a newline is output -+as "\\012"). A literal backslash is not escaped unless it is followed by 3 digits -+(0-9), in this case the literal backslash is escaped as "\\134". -+ - .PP - .SH FILES - .IP \fB@sysconfdir@/aide.conf\fR - Default aide configuration file. - .IP \fB@localstatedir@/lib/aide/aide.db\fR - Default aide database. - .IP \fB@localstatedir@/lib/aide/aide.db.new\fR - Default aide output database. - .SH SEE ALSO - .BR aide.conf (5) - .BR manual.html - .SH BUGS - There are probably bugs in this release. Please report them - at http://sourceforge.net/projects/aide . Bug fixes are more than welcome. - Unified diffs are preferred. - .SH DISCLAIMER - All trademarks are the property of their respective owners. - No animals were harmed while making this webpage or this piece of - software. Although some pizza delivery guy's feelings were hurt. - .BR -diff --git a/include/util.h b/include/util.h -index 79988536c974ca83b14696380f6006031e0fa5e4..68e6ee2a905856bc7b73f1a67633585e0c1d814d 100644 ---- a/include/util.h -+++ b/include/util.h -@@ -22,48 +22,51 @@ - #ifndef _UTIL_H_INCLUDED - #define _UTIL_H_INCLUDED - #include - #include - #include "db_config.h" - - #define HEXD2ASC(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'A')) - - #define ASC2HEXD(x) (((x) >= '0' && (x) <= '9') ? \ - ((x) - '0') : (toupper(x) - 'A' + 10)) - - #define ISXDIGIT(x) isxdigit ((unsigned char)(x)) - - #define CLEANDUP(x) (contains_unsafe (x) ? encode_string (x) : strdup (x)) - - #ifndef HAVE_STRICMP - # define stricmp(a,b) strcasecmp( (a), (b) ) - #endif - - int cmpurl(url_t*, url_t*); - - url_t* parse_url(char*); - - int contains_unsafe(const char*); - -+char *strnesc(const char *, size_t); -+char *stresc(const char *); -+ - void decode_string(char*); - - char* encode_string(const char*); - - char* perm_to_char(mode_t perm); - - void sig_handler(int signal); - - void init_sighandler(void); - - char *expand_tilde(char * path); - - #ifndef HAVE_STRNSTR - char* strnstr(char* haystack,char* needle,int n); - #endif - - #ifndef HAVE_STRNLEN - size_t strnlen(const char *s, size_t maxlen); - #endif - - int syslog_facility_lookup(char *); - - #endif -diff --git a/src/aide.c b/src/aide.c -index 8dd38b7c5a7130cc1136d0ee30f5addc9c2226e5..2b7eee14b6e1d4351ca5ddc9387344bd88a8951c 100644 ---- a/src/aide.c -+++ b/src/aide.c -@@ -164,54 +164,60 @@ static int read_param(int argc,char**argv) - error(0,_("-B must have a parameter\n")); - exit(INVALID_ARGUMENT_ERROR); - } - break; - } - case 'A': { - if (optarg!=NULL) { - int errorno=commandconf('A',optarg); - if (errorno!=0){ - error(0,_("Configuration error in after statement:%s\n"),optarg); - exit(INVALID_CONFIGURELINE_ERROR); - } - } else { - error(0,_("-A must have a parameter\n")); - exit(INVALID_ARGUMENT_ERROR); - } - break; - } - case 'l': { - if (optarg!=NULL) { - const char* pcre_error; - int pcre_erroffset; - conf->limit=malloc(strlen(optarg)+1); - strcpy(conf->limit,optarg); - if((conf->limit_crx=pcre_compile(conf->limit, PCRE_ANCHORED, &pcre_error, &pcre_erroffset, NULL)) == NULL) { -- error(0,_("Error in limit regexp '%s' at %i: %s\n"), conf->limit, pcre_erroffset, pcre_error); -+ char *limit_safe = stresc(conf->limit); -+ error(0,_("Error in limit regexp '%s' at %i: %s\n"), limit_safe, pcre_erroffset, pcre_error); -+ free(limit_safe); - exit(INVALID_ARGUMENT_ERROR); - } -- error(200,_("Limit set to '%s'\n"), conf->limit); -+ { -+ char *limit_safe = stresc(conf->limit); -+ error(200,_("Limit set to '%s'\n"), limit_safe); -+ free(limit_safe); -+ } - } else { - error(0,_("-l must have an argument\n")); - exit(INVALID_ARGUMENT_ERROR); - } - break; - } - case 'r': { - if(optarg!=NULL) { - do_repurldef(optarg); - }else { - error(0,_("-r must have an argument\n")); - } - break; - } - case 'i': { - if(conf->action==0){ - conf->action=DO_INIT; - }else { - error(0, - _("Cannot have multiple commands on a single commandline.\n")); - exit(INVALID_ARGUMENT_ERROR); - }; - break; - } - case 'C': { -@@ -566,53 +572,57 @@ int main(int argc,char**argv) - if(cmpurl(conf->db_in_url,conf->db_out_url)==RETOK){ - error(4,_("WARNING:Input and output database urls are the same.\n")); - if((conf->action&DO_INIT)&&(conf->action&DO_COMPARE)){ - error(0,_("Input and output database urls cannot be the same " - "when doing database update\n")); - exit(INVALID_ARGUMENT_ERROR); - } - if(conf->action&DO_DIFF){ - error(0,_("Both input databases cannot be the same " - "when doing database compare\n")); - exit(INVALID_ARGUMENT_ERROR); - } - }; - if((conf->action&DO_DIFF)&&(!(conf->db_new_url)||!(conf->db_in_url))){ - error(0,_("Must have both input databases defined for " - "database compare.\n")); - exit(INVALID_ARGUMENT_ERROR); - } - if (conf->action&(DO_INIT|DO_COMPARE) && conf->root_prefix_length > 0) { - DIR *dir; - if((dir = opendir(conf->root_prefix)) != NULL) { - closedir(dir); - } else { - char* er=strerror(errno); - if (er!=NULL) { -- error(0,"opendir() for root prefix %s failed: %s\n", conf->root_prefix,er); -+ char *rp_safe = stresc(conf->root_prefix); -+ error(0,"opendir() for root prefix %s failed: %s\n", rp_safe,er); -+ free(rp_safe); - } else { -- error(0,"opendir() for root prefix %s failed: %i\n", conf->root_prefix,errno); -+ char *rp_safe = stresc(conf->root_prefix); -+ error(0,"opendir() for root prefix %s failed: %i\n", rp_safe,errno); -+ free(rp_safe); - } - exit(INVALID_ARGUMENT_ERROR); - } - } - #ifdef WITH_MHASH - byte* dig=NULL; - char* digstr=NULL; - - if(conf->config_check&&FORCECONFIGMD){ - error(0,"Can't give config checksum when compiled with --enable-forced_configmd\n"); - exit(INVALID_ARGUMENT_ERROR); - } - - if((conf->do_configmd||conf->config_check)&& conf->confmd!=0){ - /* The patch automatically adds a newline so will also have to add it. */ - if(newlinelastinconfig==0){ - mhash(conf->confmd,"\n",1); - }; - mhash(conf->confmd, NULL,0); - dig=(byte*)malloc(sizeof(byte)*mhash_get_block_size(conf->confhmactype)); - mhash_deinit(conf->confmd,(void*)dig); - digstr=encode_base64(dig,mhash_get_block_size(conf->confhmactype)); - - if(!conf->config_check||FORCECONFIGMD){ - if(strncmp(digstr,conf->old_confmdstr,strlen(digstr))!=0){ -diff --git a/src/compare_db.c b/src/compare_db.c -index c17828d3e8b732096e00253f21623339f2168ccf..41e216527a9b05b90f1b601a61279fd408e2df71 100644 ---- a/src/compare_db.c -+++ b/src/compare_db.c -@@ -504,175 +504,225 @@ static void print_line(seltree* node) { - c = '<'; - } - u = '='; - break; - } - if (summary_attributes[i]&node->changed_attrs&(forced_attrs|(~ignored_changed_attrs))) { - summary[i]=c; - } else if (summary_attributes[i]&((node->old_data)->attr&~((node->new_data)->attr)&(forced_attrs|~(ignored_removed_attrs)))) { - summary[i]=r; - } else if (summary_attributes[i]&~((node->old_data)->attr)&(node->new_data)->attr&(forced_attrs|~(ignored_added_attrs))) { - summary[i]=a; - } else if (summary_attributes[i]& ( - (((node->old_data)->attr&~((node->new_data)->attr)&ignored_removed_attrs))| - (~((node->old_data)->attr)&(node->new_data)->attr&ignored_added_attrs)| - (((node->old_data)->attr&(node->new_data)->attr)&ignored_changed_attrs) - ) ) { - summary[i]=g; - } else if (summary_attributes[i]&((node->old_data)->attr&(node->new_data)->attr)) { - summary[i]=u; - } else { - summary[i]=s; - } - } - } - summary[length]='\0'; -- error(2,"\n%s: %s", summary, (node->checked&NODE_REMOVED?node->old_data:node->new_data)->filename); -+ { -+ char *filename_safe = stresc((node->checked&NODE_REMOVED?node->old_data:node->new_data)->filename); -+ error(2,"\n%s: %s", summary, filename_safe); -+ free(filename_safe); -+ } - free(summary); summary=NULL; - } else { - if (node->checked&NODE_ADDED) { -- error(2,"added: %s\n",(node->new_data)->filename); -+ { -+ char *filename_safe = stresc((node->new_data)->filename); -+ error(2,"added: %s\n",filename_safe); -+ free(filename_safe); -+ } - } else if (node->checked&NODE_REMOVED) { -- error(2,"removed: %s\n",(node->old_data)->filename); -+ { -+ char *filename_safe = stresc((node->old_data)->filename); -+ error(2,"removed: %s\n",filename_safe); -+ free(filename_safe); -+ } - } else if (node->checked&NODE_CHANGED) { -- error(2,"changed: %s\n",(node->new_data)->filename); -+ { -+ char *filename_safe = stresc((node->new_data)->filename); -+ error(2,"changed: %s\n",filename_safe); -+ free(filename_safe); -+ } - } - } - } - - static void print_dbline_attributes(db_line* oline, db_line* nline, DB_ATTR_TYPE - changed_attrs, DB_ATTR_TYPE force_attrs) { - char **ovalue, **nvalue; - int onumber, nnumber, olen, nlen, i, j, k, c; - 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"); - 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); -+ { -+ char *filename_safe = stresc((nline==NULL?oline:nline)->filename); -+ error(2,"%s\n", filename_safe); -+ free(filename_safe); -+ } - attrs=force_attrs|(~(ignored_changed_attrs)&changed_attrs); - for (j=0; j < length; ++j) { - if (details_attributes[j]&attrs) { - onumber=get_attribute_values(details_attributes[j], oline, &ovalue); - nnumber=get_attribute_values(details_attributes[j], nline, &nvalue); - i = 0; - while (i= 0 || nlen-p*k >= 0) { - c = k*(p-1); - if (!onumber) { -- error(2," %s%-9s%c %-*c %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, ' ', p-1, nlen-c>0?&nvalue[i][c]:""); -+ error(2," %s%-9s%c %-*c %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, ' ', p-1, nlen-c>0?&nv[c]:""); - } else if (!nnumber) { -- error(2," %s%-9s%c %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p-1, olen-c>0?&ovalue[i][c]:""); -+ error(2," %s%-9s%c %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p-1, olen-c>0?&ov[c]:""); - } else { -- error(2," %s%-9s%c %-*.*s| %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, p-1, olen-c>0?&ovalue[i][c]:"", p-1, nlen-c>0?&nvalue[i][c]:""); -+ error(2," %s%-9s%c %-*.*s| %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, p-1, olen-c>0?&ov[c]:"", p-1, nlen-c>0?&nv[c]:""); - } - k++; - } - ++i; -+ free(ov); -+ free(nv); - } - for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL; - for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL; - } - } - } - - - static void print_dbline_attributes_syslog(db_line* oline, db_line* nline, DB_ATTR_TYPE - changed_attrs, DB_ATTR_TYPE force_attrs) { - char **ovalue, **nvalue; - int onumber, nnumber, i, j; - int length = sizeof(details_attributes)/sizeof(DB_ATTR_TYPE); - DB_ATTR_TYPE attrs; - char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm); - if (file_type) { - error(0,"%s=", file_type); - } -- error(0,"%s", (nline==NULL?oline:nline)->filename); -+ { -+ char *filename_safe = stresc((nline==NULL?oline:nline)->filename); -+ error(0,"%s", filename_safe); -+ free(filename_safe); -+ } - attrs=force_attrs|(~(ignored_changed_attrs)&changed_attrs); - for (j=0; j < length; ++j) { - if (details_attributes[j]&attrs) { - onumber=get_attribute_values(details_attributes[j], oline, &ovalue); - nnumber=get_attribute_values(details_attributes[j], nline, &nvalue); - - if (details_attributes[j] == DB_ACL || details_attributes[j] == DB_XATTRS) { - - error(0, ";%s_old=|", details_string[j]); - - for (i = 0 ; i < onumber ; i++) { -- error(0, "%s|", ovalue[i]); -+ { -+ char *val_safe = stresc(ovalue[i]); -+ error(0, "%s|", val_safe); -+ free(val_safe); -+ } - } - - error(0, ";%s_new=|", details_string[j]); - - for (i = 0 ; i < nnumber ; i++) { -- error(0, "%s|", nvalue[i]); -+ { -+ char *val_safe = stresc(nvalue[i]); -+ error(0, "%s|", val_safe); -+ free(val_safe); -+ } - } - - } else { - -- error(0, ";%s_old=%s;%s_new=%s", details_string[j], *ovalue, details_string[j], *nvalue); -+ { -+ char *ov_safe = stresc(*ovalue); -+ char *nv_safe = stresc(*nvalue); -+ error(0, ";%s_old=%s;%s_new=%s", details_string[j], ov_safe, details_string[j], nv_safe); -+ free(ov_safe); -+ free(nv_safe); -+ } - - } - - for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL; - for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL; - } - } - error(0, "\n"); - } - - static void print_attributes_added_node(db_line* line) { - print_dbline_attributes(NULL, line, 0, line->attr); - } - - static void print_attributes_removed_node(db_line* line) { - print_dbline_attributes(line, NULL, 0, line->attr); - } - - static void print_attributes_added_node_syslog(db_line* line) { - - char *file_type = get_file_type_string(line->perm); - if (file_type) { - error(0,"%s=", file_type); - } -- error(0,"%s; added\n", line->filename); -+ { -+ char *filename_safe = stresc(line->filename); -+ error(0,"%s; added\n", filename_safe); -+ free(filename_safe); -+ } - - } - - static void print_attributes_removed_node_syslog(db_line* line) { - - char *file_type = get_file_type_string(line->perm); - if (file_type) { - error(0,"%s=", file_type); - } -- error(0,"%s; removed\n", line->filename); -+ { -+ char *filename_safe = stresc(line->filename); -+ error(0,"%s; removed\n", filename_safe); -+ free(filename_safe); -+ } - - } - - static void terse_report(seltree* node) { - list* r=NULL; - if ((node->checked&(DB_OLD|DB_NEW)) != 0) { - ntotal += ((node->checked&DB_NEW) != 0); - if (!(node->checked&DB_OLD)){ - /* File is in new db but not old. (ADDED) */ - /* unless it was moved in */ - if (!((node->checked&NODE_ALLOW_NEW)||(node->checked&NODE_MOVED_IN))) { - nadd++; - node->checked|=NODE_ADDED; - } - } else if (!(node->checked&DB_NEW)){ - /* File is in old db but not new. (REMOVED) */ - /* unless it was moved out */ - if (!((node->checked&NODE_ALLOW_RM)||(node->checked&NODE_MOVED_OUT))) { - nrem++; - node->checked|=NODE_REMOVED; - } - } else if ((node->old_data!=NULL)&&(node->new_data!=NULL)){ - /* File is in both db's and the data is still there. (CHANGED) */ - if (!(node->checked&(NODE_MOVED_IN|NODE_MOVED_OUT))){ - nchg++; -@@ -739,51 +789,53 @@ static void print_syslog_format(seltree* node) { - } - - static void print_report_header() { - char *time; - int first = 1; - - time = malloc(time_string_len * sizeof (char)); - strftime(time, time_string_len, time_format, localtime(&(conf->start_time))); - error(2,_("Start timestamp: %s (AIDE " AIDEVERSION ")\n"), time); - free(time); time=NULL; - - error(0,_("AIDE")); - if(conf->action&(DO_COMPARE|DO_DIFF)) { - error(0,_(" found %sdifferences between %s%s!!\n"), (nadd||nrem||nchg)?"":"NO ", conf->action&DO_COMPARE?_("database and filesystem"):_("the two databases"), (nadd||nrem||nchg)?"":_(". Looks okay")); - if(conf->action&(DO_INIT)) { - error(0,_("New AIDE database written to %s\n"),conf->db_out_url->value); - } - } else { - error(0,_(" initialized database at %s\n"),conf->db_out_url->value); - } - - if(conf->config_version) - error(2,_("Config version used: %s\n"),conf->config_version); - - if (conf->limit != NULL) { -- error (2,_("Limit: %s"), conf->limit); -+ char *limit_safe = stresc(conf->limit); -+ error (2,_("Limit: %s"), limit_safe); -+ free(limit_safe); - first = 0; - } - if (conf->action&(DO_INIT|DO_COMPARE) && conf->root_prefix_length > 0) { - if (first) { first=0; } - else { error (2," | "); } - error (2,_("Root prefix: %s"),conf->root_prefix); - } - if (conf->verbose_level != 5) { - if (first) { first=0; } - else { error (2," | "); } - error (2,_("Verbose level: %d"), conf->verbose_level); - } - if (!first) { error (2,"\n"); } - if (ignored_added_attrs) { - error (2,_("Ignored added attributes: %s\n"),report_attrs(ignored_added_attrs)); - } - if (ignored_removed_attrs) { - error (2,_("Ignored removed attributes: %s\n"),report_attrs(ignored_removed_attrs)); - } - if (ignored_changed_attrs) { - error (2,_("Ignored changed attributes: %s\n"),report_attrs(ignored_changed_attrs)); - } - if (forced_attrs) { - error (2,_("Forced attributes: %s\n"),report_attrs(forced_attrs)); - } -diff --git a/src/db_sql.c b/src/db_sql.c -index 154579070ccacb6e9b6b8393b989eb50c843e71d..09a32504c317607150174d2bec0fcddf47992995 100644 ---- a/src/db_sql.c -+++ b/src/db_sql.c -@@ -16,50 +16,51 @@ - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - #include "aide.h" - /*for locale support*/ - #include "locale-aide.h" - /*for locale support*/ - - #ifdef WITH_PSQL - - #include - #include - #include - #include - #include - #include "base64.h" - #include "db.h" - - #include "db_sql.h" - #include "db_config.h" - #include "libpq-fe.h" - #include "report.h" -+#include "util.h" - - #ifdef WITH_MHASH - #include - #endif - - char* db_get_sql(db_line*,db_config*); - - int _db_check_result(PGconn *conn, PGresult *res, char *query) - { - int status = 0; - int ret = RETOK; - - - if (!res || ( (PQresultStatus(res) != PGRES_COMMAND_OK) && - (PQresultStatus(res) != PGRES_TUPLES_OK) )){ - ret = RETFAIL; - if (res!=NULL) { - error(0,"Sql error %s while doing %s\n", PQerrorMessage(conn), query); - } else { - error(0,"Sql error while doing %s.\n",query); - } - } else { - error(255,"Sql went ok.\n"); - status = 1; - } -@@ -281,51 +282,55 @@ db_line* db_readline_sql(int db, db_config* conf) { - db_readline_sql_byte((void*)&(rline->haval),db,db_haval, conf); - db_readline_sql_byte((void*)&(rline->gost),db,db_gost, conf); - #endif - db_readline_sql_char((void*)&(rline->fullpath),db,db_filename, conf); - rline->filename=rline->fullpath; - db_readline_sql_char((void*)&(rline->linkname),db,db_linkname, conf); - - db_readline_sql_int((void*)&(rline->perm),db,db_perm, conf); - db_readline_sql_int((void*)&(rline->uid),db,db_uid, conf); - db_readline_sql_int((void*)&(rline->gid),db,db_gid, conf); - db_readline_sql_int((void*)&(rline->inode),db,db_inode, conf); - db_readline_sql_int((void*)&(rline->nlink),db,db_lnkcount, conf); - - db_readline_sql_int((void*)&(rline->size),db,*db_osize, conf); - db_readline_sql_int((void*)&(rline->bcount),db,db_bcount, conf); - db_readline_sql_int((void*)&(rline->attr),db,db_attr, conf); - - db_readline_sql_time((void*)&(rline->atime),db,db_atime, conf); - db_readline_sql_time((void*)&(rline->ctime),db,db_ctime, conf); - db_readline_sql_time((void*)&(rline->mtime),db,db_mtime, conf); - #ifdef WITH_ACL - rline->acl=NULL; - #endif - ((psql_data*)(*db_filep))->curread++; - -- error(255,"filename %s\n",rline->filename); -+ { -+ char *filename_safe = stresc(rline->filename); -+ error(255,"filename %s\n",filename_safe); -+ free(filename_safe); -+ } - - return rline; - } - - - void sql_writeint(int data,char *s,int i){ - char t[10]; - t[0]=0; - if (i!=0) { - s = strcat(s,","); - } - sprintf(t,"%i",data); - - strcat(s,t); - - } - - void sql_writeoct(int data,char *s,int i){ - char t[10]; - t[0]=0; - if (i!=0) { - s = strcat(s,","); - } - sprintf(t,"%lo",data); - -diff --git a/src/do_md.c b/src/do_md.c -index 77d2e15f5f9cdba5168a92feaf2f97128e705f36..4a648b6f5ff14edd553a3f8d94b1171708ccadaf 100644 ---- a/src/do_md.c -+++ b/src/do_md.c -@@ -16,50 +16,51 @@ - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - #include "aide.h" - - #ifndef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 200112L - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include "md.h" -+#include "util.h" - - #include "db_config.h" - #include "do_md.h" - #include "report.h" - #include "list.h" - /*for locale support*/ - #include "locale-aide.h" - /*for locale support*/ - - - /* This define should be somewhere else */ - #define READ_BLOCK_SIZE 16777216 - - #ifdef WITH_MHASH - #include - #endif /* WITH_MHASH */ - - /* Redhat 5.0 needs this */ - #ifdef HAVE_MMAP - #ifndef MAP_FAILED - #define MAP_FAILED (-1) - #endif /* MAP_FAILED */ - #define MMAP_BLOCK_SIZE 16777216 - #endif /* HAVE_MMAP */ - -@@ -206,55 +207,59 @@ void calc_md(struct AIDE_STAT_TYPE* old_fs,db_line* line) { - from we are about to calculate the hash is the correct one, - and we don't read from a pipe :) - */ - struct AIDE_STAT_TYPE fs; - int stat_diff,filedes; - #ifdef WITH_PRELINK - pid_t pid; - #endif - - error(255,"calc_md called\n"); - #ifdef _PARAMETER_CHECK_ - if (line==NULL) { - abort(); - } - #endif - - #ifdef HAVE_O_NOATIME - filedes=open(line->fullpath,O_RDONLY|O_NOATIME); - if(filedes<0) - #endif - filedes=open(line->fullpath,O_RDONLY); - - if (filedes==-1) { - char* er=strerror(errno); - if (er!=NULL) { -+ char *fp_safe = stresc(line->fullpath); - error(3,"do_md(): open() for %s failed: %s\n", -- line->fullpath,er); -+ fp_safe,er); -+ free(fp_safe); - } else { -+ char *fp_safe = stresc(line->fullpath); - error(3,"do_md(): open() for %s failed: %i\n", -- line->fullpath,errno); -+ fp_safe,errno); -+ free(fp_safe); - } - /* - Nop. Cannot cal hashes. Mark it. - */ - no_hash(line); - return; - } - - AIDE_FSTAT_FUNC(filedes,&fs); - if(!(line->attr&DB_RDEV)) - fs.st_rdev=0; - - #ifdef HAVE_POSIX_FADVISE - if (posix_fadvise(filedes,0,fs.st_size,POSIX_FADV_NOREUSE)!=0) { - error(255,"posix_fadvise error %s\n",strerror(errno)); - } else { - error(255,"posix_fadvise(%i,0,%li,POSIX_FADV_NOREUSE) ok\n",filedes,fs.st_size); - } - #endif - if ((stat_diff=stat_cmp(&fs,old_fs))==RETOK) { - /* - Now we have a 'valid' filehandle to read from a file. - */ - - #ifdef WITH_PRELINK -@@ -288,51 +293,55 @@ void calc_md(struct AIDE_STAT_TYPE* old_fs,db_line* line) { - off_t curpos=0; - - r_size=fs.st_size; - /* in mmap branch r_size is used as size remaining */ - while(r_size>0){ - if(r_sizefullpath,strerror(errno)); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0,"error mmap'ing %s: %s\n", fp_safe,strerror(errno)); -+ free(fp_safe); -+ } - close(filedes); - close_md(&mdc); - return; - } - conf->catch_mmap=1; - if (update_md(&mdc,buf,size)!=RETOK) { - error(0,"Message digest failed during update\n"); - close(filedes); - close_md(&mdc); - munmap(buf,size); - return; - } - munmap(buf,size); - conf->catch_mmap=0; - } - /* we have used MMAP, let's return */ - close_md(&mdc); - md2line(&mdc,line); - close(filedes); - return; - #ifdef WITH_PRELINK - } - #endif - #endif /* not HAVE_MMAP */ - // buf=malloc(READ_BLOCK_SIZE); -@@ -491,53 +500,61 @@ void acl2line(db_line* line) { - ret->acl_d = NULL; - else - { - tmp = acl_to_text(acl_d, NULL); - if (!tmp || !*tmp) - ret->acl_d = NULL; - else - ret->acl_d = strdup(tmp); - acl_free(tmp); - } - - acl_free(acl_a); - acl_free(acl_d); - } - line->acl = ret; - #endif - #ifdef WITH_SUN_ACL - if(DB_ACL&line->attr) { /* There might be a bug here. */ - int res; - line->acl=malloc(sizeof(acl_type)); - line->acl->entries=acl(line->fullpath,GETACLCNT,0,NULL); - if (line->acl->entries==-1) { - char* er=strerror(errno); - line->acl->entries=0; - if (er==NULL) { -- error(0,"ACL query failed for %s. strerror failed for %i\n",line->fullpath,errno); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0,"ACL query failed for %s. strerror failed for %i\n",fp_safe,errno); -+ free(fp_safe); -+ } - } else { -- error(0,"ACL query failed for %s:%s\n",line->fullpath,er); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0,"ACL query failed for %s:%s\n",fp_safe,er); -+ free(fp_safe); -+ } - } - } else { - line->acl->acl=malloc(sizeof(aclent_t)*line->acl->entries); - res=acl(line->fullpath,GETACL,line->acl->entries,line->acl->acl); - if (res==-1) { - error(0,"ACL error %s\n",strerror(errno)); - } else { - if (res!=line->acl->entries) { - error(0,"Tried to read %i acl but got %i\n",line->acl->entries,res); - } - } - } - }else{ - line->acl=NULL; - } - #endif - } - #endif - - #ifdef WITH_XATTR - static xattrs_type *xattr_new(void) { - xattrs_type *ret = NULL; - - ret = malloc(sizeof(xattrs_type)); - ret->num = 0; -@@ -571,100 +588,112 @@ static void xattr_add(xattrs_type *xattrs, const char *key, const char - - xattrs->num += 1; - } - - void xattrs2line(db_line *line) { - /* get all generic user xattrs. */ - xattrs_type *xattrs = NULL; - static ssize_t xsz = 1024; - static char *xatrs = NULL; - ssize_t xret = -1; - - if (!(DB_XATTRS&line->attr)) - return; - - /* assume memory allocs work, like rest of AIDE code... */ - if (!xatrs) xatrs = malloc(xsz); - - while (((xret = llistxattr(line->fullpath, xatrs, xsz)) == -1) && (errno == ERANGE)) { - xsz <<= 1; - xatrs = realloc(xatrs, xsz); - } - - if ((xret == -1) && ((errno == ENOSYS) || (errno == ENOTSUP))) { - line->attr&=(~DB_XATTRS); - } else if (xret == -1) { -- error(0, "listxattrs failed for %s:%s\n", line->fullpath, strerror(errno)); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0, "listxattrs failed for %s:%s\n", fp_safe, strerror(errno)); -+ free(fp_safe); -+ } - } else if (xret) { - const char *attr = xatrs; - static ssize_t asz = 1024; - static char *val = NULL; - - if (!val) val = malloc(asz); - - xattrs = xattr_new(); - - while (xret > 0) { - size_t len = strlen(attr); - ssize_t aret = 0; - - if (strncmp(attr, "user.", strlen("user.")) && - strncmp(attr, "root.", strlen("root."))) - goto next_attr; /* only store normal xattrs, and SELinux */ - - while (((aret = getxattr(line->fullpath, attr, val, asz)) == - -1) && (errno == ERANGE)) { - asz <<= 1; - val = realloc (val, asz); - } - - if (aret != -1) - xattr_add(xattrs, attr, val, aret); - else if (errno != ENOATTR) -- error(0, "getxattr failed for %s:%s\n", line->fullpath, strerror(errno)); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0, "getxattr failed for %s:%s\n", fp_safe, strerror(errno)); -+ free(fp_safe); -+ } - - next_attr: - attr += len + 1; - xret -= len + 1; - } - } - - line->xattrs = xattrs; - } - #endif - - #ifdef WITH_SELINUX - void selinux2line(db_line *line) { - char *cntx = NULL; - - if (!(DB_SELINUX&line->attr)) - return; - - if (lgetfilecon_raw(line->fullpath, &cntx) == -1) { - line->attr&=(~DB_SELINUX); - if ((errno != ENOATTR) && (errno != EOPNOTSUPP)) -- error(0, "lgetfilecon_raw failed for %s:%s\n", line->fullpath, strerror(errno)); -+ { -+ char *fp_safe = stresc(line->fullpath); -+ error(0, "lgetfilecon_raw failed for %s:%s\n", fp_safe, strerror(errno)); -+ free(fp_safe); -+ } - return; - } - - line->cntx = strdup(cntx); - - freecon(cntx); - } - #endif - - #ifdef WITH_E2FSATTRS - void e2fsattrs2line(db_line* line) { - unsigned long flags; - if (DB_E2FSATTRS&line->attr) { - if (fgetflags(line->fullpath, &flags) == 0) { - line->e2fsattrs=flags; - } else { - line->attr&=(~DB_E2FSATTRS); - line->e2fsattrs=0; - } - } else { - line->e2fsattrs=0; - } - } - #endif diff --git a/SOURCES/aide-0.16-crash-elf.patch b/SOURCES/aide-0.16-crash-elf.patch deleted file mode 100644 index 5aa3472..0000000 --- a/SOURCES/aide-0.16-crash-elf.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- ./src/do_md.c 2018-03-19 05:10:19.994957024 -0400 -+++ ./src/do_md.c 2018-03-19 05:19:05.829957024 -0400 -@@ -135,8 +135,13 @@ - continue; - - while (!bingo && (data = elf_getdata (scn, data)) != NULL) { -- int maxndx = data->d_size / shdr.sh_entsize; -+ int maxndx; - int ndx; -+ -+ if (shdr.sh_entsize != 0) -+ maxndx = data->d_size / shdr.sh_entsize; -+ else -+ continue; - - for (ndx = 0; ndx < maxndx; ++ndx) { - (void) gelf_getdyn (data, ndx, &dyn); diff --git a/SOURCES/aide-0.16-crypto-disable-haval-and-others.patch b/SOURCES/aide-0.16-crypto-disable-haval-and-others.patch deleted file mode 100644 index a066fd9..0000000 --- a/SOURCES/aide-0.16-crypto-disable-haval-and-others.patch +++ /dev/null @@ -1,153 +0,0 @@ -diff -up ./include/md.h.crypto ./include/md.h ---- ./include/md.h.crypto 2016-07-25 22:56:55.000000000 +0200 -+++ ./include/md.h 2018-08-29 15:00:30.827491299 +0200 -@@ -149,6 +149,7 @@ int init_md(struct md_container*); - int update_md(struct md_container*,void*,ssize_t); - int close_md(struct md_container*); - void md2line(struct md_container*,struct db_line*); -+DB_ATTR_TYPE get_available_crypto(); - - - #endif /*_MD_H_INCLUDED*/ -diff -up ./src/aide.c.crypto ./src/aide.c ---- ./src/aide.c.crypto 2018-08-29 15:00:30.825491309 +0200 -+++ ./src/aide.c 2018-08-29 15:00:30.827491299 +0200 -@@ -349,7 +349,7 @@ static void setdefaults_before_config() - - 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; -+ conf->db_attrs |= get_available_crypto(); - #ifdef WITH_MHASH - conf->db_attrs |= DB_GOST; - #ifdef HAVE_MHASH_WHIRLPOOL -diff -up ./src/md.c.crypto ./src/md.c ---- ./src/md.c.crypto 2018-08-29 15:00:30.823491319 +0200 -+++ ./src/md.c 2018-08-29 15:02:28.013903479 +0200 -@@ -78,6 +78,49 @@ DB_ATTR_TYPE hash_gcrypt2attr(int i) { - return r; - } - -+const char * hash_gcrypt2str(int i) { -+ char * r = "?"; -+#ifdef WITH_GCRYPT -+ switch (i) { -+ case GCRY_MD_MD5: { -+ r = "MD5"; -+ break; -+ } -+ case GCRY_MD_SHA1: { -+ r = "SHA1"; -+ break; -+ } -+ case GCRY_MD_RMD160: { -+ r = "RMD160"; -+ break; -+ } -+ case GCRY_MD_TIGER: { -+ r = "TIGER"; -+ break; -+ } -+ case GCRY_MD_HAVAL: { -+ r = "HAVAL"; -+ break; -+ } -+ case GCRY_MD_SHA256: { -+ r = "SHA256"; -+ break; -+ } -+ case GCRY_MD_SHA512: { -+ r = "SHA512"; -+ break; -+ } -+ case GCRY_MD_CRC32: { -+ r = "CRC32"; -+ break; -+ } -+ default: -+ break; -+ } -+#endif -+ return r; -+} -+ - DB_ATTR_TYPE hash_mhash2attr(int i) { - DB_ATTR_TYPE r=0; - #ifdef WITH_MHASH -@@ -163,6 +206,44 @@ DB_ATTR_TYPE hash_mhash2attr(int i) { - Initialise md_container according it's todo_attr field - */ - -+DB_ATTR_TYPE get_available_crypto() { -+ -+ DB_ATTR_TYPE ret = 0; -+ -+/* -+ * This function is usually called before config processing -+ * and default verbose level is 5 -+ */ -+#define lvl 255 -+ -+ error(lvl, "get_available_crypto called\n"); -+ -+#ifdef WITH_GCRYPT -+ -+ /* -+ * some initialization for FIPS -+ */ -+ gcry_check_version(NULL); -+ error(lvl, "Found algos:"); -+ -+ for(int i=0;i<=HASH_GCRYPT_COUNT;i++) { -+ -+ if ( (hash_gcrypt2attr(i) & HASH_USE_GCRYPT) == 0 ) -+ continue; -+ -+ if (gcry_md_algo_info(i, GCRYCTL_TEST_ALGO, NULL, NULL) == 0) { -+ ret |= hash_gcrypt2attr(i); -+ error(lvl, " %s", hash_gcrypt2str(i)); -+ } -+ } -+ error(lvl, "\n"); -+ -+#endif -+ -+ error(lvl, "get_available_crypto_returned with %lld\n", ret); -+ return ret; -+} -+ - int init_md(struct md_container* md) { - - int i; -@@ -201,18 +282,27 @@ int init_md(struct md_container* md) { - } - #endif - #ifdef WITH_GCRYPT -- if(gcry_md_open(&md->mdh,0,GCRY_MD_FLAG_SECURE)!=GPG_ERR_NO_ERROR){ -+ if(gcry_md_open(&md->mdh,0,GCRY_MD_FLAG_SECURE)!=GPG_ERR_NO_ERROR){ - error(0,"gcrypt_md_open failed\n"); - exit(IO_ERROR); - } - for(i=0;i<=HASH_GCRYPT_COUNT;i++) { -+ -+ - if (((hash_gcrypt2attr(i)&HASH_USE_GCRYPT)&md->todo_attr)!=0) { -- DB_ATTR_TYPE h=hash_gcrypt2attr(i); -- error(255,"inserting %llu\n",h); -+ -+ DB_ATTR_TYPE h=hash_gcrypt2attr(i); -+ -+ if (gcry_md_algo_info(i, GCRYCTL_TEST_ALGO, NULL, NULL) != 0) { -+ error(0,"Algo %s is not available\n", hash_gcrypt2str(i)); -+ exit(-1); -+ } -+ -+ error(255,"inserting %llu\n",h); - if(gcry_md_enable(md->mdh,i)==GPG_ERR_NO_ERROR){ - md->calc_attr|=h; - } else { -- error(0,"gcry_md_enable %i failed",i); -+ error(0,"gcry_md_enable %i failed\n",i); - md->todo_attr&=~h; - } - } diff --git a/SOURCES/aide-0.16b1-fipsfix.patch b/SOURCES/aide-0.16b1-fipsfix.patch deleted file mode 100644 index 434d74e..0000000 --- a/SOURCES/aide-0.16b1-fipsfix.patch +++ /dev/null @@ -1,103 +0,0 @@ -diff -up ./src/aide.c.orig ./aide-0.16b1/src/aide.c ---- ./src/aide.c.orig 2016-07-12 11:10:08.013158385 +0200 -+++ ./src/aide.c 2016-07-12 11:30:54.867833064 +0200 -@@ -511,9 +511,28 @@ int main(int argc,char**argv) - #endif - umask(0177); - init_sighandler(); -- - setdefaults_before_config(); - -+#if WITH_GCRYPT -+ error(255,"Gcrypt library initialization\n"); -+ /* -+ * Initialize libgcrypt as per -+ * http://www.gnupg.org/documentation/manuals/gcrypt/Initializing-the-library.html -+ * -+ * -+ */ -+ gcry_control(GCRYCTL_SET_ENFORCED_FIPS_FLAG, 0); -+ gcry_control(GCRYCTL_INIT_SECMEM, 1); -+ -+ if(!gcry_check_version(GCRYPT_VERSION)) { -+ error(0,"libgcrypt version mismatch\n"); -+ exit(VERSION_MISMATCH_ERROR); -+ } -+ -+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); -+#endif /* WITH_GCRYPT */ -+ -+ - if(read_param(argc,argv)==RETFAIL){ - error(0, _("Invalid argument\n") ); - exit(INVALID_ARGUMENT_ERROR); -@@ -646,6 +665,9 @@ int main(int argc,char**argv) - } - #endif - } -+#ifdef WITH_GCRYPT -+ gcry_control(GCRYCTL_TERM_SECMEM, 0); -+#endif /* WITH_GCRYPT */ - return RETOK; - } - const char* aide_key_3=CONFHMACKEY_03; -diff -up ./src/md.c.orig ./aide-0.16b1/src/md.c ---- ./src/md.c.orig 2016-04-15 23:30:16.000000000 +0200 -+++ ./src/md.c 2016-07-12 11:35:04.007675329 +0200 -@@ -201,14 +201,7 @@ int init_md(struct md_container* md) { - } - #endif - #ifdef WITH_GCRYPT -- error(255,"Gcrypt library initialization\n"); -- if(!gcry_check_version(GCRYPT_VERSION)) { -- error(0,"libgcrypt version mismatch\n"); -- exit(VERSION_MISMATCH_ERROR); -- } -- gcry_control(GCRYCTL_DISABLE_SECMEM, 0); -- gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); -- if(gcry_md_open(&md->mdh,0,0)!=GPG_ERR_NO_ERROR){ -+ if(gcry_md_open(&md->mdh,0,GCRY_MD_FLAG_SECURE)!=GPG_ERR_NO_ERROR){ - error(0,"gcrypt_md_open failed\n"); - exit(IO_ERROR); - } -@@ -299,7 +292,7 @@ int close_md(struct md_container* md) { - - /*. There might be more hashes in the library. Add those here.. */ - -- gcry_md_reset(md->mdh); -+ gcry_md_close(md->mdh); - #endif - - #ifdef WITH_MHASH -diff -up ./src/util.c.orig ./aide-0.16b1/src/util.c ---- ./src/util.c.orig 2016-07-12 11:39:17.023437355 +0200 -+++ ./src/util.c 2016-07-12 11:39:51.618721157 +0200 -@@ -519,28 +519,5 @@ int syslog_facility_lookup(char *s) - return(AIDE_SYSLOG_FACILITY); - } - --/* We need these dummy stubs to fool the linker into believing that -- we do not need them at link time */ -- --void* dlopen(char*filename,int flag) --{ -- return NULL; --} -- --void* dlsym(void*handle,char*symbol) --{ -- return NULL; --} -- --void* dlclose(void*handle) --{ -- return NULL; --} -- --const char* dlerror(void) --{ -- return NULL; --} -- - const char* aide_key_2=CONFHMACKEY_02; - const char* db_key_2=DBHMACKEY_02; diff --git a/SOURCES/aide-0.16rc1-man.patch b/SOURCES/aide-0.16rc1-man.patch deleted file mode 100644 index 4715552..0000000 --- a/SOURCES/aide-0.16rc1-man.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up ./doc/aide.1.in.orig ./doc/aide.1.in ---- ./doc/aide.1.in.orig 2016-07-12 16:10:01.724595895 +0200 -+++ ./doc/aide.1.in 2016-07-12 16:06:21.968639822 +0200 -@@ -103,9 +103,9 @@ echo | base64 \-d | h - .SH FILES - .IP \fB@sysconfdir@/aide.conf\fR - Default aide configuration file. --.IP \fB@sysconfdir@/aide.db\fR -+.IP \fB@localstatedir@/lib/aide/aide.db\fR - Default aide database. --.IP \fB@sysconfdir@/aide.db.new\fR -+.IP \fB@localstatedir@/lib/aide/aide.db.new\fR - Default aide output database. - .SH SEE ALSO - .BR aide.conf (5) diff --git a/SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch b/SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch new file mode 100644 index 0000000..4985991 --- /dev/null +++ b/SOURCES/aide-0.18-CVE-2025-54389-control-chars.patch @@ -0,0 +1,446 @@ +From 2122024810bc9246ec4abc3b2d87e657a4e4a499 Mon Sep 17 00:00:00 2001 +From: Darren Archibald +Date: Tue, 26 Aug 2025 05:49:31 -0700 +Subject: [PATCH] escape control chars (CVE-2025-43289) + +Signed-off-by: Darren Archibald +--- + doc/aide.1 | 13 +++++++++++ + include/util.h | 3 +++ + src/aide.c | 3 ++- + src/gen_list.c | 14 ++++++++---- + src/log.c | 26 +++++++++++++++++---- + src/report_json.c | 57 +++++++++++++++++++++++++++++++++++++++++----- + src/report_plain.c | 56 ++++++++++++++++++++++++++++++--------------- + src/util.c | 34 +++++++++++++++++++++++++++ + 8 files changed, 172 insertions(+), 34 deletions(-) + +diff --git a/doc/aide.1 b/doc/aide.1 +index c5b996b..02af050 100644 +--- a/doc/aide.1 ++++ b/doc/aide.1 +@@ -130,12 +130,25 @@ SIGUSR1 toggles the log_level between current and debug level. + .PP + .SH NOTES + ++.IP "Checksum encoding" ++ + The checksums in the database and in the output are by default base64 + encoded (see also report_base16 option). + To decode them you can use the following shell command: + + echo | base64 \-d | hexdump \-v \-e '32/1 "%02x" "\\n"' + ++.IP "Control characters" ++ ++Control characters (00-31 and 127) are always escaped in log and plain report ++output. They are escaped by a literal backslash (\\) followed by exactly 3 ++digits representing the character in octal notation (e.g. a newline is output ++as "\fB\\012\fR"). A literal backslash is not escaped unless it is followed by ++3 digits (0-9), in this case the literal backslash is escaped as ++"\fB\\134\fR". Reports in JSON format are escaped according to the JSON specs ++(e.g. a newline is output as "\fB\\b\fR" or an escape (\fBESC\fR) is output as ++"\fB\\u001b\fR") ++ + .PP + .SH FILES + +diff --git a/include/util.h b/include/util.h +index 897ac64..c22c9d6 100644 +--- a/include/util.h ++++ b/include/util.h +@@ -57,6 +57,9 @@ int cmpurl(url_t*, url_t*); + + int contains_unsafe(const char*); + ++char *strnesc(const char *, size_t); ++char *stresc(const char *); ++ + void decode_string(char*); + + char* encode_string(const char*); +diff --git a/src/aide.c b/src/aide.c +index 5de0492..77928f0 100644 +--- a/src/aide.c ++++ b/src/aide.c +@@ -285,7 +285,8 @@ static void read_param(int argc,char**argv) + if((conf->limit_crx=pcre2_compile((PCRE2_SPTR) conf->limit, PCRE2_ZERO_TERMINATED, PCRE2_UTF|PCRE2_ANCHORED, &pcre2_errorcode, &pcre2_erroffset, NULL)) == NULL) { + PCRE2_UCHAR pcre2_error[128]; + pcre2_get_error_message(pcre2_errorcode, pcre2_error, 128); +- INVALID_ARGUMENT("--limit", error in regular expression '%s' at %zu: %s, conf->limit, pcre2_erroffset, pcre2_error) ++ char * limit_safe = stresc(conf->limit); ++ INVALID_ARGUMENT("--limit", error in regular expression '%s' at %zu: %s, limit_safe, pcre2_erroffset, pcre2_error) + + } + conf->limit_md = pcre2_match_data_create_from_pattern(conf->limit_crx, NULL); +diff --git a/src/gen_list.c b/src/gen_list.c +index e1633d3..b34867e 100644 +--- a/src/gen_list.c ++++ b/src/gen_list.c +@@ -339,35 +339,39 @@ void print_match(char* filename, rx_rule *rule, match_result match, RESTRICTION_ + char * str; + char* attr_str; + char file_type = get_restriction_char(restriction); ++ char *filename_safe = stresc(filename); + switch (match) { + case RESULT_SELECTIVE_MATCH: + str = get_restriction_string(rule->restriction); + attr_str = diff_attributes(0, rule->attr); +- fprintf(stdout, "[X] %c '%s': selective rule: '%s %s %s' (%s:%d: '%s%s%s')\n", file_type, filename, rule->rx, str, attr_str, rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); ++ fprintf(stdout, "[X] %c '%s': selective rule: '%s %s %s' (%s:%d: '%s%s%s')\n", file_type, filename_safe, rule->rx, str, attr_str, rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); + free(attr_str); + free(str); + break; + case RESULT_EQUAL_MATCH: + str = get_restriction_string(rule->restriction); + attr_str = diff_attributes(0, rule->attr); +- fprintf(stdout, "[X] %c '%s': equal rule: '=%s %s %s' (%s:%d: '%s%s%s')\n", file_type, filename, rule->rx, str, attr_str, rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); ++ fprintf(stdout, "[X] %c '%s': equal rule: '=%s %s %s' (%s:%d: '%s%s%s')\n", file_type, filename_safe, rule->rx, str, attr_str, rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); + free(attr_str); + free(str); + break; + case RESULT_PARTIAL_MATCH: + case RESULT_NO_MATCH: + if (rule) { +- fprintf(stdout, "[ ] %c '%s': negative rule: '!%s %s' (%s:%d: '%s%s%s')\n", file_type, filename, rule->rx, str = get_restriction_string(rule->restriction), rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); ++ fprintf(stdout, "[ ] %c '%s': negative rule: '!%s %s' (%s:%d: '%s%s%s')\n", file_type, filename_safe, rule->rx, str = get_restriction_string(rule->restriction), rule->config_filename, rule->config_linenumber, rule->config_line, rule->prefix?"', prefix: '":"", rule->prefix?rule->prefix:""); + free(str); + } else { +- fprintf(stdout, "[ ] %c '%s': no matching rule\n", file_type, filename); ++ fprintf(stdout, "[ ] %c '%s': no matching rule\n", file_type, filename_safe); + } + break; + case RESULT_PARTIAL_LIMIT_MATCH: + case RESULT_NO_LIMIT_MATCH: +- fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", file_type, filename, conf->limit); ++ str = stresc(conf->limit); ++ fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", file_type, filename_safe, str); ++ free(str); + break; + } ++ free(filename_safe); + } + + /* +diff --git a/src/log.c b/src/log.c +index 3f741a6..ce5417c 100644 +--- a/src/log.c ++++ b/src/log.c +@@ -30,6 +30,7 @@ + + #include "log.h" + #include "errorcodes.h" ++#include "util.h" + + LOG_LEVEL prev_log_level = LOG_LEVEL_UNSET; + LOG_LEVEL log_level = LOG_LEVEL_UNSET; +@@ -118,7 +119,9 @@ static void log_cached_lines(void) { + for(int i = 0; i < ncachedlines; ++i) { + LOG_LEVEL level = cached_lines[i].level; + if (level == LOG_LEVEL_ERROR || level <= log_level) { +- fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, cached_lines[i].message); ++ char * msg_safe = stresc(cached_lines[i].message); ++ fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, msg_safe); ++ free(msg_safe); + } + free(cached_lines[i].message); + } +@@ -135,9 +138,24 @@ static void vlog_msg(LOG_LEVEL level,const char* format, va_list ap) { + FILE* url = stderr; + + if (level == LOG_LEVEL_ERROR || level <= log_level) { +- fprintf(url, "%s: ", log_level_array[level-1].log_string ); +- vfprintf(url, format, ap); +- fprintf(url, "\n"); ++ ++ va_list aq; ++ va_copy(aq, ap); ++ size_t n = vsnprintf(NULL, 0, format, aq) + 1; ++ va_end(aq); ++ ++ int size = n * sizeof(char); ++ char *msg_unsafe = malloc(size); ++ if (msg_unsafe == NULL) { ++ fprintf(stderr, "%s: malloc: failed to allocate %d bytes of memory\n", log_level_array[LOG_LEVEL_ERROR-1].log_string, size); ++ exit(MEMORY_ALLOCATION_FAILURE); ++ } ++ ++ vsnprintf(msg_unsafe, n, format, ap); ++ char *msg_safe = stresc(msg_unsafe); ++ free(msg_unsafe); ++ fprintf(url, "%s: %s\n", log_level_array[level-1].log_string, msg_safe); ++ free(msg_safe); + } else if (log_level == LOG_LEVEL_UNSET) { + cache_line(level, format, ap); + } +diff --git a/src/report_json.c b/src/report_json.c +index 2fc77bc..47e7fe7 100644 +--- a/src/report_json.c ++++ b/src/report_json.c +@@ -29,6 +29,8 @@ + #include "report.h" + #include "seltree_struct.h" + #include "stdbool.h" ++#include "string.h" ++#include "stdio.h" + #include "url.h" + + #define JSON_FMT_ARRAY_BEGIN "%*c\"%s\": [\n" +@@ -57,12 +59,53 @@ static int _escape_json_string(const char *src, char *escaped_string) { + int n = 0; + + for (i = 0; i < strlen(src); ++i) { +- if (src[i] == '\\') { +- if (escaped_string) { escaped_string[n] = '\\'; } +- n++; ++ switch(src[i]) { ++ case '\n': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = 'n'; } ++ n++; ++ break; ++ case '\t': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = 't'; } ++ n++; ++ break; ++ case '\b': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = 'b'; } ++ n++; ++ break; ++ case '\f': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = 'f'; } ++ n++; ++ break; ++ case '\r': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = 'r'; } ++ n++; ++ break; ++ case '"': ++ case '\\': ++ if (escaped_string) { escaped_string[n] = '\\'; } ++ n++; ++ if (escaped_string) { escaped_string[n] = src[i]; } ++ n++; ++ break; ++ default: ++ if (src[i] >= 0 && (src[i] < 0x1f || src[i] == 0x7f)) { ++ if (escaped_string) { snprintf(&escaped_string[n], 7, "\\u%04d", src[i]); } ++ n += 6; ++ } else { ++ if (escaped_string) { escaped_string[n] = src[i]; } ++ n++; ++ } + } +- if (escaped_string) { escaped_string[n] = src[i]; } +- n++; + } + if (escaped_string) { escaped_string[n] = '\0'; } + n++; +@@ -302,9 +345,11 @@ static void print_report_diff_attrs_entries_json(report_t *report) { + report_printf(report, JSON_FMT_OBJECT_BEGIN, 2, ' ', "different_attributes"); + for(int i = 0; i < report->num_diff_attrs_entries; ++i) { + char *str = NULL; ++ char *escaped_filename = _get_escaped_json_string(report->diff_attrs_entries[i].entry); + report_printf(report, i+1num_diff_attrs_entries?JSON_FMT_STRING_COMMA:JSON_FMT_STRING_LAST , 4, ' ', +- report->diff_attrs_entries[i].entry, ++ escaped_filename, + str= diff_attributes(report->diff_attrs_entries[i].old_attrs, report->diff_attrs_entries[i].new_attrs)); ++ free(escaped_filename); + free(str); + } + report->num_diff_attrs_entries = 0; +diff --git a/src/report_plain.c b/src/report_plain.c +index c87fc72..7d8a746 100644 +--- a/src/report_plain.c ++++ b/src/report_plain.c +@@ -55,7 +55,9 @@ static char* _get_not_grouped_list_string(report_t *report) { + static void _print_config_option(report_t *report, config_option option, const char* value) { + if (first) { first=false; } + else { report_printf(report," | "); } +- report_printf(report, "%s: %s", config_options[option].report_string, value); ++ char *value_safe = stresc(value); ++ report_printf(report, "%s: %s", config_options[option].report_string, value_safe); ++ free(value_safe); + } + + static void _print_report_option(report_t *report, config_option option, const char* value) { +@@ -63,37 +65,49 @@ static void _print_report_option(report_t *report, config_option option, const c + } + + static void _print_attribute(report_t *report, db_line* oline, db_line* nline, ATTRIBUTE attribute) { +- char **ovalue = NULL; +- char **nvalue = NULL; ++ char **ovalues = NULL; ++ char **nvalues = NULL; + int onumber, nnumber, i, c; + int p = (width_details-(4 + MAX_WIDTH_DETAILS_STRING))/2; + + DB_ATTR_TYPE attr = ATTR(attribute); + const char* name = attributes[attribute].details_string; + +- onumber=get_attribute_values(attr, oline, &ovalue, report); +- nnumber=get_attribute_values(attr, nline, &nvalue, report); ++ onumber=get_attribute_values(attr, oline, &ovalues, report); ++ nnumber=get_attribute_values(attr, nline, &nvalues, report); + + i = 0; + while (i= 0 || nlen-p*k >= 0) { + c = k*(p-1); + if (!onumber) { +- report_printf(report," %-*s%c %-*c %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p, ' ', p-1, nlen-c>0?&nvalue[i][c]:""); ++ report_printf(report," %-*s%c %-*c %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p, ' ', p-1, nlen-c>0?&nvalue[c]:""); + } else if (!nnumber) { +- report_printf(report," %-*s%c %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p-1, olen-c>0?&ovalue[i][c]:""); ++ report_printf(report," %-*s%c %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p-1, olen-c>0?&ovalue[c]:""); + } else { +- report_printf(report," %-*s%c %-*.*s| %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p, p-1, olen-c>0?&ovalue[i][c]:"", p-1, nlen-c>0?&nvalue[i][c]:""); ++ report_printf(report," %-*s%c %-*.*s| %.*s\n", MAX_WIDTH_DETAILS_STRING, (i+k)?"":name, (i+k)?' ':':', p, p-1, olen-c>0?&ovalue[c]:"", p-1, nlen-c>0?&nvalue[c]:""); + } + k++; + } + ++i; ++ free(ovalue); ++ free(nvalue); + } +- for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL; +- for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL; ++ for(i=0; i < onumber; ++i) { free(ovalues[i]); ovalues[i]=NULL; } free(ovalues); ovalues=NULL; ++ for(i=0; i < nnumber; ++i) { free(nvalues[i]); nvalues[i]=NULL; } free(nvalues); nvalues=NULL; + } + + static void _print_database_attributes(report_t *report, db_line* db) { +@@ -136,19 +150,21 @@ static void print_report_summary_plain(report_t *report) { + } + + static void print_line_plain(report_t* report, seltree* node) { ++ char *filename_safe = stresc(((node->checked&NODE_REMOVED)?node->old_data:node->new_data)->filename); + if(report->summarize_changes) { + char* summary = get_summarize_changes_string(report, node); +- report_printf(report, "\n%s: %s", summary, ((node->checked&NODE_REMOVED)?node->old_data:node->new_data)->filename); ++ report_printf(report, "\n%s: %s", summary, filename_safe); + free(summary); summary=NULL; + } else { + if (node->checked&NODE_ADDED) { +- report_printf(report, _("\nadded: %s"),(node->new_data)->filename); ++ report_printf(report, _("\nadded: %s"),filename_safe); + } else if (node->checked&NODE_REMOVED) { +- report_printf(report, _("\nremoved: %s"),(node->old_data)->filename); ++ report_printf(report, _("\nremoved: %s"),filename_safe); + } else if (node->checked&NODE_CHANGED) { +- report_printf(report, _("\nchanged: %s"),(node->new_data)->filename); ++ report_printf(report, _("\nchanged: %s"),filename_safe); + } + } ++ free(filename_safe); + } + + static void print_report_dbline_attributes_plain(report_t *report, db_line* oline, db_line* nline, DB_ATTR_TYPE report_attrs) { +@@ -158,7 +174,9 @@ static void print_report_dbline_attributes_plain(report_t *report, db_line* olin + if (file_type) { + report_printf(report, "%s: ", file_type); + } +- report_printf(report, "%s\n", (nline==NULL?oline:nline)->filename); ++ char *filename_safe = stresc((nline==NULL?oline:nline)->filename); ++ report_printf(report, "%s\n", filename_safe); ++ free(filename_safe); + + print_dbline_attrs(report, oline, nline, report_attrs, _print_attribute); + } +@@ -195,9 +213,11 @@ static void print_report_details_plain(report_t *report, seltree* node) { + static void print_report_diff_attrs_entries_plain(report_t *report) { + for(int i = 0; i < report->num_diff_attrs_entries; ++i) { + char *str = NULL; ++ char *entry_safe = stresc(report->diff_attrs_entries[i].entry); + report_printf(report, "Entry %s in databases has different attributes: %s\n", +- report->diff_attrs_entries[i].entry, ++ entry_safe, + str= diff_attributes(report->diff_attrs_entries[i].old_attrs, report->diff_attrs_entries[i].new_attrs)); ++ free(entry_safe); + free(str); + } + report->num_diff_attrs_entries = 0; +diff --git a/src/util.c b/src/util.c +index 87f6801..f5c5e60 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -105,6 +105,40 @@ int cmpurl(url_t* u1,url_t* u2) + return RETOK; + } + ++static size_t escape_str(const char *unescaped_str, char *str, size_t s) { ++ size_t n = 0; ++ size_t i = 0; ++ char c; ++ while (i < s && (c = unescaped_str[i])) { ++ if ((c >= 0 && (c < 0x1f || c == 0x7f)) || ++ (c == '\\' && isdigit(unescaped_str[i+1]) ++ && isdigit(unescaped_str[i+2]) ++ && isdigit(unescaped_str[i+3]) ++ ) ) { ++ if (str) { snprintf(&str[n], 5, "\\%03o", c); } ++ n += 4; ++ } else { ++ if (str) { str[n] = c; } ++ n++; ++ } ++ i++; ++ } ++ if (str) { str[n] = '\0'; } ++ n++; ++ return n; ++} ++ ++char *strnesc(const char *unescaped_str, size_t s) { ++ int n = escape_str(unescaped_str, NULL, s); ++ char *str = checked_malloc(n); ++ escape_str(unescaped_str, str, s); ++ return str; ++} ++ ++char *stresc(const char *unescaped_str) { ++ return strnesc(unescaped_str, strlen(unescaped_str)); ++} ++ + /* Returns 1 if the string contains unsafe characters, 0 otherwise. */ + int contains_unsafe (const char *s) + { +diff --git a/ChangeLog b/ChangeLog +index 69a6fd5..1ed4754 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2025-08-07 Hannes von Haugwitz ++ * Escape control characters in report and log output (CVE-2025-54389), ++ thanks to Rajesh Pangare for reporting this issue ++ + 2023-08-01 Hannes von Haugwitz + * Release aide 0.18.6 + +-- +2.31.1 + diff --git a/SOURCES/aide-verbose.patch b/SOURCES/aide-verbose.patch new file mode 100644 index 0000000..d95bb14 --- /dev/null +++ b/SOURCES/aide-verbose.patch @@ -0,0 +1,34 @@ +diff -up ./src/conf_eval.c.verbose ./src/conf_eval.c +--- ./src/conf_eval.c.verbose 2023-04-01 18:25:38.000000000 +0200 ++++ ./src/conf_eval.c 2024-05-15 00:08:41.040033220 +0200 +@@ -187,6 +187,7 @@ static void set_database_attr_option(DB_ + static void eval_config_statement(config_option_statement statement, int linenumber, char *filename, char* linebuf) { + char *str; + bool b; ++ long num; + DB_ATTR_TYPE attr; + switch (statement.option) { + ATTRIBUTE_CONFIG_OPTION_CASE(REPORT_IGNORE_ADDED_ATTRS_OPTION, report_ignore_added_attrs) +@@ -298,8 +299,20 @@ static void eval_config_statement(config + LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "set 'config_version' option to '%s'", str) + break; + case VERBOSE_OPTION: +- log_msg(LOG_LEVEL_ERROR, "%s:%d: 'verbose' option is no longer supported, use 'log_level' and 'report_level' options instead (see man aide.conf for details) (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); +- exit(INVALID_CONFIGURELINE_ERROR); ++ log_msg(LOG_LEVEL_CONFIG, "%s:%d: 'verbose' option is deprecated, use 'log_level' and 'report_level' options instead (see man aide.conf for details) (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); ++ str = eval_string_expression(statement.e, linenumber, filename, linebuf); ++ num = strtol(str, NULL, 10); ++ ++ if (num < 0 || num > 255) { ++ LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "invalid verbose level: '%s'", str); ++ exit(INVALID_CONFIGURELINE_ERROR); ++ } ++ ++ if (num >= 10) { ++ set_log_level(LOG_LEVEL_DEBUG); ++ } ++ ++ free(str); + break; + case LIMIT_CMDLINE_OPTION: + /* command-line options are ignored here */ diff --git a/SOURCES/aide.conf b/SOURCES/aide.conf index b934dc3..6818526 100644 --- a/SOURCES/aide.conf +++ b/SOURCES/aide.conf @@ -4,7 +4,7 @@ @@define LOGDIR /var/log/aide # The location of the database to be read. -database=file:@@{DBDIR}/aide.db.gz +database_in=file:@@{DBDIR}/aide.db.gz # The location of the database to be written. #database_out=sql:host:port:database:login_name:passwd:table @@ -15,7 +15,8 @@ database_out=file:@@{DBDIR}/aide.db.new.gz gzip_dbout=yes # Default. -verbose=5 +log_level=warning +report_level=changed_attributes report_url=file:@@{LOGDIR}/aide.log report_url=stdout @@ -51,6 +52,8 @@ report_url=stdout #crc32: crc32 checksum (MHASH only) #whirlpool: whirlpool checksum (MHASH only) +FIPSR = p+i+n+u+g+s+acl+selinux+xattrs+sha256 + #R: p+i+n+u+g+s+m+c+acl+selinux+xattrs+md5 #L: p+i+n+u+g+acl+selinux+xattrs #E: Empty group @@ -63,245 +66,150 @@ ALLXTRAHASHES = sha1+rmd160+sha256+sha512+tiger # Everything but access time (Ie. all changes) EVERYTHING = R+ALLXTRAHASHES -# Sane -# NORMAL = R+sha512 -NORMAL = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha512 +# Sane, with multiple hashes +# NORMAL = R+rmd160+sha256+whirlpool +NORMAL = FIPSR+sha512 # For directories, don't bother doing hashes DIR = p+i+n+u+g+acl+selinux+xattrs # Access control only -PERMS = p+u+g+acl+selinux+xattrs +PERMS = p+i+u+g+acl+selinux # Logfile are special, in that they often change -LOG = p+u+g+n+S+acl+selinux+xattrs +LOG = > -# Content + file type. -CONTENT = sha512+ftype - -# Extended content + file type + access. -CONTENT_EX = sha512+ftype+p+u+g+n+acl+selinux+xattrs +# Just do sha256 and sha512 hashes +LSPP = FIPSR+sha512 # Some files get updated automatically, so the inode/ctime/mtime change # but we want to know when the data inside them changes -DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha512 +DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha256 # Next decide what directories/files you want in the database. -/boot CONTENT_EX -/opt CONTENT - -# Admins dot files constantly change, just check perms -/root/\..* PERMS -# Otherwise get all of /root. -/root CONTENT_EX - +/boot NORMAL +/bin NORMAL +/sbin NORMAL +/lib NORMAL +/lib64 NORMAL +/opt NORMAL +/usr NORMAL +/root NORMAL # These are too volatile !/usr/src !/usr/tmp -# Otherwise get all of /usr. -/usr CONTENT_EX +# Check only permissions, inode, user and group for /etc, but +# cover some important files closely. +/etc PERMS +!/etc/mtab +# Ignore backup files +!/etc/.*~ +/etc/exports NORMAL +/etc/fstab NORMAL +/etc/passwd NORMAL +/etc/group NORMAL +/etc/gshadow NORMAL +/etc/shadow NORMAL +/etc/security/opasswd NORMAL -# trusted databases -/etc/hosts$ CONTENT_EX -/etc/host.conf$ CONTENT_EX -/etc/hostname$ CONTENT_EX -/etc/issue$ CONTENT_EX -/etc/issue.net$ CONTENT_EX -/etc/protocols$ CONTENT_EX -/etc/services$ CONTENT_EX -/etc/localtime$ CONTENT_EX -/etc/alternatives CONTENT_EX -/etc/sysconfig CONTENT_EX -/etc/mime.types$ CONTENT_EX -/etc/terminfo CONTENT_EX -/etc/exports$ CONTENT_EX -/etc/fstab$ CONTENT_EX -/etc/passwd$ CONTENT_EX -/etc/group$ CONTENT_EX -/etc/gshadow$ CONTENT_EX -/etc/shadow$ CONTENT_EX -/etc/subgid$ CONTENT_EX -/etc/subuid$ CONTENT_EX -/etc/security/opasswd$ CONTENT_EX -/etc/skel CONTENT_EX -/etc/subuid$ CONTENT_EX -/etc/subgid$ CONTENT_EX -/etc/sssd CONTENT_EX -/etc/machine-id$ CONTENT_EX -/etc/swid CONTENT_EX -/etc/system-release-cpe$ CONTENT_EX -/etc/shells$ CONTENT_EX -/etc/tmux.conf$ CONTENT_EX -/etc/xattr.conf$ CONTENT_EX +/etc/hosts.allow NORMAL +/etc/hosts.deny NORMAL +/etc/sudoers NORMAL +/etc/skel NORMAL -# networking -/etc/hosts.allow$ CONTENT_EX -/etc/hosts.deny$ CONTENT_EX -/etc/firewalld CONTENT_EX -!/etc/NetworkManager/system-connections -/etc/NetworkManager CONTENT_EX -/etc/networks$ CONTENT_EX -/etc/dhcp CONTENT_EX -/etc/wpa_supplicant CONTENT_EX -/etc/resolv.conf$ DATAONLY -/etc/nscd.conf$ CONTENT_EX +/etc/logrotate.d NORMAL -# logins and accounts -/etc/login.defs$ CONTENT_EX -/etc/libuser.conf$ CONTENT_EX -/var/log/faillog$ PERMS -/var/log/lastlog$ PERMS -/var/run/faillock PERMS -/etc/pam.d CONTENT_EX -/etc/security CONTENT_EX -/etc/securetty$ CONTENT_EX -/etc/polkit-1 CONTENT_EX -/etc/sudo.conf$ CONTENT_EX -/etc/sudoers$ CONTENT_EX -/etc/sudoers.d CONTENT_EX +/etc/resolv.conf DATAONLY -# Shell/X startup files -/etc/profile$ CONTENT_EX -/etc/profile.d CONTENT_EX -/etc/bashrc$ CONTENT_EX -/etc/bash_completion.d CONTENT_EX -/etc/zprofile$ CONTENT_EX -/etc/zshrc$ CONTENT_EX -/etc/zlogin$ CONTENT_EX -/etc/zlogout$ CONTENT_EX -/etc/X11 CONTENT_EX +/etc/nscd.conf NORMAL +/etc/securetty NORMAL + +# Shell/X starting files +/etc/profile NORMAL +/etc/bashrc NORMAL +/etc/bash_completion.d/ NORMAL +/etc/login.defs NORMAL +/etc/zprofile NORMAL +/etc/zshrc NORMAL +/etc/zlogin NORMAL +/etc/zlogout NORMAL +/etc/profile.d/ NORMAL +/etc/X11/ NORMAL # Pkg manager -/etc/dnf CONTENT_EX -/etc/yum.conf$ CONTENT_EX -/etc/yum CONTENT_EX -/etc/yum.repos.d CONTENT_EX +/etc/yum.conf NORMAL +/etc/yumex.conf NORMAL +/etc/yumex.profiles.conf NORMAL +/etc/yum/ NORMAL +/etc/yum.repos.d/ NORMAL + +/var/log LOG +/var/run/utmp LOG # This gets new/removes-old filenames daily !/var/log/sa # As we are checking it, we've truncated yesterdays size to zero. !/var/log/aide.log -# auditing +# LSPP rules... # AIDE produces an audit record, so this becomes perpetual motion. -/var/log/audit PERMS -/etc/audit CONTENT_EX -/etc/libaudit.conf$ CONTENT_EX -/etc/aide.conf$ CONTENT_EX +# /var/log/audit/ LSPP +/etc/audit/ LSPP +/etc/libaudit.conf LSPP +/usr/sbin/stunnel LSPP +/var/spool/at LSPP +/etc/at.allow LSPP +/etc/at.deny LSPP +/etc/cron.allow LSPP +/etc/cron.deny LSPP +/etc/cron.d/ LSPP +/etc/cron.daily/ LSPP +/etc/cron.hourly/ LSPP +/etc/cron.monthly/ LSPP +/etc/cron.weekly/ LSPP +/etc/crontab LSPP +/var/spool/cron/root LSPP -# System logs -/etc/rsyslog.conf$ CONTENT_EX -/etc/rsyslog.d CONTENT_EX -/etc/logrotate.conf$ CONTENT_EX -/etc/logrotate.d CONTENT_EX -/etc/systemd/journald.conf$ CONTENT_EX -/var/log LOG+ANF+ARF -/var/run/utmp LOG +/etc/login.defs LSPP +/etc/securetty LSPP +/var/log/faillog LSPP +/var/log/lastlog LSPP -# secrets -/etc/pkcs11 CONTENT_EX -/etc/pki CONTENT_EX -/etc/crypto-policies CONTENT_EX -/etc/certmonger CONTENT_EX -/var/lib/systemd/random-seed$ PERMS +/etc/hosts LSPP +/etc/sysconfig LSPP -# init system -/etc/systemd CONTENT_EX -/etc/rc.d CONTENT_EX -/etc/tmpfiles.d CONTENT_EX +/etc/inittab LSPP +/etc/grub/ LSPP +/etc/rc.d LSPP -# boot config -/etc/default CONTENT_EX -/etc/grub.d CONTENT_EX -/etc/dracut.conf$ CONTENT_EX -/etc/dracut.conf.d CONTENT_EX +/etc/ld.so.conf LSPP -# glibc linker -/etc/ld.so.cache$ CONTENT_EX -/etc/ld.so.conf$ CONTENT_EX -/etc/ld.so.conf.d CONTENT_EX -/etc/ld.so.preload$ CONTENT_EX +/etc/localtime LSPP -# kernel config -/etc/sysctl.conf$ CONTENT_EX -/etc/sysctl.d CONTENT_EX -/etc/modprobe.d CONTENT_EX -/etc/modules-load.d CONTENT_EX -/etc/depmod.d CONTENT_EX -/etc/udev CONTENT_EX -/etc/crypttab$ CONTENT_EX +/etc/sysctl.conf LSPP -#### Daemons #### +/etc/modprobe.conf LSPP -# cron jobs -/var/spool/at CONTENT -/etc/at.allow$ CONTENT -/etc/at.deny$ CONTENT -/var/spool/anacron CONTENT -/etc/anacrontab$ CONTENT_EX -/etc/cron.allow$ CONTENT_EX -/etc/cron.deny$ CONTENT_EX -/etc/cron.d CONTENT_EX -/etc/cron.daily CONTENT_EX -/etc/cron.hourly CONTENT_EX -/etc/cron.monthly CONTENT_EX -/etc/cron.weekly CONTENT_EX -/etc/crontab$ CONTENT_EX -/var/spool/cron/root CONTENT +/etc/pam.d LSPP +/etc/security LSPP +/etc/aliases LSPP +/etc/postfix LSPP -# time keeping -/etc/chrony.conf$ CONTENT_EX -/etc/chrony.keys$ CONTENT_EX +/etc/ssh/sshd_config LSPP +/etc/ssh/ssh_config LSPP -# mail -/etc/aliases$ CONTENT_EX -/etc/aliases.db$ CONTENT_EX -/etc/postfix CONTENT_EX +/etc/stunnel LSPP -# ssh -/etc/ssh/sshd_config$ CONTENT_EX -/etc/ssh/ssh_config$ CONTENT_EX +/etc/vsftpd.ftpusers LSPP +/etc/vsftpd LSPP -# stunnel -/etc/stunnel CONTENT_EX - -# printing -/etc/cups CONTENT_EX -/etc/cupshelpers CONTENT_EX -/etc/avahi CONTENT_EX - -# web server -/etc/httpd CONTENT_EX - -# dns -/etc/named CONTENT_EX -/etc/named.conf$ CONTENT_EX -/etc/named.iscdlv.key$ CONTENT_EX -/etc/named.rfc1912.zones$ CONTENT_EX -/etc/named.root.key$ CONTENT_EX - -# xinetd -/etc/xinetd.conf$ CONTENT_EX -/etc/xinetd.d CONTENT_EX - -# IPsec -/etc/ipsec.conf$ CONTENT_EX -/etc/ipsec.secrets$ CONTENT_EX -/etc/ipsec.d CONTENT_EX - -# USB guard -/etc/usbguard CONTENT_EX - -# Ignore some files -!/etc/mtab$ -!/etc/.*~ - -# Now everything else -/etc PERMS +/etc/issue LSPP +/etc/issue.net LSPP +/etc/cups LSPP # With AIDE's default verbosity level of 5, these would give lots of # warnings upon tree traversal. It might change with future version. @@ -310,8 +218,8 @@ DATAONLY = p+n+u+g+s+acl+selinux+xattrs+sha512 #=/home DIR # Ditto /var/log/sa reason... +!/boot/grub2/grubenv !/var/log/and-httpd # Admins dot files constantly change, just check perms /root/\..* PERMS -!/root/.xauth* diff --git a/SOURCES/coverity.patch b/SOURCES/coverity.patch deleted file mode 100644 index 9b981be..0000000 --- a/SOURCES/coverity.patch +++ /dev/null @@ -1,642 +0,0 @@ -diff -up ./include/be.h.coverity ./include/be.h ---- ./include/be.h.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./include/be.h 2018-10-10 19:27:18.680632681 +0200 -@@ -22,6 +22,6 @@ - #define _BE_H_INCLUDED - #include "db_config.h" - --FILE* be_init(int inout,url_t* u,int iszipped); -+void* be_init(int inout,url_t* u,int iszipped); - - #endif /* _BE_H_INCLUDED */ -diff -up ./include/db_config.h.coverity ./include/db_config.h ---- ./include/db_config.h.coverity 2018-10-10 19:27:18.672632611 +0200 -+++ ./include/db_config.h 2018-10-10 19:27:18.681632689 +0200 -@@ -376,7 +376,7 @@ typedef struct db_config { - #endif - - url_t* initial_report_url; -- FILE* initial_report_fd; -+ void* initial_report_fd; - - /* report_url is a list of url_t*s */ - list* report_url; -diff -up ./src/aide.c.coverity ./src/aide.c ---- ./src/aide.c.coverity 2018-10-10 19:27:18.678632663 +0200 -+++ ./src/aide.c 2018-10-10 19:27:18.681632689 +0200 -@@ -278,7 +278,7 @@ static void setdefaults_before_config() - error(0,_("Couldn't get hostname")); - free(s); - } else { -- s=(char*)realloc((void*)s,strlen(s)+1); -+ // s=(char*)realloc((void*)s,strlen(s)+1); - do_define("HOSTNAME",s); - } - -@@ -506,8 +506,6 @@ static void setdefaults_after_config() - int main(int argc,char**argv) - { - int errorno=0; -- byte* dig=NULL; -- char* digstr=NULL; - - #ifdef USE_LOCALE - setlocale(LC_ALL,""); -@@ -544,6 +542,10 @@ int main(int argc,char**argv) - } - - errorno=commandconf('C',conf->config_file); -+ if (errorno==RETFAIL){ -+ error(0,_("Configuration error\n")); -+ exit(INVALID_CONFIGURELINE_ERROR); -+ } - - errorno=commandconf('D',""); - if (errorno==RETFAIL){ -@@ -594,6 +596,9 @@ int main(int argc,char**argv) - } - } - #ifdef WITH_MHASH -+ byte* dig=NULL; -+ char* digstr=NULL; -+ - if(conf->config_check&&FORCECONFIGMD){ - error(0,"Can't give config checksum when compiled with --enable-forced_configmd\n"); - exit(INVALID_ARGUMENT_ERROR); -diff -up ./src/base64.c.coverity ./src/base64.c ---- ./src/base64.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/base64.c 2018-10-10 19:27:18.681632689 +0200 -@@ -209,6 +209,7 @@ byte* decode_base64(char* src,size_t ssi - case FAIL: - error(3, "decode_base64: Illegal character: %c\n", *inb); - error(230, "decode_base64: Illegal line:\n%s\n", src); -+ free(outbuf); - return NULL; - break; - case SKIP: -@@ -260,7 +261,7 @@ size_t length_base64(char* src,size_t ss - int l; - int left; - size_t pos; -- unsigned long triple; -+ //unsigned long triple; - - error(235, "decode base64\n"); - /* Exit on empty input */ -@@ -273,7 +274,7 @@ size_t length_base64(char* src,size_t ss - inb = src; - - l = 0; -- triple = 0; -+ //triple = 0; - pos=0; - left = ssize; - /* -@@ -293,7 +294,7 @@ size_t length_base64(char* src,size_t ss - case SKIP: - break; - default: -- triple = triple<<6 | (0x3f & i); -+ //triple = triple<<6 | (0x3f & i); - l++; - break; - } -@@ -302,10 +303,10 @@ size_t length_base64(char* src,size_t ss - switch(l) - { - case 2: -- triple = triple>>4; -+ //triple = triple>>4; - break; - case 3: -- triple = triple>>2; -+ //triple = triple>>2; - break; - default: - break; -@@ -314,7 +315,7 @@ size_t length_base64(char* src,size_t ss - { - pos++; - } -- triple = 0; -+ //triple = 0; - l = 0; - } - inb++; -diff -up ./src/be.c.coverity ./src/be.c ---- ./src/be.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/be.c 2018-10-10 19:27:18.681632689 +0200 -@@ -117,9 +117,9 @@ static char* get_first_value(char** in){ - - #endif - --FILE* be_init(int inout,url_t* u,int iszipped) -+void* be_init(int inout,url_t* u,int iszipped) - { -- FILE* fh=NULL; -+ void* fh=NULL; - long a=0; - char* err=NULL; - int fd; -diff -up ./src/commandconf.c.coverity ./src/commandconf.c ---- ./src/commandconf.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/commandconf.c 2018-10-10 19:27:18.682632698 +0200 -@@ -106,7 +106,7 @@ int commandconf(const char mode,const ch - rv=0; - } else { - -- rv=access(config,R_OK); -+ if (config != NULL) rv=access(config,R_OK); - if(rv==-1){ - error(0,_("Cannot access config file: %s: %s\n"),config,strerror(errno)); - } -@@ -166,14 +166,11 @@ int commandconf(const char mode,const ch - int conf_input_wrapper(char* buf, int max_size, FILE* in) - { - int retval=0; -- int c=0; -- char* tmp=NULL; -- void* key=NULL; -- int keylen=0; - - /* FIXME Add support for gzipped config. :) */ - #ifdef WITH_MHASH - /* Read a character at a time until we are doing md */ -+ int c=0; - if(conf->do_configmd){ - retval=fread(buf,1,max_size,in); - }else { -@@ -185,6 +182,9 @@ int conf_input_wrapper(char* buf, int ma - #endif - - #ifdef WITH_MHASH -+ char* tmp=NULL; -+ void* key=NULL; -+ int keylen=0; - if(conf->do_configmd||conf->config_check){ - if(((conf->do_configmd==1)&&conf->config_check)||!conf->confmd){ - if(conf->do_configmd==1){ -@@ -276,6 +276,9 @@ int db_input_wrapper(char* buf, int max_ - #endif - break; - } -+ default: { -+ return 0; -+ } - } - - #ifdef WITH_CURL -@@ -651,7 +654,6 @@ int handle_endif(int doit,int allow_else - case 0 : { - conferror("@@endif or @@else expected"); - return -1; -- count=0; - } - - default : { -@@ -816,6 +818,7 @@ void do_dbdef(int dbtype,char* val) - if(u==NULL||u->type==url_unknown||u->type==url_stdout - ||u->type==url_stderr) { - error(0,_("Unsupported input URL-type:%s\n"),val); -+ free(u); - } - else { - *conf_db_url=u; -@@ -825,6 +828,7 @@ void do_dbdef(int dbtype,char* val) - case DB_WRITE: { - if(u==NULL||u->type==url_unknown||u->type==url_stdin){ - error(0,_("Unsupported output URL-type:%s\n"),val); -+ free(u); - } - else{ - conf->db_out_url=u; -@@ -848,6 +852,7 @@ void do_dbindef(char* val) - if(u==NULL||u->type==url_unknown||u->type==url_stdout - ||u->type==url_stderr) { - error(0,_("Unsupported input URL-type:%s\n"),val); -+ free(u); - } - else { - conf->db_in_url=u; -@@ -869,6 +874,7 @@ void do_dboutdef(char* val) - * both input and output urls */ - if(u==NULL||u->type==url_unknown||u->type==url_stdin){ - error(0,_("Unsupported output URL-type:%s\n"),val); -+ free(u); - } - else{ - conf->db_out_url=u; -@@ -894,7 +900,8 @@ void do_repurldef(char* val) - } else { - error_init(u,0); - } -- -+ -+ free(u); - } - - void do_verbdef(char* val) -@@ -984,7 +991,7 @@ void do_report_ignore_e2fsattrs(char* va - break; - } - } -- *val++; -+ val++; - } - } - #endif -diff -up ./src/compare_db.c.coverity ./src/compare_db.c ---- ./src/compare_db.c.coverity 2018-10-10 19:27:18.673632619 +0200 -+++ ./src/compare_db.c 2018-10-10 19:27:18.682632698 +0200 -@@ -312,7 +312,7 @@ static int acl2array(acl_type* acl, char - if (conf->syslog_format) { - *values = malloc(2 * sizeof(char*)); - -- char *A, *D = ""; -+ char *A= "", *D = ""; - - if (acl->acl_a) { A = acl->acl_a; } - if (acl->acl_d) { D = acl->acl_d; } -diff -up ./src/conf_lex.l.coverity ./src/conf_lex.l ---- ./src/conf_lex.l.coverity 2018-10-10 19:27:18.673632619 +0200 -+++ ./src/conf_lex.l 2018-10-10 19:27:18.682632698 +0200 -@@ -133,7 +133,7 @@ int var_in_conflval=0; - [\ \t]*\n { - conf_lineno++; - return (TNEWLINE); -- BEGIN 0; -+// BEGIN 0; - } - - \+ { -diff -up ./src/db.c.coverity ./src/db.c ---- ./src/db.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/db.c 2018-10-10 19:27:18.683632707 +0200 -@@ -27,6 +27,7 @@ - #include "db_file.h" - #include "db_disk.h" - #include "md.h" -+#include "fopen.h" - - #ifdef WITH_PSQL - #include "db_sql.h" -@@ -269,6 +270,9 @@ db_line* db_readline(int db){ - db_order=&(conf->db_new_order); - break; - } -+ default: { -+ return NULL; -+ } - } - - switch (db_url->type) { -@@ -368,7 +372,7 @@ db_line* db_char2line(char** ss,int db){ - - int i; - db_line* line=(db_line*)malloc(sizeof(db_line)*1); -- int* db_osize=0; -+ int* db_osize=NULL; - DB_FIELD** db_order=NULL; - - switch (db) { -@@ -382,6 +386,10 @@ db_line* db_char2line(char** ss,int db){ - db_order=&(conf->db_new_order); - break; - } -+ default: { -+ free(line); -+ return NULL; -+ } - } - - -@@ -601,7 +609,9 @@ db_line* db_char2line(char** ss,int db){ - size_t vsz = 0; - - tval = strtok(NULL, ","); -- line->xattrs->ents[num].key = db_readchar(strdup(tval)); -+ char * tmp = strdup(tval); -+ line->xattrs->ents[num].key = db_readchar(tmp); -+ free(tmp); - tval = strtok(NULL, ","); - val = base64tobyte(tval, strlen(tval), &vsz); - line->xattrs->ents[num].val = val; -@@ -648,6 +658,8 @@ db_line* db_char2line(char** ss,int db){ - - default : { - error(0,_("Not implemented in db_char2line %i \n"),(*db_order)[i]); -+ free_db_line(line); -+ free(line); - return NULL; - } - -@@ -826,7 +838,7 @@ void db_close() { - case url_ftp: - { - if (conf->db_out!=NULL) { -- url_fclose(conf->db_out); -+ url_fclose((URL_FILE*)conf->db_out); - } - break; - } -diff -up ./src/db_disk.c.coverity ./src/db_disk.c ---- ./src/db_disk.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/db_disk.c 2018-10-10 19:28:00.108995089 +0200 -@@ -79,9 +79,15 @@ static DIR *open_dir(char* path) { - - static void next_in_dir (void) - { -+ - #ifdef HAVE_READDIR_R -- if (dirh != NULL) -+ if (dirh != NULL) { -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - rdres = AIDE_READDIR_R_FUNC (dirh, entp, resp); -+#pragma GCC diagnostic pop -+ } -+ - #else - #ifdef HAVE_READDIR - if (dirh != NULL) { -diff -up ./src/db_file.c.coverity ./src/db_file.c ---- ./src/db_file.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/db_file.c 2018-10-10 19:27:18.683632707 +0200 -@@ -171,7 +171,7 @@ int dofprintf( const char* s,...) - int db_file_read_spec(int db){ - - int i=0; -- int* db_osize=0; -+ int* db_osize=NULL; - DB_FIELD** db_order=NULL; - - switch (db) { -@@ -187,6 +187,9 @@ int db_file_read_spec(int db){ - db_lineno=&db_new_lineno; - break; - } -+ default: { -+ return RETFAIL; -+ } - } - - *db_order=(DB_FIELD*) malloc(1*sizeof(DB_FIELD)); -@@ -198,13 +201,10 @@ int db_file_read_spec(int db){ - int l; - - -- /* Yes... we do not check if realloc returns nonnull */ -- -- *db_order=(DB_FIELD*) -- realloc((void*)*db_order, -+ void * tmp = realloc((void*)*db_order, - ((*db_osize)+1)*sizeof(DB_FIELD)); -- -- if(*db_order==NULL){ -+ if (tmp != NULL) *db_order=(DB_FIELD*) tmp; -+ else { - return RETFAIL; - } - -@@ -291,8 +291,8 @@ char** db_readline_file(int db){ - int* domd=NULL; - #ifdef WITH_MHASH - MHASH* md=NULL; --#endif - char** oldmdstr=NULL; -+#endif - int* db_osize=0; - DB_FIELD** db_order=NULL; - FILE** db_filep=NULL; -@@ -302,9 +302,9 @@ char** db_readline_file(int db){ - case DB_OLD: { - #ifdef WITH_MHASH - md=&(conf->dboldmd); -+ oldmdstr=&(conf->old_dboldmdstr); - #endif - domd=&(conf->do_dboldmd); -- oldmdstr=&(conf->old_dboldmdstr); - - db_osize=&(conf->db_in_size); - db_order=&(conf->db_in_order); -@@ -316,9 +316,9 @@ char** db_readline_file(int db){ - case DB_NEW: { - #ifdef WITH_MHASH - md=&(conf->dbnewmd); -+ oldmdstr=&(conf->old_dbnewmdstr); - #endif - domd=&(conf->do_dbnewmd); -- oldmdstr=&(conf->old_dbnewmdstr); - - db_osize=&(conf->db_new_size); - db_order=&(conf->db_new_order); -@@ -328,7 +328,9 @@ char** db_readline_file(int db){ - break; - } - } -- -+ -+ if (db_osize == NULL) return NULL; -+ - if (*db_osize==0) { - db_buff(db,*db_filep); - -@@ -737,8 +739,6 @@ int db_writespec_file(db_config* dbconf) - int i=0; - int j=0; - int retval=1; -- void*key=NULL; -- int keylen=0; - struct tm* st; - time_t tim=time(&tim); - st=localtime(&tim); -@@ -750,6 +750,8 @@ int db_writespec_file(db_config* dbconf) - - #ifdef WITH_MHASH - /* From hereon everything must MD'd before write to db */ -+ void*key=NULL; -+ int keylen=0; - if((key=get_db_key())!=NULL){ - keylen=get_db_key_len(); - dbconf->do_dbnewmd=1; -diff -up ./src/do_md.c.coverity ./src/do_md.c ---- ./src/do_md.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/do_md.c 2018-10-10 19:27:18.683632707 +0200 -@@ -202,7 +202,6 @@ void calc_md(struct AIDE_STAT_TYPE* old_ - and we don't read from a pipe :) - */ - struct AIDE_STAT_TYPE fs; -- int sres=0; - int stat_diff,filedes; - #ifdef WITH_PRELINK - pid_t pid; -@@ -237,7 +236,7 @@ void calc_md(struct AIDE_STAT_TYPE* old_ - return; - } - -- sres=AIDE_FSTAT_FUNC(filedes,&fs); -+ AIDE_FSTAT_FUNC(filedes,&fs); - if(!(line->attr&DB_RDEV)) - fs.st_rdev=0; - -@@ -331,7 +330,7 @@ void calc_md(struct AIDE_STAT_TYPE* old_ - } - #endif - #endif /* not HAVE_MMAP */ -- buf=malloc(READ_BLOCK_SIZE); -+// buf=malloc(READ_BLOCK_SIZE); - #if READ_BLOCK_SIZE>SSIZE_MAX - #error "READ_BLOCK_SIZE" is too large. Max value is SSIZE_MAX, and current is READ_BLOCK_SIZE - #endif -diff -up ./src/gen_list.c.coverity ./src/gen_list.c ---- ./src/gen_list.c.coverity 2016-07-25 22:56:55.000000000 +0200 -+++ ./src/gen_list.c 2018-10-10 19:27:18.684632716 +0200 -@@ -843,15 +843,15 @@ static void add_file_to_tree(seltree* tr - DB_ATTR_TYPE localignorelist=0; - DB_ATTR_TYPE ignored_added_attrs, ignored_removed_attrs, ignored_changed_attrs; - -+ if(file==NULL){ -+ error(0, "add_file_to_tree was called with NULL db_line\n"); -+ } -+ - node=get_seltree_node(tree,file->filename); - - if(!node){ - node=new_seltree_node(tree,file->filename,0,NULL); - } -- -- if(file==NULL){ -- error(0, "add_file_to_tree was called with NULL db_line\n"); -- } - - /* add note to this node which db has modified it */ - node->checked|=db; -diff -up ./src/md.c.coverity ./src/md.c ---- ./src/md.c.coverity 2018-10-10 19:27:18.679632672 +0200 -+++ ./src/md.c 2018-10-10 19:27:18.684632716 +0200 -@@ -36,8 +36,8 @@ - */ - - DB_ATTR_TYPE hash_gcrypt2attr(int i) { -- DB_ATTR_TYPE r=0; - #ifdef WITH_GCRYPT -+ DB_ATTR_TYPE r=0; - switch (i) { - case GCRY_MD_MD5: { - r=DB_MD5; -@@ -74,13 +74,15 @@ DB_ATTR_TYPE hash_gcrypt2attr(int i) { - default: - break; - } --#endif - return r; -+#else /* !WITH_GCRYPT */ -+ return 0; -+#endif - } - - const char * hash_gcrypt2str(int i) { -- char * r = "?"; - #ifdef WITH_GCRYPT -+ char * r = "?"; - switch (i) { - case GCRY_MD_MD5: { - r = "MD5"; -@@ -117,13 +119,17 @@ const char * hash_gcrypt2str(int i) { - default: - break; - } --#endif - return r; -+#else /* !WITH_GCRYPT */ -+ return "?"; -+#endif - } - -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wunused-parameter" - DB_ATTR_TYPE hash_mhash2attr(int i) { -- DB_ATTR_TYPE r=0; - #ifdef WITH_MHASH -+ DB_ATTR_TYPE r=0; - switch (i) { - case MHASH_CRC32: { - r=DB_CRC32; -@@ -198,10 +204,15 @@ DB_ATTR_TYPE hash_mhash2attr(int i) { - default: - break; - } --#endif -+ - return r; -+#else /*!WITH_MHASH */ -+ return 0; -+#endif - } - -+#pragma GCC diagnostic pop -+ - /* - Initialise md_container according it's todo_attr field - */ -@@ -317,7 +328,6 @@ int init_md(struct md_container* md) { - */ - - int update_md(struct md_container* md,void* data,ssize_t size) { -- int i; - - error(255,"update_md called\n"); - -@@ -328,6 +338,7 @@ int update_md(struct md_container* md,vo - #endif - - #ifdef WITH_MHASH -+ int i; - - for(i=0;i<=HASH_MHASH_COUNT;i++) { - if (md->mhash_mdh[i]!=MHASH_FAILED) { -@@ -348,7 +359,6 @@ int update_md(struct md_container* md,vo - */ - - int close_md(struct md_container* md) { -- int i; - #ifdef _PARAMETER_CHECK_ - if (md==NULL) { - return RETFAIL; -@@ -356,6 +366,7 @@ int close_md(struct md_container* md) { - #endif - error(255,"close_md called \n"); - #ifdef WITH_MHASH -+ int i; - for(i=0;i<=HASH_MHASH_COUNT;i++) { - if (md->mhash_mdh[i]!=MHASH_FAILED) { - mhash (md->mhash_mdh[i], NULL, 0); -diff -up ./src/util.c.coverity ./src/util.c ---- ./src/util.c.coverity 2018-10-10 19:27:18.670632593 +0200 -+++ ./src/util.c 2018-10-10 19:27:18.684632716 +0200 -@@ -105,13 +105,15 @@ url_t* parse_url(char* val) - for(i=0;r[0]!='/'&&r[0]!='\0';r++,i++); - if(r[0]=='\0'){ - error(0,"Invalid file-URL,no path after hostname: file:%s\n",t); -+ free(hostname); - return NULL; - } - u->value=strdup(r); - r[0]='\0'; - if(gethostname(hostname,MAXHOSTNAMELEN)==-1){ -- strncpy(hostname,"localhost", 10); -+ strncpy(hostname,"localhost", 10); - } -+ - if( (strcmp(t,"localhost")==0)||(strcmp(t,hostname)==0)){ - free(hostname); - break; -@@ -120,7 +122,7 @@ url_t* parse_url(char* val) - free(hostname); - return NULL; - } -- free(hostname); -+ - break; - } - u->value=strdup(r); diff --git a/SOURCES/coverity2.patch b/SOURCES/coverity2.patch deleted file mode 100644 index 5052ba3..0000000 --- a/SOURCES/coverity2.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --up ./src/compare_db.c ./src/compare_db.c ---- ./src/compare_db.c -+++ ./src/compare_db.c -@@ -438,7 +438,11 @@ snprintf(*values[0], l, "%s",s); - } else { - *values = malloc(1 * sizeof (char*)); - if (DB_FTYPE&attr) { -- easy_string(get_file_type_string(line->perm)) -+ char *file_type = get_file_type_string(line->perm); -+ if (!file_type) { -+ error(2,"%s: ", file_type); -+ } -+ easy_string(file_type) - } else if (DB_LINKNAME&attr) { - easy_string(line->linkname) - easy_number((DB_SIZE|DB_SIZEG),size,"%li") -diff -up ./src/db_file.c ./src/db_file.c ---- ./src/db_file.c -+++ ./src/db_file.c -@@ -194,6 +194,10 @@ int db_file_read_spec(int db){ - - *db_order=(DB_FIELD*) malloc(1*sizeof(DB_FIELD)); - -+ if (*db_order == NULL){ -+ error(1,"malloc for *db_order failed in %s", __func__); -+ } -+ - while ((i=db_scan())!=TNEWLINE){ - switch (i) { - - diff --git a/SOURCES/gnutls.patch b/SOURCES/gnutls.patch new file mode 100644 index 0000000..4a8607e --- /dev/null +++ b/SOURCES/gnutls.patch @@ -0,0 +1,487 @@ +diff -up ./configure.ac.gnutls ./configure.ac +--- ./configure.ac.gnutls 2023-06-13 20:53:43.000000000 +0200 ++++ ./configure.ac 2024-05-14 19:09:47.419448389 +0200 +@@ -350,6 +350,10 @@ AC_MSG_CHECKING(for Mhash) + AC_ARG_WITH([mhash], AS_HELP_STRING([--with-mhash], [use Mhash (default: check)]), [with_mhash=$withval], [with_mhash=check]) + AC_MSG_RESULT([$with_mhash]) + ++AC_MSG_CHECKING(for GnuTLS) ++AC_ARG_WITH([gnutls], AS_HELP_STRING([--with-gnutls], [use GnuTLS library (default: check)]), [with_gnutls=$withval], [with_gnutls=check]) ++AC_MSG_RESULT([$with_gnutls]) ++ + AC_MSG_CHECKING(for GNU crypto library) + AC_ARG_WITH([gcrypt], AS_HELP_STRING([--with-gcrypt], [use GNU crypto library (default: check)]), [with_gcrypt=$withval], [with_gcrypt=check]) + AC_MSG_RESULT([$with_gcrypt]) +@@ -363,19 +367,29 @@ AS_IF([test x"$with_mhash" = xyes], [ + )],AC_DEFINE(HAVE_MHASH_WHIRLPOOL,1,[mhash has whirlpool])) + AS_IF([test x"$with_gcrypt" = xcheck], [ + with_gcrypt=no ++ with_gnutls=no + ]) + ]) + AIDE_PKG_CHECK_MODULES_OPTIONAL(gcrypt, GCRYPT, libgcrypt) ++AIDE_PKG_CHECK_MODULES_OPTIONAL(gnutls, GNUTLS, gnutls) + AS_IF([test x"$with_mhash" != xno && test x"$with_gcrypt" != xno], [ + AC_MSG_ERROR([Using gcrypt together with mhash makes no sense. To disable mhash use --without-mhash]) + ]) +-AS_IF([test x"$with_mhash" = xno && test x"$with_gcrypt" = xno], [ +- AC_MSG_ERROR([AIDE requires mhash or libcrypt for hashsum calculation]) ++AS_IF([test x"$with_mhash" != xno && test x"$with_gnutls" != xno], [ ++ AC_MSG_ERROR([Using gnutls together with mhash makes no sense. To disable mhash use --without-mhash]) ++]) ++AS_IF([test x"$with_gcrypt" != xno && test x"$with_gnutls" != xno], [ ++ AC_MSG_ERROR([Using gnutls together with gcrypt makes no sense. To disable gcrypt use --without-gcrypt]) ++]) ++AS_IF([test x"$with_mhash" = xno && test x"$with_gcrypt" = xno && test x"$with_gnutls" == xno], [ ++ AC_MSG_ERROR([AIDE requires mhash, gnutls or libcrypt for hashsum calculation]) + ]) + compoptionstring="${compoptionstring}use Mhash: $with_mhash\\n" + AM_CONDITIONAL(HAVE_MHASH, [test "x$MHASH_LIBS" != "x"]) + compoptionstring="${compoptionstring}use GNU crypto library: $with_gcrypt\\n" + AM_CONDITIONAL(HAVE_GCRYPT, [test "x$GCRYPT_LIBS" != "x"]) ++compoptionstring="${compoptionstring}use GnuTLS: $with_gnutls\\n" ++AM_CONDITIONAL(HAVE_GNUTLS, [test "x$GNUTLS_LIBS" != "x"]) + + AIDE_PKG_CHECK(audit, Linux Auditing Framework, no, AUDIT, audit) + +diff -up ./doc/aide.conf.5.gnutls ./doc/aide.conf.5 +--- ./doc/aide.conf.5.gnutls 2023-08-01 10:47:59.000000000 +0200 ++++ ./doc/aide.conf.5 2024-05-14 19:09:47.420448380 +0200 +@@ -866,6 +866,7 @@ haval256 checksum + .TP + .B "crc32" + crc32 checksum ++(\fIlibmhash\fR and \fIlibgcrypt\fR only) + .TP + .B "crc32b" + crc32 checksum +@@ -876,14 +877,15 @@ GOST R 34.11-94 checksum + .TP + .B "whirlpool" + whirlpool checksum ++(\fIlibgcrypt\fR and \fIlibmhash\fRonly) + .TP + .B "stribog256" + GOST R 34.11-2012, 256 bit checksum +-(\fIlibgcrypt\fR only, added in AIDE v0.17) ++(\fIlibgcrypt\fR and \fIgnutls\fR only, added in AIDE v0.17) + .TP + .B "stribog512" + GOST R 34.11-2012, 512 bit checksum +-(\fIlibgcrypt\fR only, added in AIDE v0.17) ++(\fIlibgcrypt\fR and \fIgnutls\fR only, added in AIDE v0.17) + .PP + + Use 'aide --version' to show which hashsums are available. +diff -up ./include/md.h.gnutls ./include/md.h +--- ./include/md.h.gnutls 2023-04-01 18:25:38.000000000 +0200 ++++ ./include/md.h 2024-05-14 19:09:47.420448380 +0200 +@@ -29,6 +29,10 @@ + #ifdef WITH_GCRYPT + #include + #endif ++#ifdef WITH_GNUTLS ++#include ++#include ++#endif + #include + #include "attributes.h" + #include "hashsum.h" +@@ -61,6 +65,10 @@ typedef struct md_container { + gcry_md_hd_t mdh; + #endif + ++#ifdef WITH_GNUTLS ++ gnutls_hash_hd_t gnutls_mdh[num_hashes]; ++#endif ++ + } md_container; + + typedef struct md_hashsums { +diff -up ./Makefile.am.gnutls ./Makefile.am +--- ./Makefile.am.gnutls 2024-05-14 19:09:47.420448380 +0200 ++++ ./Makefile.am 2024-05-14 19:23:09.347757387 +0200 +@@ -64,17 +64,35 @@ if HAVE_CURL + aide_SOURCES += include/fopen.h src/fopen.c + endif + +-aide_CFLAGS = @AIDE_DEFS@ -W -Wall -g ${PTHREAD_CFLAGS} +-aide_LDADD = -lm ${PCRE2_LIBS} ${ZLIB_LIBS} ${MHASH_LIBS} ${GCRYPT_LIBS} ${POSIX_ACL_LIBS} ${SELINUX_LIBS} ${AUDIT_LIBS} ${XATTR_LIBS} ${ELF_LIBS} ${E2FSATTRS_LIBS} ${CAPABILITIES_LIBS} ${CURL_LIBS} ${PTHREAD_LIBS} ++aide_CFLAGS = @AIDE_DEFS@ -W -Wall -g ${PTHREAD_CFLAGS} ${GNUTLS_CFLAGS} ++aide_LDADD = -lm ${PCRE2_LIBS} ${ZLIB_LIBS} ${MHASH_LIBS} ${GNUTLS_LIBS} ${GCRYPT_LIBS} ${POSIX_ACL_LIBS} ${SELINUX_LIBS} ${AUDIT_LIBS} ${XATTR_LIBS} ${ELF_LIBS} ${E2FSATTRS_LIBS} ${CAPABILITIES_LIBS} ${CURL_LIBS} ${PTHREAD_LIBS} + + if HAVE_CHECK +-TESTS = check_aide +-check_PROGRAMS = check_aide ++TESTS = check_aide check_md ++check_PROGRAMS = check_aide check_md + check_aide_SOURCES = tests/check_aide.c tests/check_aide.h \ + tests/check_attributes.c src/attributes.c \ + src/log.c src/util.c +-check_aide_CFLAGS = -I$(top_srcdir)/include $(CHECK_CFLAGS) +-check_aide_LDADD = -lm ${PCRE2_LIBS} ${MHASH_LIBS} ${GCRYPT_LIBS} $(CHECK_LIBS) ++check_aide_CFLAGS = -I$(top_srcdir)/include $(CHECK_CFLAGS) ${GNUTLS_CFLAGS} ++check_aide_LDADD = -lm ${PCRE2_LIBS} ${MHASH_LIBS} ${GCRYPT_LIBS} $(CHECK_LIBS) ${GNUTLS_LIBS} ++ ++check_md_SOURCES = tests/check_md.c tests/check_md.h \ ++ tests/check_hashes.c \ ++ src/log.c src/util.c src/md.c src/base64.c src/hashsum.c src/attributes.c ++ ++check_md_CFLAGS = -I$(top_srcdir)/include \ ++ $(CHECK_CFLAGS) \ ++ $(GCRYPT_CFLAGS) \ ++ $(GNUTLS_CFLAGS) \ ++ $(MHASH_CFLAGS) \ ++ $(PCRE2_CFLAGS) ++check_md_LDADD = -lm \ ++ $(CHECK_LIBS) \ ++ ${GCRYPT_LIBS} \ ++ ${GNUTLS_LIBS} \ ++ ${MHASH_LIBS} \ ++ ${PCRE2_LIBS} ++ + endif # HAVE_CHECK + + AM_CFLAGS = @AIDE_DEFS@ -W -Wall -g +diff -up ./README.gnutls ./README +--- ./README.gnutls 2023-08-01 10:47:59.000000000 +0200 ++++ ./README 2024-05-14 19:09:47.419448389 +0200 +@@ -132,11 +132,15 @@ + o GNU make. + o pkg-config + o PCRE2 library +- o Mhash (optional, but highly recommended). Mhash is currently +- available from http://mhash.sourceforge.net/. A static version of +- libmhash needs to be build using the --enable-static=yes +- configure option. ++ ++ One of the following crypto libraries: ++ ++ o Mhash. Mhash is currently available from ++ http://mhash.sourceforge.net/. A static version of libmhash needs ++ to be build using the --enable-static=yes configure option. + Aide requires at least mhash version 0.9.2 ++ o GNU libgcrypt ++ o GnuTLS + + o libcheck (optional, needed for 'make check', license: LGPL-2.1) + +diff -up ./src/aide.c.gnutls ./src/aide.c +--- ./src/aide.c.gnutls 2023-06-13 20:52:39.000000000 +0200 ++++ ./src/aide.c 2024-05-14 19:09:47.420448380 +0200 +@@ -66,6 +66,9 @@ char* after = NULL; + #include + #define NEED_LIBGCRYPT_VERSION "1.8.0" + #endif ++#ifdef WITH_GNUTLS ++#include ++#endif + + static void usage(int exitvalue) + { +@@ -522,9 +525,6 @@ static void setdefaults_before_config() + DB_ATTR_TYPE common_attrs = ATTR(attr_perm)|ATTR(attr_ftype)|ATTR(attr_inode)|ATTR(attr_linkcount)|ATTR(attr_uid)|ATTR(attr_gid); + + DB_ATTR_TYPE GROUP_R_HASHES=0LLU; +-#ifdef WITH_MHASH +- GROUP_R_HASHES=ATTR(attr_md5); +-#endif + #ifdef WITH_GCRYPT + if (gcry_fips_mode_active()) { + char* str; +@@ -533,6 +533,8 @@ static void setdefaults_before_config() + } else { + GROUP_R_HASHES = ATTR(attr_md5); + } ++#else /* WITH_MHASH or WITH_GNUTLS */ ++ GROUP_R_HASHES=ATTR(attr_md5); + #endif + + log_msg(LOG_LEVEL_INFO, "define default groups definitions"); +diff -up ./src/hashsum.c.gnutls ./src/hashsum.c +--- ./src/hashsum.c.gnutls 2023-04-01 18:25:38.000000000 +0200 ++++ ./src/hashsum.c 2024-05-14 19:09:47.420448380 +0200 +@@ -29,6 +29,9 @@ + #ifdef WITH_GCRYPT + #include + #endif ++#ifdef WITH_GNUTLS ++#include ++#endif + + hashsum_t hashsums[] = { + { attr_md5, 16 }, +@@ -86,6 +89,24 @@ int algorithms[] = { /* order must match + }; + #endif + ++#ifdef WITH_GNUTLS ++int algorithms[] = { /* order must match hashsums array */ ++ GNUTLS_DIG_MD5, ++ GNUTLS_DIG_SHA1, ++ GNUTLS_DIG_SHA256, ++ GNUTLS_DIG_SHA512, ++ GNUTLS_DIG_RMD160, ++ -1, /* TIGER is not available */ ++ -1, /* CRC32 is not available */ ++ -1, /* CRC32B is not available */ ++ -1, /* GCRY_MD_HAVAL is not available */ ++ -1, /* WHIRLPOOL is not available */ ++ -1, /* GNUTLS_DIG_GOSTR_94 gives different results than Gcrypt */ ++ GNUTLS_DIG_STREEBOG_256, ++ GNUTLS_DIG_STREEBOG_512, ++}; ++#endif ++ + DB_ATTR_TYPE get_hashes(bool include_unsupported) { + DB_ATTR_TYPE attr = 0LLU; + for (int i = 0; i < num_hashes; ++i) { +diff -up ./src/md.c.gnutls ./src/md.c +--- ./src/md.c.gnutls 2023-04-01 18:25:38.000000000 +0200 ++++ ./src/md.c 2024-05-14 19:28:09.651209390 +0200 +@@ -40,6 +40,11 @@ + #include + #endif + ++#ifdef WITH_GNUTLS ++#include ++#include ++#endif ++ + /* + Initialise md_container according its todo_attr field + */ +@@ -90,6 +95,22 @@ int init_md(struct md_container* md, con + } + } + #endif ++#ifdef WITH_GNUTLS ++ for (HASHSUM i = 0 ; i < num_hashes ; ++i) { ++ DB_ATTR_TYPE h = ATTR(hashsums[i].attribute); ++ if (h&md->todo_attr) { ++ if(gnutls_hash_init(&(md->gnutls_mdh[i]),algorithms[i])>=0){ ++ md->calc_attr|=h; ++ } else { ++ log_msg(LOG_LEVEL_WARNING,"%s: gnutls_hash_init (%s) failed for '%s'", filename, attributes[hashsums[i].attribute].db_name, filename); ++ md->todo_attr&=~h; ++ md->gnutls_mdh[i] = NULL; ++ } ++ } else { ++ md->gnutls_mdh[i] = NULL; ++ } ++ } ++#endif + char *str; + log_msg(LOG_LEVEL_DEBUG, "%s> initialized md_container: %s (%p)", filename, str = diff_attributes(0, md->calc_attr), md); + free(str); +@@ -120,6 +141,13 @@ int update_md(struct md_container* md,vo + #ifdef WITH_GCRYPT + gcry_md_write(md->mdh, data, size); + #endif ++#ifdef WITH_GNUTLS ++ for (HASHSUM i = 0 ; i < num_hashes ; ++i) { ++ if(md->gnutls_mdh[i] != NULL){ ++ gnutls_hash(md->gnutls_mdh[i], data, size); ++ } ++ } ++#endif + return RETOK; + } + +@@ -163,6 +191,14 @@ int close_md(struct md_container* md, md + } + } + #endif ++#ifdef WITH_GNUTLS ++ for (HASHSUM i = 0 ; i < num_hashes ; ++i) { ++ if(md->gnutls_mdh[i] != NULL){ ++ gnutls_hash_deinit(md->gnutls_mdh[i], hs?hs->hashsums[i]:NULL); ++ md->gnutls_mdh[i] = NULL; ++ } ++ } ++#endif /* WITH_MHASH */ + if (hs) { + hs->attrs = md->calc_attr; + } +diff -up ./tests/check_hashes.c.gnutls ./tests/check_hashes.c +--- ./tests/check_hashes.c.gnutls 2024-05-14 19:09:47.420448380 +0200 ++++ ./tests/check_hashes.c 2024-05-14 19:09:47.420448380 +0200 +@@ -0,0 +1,111 @@ ++/* ++ * AIDE (Advanced Intrusion Detection Environment) ++ * ++ * Copyright (C) 2024 Jakub Jelen ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include "hashsum.h" ++#include "md.h" ++ ++typedef struct { ++ const char *input; ++ ssize_t input_len; ++ md_hashsums expected; ++} diff_digests_t; ++ ++static diff_digests_t diff_digests_tests[] = { ++ { "", 0, {{ ++ "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", ++ "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", ++ "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55", ++ "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e", ++ "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31", ++ "\x24\xf0\x13\x0c\x63\xac\x93\x32\x16\x16\x6e\x76\xb1\xbb\x92\x5f\xf3\x73\xde\x2d\x49\x58\x4e\x7a", ++ "\x00\x00\x00\x00", ++ "\x00\x00\x00\x00", ++ "\x4f\x69\x38\x53\x1f\x0b\xc8\x99\x1f\x62\xda\x7b\xbd\x6f\x7d\xe3\xfa\xd4\x45\x62\xb8\xc6\xf4\xeb\xf1\x46\xd5\xb4\xe4\x6f\x7c\x17", ++ "\x19\xfa\x61\xd7\x55\x22\xa4\x66\x9b\x44\xe3\x9c\x1d\x2e\x17\x26\xc5\x30\x23\x21\x30\xd4\x07\xf8\x9a\xfe\xe0\x96\x49\x97\xf7\xa7\x3e\x83\xbe\x69\x8b\x28\x8f\xeb\xcf\x88\xe3\xe0\x3c\x4f\x07\x57\xea\x89\x64\xe5\x9b\x63\xd9\x37\x08\xb1\x38\xcc\x42\xa6\x6e\xb3", ++ "\xce\x85\xb9\x9c\xc4\x67\x52\xff\xfe\xe3\x5c\xab\x9a\x7b\x02\x78\xab\xb4\xc2\xd2\x05\x5c\xff\x68\x5a\xf4\x91\x2c\x49\x49\x0f\x8d", ++ "\x3f\x53\x9a\x21\x3e\x97\xc8\x02\xcc\x22\x9d\x47\x4c\x6a\xa3\x2a\x82\x5a\x36\x0b\x2a\x93\x3a\x94\x9f\xd9\x25\x20\x8d\x9c\xe1\xbb", ++ "\x8e\x94\x5d\xa2\x09\xaa\x86\x9f\x04\x55\x92\x85\x29\xbc\xae\x46\x79\xe9\x87\x3a\xb7\x07\xb5\x53\x15\xf5\x6c\xeb\x98\xbe\xf0\xa7\x36\x2f\x71\x55\x28\x35\x6e\xe8\x3c\xda\x5f\x2a\xac\x4c\x6a\xd2\xba\x3a\x71\x5c\x1b\xcd\x81\xcb\x8e\x9f\x90\xbf\x4c\x1c\x1a\x8a" } ++ }}, ++ { "hello", 5, {{ ++ "\x5d\x41\x40\x2a\xbc\x4b\x2a\x76\xb9\x71\x9d\x91\x10\x17\xc5\x92", ++ "\xaa\xf4\xc6\x1d\xdc\xc5\xe8\xa2\xda\xbe\xde\x0f\x3b\x48\x2c\xd9\xae\xa9\x43\x4d", ++ "\x2c\xf2\x4d\xba\x5f\xb0\xa3\x0e\x26\xe8\x3b\x2a\xc5\xb9\xe2\x9e\x1b\x16\x1e\x5c\x1f\xa7\x42\x5e\x73\x04\x33\x62\x93\x8b\x98\x24", ++ "\x9b\x71\xd2\x24\xbd\x62\xf3\x78\x5d\x96\xd4\x6a\xd3\xea\x3d\x73\x31\x9b\xfb\xc2\x89\x0c\xaa\xda\xe2\xdf\xf7\x25\x19\x67\x3c\xa7\x23\x23\xc3\xd9\x9b\xa5\xc1\x1d\x7c\x7a\xcc\x6e\x14\xb8\xc5\xda\x0c\x46\x63\x47\x5c\x2e\x5c\x3a\xde\xf4\x6f\x73\xbc\xde\xc0\x43", ++ "\x10\x8f\x07\xb8\x38\x24\x12\x61\x2c\x04\x8d\x07\xd1\x3f\x81\x41\x18\x44\x5a\xcd", ++ "\xa7\x88\x62\x33\x6f\x7f\xfd\x2c\x8a\x38\x74\xf8\x9b\x1b\x74\xf2\xf2\x7b\xdb\xca\x39\x66\x02\x54", ++#ifdef WITH_MHASH ++ "\x3d\x65\x31\x19", ++#else ++ "\x36\x10\xa6\x86", ++#endif ++ "\x86\xa6\x10\x36", ++ "\x26\x71\x8e\x4f\xb0\x55\x95\xcb\x87\x03\xa6\x72\xa8\xae\x91\xee\xa0\x71\xca\xc5\xe7\x42\x61\x73\xd4\xc2\x5a\x61\x1c\x4b\x80\x22", ++ "\x0a\x25\xf5\x5d\x73\x08\xec\xa6\xb9\x56\x7a\x7e\xd3\xbd\x1b\x46\x32\x7f\x0f\x1f\xfd\xc8\x04\xdd\x8b\xb5\xaf\x40\xe8\x8d\x78\xb8\x8d\xf0\xd0\x02\xa8\x9e\x2f\xdb\xd5\x87\x6c\x52\x3f\x1b\x67\xbc\x44\xe9\xf8\x70\x47\x59\x8e\x75\x48\x29\x8e\xa1\xc8\x1c\xfd\x73", ++ "\xa7\xeb\x5d\x08\xdd\xf2\x36\x3f\x1e\xa0\x31\x7a\x80\x3f\xce\xf8\x1d\x33\x86\x3c\x8b\x2f\x9f\x6d\x7d\x14\x95\x1d\x22\x9f\x45\x67", ++ "\x3f\xb0\x70\x0a\x41\xce\x6e\x41\x41\x3b\xa7\x64\xf9\x8b\xf2\x13\x5b\xa6\xde\xd5\x16\xbe\xa2\xfa\xe8\x42\x9c\xc5\xbd\xd4\x6d\x6d", ++ "\x8d\xf4\x14\x26\x09\x66\xbe\xb7\xb3\x4d\x92\x07\x63\x07\x9e\x15\xdf\x1f\x63\x29\x7e\xb3\xdd\x43\x11\xe8\xb5\x85\xd4\xbf\x2f\x59\x23\x21\x4f\x1d\xfe\xd3\xfd\xee\x4a\xaf\x01\x83\x30\xa1\x2a\xcd\xe0\xef\xcc\x33\x8e\xb5\x29\x22\xf3\xe5\x71\x21\x2d\x42\xc8\xde" } ++ }}, ++}; ++ ++static int num_diff_digests_tests = sizeof diff_digests_tests / sizeof(diff_digests_t); ++ ++START_TEST (test_diff_digests) { ++ const char *filename = "filename"; /* used only in the debug logs */ ++ md_hashsums hs = {0}; ++ struct md_container *mdc = calloc(1, sizeof(struct md_container)); ++ mdc->todo_attr = get_hashes(false); ++ ++#ifdef WITH_GCRYPT ++ gcry_control(GCRYCTL_DISABLE_SECMEM, 0); ++ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); ++#endif ++ ++ init_md(mdc, filename); ++ update_md(mdc, (void *)diff_digests_tests[_i].input, diff_digests_tests[_i].input_len); ++ close_md(mdc, &hs, filename); ++ free(mdc); ++ ++ for (HASHSUM i = 0 ; i < num_hashes ; ++i) { ++ DB_ATTR_TYPE attr = ATTR(hashsums[i].attribute); ++ if (algorithms[i] >= 0 && hs.attrs&attr) { ++ ck_assert_mem_eq(diff_digests_tests[_i].expected.hashsums[i], hs.hashsums[i], hashsums[i].length); ++ } ++ } ++} ++END_TEST ++ ++Suite *make_md_suite(void) { ++ ++ Suite *s = suite_create ("md"); ++ ++ TCase *tc_diff_digests = tcase_create ("diff_digests"); ++ ++ tcase_add_loop_test (tc_diff_digests, test_diff_digests, 0, num_diff_digests_tests); ++ ++ suite_add_tcase (s, tc_diff_digests); ++ ++ return s; ++} ++ +diff -up ./tests/check_md.c.gnutls ./tests/check_md.c +--- ./tests/check_md.c.gnutls 2024-05-14 19:09:47.420448380 +0200 ++++ ./tests/check_md.c 2024-05-14 19:09:47.420448380 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * AIDE (Advanced Intrusion Detection Environment) ++ * ++ * Copyright (C) 2024 Jakub Jelen ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++ ++#include "check_md.h" ++ ++int main (void) { ++ int number_failed; ++ SRunner *sr; ++ ++ sr = srunner_create (make_md_suite()); ++ ++ srunner_run_all (sr, CK_NORMAL); ++ number_failed = srunner_ntests_failed (sr); ++ ++ srunner_free (sr); ++ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; ++} +diff -up ./tests/check_md.h.gnutls ./tests/check_md.h +--- ./tests/check_md.h.gnutls 2024-05-14 19:09:47.421448372 +0200 ++++ ./tests/check_md.h 2024-05-14 19:09:47.421448372 +0200 +@@ -0,0 +1,23 @@ ++/* ++ * AIDE (Advanced Intrusion Detection Environment) ++ * ++ * Copyright (C) 2024 Jakub Jelen ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++ ++Suite *make_md_suite(void); diff --git a/SPECS/aide.spec b/SPECS/aide.spec index 8756006..c70c379 100644 --- a/SPECS/aide.spec +++ b/SPECS/aide.spec @@ -1,9 +1,9 @@ Summary: Intrusion detection environment Name: aide -Version: 0.16 -Release: 15%{?dist}.2 +Version: 0.18.6 +Release: 8%{?dist}.2 URL: http://sourceforge.net/projects/aide -License: GPLv2+ +License: GPL-2.0-or-later Source0: %{url}/files/aide/%{version}/%{name}-%{version}.tar.gz Source1: aide.conf Source2: README.quickstart @@ -12,52 +12,44 @@ Source3: aide.logrotate BuildRequires: gcc BuildRequires: make BuildRequires: bison flex -BuildRequires: pcre-devel -BuildRequires: libgpg-error-devel libgcrypt-devel +BuildRequires: pcre2-devel +BuildRequires: libgpg-error-devel gnutls-devel BuildRequires: zlib-devel BuildRequires: libcurl-devel BuildRequires: libacl-devel BuildRequires: pkgconfig(libselinux) BuildRequires: libattr-devel BuildRequires: e2fsprogs-devel -Buildrequires: audit-libs-devel +BuildRequires: audit-libs-devel +BuildRequires: autoconf autoconf-archive +BuildRequires: automake libtool -Requires: libgcrypt >= 1.8.5 +Patch1: aide-verbose.patch +Patch2: gnutls.patch +Patch3: aide-0.18-CVE-2025-54389-control-chars.patch -# Customize the database file location in the man page. -Patch1: aide-0.16rc1-man.patch -# fix aide in FIPS mode -Patch2: aide-0.16b1-fipsfix.patch - -Patch3: aide-0.15-syslog-format.patch -Patch4: aide-0.16-crypto-disable-haval-and-others.patch -Patch5: coverity.patch -Patch6: aide-0.16-crash-elf.patch - -# 1676487 - Null pointer dereference fix spotted by coverity -Patch7: coverity2.patch - -# 2041957 - CVE-2021-45417 aide: heap-based buffer overflow on outputs larger than B64_BUF -Patch8: aide-0.16-CVE-2021-45417.patch - -# CVE-2025-54389 aide: improper output neutralization enables bypassing -Patch9: aide-0.16-CVE-2025-54389.patch -Patch10: aide-0.16-CVE-2025-54389-part2.patch %description AIDE (Advanced Intrusion Detection Environment) is a file integrity checker and intrusion detection program. %prep -%autosetup -p1 +%setup +#%%autosetup -p1 cp -a %{S:2} . +%patch -P 1 -p1 -b .verbose +%patch -P 2 -p1 -b .gnutls +%patch -P 3 -p1 -b .CVE-2025-54389 + %build +autoreconf -ivf %configure \ --disable-static \ --with-config_file=%{_sysconfdir}/aide.conf \ - --with-gcrypt \ + --with-gnutls \ + --without-gcrypt \ --with-zlib \ --with-curl \ --with-posix-acl \ @@ -65,7 +57,6 @@ cp -a %{S:2} . --with-xattr \ --with-e2fsattrs \ --with-audit - %make_build %install @@ -77,7 +68,7 @@ mkdir -p -m0700 %{buildroot}%{_localstatedir}/lib/aide %files %license COPYING -%doc AUTHORS ChangeLog NEWS README doc/manual.html contrib/ +%doc AUTHORS ChangeLog NEWS README contrib/ %doc README.quickstart %{_sbindir}/aide %{_mandir}/man1/*.1* @@ -88,61 +79,106 @@ mkdir -p -m0700 %{buildroot}%{_localstatedir}/lib/aide %dir %attr(0700,root,root) %{_localstatedir}/log/aide %changelog -* Thu Aug 21 2025 Attila Lakatos - 0.16.15.2 -- CVE-2025-54389 aide: improper output neutralization enables bypassing - resolves: RHEL-109907 +* Tue Aug 26 2025 Darren Archibald - 0.18.6-8.2 +- aide: improper output neutralization enables bypassing (CVE-2025-54389) +Resolves: rhbz#2388019 -* Tue Jan 25 2022 Radovan Sroka - 0.16.15 -- backported fix for CVE-2021-45417 - resolves: rhbz#2041957 +* Wed Jan 29 2025 Radovan Sroka - 0.18.6-8 +RHEL 10.0 ERRATUM +- /boot/grub2/grubenv's timestamp is getting modified continuously due to "boot_success" implementation +Resolves: RHEL-4320 -* Tue Jun 30 2020 Radovan Sroka = 0.16.14 -- strict require for libgcrypt - resolves: rhbz#1852407 +* Tue Oct 29 2024 Troy Dawson - 0.18.6-7 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Tue May 19 2020 Attila Lakatos - 0.16-13 -- RHEL 8.3 -- minor edit of aide.conf to make it consistent - resolves: rhbz#1740754 +* Mon Jun 24 2024 Troy Dawson - 0.18.6-6 +- Bump release for June 2024 mass rebuild -* Mon Apr 06 2020 Attila Lakatos - 0.16-12 -- RHEL 8.3 -- minor edit of aide.conf - resolves: rhbz#1740754 -- do not generate false warnings when report_ignore_e2fsattrs is specified in aide.conf - resolves: rhbz#1806323 +* Fri May 17 2024 Radovan Sroka - 0.18.6-5 +REDHAT 10.0 ERRATUM +- fix verbose patch +- get rid of libgcrypt +Resolves: RHEL-36780 -* Wed Jul 24 2019 Radovan Sroka - 0.16-11 -- rebuild -- minor edit of aide.conf +* Mon Feb 12 2024 Radovan Sroka - 0.18.6-4 +- rebase to 0.18.6 -* Tue Jul 23 2019 Radovan Sroka - 0.16-10 -- respin -- minor edit of aide.conf +* Mon Jan 22 2024 Fedora Release Engineering - 0.18.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Tue Jul 23 2019 Radovan Sroka - 0.16-9 -- Null pointer dereference fix spotted by coverity - resolves: rhbz#1676487 -- aide.conf needs updates for RHEL 8 - resolves: rhbz#1708015 +* Fri Jan 19 2024 Fedora Release Engineering - 0.18.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Tue Oct 09 2018 Radovan Sroka - 0.16-8 -- fixed wrong line wrapping of messages in the syslog format - resolves: rhbz#1628153 -- fixed coverity issues - resolves: rhbz#1602441 -- fixed crash when processing .dynamic section - resolves: rhbz#1597250 +* Tue Oct 24 2023 Radovan Sroka - 0.18.6-1 +- rebase to 0.18.6 -* Wed Aug 29 2018 Radovan Sroka - 0.16-7 -- fixed crypto problem with libgcrypt (fips) -- resolves: rhbz#1623045 +* Wed Jul 19 2023 Fedora Release Engineering - 0.18.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Wed Aug 22 2018 Radovan Sroka - 0.16-6 -- ported syslog format from rhel7 - resolves: rhbz#1584136 -- fixed crypto problem with libgcrypt - resolves: rhbz#1584120 +* Wed Jun 21 2023 Radovan Sroka - 0.18.4-1 +- aide-0.18.4 is available +Resolves: rhbz#1910486 +- Please port your pcre dependency to pcre2. Pcre has been deprecated +Resolves: rhbz#2128267 + +* Tue Jun 13 2023 Radovan Sroka - 0.16-23 +- migrated to SPDX license + +* Wed Jan 18 2023 Fedora Release Engineering - 0.16-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Fri Nov 25 2022 Florian Weimer - 0.16-21 +- Apply upstream patches to port configure to C99 + +* Wed Jul 20 2022 Fedora Release Engineering - 0.16-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jan 19 2022 Fedora Release Engineering - 0.16-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Wed Jul 21 2021 Fedora Release Engineering - 0.16-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Mon Jan 25 2021 Fedora Release Engineering - 0.16-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Fri Jul 31 2020 Fedora Release Engineering - 0.16-16 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 0.16-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Jun 24 2020 Radovan Sroka 0.16-14 +- AIDE breaks when setting report_ignore_e2fsattrs + Resolves: rhbz#1850276 + +* Tue Jan 28 2020 Fedora Release Engineering - 0.16-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Jul 31 2019 Radovan Sroka - 0.16-12 +- backport some patches + Resolves: rhbz#1717140 + +* Wed Jul 24 2019 Fedora Release Engineering - 0.16-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Wed Feb 20 2019 Daniel Kopecek - 0.16-10 +- Fix building with curl + Resolves: rhbz#1674637 + +* Thu Jan 31 2019 Fedora Release Engineering - 0.16-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Jul 31 2018 Florian Weimer - 0.16-8 +- Rebuild with fixed binutils + +* Thu Jul 12 2018 Fedora Release Engineering - 0.16-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Feb 20 2018 Igor Gnatenko - 0.16-6 +- Rebuild * Wed Feb 07 2018 Fedora Release Engineering - 0.16-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild