/** * Verify that calculated hash doesn't depend on message alignment. */ static void test_alignment(void) { int i, start, hash_id, alignment_size; /* loop by sums */ for(i = 0, hash_id = 1; (hash_id & RHASH_ALL_HASHES); hash_id <<= 1, i++) { char expected_hash[130]; assert(rhash_get_digest_size(hash_id) < (int)sizeof(expected_hash)); alignment_size = (hash_id & (RHASH_TTH | RHASH_TIGER | RHASH_WHIRLPOOL | RHASH_SHA512) ? 8 : 4); /* start message with different alignment */ for(start = 0; start < alignment_size; start++) { char message[30]; int j, msg_length = 11 + alignment_size; /* fill the buffer fifth shifted letter sequence */ for(j = 0; j < msg_length; j++) message[start + j] = 'a' + j; message[start + j] = 0; if(start == 0) { /* save original hash value */ strcpy(expected_hash, hash_message(hash_id, message + start, 0)); } else { /* verify obtained hash value */ assert_hash(hash_id, message + start, expected_hash, 0); } } } }
/* ------------------------------------------------------------------------- make_log_entry has 1 main flaws: The message in its entirity, must fit into the tempbuffer. So it must be shorter than MAXLOGSIZE ------------------------------------------------------------------------- */ void make_log_entry(enum loglevels loglevel, enum logtypes logtype, const char *file, int line, char *message, ...) { /* fn is not reentrant but is used in signal handler * with LOGGER it's a little late source name and line number * are already changed. */ static int inlog = 0; int i, j; int fd, len; char temp_buffer[MAXLOGSIZE]; char log_details_buffer[MAXLOGSIZE]; va_list args; struct iovec iov[2]; if (inlog) return; inlog = 1; if (!log_config.inited) { log_init(); } if (type_configs[logtype].syslog) { if (type_configs[logtype].level >= loglevel) { /* Initialise the Messages and send it to syslog */ va_start(args, message); vsnprintf(temp_buffer, MAXLOGSIZE -1, message, args); va_end(args); temp_buffer[MAXLOGSIZE -1] = 0; make_syslog_entry(loglevel, logtype, temp_buffer); } inlog = 0; return; } /* logging to a file */ log_src_filename = file; log_src_linenumber = line; /* Check if requested logtype is setup */ if (type_configs[logtype].set) /* Yes */ fd = type_configs[logtype].fd; else /* No: use default */ fd = type_configs[logtype_default].fd; if (fd < 0) { /* no where to send the output, give up */ goto exit; } /* Initialise the Messages */ va_start(args, message); len = vsnprintf(temp_buffer, MAXLOGSIZE -1, message, args); va_end(args); /* Append \n */ if (len ==-1 || len >= MAXLOGSIZE -1) { /* vsnprintf hit the buffer size*/ temp_buffer[MAXLOGSIZE-2] = '\n'; temp_buffer[MAXLOGSIZE-1] = 0; } else { temp_buffer[len] = '\n'; temp_buffer[len+1] = 0; } if (type_configs[logtype].level >= log_debug) goto log; /* bypass flooding checks */ goto log; /* Prevent flooding: hash the message and check if we got the same one recently */ int hash = hash_message(temp_buffer) + log_src_linenumber; /* Search for the same message by hash */ for (i = log_flood_entries - 1; i >= 0; i--) { if (log_flood_array[i].hash == hash) { /* found same message */ log_flood_array[i].count++; /* Check if that message has reached LOG_FLOODING_MAXCOUNT */ if (log_flood_array[i].count >= LOG_FLOODING_MAXCOUNT) { /* yes, log it and remove from array */ /* reusing log_details_buffer */ sprintf(log_details_buffer, "message repeated %i times\n", LOG_FLOODING_MAXCOUNT - 1); write(fd, log_details_buffer, strlen(log_details_buffer)); if ((i + 1) == LOG_FLOODING_ARRAY_SIZE) { /* last array element, just decrement count */ log_flood_entries--; goto exit; } /* move array elements down */ for (j = i + 1; j != LOG_FLOODING_ARRAY_SIZE ; j++) log_flood_array[j-1] = log_flood_array[j]; log_flood_entries--; } if (log_flood_array[i].count < LOG_FLOODING_MINCOUNT) /* log it */ goto log; /* discard it */ goto exit; } /* if */ } /* for */ /* No matching message found, add this message to array*/ if (log_flood_entries == LOG_FLOODING_ARRAY_SIZE) { /* array is full, discard oldest entry printing "message repeated..." if count > 1 */ if (log_flood_array[0].count >= LOG_FLOODING_MINCOUNT) { /* reusing log_details_buffer */ sprintf(log_details_buffer, "message repeated %i times\n", log_flood_array[0].count - LOG_FLOODING_MINCOUNT + 1); write(fd, log_details_buffer, strlen(log_details_buffer)); } for (i = 1; i < LOG_FLOODING_ARRAY_SIZE; i++) { log_flood_array[i-1] = log_flood_array[i]; } log_flood_entries--; } log_flood_array[log_flood_entries].count = 1; log_flood_array[log_flood_entries].hash = hash; log_flood_entries++; log: if ( ! log_config.console) { generate_message_details(log_details_buffer, sizeof(log_details_buffer), type_configs[logtype].set ? type_configs[logtype].display_options : type_configs[logtype_default].display_options, loglevel, logtype); /* If default wasnt setup its fd is -1 */ iov[0].iov_base = log_details_buffer; iov[0].iov_len = strlen(log_details_buffer); iov[1].iov_base = temp_buffer; iov[1].iov_len = strlen(temp_buffer); writev( fd, iov, 2); } else { write(fd, temp_buffer, strlen(temp_buffer)); } exit: inlog = 0; }