Exemplo n.º 1
0
END_TEST

START_TEST(test_unixinvalidsockets)
{
    char buffer[BUFFERSIZE];

    ck_assert_int_eq(OS_SendUnix(-1, SENDSTRING, strlen(SENDSTRING)), OS_SOCKTERR);

    ck_assert_int_eq(OS_RecvUnix(-1, BUFFERSIZE, buffer), 0);
}
Exemplo n.º 2
0
END_TEST

START_TEST(test_unix)
{
    int fd;

    /* create socket path */
    char socket_path[256];
    strncpy(socket_path, "/tmp/tmp_file-XXXXXX", 256);
    fd = mkstemp(socket_path);
    close(fd);

    int server_socket, client_socket;
    const int msg_size = 2048;
    char buffer[BUFFERSIZE];

    ck_assert_int_ge((server_socket = OS_BindUnixDomain(socket_path, 0660, msg_size)), 0);

    ck_assert_int_ge(OS_getsocketsize(server_socket), msg_size);

    ck_assert_int_ge((client_socket = OS_ConnectUnixDomain(socket_path, msg_size)), 0);

    ck_assert_int_eq(OS_SendUnix(client_socket, SENDSTRING, 5), 0);

    ck_assert_int_eq(OS_RecvUnix(server_socket, BUFFERSIZE, buffer), 5);

    ck_assert_str_eq(buffer, "Hello");

    ck_assert_int_eq(OS_SendUnix(client_socket, SENDSTRING, 0), 0);

    ck_assert_int_eq(OS_RecvUnix(server_socket, BUFFERSIZE, buffer), strlen(SENDSTRING) + 1);

    ck_assert_str_eq(buffer, SENDSTRING);

    OS_CloseSocket(client_socket);
    OS_CloseSocket(server_socket);

    unlink(socket_path);
}
Exemplo n.º 3
0
void OS_ReadMSG_analysisd(int m_queue)
#endif
{
    int i;
    char msg[OS_MAXSTR +1];
    Eventinfo *lf;

    RuleInfo *stats_rule = NULL;


    /* Null to global currently pointers */
    currently_rule = NULL;

    /* Initiating the logs */
    OS_InitLog();


    /* Initiating the integrity database */
    SyscheckInit();


    /* Initializing Rootcheck */
    RootcheckInit();


    /* Initializing host info */
    HostinfoInit();


    /* Creating the event list */
    OS_CreateEventList(Config.memorysize);


    /* Initiating the FTS list */
    if(!FTS_Init())
    {
        ErrorExit(FTS_LIST_ERROR, ARGV0);
    }

    /* Initialize the Accumulator */
    if(!Accumulate_Init()) {
        merror("accumulator: ERROR: Initialization failed");
        exit(1);
    }

    /* Starting the active response queues */
    if(Config.ar)
    {
        /* Waiting the ARQ to settle .. */
        sleep(3);


        #ifndef LOCAL
        if(Config.ar & REMOTE_AR)
        {
            if((arq = StartMQ(ARQUEUE, WRITE)) < 0)
            {
                merror(ARQ_ERROR, ARGV0);

                /* If LOCAL_AR is set, keep it there */
                if(Config.ar & LOCAL_AR)
                {
                    Config.ar = 0;
                    Config.ar|=LOCAL_AR;
                }
                else
                {
                    Config.ar = 0;
                }
            }
            else
            {
                verbose(CONN_TO, ARGV0, ARQUEUE, "active-response");
            }
        }

        #else
        /* Only for LOCAL_ONLY installs */
        if(Config.ar & REMOTE_AR)
        {
            if(Config.ar & LOCAL_AR)
            {
                Config.ar = 0;
                Config.ar|=LOCAL_AR;
            }
            else
            {
                Config.ar = 0;
            }
        }
        #endif

        if(Config.ar & LOCAL_AR)
        {
            if((execdq = StartMQ(EXECQUEUE, WRITE)) < 0)
            {
                merror(ARQ_ERROR, ARGV0);

                /* If REMOTE_AR is set, keep it there */
                if(Config.ar & REMOTE_AR)
                {
                    Config.ar = 0;
                    Config.ar|=REMOTE_AR;
                }
                else
                {
                    Config.ar = 0;
                }
            }
            else
            {
                verbose(CONN_TO, ARGV0, EXECQUEUE, "exec");
            }
        }
    }
    debug1("%s: DEBUG: Active response Init completed.", ARGV0);


    /* Getting currently time before starting */
    c_time = time(NULL);


    /* Starting the hourly/weekly stats */
    if(Start_Hour() < 0)
        Config.stats = 0;
    else
    {
        /* Initializing stats rules */
        stats_rule = zerorulemember(
                STATS_MODULE,
                Config.stats,
                0,0,0,0,0,0);

        if(!stats_rule)
        {
            ErrorExit(MEM_ERROR, ARGV0);
        }
        stats_rule->group = "stats,";
        stats_rule->comment = "Excessive number of events (above normal).";
    }


    /* Doing some cleanup */
    memset(msg, '\0', OS_MAXSTR +1);


    /* Initializing the logs */
    {
        lf = (Eventinfo *)calloc(1,sizeof(Eventinfo));
        if(!lf)
            ErrorExit(MEM_ERROR, ARGV0);
        lf->year = prev_year;
        strncpy(lf->mon, prev_month, 3);
        lf->day = today;

        if(OS_GetLogLocation(lf) < 0)
        {
            ErrorExit("%s: Error allocating log files", ARGV0);
        }

        Free_Eventinfo(lf);
    }


    debug1("%s: DEBUG: Startup completed. Waiting for new messages..",ARGV0);

    if(Config.custom_alert_output)
      debug1("%s: INFO: Custom output found.!",ARGV0);

    /* Daemon loop */
    while(1)
    {
        lf = (Eventinfo *)calloc(1,sizeof(Eventinfo));

        /* This shouldn't happen .. */
        if(lf == NULL)
        {
            ErrorExit(MEM_ERROR,ARGV0);
        }

        DEBUG_MSG("%s: DEBUG: Waiting for msgs - %d ", ARGV0, (int)time(0));


        /* Receive message from queue */
        if((i = OS_RecvUnix(m_queue, OS_MAXSTR, msg)))
        {
            RuleNode *rulenode_pt;

            /* Getting the time we received the event */
            c_time = time(NULL);


            /* Default values for the log info */
            Zero_Eventinfo(lf);


            /* Checking for a valid message. */
            if(i < 4)
            {
                merror(IMSG_ERROR, ARGV0, msg);
                Free_Eventinfo(lf);
                continue;
            }


            /* Message before extracting header */
            DEBUG_MSG("%s: DEBUG: Received msg: %s ", ARGV0, msg);


            /* Clean the msg appropriately */
            if(OS_CleanMSG(msg, lf) < 0)
            {
                merror(IMSG_ERROR,ARGV0, msg);
                Free_Eventinfo(lf);
                continue;
            }


            /* Msg cleaned */
            DEBUG_MSG("%s: DEBUG: Msg cleanup: %s ", ARGV0, lf->log);


            /* Currently rule must be null in here */
            currently_rule = NULL;


            /** Checking the date/hour changes **/

            /* Update the hour */
            if(thishour != __crt_hour)
            {
                /* Search all the rules and print the number
                 * of alerts that each one fired.
                 */
                DumpLogstats();
                thishour = __crt_hour;

                /* Check if the date has changed */
                if(today != lf->day)
                {
                    if(Config.stats)
                    {
                        /* Update the hourly stats (done daily) */
                        Update_Hour();
                    }

                    if(OS_GetLogLocation(lf) < 0)
                    {
                        ErrorExit("%s: Error allocating log files", ARGV0);
                    }

                    today = lf->day;
                    strncpy(prev_month, lf->mon, 3);
                    prev_year = lf->year;
                }
            }


            /* Incrementing number of events received */
            hourly_events++;


            /***  Running decoders ***/

            /* Integrity check from syscheck */
            if(msg[0] == SYSCHECK_MQ)
            {
                hourly_syscheck++;

                if(!DecodeSyscheck(lf))
                {
                    /* We don't process syscheck events further */
                    goto CLMEM;
                }

                /* Getting log size */
                lf->size = strlen(lf->log);
            }

            /* Rootcheck decoding */
            else if(msg[0] == ROOTCHECK_MQ)
            {
                if(!DecodeRootcheck(lf))
                {
                    /* We don't process rootcheck events further */
                    goto CLMEM;
                }
                lf->size = strlen(lf->log);
            }

            /* Host information special decoder */
            else if(msg[0] == HOSTINFO_MQ)
            {
                if(!DecodeHostinfo(lf))
                {
                    /* We don't process hostinfo events further */
                    goto CLMEM;
                }
                lf->size = strlen(lf->log);
            }

            /* Run the general Decoders  */
            else
            {
                /* Getting log size */
                lf->size = strlen(lf->log);

                DecodeEvent(lf);
            }

            /* Run accumulator */
            if( lf->decoder_info->accumulate == 1 ) {
                lf = Accumulate(lf);
            }

            /* Firewall event */
            if(lf->decoder_info->type == FIREWALL)
            {
                /* If we could not get any information from
                 * the log, just ignore it
                 */
                hourly_firewall++;
                if(Config.logfw)
                {
                    if(!FW_Log(lf))
                    {
                        goto CLMEM;
                    }
                }
            }


            /* We only check if the last message is
             * duplicated on syslog.
             */
            else if(lf->decoder_info->type == SYSLOG)
            {
                /* Checking if the message is duplicated */
                if(LastMsg_Stats(lf->full_log) == 1)
                    goto CLMEM;
                else
                    LastMsg_Change(lf->full_log);
            }


            /* Stats checking */
            if(Config.stats)
            {
                if(Check_Hour() == 1)
                {
                    void *saved_rule = lf->generated_rule;
                    char *saved_log;

                    /* Saving previous log */
                    saved_log = lf->full_log;

                    lf->generated_rule = stats_rule;
                    lf->full_log = __stats_comment;


                    /* alert for statistical analysis */
                    if(stats_rule->alert_opts & DO_LOGALERT)
                    {
                        __crt_ftell = ftell(_aflog);
                        if(Config.custom_alert_output)
                        {
                          OS_CustomLog(lf,Config.custom_alert_output_format);
                        }
                        else
                        {
                          OS_Log(lf);
                        }

                    }


                    /* Set lf to the old values */
                    lf->generated_rule = saved_rule;
                    lf->full_log = saved_log;
                }
            }


            /* Checking the rules */
            DEBUG_MSG("%s: DEBUG: Checking the rules - %d ",
                           ARGV0, lf->decoder_info->type);


            /* Looping all the rules */
            rulenode_pt = OS_GetFirstRule();
            if(!rulenode_pt)
            {
                ErrorExit("%s: Rules in an inconsistent state. Exiting.",
                        ARGV0);
            }


            do
            {
                if(lf->decoder_info->type == OSSEC_ALERT)
                {
                    if(!lf->generated_rule)
                    {
                        goto CLMEM;
                    }

                    /* We go ahead in here and process the alert. */
                    currently_rule = lf->generated_rule;
                }

                /* The categories must match */
                else if(rulenode_pt->ruleinfo->category !=
                        lf->decoder_info->type)
                {
                    continue;
                }

                /* Checking each rule. */
                else if((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt))
                        == NULL)
                {
                    continue;
                }


                /* Ignore level 0 */
                if(currently_rule->level == 0)
                {
                    break;
                }


                /* Checking ignore time */
                if(currently_rule->ignore_time)
                {
                    if(currently_rule->time_ignored == 0)
                    {
                        currently_rule->time_ignored = lf->time;
                    }
                    /* If the currently time - the time the rule was ignored
                     * is less than the time it should be ignored,
                     * leave (do not alert again).
                     */
                    else if((lf->time - currently_rule->time_ignored)
                            < currently_rule->ignore_time)
                    {
                        break;
                    }
                    else
                    {
                        currently_rule->time_ignored = lf->time;
                    }
                }


                /* Pointer to the rule that generated it */
                lf->generated_rule = currently_rule;


                /* Checking if we should ignore it */
                if(currently_rule->ckignore && IGnore(lf))
                {
                    /* Ignoring rule */
                    lf->generated_rule = NULL;
                    break;
                }


                /* Checking if we need to add to ignore list */
                if(currently_rule->ignore)
                {
                    AddtoIGnore(lf);
                }


                /* Log the alert if configured to ... */
                if(currently_rule->alert_opts & DO_LOGALERT)
                {
                    __crt_ftell = ftell(_aflog);

                    if(Config.custom_alert_output)
                    {
                      OS_CustomLog(lf,Config.custom_alert_output_format);
                    }
                    else
                    {
                      OS_Log(lf);
                    }
                }


                /* Log to prelude */
                #ifdef PRELUDE
                if(Config.prelude)
                {
                    if(Config.prelude_log_level <= currently_rule->level)
                    {
                        OS_PreludeLog(lf);
                    }
                }
                #endif

                /* Log to zeromq */
                #ifdef ZEROMQ_OUTPUT
                if(Config.zeromq_output)
                {
                    zeromq_output_event(lf);
                }
                #endif


                /* Log to Picviz */
                if (Config.picviz)
                {
                    OS_PicvizLog(lf);
                }


                /* Execute an active response */
                if(currently_rule->ar)
                {
                    int do_ar;
                    active_response **rule_ar;

                    rule_ar = currently_rule->ar;

                    while(*rule_ar)
                    {
                        do_ar = 1;
                        if((*rule_ar)->ar_cmd->expect & USERNAME)
                        {
                            if(!lf->dstuser ||
                                !OS_PRegex(lf->dstuser,"^[a-zA-Z._0-9@?-]*$"))
                            {
                                if(lf->dstuser)
                                    merror(CRAFTED_USER, ARGV0, lf->dstuser);
                                do_ar = 0;
                            }
                        }
                        if((*rule_ar)->ar_cmd->expect & SRCIP)
                        {
                            if(!lf->srcip ||
                                !OS_PRegex(lf->srcip, "^[a-zA-Z.:_0-9-]*$"))
                            {
                                if(lf->srcip)
                                    merror(CRAFTED_IP, ARGV0, lf->srcip);
                                do_ar = 0;
                            }
                        }
                        if((*rule_ar)->ar_cmd->expect & FILENAME)
                        {
                            if(!lf->filename)
                            {
                                do_ar = 0;
                            }
                        }

                        if(do_ar)
                        {
                            OS_Exec(&execdq, &arq, lf, *rule_ar);
                        }
                        rule_ar++;
                    }
                }


                /* Copy the structure to the state memory of if_matched_sid */
                if(currently_rule->sid_prev_matched)
                {
                    if(!OSList_AddData(currently_rule->sid_prev_matched, lf))
                    {
                        merror("%s: Unable to add data to sig list.", ARGV0);
                    }
                    else
                    {
                        lf->sid_node_to_delete =
                            currently_rule->sid_prev_matched->last_node;
                    }
                }
                /* Group list */
                else if(currently_rule->group_prev_matched)
                {
                    i = 0;

                    while(i < currently_rule->group_prev_matched_sz)
                    {
                        if(!OSList_AddData(
                                currently_rule->group_prev_matched[i],
                                lf))
                        {
                           merror("%s: Unable to add data to grp list.",ARGV0);
                        }
                        i++;
                    }
                }

                OS_AddEvent(lf);

                break;

            }while((rulenode_pt = rulenode_pt->next) != NULL);


            /* If configured to log all, do it */
            if(Config.logall)
                OS_Store(lf);


            /* Cleaning the memory */
            CLMEM:


            /* Only clear the memory if the eventinfo was not
             * added to the stateful memory
             * -- message is free inside clean event --
             */
            if(lf->generated_rule == NULL)
                Free_Eventinfo(lf);

        }
        else
        {
            free(lf);
        }
    }
    return;
}
Exemplo n.º 4
0
/** void *AR_Forward(void *arg) v0.1
 * Start of a new thread. Only returns
 * on unrecoverable errors.
 */
