X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fos_execd%2Fexecd.c;h=09b510796319506dde2d4b388c300ebcd57e9e08;hp=d1b637c8952254e4a76fe8616c42e32e36f612c4;hb=6ef2f786c6c8ead94841b5f93baf9f43421f08c8;hpb=301048b51990573e58a30dc4a5bb4ec285cad554 diff --git a/src/os_execd/execd.c b/src/os_execd/execd.c index d1b637c..09b5107 100755 --- a/src/os_execd/execd.c +++ b/src/os_execd/execd.c @@ -1,4 +1,5 @@ -/* @(#) $Id$ */ +/* @(#) $Id: ./src/os_execd/execd.c, 2011/09/08 dcid Exp $ + */ /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. @@ -32,17 +33,19 @@ typedef struct _timeout_data /* Timeout list */ OSList *timeout_list; OSListNode *timeout_node; - +OSHash *repeated_hash; +int repeated_offenders_timeout[] = {0,0,0,0,0,0,0}; + -/** +/** * Shudowns execd properly. */ void execd_shutdown() { /* Removing pending active responses. */ merror(EXEC_SHUTDOWN, ARGV0); - + timeout_node = OSList_GetFirstNode(timeout_list); while(timeout_node) { @@ -82,7 +85,7 @@ int main(int argc, char **argv) /* Setting the name */ OS_SetName(ARGV0); - + while((c = getopt(argc, argv, "Vtdhfu:g:D:c:")) != -1){ switch(c){ @@ -107,6 +110,7 @@ int main(int argc, char **argv) if(!optarg) ErrorExit("%s: -D needs an argument.",ARGV0); dir = optarg; + break; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument.",ARGV0); @@ -114,7 +118,7 @@ int main(int argc, char **argv) break; case 't': test_config = 1; - break; + break; default: help(ARGV0); break; @@ -130,7 +134,7 @@ int main(int argc, char **argv) ErrorExit(USER_ERROR,ARGV0,"",group); - /* Privilege separation */ + /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); @@ -145,18 +149,18 @@ int main(int argc, char **argv) /* Exit if test_config */ if(test_config) exit(0); - - + + /* Signal manipulation */ StartSIG2(ARGV0, execd_shutdown); - - if (!run_foreground) + + if (!run_foreground) { /* Going daemon */ nowDaemon(); goDaemon(); - } + } /* Active response disabled */ @@ -165,12 +169,12 @@ int main(int argc, char **argv) verbose(EXEC_DISABLED, ARGV0); exit(0); } - + /* Creating the PID file */ if(CreatePID(ARGV0, getpid()) < 0) merror(PID_ERROR, ARGV0); - + /* Starting queue (exec queue) */ if((m_queue = StartMQ(EXECQUEUEPATH,READ)) < 0) ErrorExit(QUEUE_ERROR, ARGV0, EXECQUEUEPATH, strerror(errno)); @@ -178,11 +182,11 @@ int main(int argc, char **argv) /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); - - /* The real daemon Now */ + + /* The real daemon Now */ ExecdStart(m_queue); - + exit(0); } @@ -206,7 +210,7 @@ void FreeTimeoutEntry(void *timeout_entry_pt) { return; } - + tmp_str = timeout_entry->command; /* Clearing the command arguments */ @@ -239,7 +243,7 @@ void ExecdStart(int q) { int i, childcount = 0; time_t curr_time; - + char buffer[OS_MAXSTR + 1]; char *tmp_msg = NULL; char *name; @@ -251,32 +255,43 @@ void ExecdStart(int q) fd_set fdset; struct timeval socket_timeout; - + /* Clearing the buffer */ memset(buffer, '\0', OS_MAXSTR +1); - - + + /* Initializing the cmd arguments */ for(i = 0; i<= MAX_ARGS +1; i++) { cmd_args[i] = NULL; } - - + + /* Creating list for timeout */ - timeout_list = OSList_Create(); + timeout_list = OSList_Create(); if(!timeout_list) { ErrorExit(LIST_ERROR, ARGV0); } - - + + + if(repeated_offenders_timeout[0] != 0) + { + repeated_hash = OSHash_Create(); + } + else + { + repeated_hash = NULL; + } + + + /* Main loop. */ while(1) { int timeout_value; int added_before = 0; - + char **timeout_args; timeout_data *timeout_entry; @@ -289,6 +304,7 @@ void ExecdStart(int q) if (wp < 0) { merror(WAITPID_ERROR, ARGV0); + break; } /* if = 0, we still need to wait for the child process */ @@ -315,13 +331,13 @@ void ExecdStart(int q) timeout_data *list_entry; list_entry = (timeout_data *)timeout_node->data; - + /* Timeouted */ - if((curr_time - list_entry->time_of_addition) > + if((curr_time - list_entry->time_of_addition) > list_entry->time_to_block) { ExecCmd(list_entry->command); - + /* Deletecurrently node already sets the pointer to next */ OSList_DeleteCurrentlyNode(timeout_list); timeout_node = OSList_GetCurrentlyNode(timeout_list); @@ -338,7 +354,7 @@ void ExecdStart(int q) } } - + /* Setting timeout to EXECD_TIMEOUT */ socket_timeout.tv_sec = EXECD_TIMEOUT; socket_timeout.tv_usec= 0; @@ -379,8 +395,8 @@ void ExecdStart(int q) /* Getting application name */ name = buffer; - - + + /* Zeroing the name */ tmp_msg = strchr(buffer, ' '); if(!tmp_msg) @@ -413,10 +429,10 @@ void ExecdStart(int q) /* Allocating memory for the timeout argument */ os_calloc(MAX_ARGS+2, sizeof(char *), timeout_args); - + /* Adding initial variables to the cmd_arg and to the timeout cmd */ - cmd_args[0] = command; + cmd_args[0] = command; cmd_args[1] = ADD_ENTRY; os_strdup(command, timeout_args[0]); os_strdup(DELETE_ENTRY, timeout_args[1]); @@ -447,7 +463,7 @@ void ExecdStart(int q) i++; } - + /* Check this command was already executed. */ timeout_node = OSList_GetFirstNode(timeout_list); @@ -460,14 +476,16 @@ void ExecdStart(int q) added_before = 1; merror("%s: Invalid number of arguments.", ARGV0); } - + + + while(timeout_node) { timeout_data *list_entry; list_entry = (timeout_data *)timeout_node->data; if((strcmp(list_entry->command[3], timeout_args[3]) == 0) && - (strcmp(list_entry->command[0], timeout_args[0]) == 0)) + (strcmp(list_entry->command[0], timeout_args[0]) == 0)) { /* Means we executed this command before * and we don't need to add it again. @@ -477,6 +495,42 @@ void ExecdStart(int q) /* updating the timeout */ list_entry->time_of_addition = curr_time; + + if(repeated_offenders_timeout[0] != 0 && + repeated_hash != NULL && + strncmp(timeout_args[3],"-", 1) != 0) + { + char *ntimes = NULL; + char rkey[256]; + rkey[255] = '\0'; + snprintf(rkey, 255, "%s%s", list_entry->command[0], + timeout_args[3]); + + if((ntimes = OSHash_Get(repeated_hash, rkey))) + { + int ntimes_int = 0; + int i2 = 0; + int new_timeout = 0; + ntimes_int = atoi(ntimes); + while(repeated_offenders_timeout[i2] != 0) + { + i2++; + } + if(ntimes_int >= i2) + { + new_timeout = repeated_offenders_timeout[i2 - 1]*60; + } + else + { + os_calloc(10, sizeof(char), ntimes); + new_timeout = repeated_offenders_timeout[ntimes_int]*60; + ntimes_int++; + snprintf(ntimes, 9, "%d", ntimes_int); + OSHash_Update(repeated_hash,rkey,ntimes); + } + list_entry->time_to_block = new_timeout; + } + } break; } @@ -494,6 +548,48 @@ void ExecdStart(int q) /* We don't need to add to the list if the timeout_value == 0 */ if(timeout_value) { + char *ntimes; + char rkey[256]; + rkey[255] = '\0'; + snprintf(rkey, 255, "%s%s", timeout_args[0], + timeout_args[3]); + + if(repeated_hash != NULL) + { + if((ntimes = OSHash_Get(repeated_hash, rkey))) + { + int ntimes_int = 0; + int i2 = 0; + int new_timeout = 0; + + ntimes_int = atoi(ntimes); + while(repeated_offenders_timeout[i2] != 0) + { + i2++; + } + if(ntimes_int >= i2) + { + new_timeout = repeated_offenders_timeout[i2 - 1]*60; + } + else + { + os_calloc(10, sizeof(char), ntimes); + new_timeout = repeated_offenders_timeout[ntimes_int]*60; + ntimes_int++; + snprintf(ntimes, 9, "%d", ntimes_int); + OSHash_Update(repeated_hash, rkey, ntimes); + } + timeout_value = new_timeout; + } + else + { + /* Adding to the repeated offenders list. */ + OSHash_Add(repeated_hash, + strdup(rkey),strdup("0")); + } + } + + /* Creating the timeout entry */ os_calloc(1, sizeof(timeout_data), timeout_entry); timeout_entry->command = timeout_args; @@ -506,9 +602,9 @@ void ExecdStart(int q) { merror(LIST_ADD_ERROR, ARGV0); FreeTimeoutEntry(timeout_entry); - } + } } - + /* If no timeout, we still need to free it in here */ else { @@ -524,7 +620,7 @@ void ExecdStart(int q) childcount++; } - + /* We didn't add it to the timeout list */ else {