-/* @(#) $Id$ */
+/* @(#) $Id: ./src/os_execd/execd.c, 2011/09/08 dcid Exp $
+ */
/* Copyright (C) 2009 Trend Micro Inc.
* All right reserved.
/* 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)
{
/* Setting the name */
OS_SetName(ARGV0);
-
+
while((c = getopt(argc, argv, "Vtdhfu:g:D:c:")) != -1){
switch(c){
if(!optarg)
ErrorExit("%s: -D needs an argument.",ARGV0);
dir = optarg;
+ break;
case 'c':
if(!optarg)
ErrorExit("%s: -c needs an argument.",ARGV0);
break;
case 't':
test_config = 1;
- break;
+ break;
default:
help(ARGV0);
break;
ErrorExit(USER_ERROR,ARGV0,"",group);
- /* Privilege separation */
+ /* Privilege separation */
if(Privsep_SetGroup(gid) < 0)
ErrorExit(SETGID_ERROR,ARGV0,group);
/* 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 */
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));
/* Start up message */
verbose(STARTUP_MSG, ARGV0, (int)getpid());
-
- /* The real daemon Now */
+
+ /* The real daemon Now */
ExecdStart(m_queue);
-
+
exit(0);
}
{
return;
}
-
+
tmp_str = timeout_entry->command;
/* Clearing the command arguments */
{
int i, childcount = 0;
time_t curr_time;
-
+
char buffer[OS_MAXSTR + 1];
char *tmp_msg = NULL;
char *name;
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;
if (wp < 0)
{
merror(WAITPID_ERROR, ARGV0);
+ break;
}
/* if = 0, we still need to wait for the child process */
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);
}
}
-
+
/* Setting timeout to EXECD_TIMEOUT */
socket_timeout.tv_sec = EXECD_TIMEOUT;
socket_timeout.tv_usec= 0;
/* Getting application name */
name = buffer;
-
-
+
+
/* Zeroing the name */
tmp_msg = strchr(buffer, ' ');
if(!tmp_msg)
/* 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]);
i++;
}
-
+
/* Check this command was already executed. */
timeout_node = OSList_GetFirstNode(timeout_list);
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.
/* 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;
}
/* 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;
{
merror(LIST_ADD_ERROR, ARGV0);
FreeTimeoutEntry(timeout_entry);
- }
+ }
}
-
+
/* If no timeout, we still need to free it in here */
else
{
childcount++;
}
-
+
/* We didn't add it to the timeout list */
else
{