void *AR_Forward(void *arg)
{
    int i = 0;
    int arq = 0;
    int agent_id = 0;
    int ar_location = 0;
    
    char msg_to_send[OS_SIZE_1024 +1];
    
    char msg[OS_SIZE_1024 +1];
    char *location = NULL;
    char *ar_location_str = NULL;
    char *ar_agent_id = NULL;
    char *tmp_str = NULL;


    /* Creating the unix queue */
    if((arq = StartMQ(ARQUEUE, READ)) < 0)
    {
        ErrorExit(QUEUE_ERROR, ARGV0, ARQUEUE, strerror(errno));
    }

    memset(msg, '\0', OS_SIZE_1024 +1);

    /* Daemon loop */
    while(1)
    {
        if(OS_RecvUnix(arq, OS_SIZE_1024, msg))
        {
            /* Always zeroing the location */
            ar_location = 0;
            
            
            /* Getting the location */
            location = msg;


            /* Location is going to be the agent name */
            tmp_str = strchr(msg, ')');
            if(!tmp_str)
            {
                merror(EXECD_INV_MSG, ARGV0, msg);
                continue;
            }
            *tmp_str = '\0';


            /* Going after the ')' and space */
            tmp_str += 2;


            /* Extracting the source ip */
            tmp_str = strchr(tmp_str, ' ');
            if(!tmp_str)
            {
                merror(EXECD_INV_MSG, ARGV0, msg);
                continue;
            }
            tmp_str++;
            location++;


            /* Setting ar_location */
            ar_location_str = tmp_str;
            if(*tmp_str == ALL_AGENTS_C)
            {
                ar_location|=ALL_AGENTS;
            }
            tmp_str++;
            if(*tmp_str == REMOTE_AGENT_C)
            {
                ar_location|=REMOTE_AGENT;
            }
            else if(*tmp_str == NO_AR_C)
            {
                ar_location|=NO_AR_MSG;
            }
            tmp_str++;
            if(*tmp_str == SPECIFIC_AGENT_C)
            {
                ar_location|=SPECIFIC_AGENT;
            }
            
            
            /*** Extracting the active response location ***/
            tmp_str = strchr(ar_location_str, ' ');
            if(!tmp_str)
            {
                merror(EXECD_INV_MSG, ARGV0, msg);
                continue;
            }
            *tmp_str = '\0';
            tmp_str++;


            /*** Extracting the agent id */
            ar_agent_id = tmp_str;
            tmp_str = strchr(tmp_str, ' ');
            if(!tmp_str)
            {
                merror(EXECD_INV_MSG, ARGV0, msg);
                continue;
            }
            *tmp_str = '\0';
            tmp_str++;
            
            
            /*** Creating the new message ***/
            if(ar_location & NO_AR_MSG)
            {
                snprintf(msg_to_send, OS_SIZE_1024, "%s%s", 
                                      CONTROL_HEADER,
                                      tmp_str);
            }
            else
            {
                snprintf(msg_to_send, OS_SIZE_1024, "%s%s%s", 
                                      CONTROL_HEADER,
                                      EXECD_HEADER,
                                      tmp_str);
            }

            
            /* Lock use of keys */
            key_lock();
            
            
            /* Sending to ALL agents */
            if(ar_location & ALL_AGENTS)
            {
                for(i = 0;i< keys.keysize; i++)
                {
                    send_msg(i, msg_to_send);
                }
            }

            /* Send to the remote agent that generated the event */
            else if((ar_location & REMOTE_AGENT) && (location != NULL))
            {
                agent_id = OS_IsAllowedName(&keys, location);
                if(agent_id < 0)
                {
                    key_unlock();
                    merror(AR_NOAGENT_ERROR, ARGV0, location);
                    continue;
                }
                
                send_msg(agent_id, msg_to_send);
            }

            /* Send to a pre-defined agent */
            else if(ar_location & SPECIFIC_AGENT)
            {
                ar_location++;

                agent_id = OS_IsAllowedID(&keys, ar_agent_id);
                
                if(agent_id < 0)
                {
                    key_unlock();
                    merror(AR_NOAGENT_ERROR, ARGV0, ar_agent_id);
                    continue;
                }

                send_msg(agent_id, msg_to_send);
            }

            /* Lock use of keys */
            key_unlock();
        }
    }
}
Exemplo n.º 5
0
/** void ExecdStart(int q) v0.2
 * Main function on the execd. Does all the data receiving ,etc.
 */
static void ExecdStart(int q)
{
    int i, childcount = 0;
    time_t curr_time;

    char buffer[OS_MAXSTR + 1];
    char *tmp_msg = NULL;
    char *name;
    char *command;
    char *cmd_args[MAX_ARGS +2];


    /* Select */
    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();
    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;


        /* Cleaning up any child. */
        while (childcount)
        {
            int wp;
            wp = waitpid((pid_t) -1, NULL, WNOHANG);
            if (wp < 0)
            {
                merror(WAITPID_ERROR, ARGV0, errno, strerror(errno));
                break;
            }

            /* if = 0, we still need to wait for the child process */
            else if (wp == 0)
            {
                break;
            }
            /* Child completed if wp > 0 */
            else
            {
                childcount--;
            }
        }


        /* Getting currently time */
        curr_time = time(0);


        /* Checking if there is any timeouted command to execute. */
        timeout_node = OSList_GetFirstNode(timeout_list);
        while(timeout_node)
        {
            timeout_data *list_entry;

            list_entry = (timeout_data *)timeout_node->data;

            /* Timeouted */
            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);

                /* Clearing the memory */
                FreeTimeoutEntry(list_entry);

                childcount++;
            }

            else
            {
                timeout_node = OSList_GetNextNode(timeout_list);
            }
        }


        /* Setting timeout to EXECD_TIMEOUT */
        socket_timeout.tv_sec = EXECD_TIMEOUT;
        socket_timeout.tv_usec= 0;



        /* Setting FD values */
        FD_ZERO(&fdset);
        FD_SET(q, &fdset);

        /* Adding timeout */
        if(select(q+1, &fdset, NULL, NULL, &socket_timeout) == 0)
        {
            /* Timeout .. */
            continue;
        }


        /* Checking for error */
        if(!FD_ISSET(q, &fdset))
        {
            merror(SELECT_ERROR, ARGV0, errno, strerror(errno));
            continue;
        }


        /* Receiving the message */
        if(OS_RecvUnix(q, OS_MAXSTR, buffer) == 0)
        {
            merror(QUEUE_ERROR, ARGV0, EXECQUEUEPATH, strerror(errno));
            continue;
        }


        /* Currently time */
        curr_time = time(0);


        /* Getting application name */
        name = buffer;


        /* Zeroing the name */
        tmp_msg = strchr(buffer, ' ');
        if(!tmp_msg)
        {
            merror(EXECD_INV_MSG, ARGV0, buffer);
            continue;
        }
        *tmp_msg = '\0';
        tmp_msg++;


        /* Getting the command to execute (valid name) */
        command = GetCommandbyName(name, &timeout_value);
        if(!command)
        {
            ReadExecConfig();
            command = GetCommandbyName(name, &timeout_value);
            if(!command)
            {
                merror(EXEC_INV_NAME, ARGV0, name);
                continue;
            }
        }


        /* Command not present. */
        if(command[0] == '\0')
            continue;


        /* 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[1] = ADD_ENTRY;
        os_strdup(command, timeout_args[0]);
        os_strdup(DELETE_ENTRY, timeout_args[1]);

        cmd_args[2] = NULL;
        timeout_args[2] = NULL;


        /* Getting the arguments. */
        i = 2;
        while(i < (MAX_ARGS -1))
        {
            cmd_args[i] = tmp_msg;
            cmd_args[i+1] = NULL;

            tmp_msg = strchr(tmp_msg, ' ');
            if(!tmp_msg)
            {
                timeout_args[i] = strdup(cmd_args[i]);
                timeout_args[i+1] = NULL;
                break;
            }
            *tmp_msg = '\0';
            tmp_msg++;

            timeout_args[i] = strdup(cmd_args[i]);
            timeout_args[i+1] = NULL;

            i++;
        }


        /* Check this command was already executed. */
        timeout_node = OSList_GetFirstNode(timeout_list);
        added_before = 0;


        /* Checking for the username and ip argument */
        if(!timeout_args[2] || !timeout_args[3])
        {
            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))
            {
                /* Means we executed this command before
                 * and we don't need to add it again.
                 */
                added_before = 1;


                /* 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 = (char *) 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
                        {
                            free(ntimes);       // In hash_op.c, data belongs to caller
                            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;
            }

            /* Continue with the next entry in timeout list*/
            timeout_node = OSList_GetNextNode(timeout_list);
        }


        /* If it wasn't added before, do it now */
        if(!added_before)
        {
            /* executing command */
            ExecCmd(cmd_args);

            /* 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 = (char *) 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,
                           rkey, strdup("0"));
                  }
                }


                /* Creating the timeout entry */
                os_calloc(1, sizeof(timeout_data), timeout_entry);
                timeout_entry->command = timeout_args;
                timeout_entry->time_of_addition = curr_time;
                timeout_entry->time_to_block = timeout_value;


                /* Adding command to the timeout list */
                if(!OSList_AddData(timeout_list, timeout_entry))
                {
                    merror(LIST_ADD_ERROR, ARGV0);
                    FreeTimeoutEntry(timeout_entry);
                }
            }

            /* If no timeout, we still need to free it in here */
            else
            {
                char **ss_ta = timeout_args;
                while(*timeout_args)
                {
                    os_free(*timeout_args);
                    *timeout_args = NULL;
                    timeout_args++;
                }
                os_free(ss_ta);
            }

            childcount++;
        }

        /* We didn't add it to the timeout list */
        else
        {
            char **ss_ta = timeout_args;

            /* Clear the timeout arguments */
            while(*timeout_args)
            {
                os_free(*timeout_args);
                *timeout_args = NULL;
                timeout_args++;
            }

            os_free(ss_ta);
        }

        /* Some cleanup */
        while(i > 0)
        {
            cmd_args[i] = NULL;
            i--;
        }
    }
}