Esempio n. 1
0
/* Receive events from the server */
int receive_msg()
{
    ssize_t recv_b;
    netsize_t length;
    int reads = 0;
    char buffer[OS_MAXSTR + 1];
    char cleartext[OS_MAXSTR + 1];
    char *tmp_msg;

    memset(cleartext, '\0', OS_MAXSTR + 1);
    memset(buffer, '\0', OS_MAXSTR + 1);

    /* Read until no more messages are available */
    while (1) {
        if (agt->protocol == TCP_PROTO) {
            /* Only one read per call */
            if (reads++) {
                break;
            }

            recv_b = recv(agt->sock, (char*)&length, sizeof(length), MSG_WAITALL);

            /* Manager disconnected */
            if (recv_b <= 0) {
                return -1;
            }

            recv_b = recv(agt->sock, buffer, length, MSG_WAITALL);

            if (recv_b != length) {
                merror(RECV_ERROR, ARGV0);
                continue;
            }

        } else {
            recv_b = recv(agt->sock, buffer, OS_SIZE_1024, MSG_DONTWAIT);

            if (recv_b <= 0) {
                break;
            }
        }

        buffer[recv_b] = '\0';

        tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b - 1);
        if (tmp_msg == NULL) {
            merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]);
            continue;
        }

        /* Check for commands */
        if (IsValidHeader(tmp_msg)) {
            available_server = (int)time(NULL);

#ifdef WIN32
            /* Run timeout commands */
            if (agt->execdq >= 0) {
                WinTimeoutRun(available_server);
            }
#endif

            /* If it is an active response message */
            if (strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0) {
                tmp_msg += strlen(EXECD_HEADER);
#ifndef WIN32
                if (agt->execdq >= 0) {
                    if (OS_SendUnix(agt->execdq, tmp_msg, 0) < 0) {
                        merror("%s: Error communicating with execd",
                               ARGV0);
                    }
                }
#else
                /* Run on Windows */
                if (agt->execdq >= 0) {
                    WinExecdRun(tmp_msg);
                }
#endif

                continue;
            }

            /* Restart syscheck */
            else if (strcmp(tmp_msg, HC_SK_RESTART) == 0) {
                os_set_restart_syscheck();
                continue;
            }

            /* Ack from server */
            else if (strcmp(tmp_msg, HC_ACK) == 0) {
                continue;
            }

            /* Close any open file pointer if it was being written to */
            if (fp) {
                fclose(fp);
                fp = NULL;
            }

            /* File update message */
            if (strncmp(tmp_msg, FILE_UPDATE_HEADER,
                        strlen(FILE_UPDATE_HEADER)) == 0) {
                char *validate_file;

                tmp_msg += strlen(FILE_UPDATE_HEADER);

                /* Going to after the file sum */
                validate_file = strchr(tmp_msg, ' ');
                if (!validate_file) {
                    continue;
                }

                *validate_file = '\0';

                /* Copy the file sum */
                strncpy(file_sum, tmp_msg, 33);

                /* Set tmp_msg to the beginning of the file name */
                validate_file++;
                tmp_msg = validate_file;

                if ((validate_file = strchr(tmp_msg, '\n')) != NULL) {
                    *validate_file = '\0';
                }

                while ((validate_file = strchr(tmp_msg, '/')) != NULL) {
                    *validate_file = '-';
                }

                if (tmp_msg[0] == '.') {
                    tmp_msg[0] = '-';
                }

                snprintf(file, OS_SIZE_1024, "%s/%s",
                         SHAREDCFG_DIR,
                         tmp_msg);

                fp = fopen(file, "w");
                if (!fp) {
                    merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno));
                }
            }

            else if (strncmp(tmp_msg, FILE_CLOSE_HEADER,
                             strlen(FILE_CLOSE_HEADER)) == 0) {
                /* No error */
                os_md5 currently_md5;

                /* Close for the rename to work */
                if (fp) {
                    fclose(fp);
                    fp = NULL;
                }

                if (file[0] == '\0') {
                    /* Nothing to be done */
                }

                else if (OS_MD5_File(file, currently_md5, OS_TEXT) < 0) {
                    /* Remove file */
                    unlink(file);
                    file[0] = '\0';
                } else {
                    if (strcmp(currently_md5, file_sum) != 0) {
                        debug1("%s: ERROR: Failed md5 for: %s -- deleting.",
                               ARGV0, file);
                        unlink(file);
                    } else {
                        char *final_file;

                        /* Rename the file to its original name */
                        final_file = strrchr(file, '/');
                        if (final_file) {
                            if (strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0) {
                                UnmergeFiles(file, SHAREDCFG_DIR);
                            }
                        } else {
                            /* Remove file */
                            unlink(file);
                        }
                    }

                    file[0] = '\0';
                }
            }

            else {
                merror("%s: WARN: Unknown message received from server.", ARGV0);
            }
        }

        else if (fp) {
            available_server = (int)time(NULL);
            fprintf(fp, "%s", tmp_msg);
        }

        else {
            merror("%s: WARN: Unknown message received. No action defined.",
                   ARGV0);
        }
    }

    return 0;
}
Esempio n. 2
0
/* receiver_thread:
 * Receive events from the server.
 */
void *receiver_thread(void *none)
{
    int recv_b;

    char file[OS_SIZE_1024 +1];
    char buffer[OS_MAXSTR +1];

    char cleartext[OS_MAXSTR + 1];
    char *tmp_msg;

    char file_sum[34];

    fd_set fdset;
    struct timeval selecttime;

    FILE *fp;


    /* Setting FP to null, before starting */
    fp = NULL;

    memset(cleartext, '\0', OS_MAXSTR +1);
    memset(buffer, '\0', OS_MAXSTR +1);
    memset(file, '\0', OS_SIZE_1024 +1);
    memset(file_sum, '\0', 34);


    while(1)
    {
        /* sock must be set. */
        if(agt->sock == -1)
        {
            sleep(5);
            continue;
        }

        FD_ZERO(&fdset);
        FD_SET(agt->sock, &fdset);


        /* Wait for 30 seconds. */
        selecttime.tv_sec = 30;
        selecttime.tv_usec = 0;


        /* Wait with a timeout for any descriptor */
        recv_b = select(0, &fdset, NULL, NULL, &selecttime);
        if(recv_b == -1)
        {
            merror(SELECT_ERROR, ARGV0);
            sleep(30);
            continue;
        }
        else if(recv_b == 0)
        {
            continue;
        }

        /* Read until no more messages are available */
        while((recv_b = recv(agt->sock,buffer,OS_SIZE_1024, 0))>0)
        {
            /* Id of zero -- only one key allowed */
            tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b -1);
            if(tmp_msg == NULL)
            {
                merror(MSG_ERROR,ARGV0,agt->rip[agt->rip_id]);
                continue;
            }


            /* Check for commands */
            if(IsValidHeader(tmp_msg))
            {
                /* This is the only thread that modifies it */
                available_server = (int)time(NULL);


                /* Run timeout commands. */
                if(agt->execdq >= 0)
                    WinTimeoutRun(available_server);

                /* If it is an active response message */
                if(strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0)
                {
                    tmp_msg+=strlen(EXECD_HEADER);


                    /* Run on windows. */
                    if(agt->execdq >= 0)
                    {
                        WinExecdRun(tmp_msg);
                    }


                    continue;
                }


                /* Restart syscheck. */
                else if(strcmp(tmp_msg, HC_SK_RESTART) == 0)
                {
                    os_set_restart_syscheck();
                    continue;
                }


                /* Ack from server */
                else if(strcmp(tmp_msg, HC_ACK) == 0)
                {
                    continue;
                }

                /* Close any open file pointer if it was being written to */
                if(fp)
                {
                    fclose(fp);
                    fp = NULL;
                }

                /* File update message */
                if(strncmp(tmp_msg, FILE_UPDATE_HEADER,
                                    strlen(FILE_UPDATE_HEADER)) == 0)
                {
                    char *validate_file;
                    tmp_msg+=strlen(FILE_UPDATE_HEADER);

                    /* Going to after the file sum */
                    validate_file = strchr(tmp_msg, ' ');
                    if(!validate_file)
                    {
                        continue;
                    }

                    *validate_file = '\0';

                    /* copying the file sum */
                    strncpy(file_sum, tmp_msg, 33);


                    /* Setting tmp_msg to the beginning of the file name */
                    validate_file++;
                    tmp_msg = validate_file;


                    if((validate_file = strchr(tmp_msg, '\n')) != NULL)
                    {
                        *validate_file = '\0';
                    }

                    while((validate_file = strchr(tmp_msg, '/')) != NULL)
                    {
                        *validate_file = '-';
                    }

                    if(tmp_msg[0] == '.')
                        tmp_msg[0] = '-';


                    snprintf(file, OS_SIZE_1024, "%s/%s",
                            SHAREDCFG_DIR,
                            tmp_msg);

                    fp = fopen(file, "w");
                    if(!fp)
                    {
                        merror(FOPEN_ERROR, ARGV0, file);
                    }
                }

                else if(strncmp(tmp_msg, FILE_CLOSE_HEADER,
                                         strlen(FILE_CLOSE_HEADER)) == 0)
                {
                    /* no error */
                    os_md5 currently_md5;

                    /* Making sure to close for the rename to work */
                    if(fp)
                    {
                        fclose(fp);
                        fp = NULL;
                    }

                    if(file[0] == '\0')
                    {
                        /* nada */
                    }

                    else if(OS_MD5_File(file, currently_md5) < 0)
                    {
                        /* Removing file */
                        unlink(file);
                        file[0] = '\0';
                    }
                    else
                    {
                        if(strcmp(currently_md5, file_sum) != 0)
                        {
                            debug1("%s: Failed md5 for: %s -- deleting.",
                                   ARGV0, file);
                            unlink(file);
                        }
                        else
                        {
                            char *final_file;

                            /* Renaming the file to its orignal name */
                            final_file = strrchr(file, '/');
                            if(final_file)
                            {
                                if(strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0)
                                {
                                    UnmergeFiles(file, SHAREDCFG_DIR);
                                }
                            }
                            else
                            {
                                unlink(file);
                            }
                        }

                        file[0] = '\0';
                    }
                }

                else
                {
                    merror("%s: WARN: Unknown message received from server.", ARGV0);
                }
            }

            else if(fp)
            {
                available_server = (int)time(NULL);
                fprintf(fp, "%s", tmp_msg);
            }

            else
            {
                merror("%s: WARN: Unknown message received. No action defined.",
                       ARGV0);
            }
        }
    }


    /* Cleaning up */
    if(fp)
    {
        fclose(fp);
        if(file[0] != '\0')
            unlink(file);
    }

    return(NULL);

}
Esempio n. 3
0
/* start_agent: Sends the synchronization message to
 * the server and waits for the ack.
 */
void start_agent(int is_startup)
{
    int recv_b = 0, attempts = 0, g_attempts = 1;

    char *tmp_msg;
    char msg[OS_MAXSTR +2];
    char buffer[OS_MAXSTR +1];
    char cleartext[OS_MAXSTR +1];
    char fmsg[OS_MAXSTR +1];


    memset(msg, '\0', OS_MAXSTR +2);
    memset(buffer, '\0', OS_MAXSTR +1);
    memset(cleartext, '\0', OS_MAXSTR +1);
    memset(fmsg, '\0', OS_MAXSTR +1);
    snprintf(msg, OS_MAXSTR, "%s%s", CONTROL_HEADER, HC_STARTUP);


    #ifdef ONEWAY
    return;
    #endif


    /* Sending start message and waiting for the ack */
    while(1)
    {
        /* Sending start up message */
        send_msg(0, msg);
        attempts = 0;


        /* Read until our reply comes back */
        while(((recv_b = recv(agt->sock, buffer, OS_MAXSTR,
                              MSG_DONTWAIT)) >= 0) || (attempts <= 5))
        {
            if(recv_b <= 0)
            {
                /* Sleep five seconds before trying to get the reply from
                 * the server again.
                 */
                attempts++;
                sleep(attempts);

                /* Sending message again (after three attempts) */
                if(attempts >= 3)
                {
                    send_msg(0, msg);
                }

                continue;
            }

            /* Id of zero -- only one key allowed */
            tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b -1);
            if(tmp_msg == NULL)
            {
                merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]);
                continue;
            }


            /* Check for commands */
            if(IsValidHeader(tmp_msg))
            {
                /* If it is an ack reply */
                if(strcmp(tmp_msg, HC_ACK) == 0)
                {
                    available_server = time(0);

                    verbose(AG_CONNECTED, ARGV0, agt->rip[agt->rip_id],
                                                 agt->port);

                    if(is_startup)
                    {
                        /* Send log message about start up */
                        snprintf(msg, OS_MAXSTR, OS_AG_STARTED,
                                keys.keyentries[0]->name,
                                keys.keyentries[0]->ip->ip);
                        snprintf(fmsg, OS_MAXSTR, "%c:%s:%s", LOCALFILE_MQ,
                                                  "ossec", msg);
                        send_msg(0, fmsg);
                    }
                    return;
                }
            }
        }

        /* Waiting for servers reply */
        merror(AG_WAIT_SERVER, ARGV0, agt->rip[agt->rip_id]);


        /* If we have more than one server, try all. */
        if(agt->rip[1])
        {
            int curr_rip = agt->rip_id;
            merror("%s: INFO: Trying next server ip in the line: '%s'.", ARGV0,
                   agt->rip[agt->rip_id + 1] != NULL?agt->rip[agt->rip_id + 1]:agt->rip[0]);
            connect_server(agt->rip_id +1);

            if(agt->rip_id == curr_rip)
            {
                sleep(g_attempts);
                g_attempts+=(attempts * 3);
            }
            else
            {
                g_attempts+=5;
                sleep(g_attempts);
            }
        }
        else
        {
            sleep(g_attempts);
            g_attempts+=(attempts * 3);

            connect_server(0);
        }
    }


    return;
}
Esempio n. 4
0
/* Handle secure connections */
void HandleSecure()
{
    int agentid;
    char buffer[OS_MAXSTR + 1];
    char cleartext_msg[OS_MAXSTR + 1];
    char srcip[IPSIZE + 1];
    char *tmp_msg;
    char srcmsg[OS_FLSIZE + 1];
    ssize_t recv_b;
    struct sockaddr_in peer_info;
    socklen_t peer_size;

    /* Send msg init */
    send_msg_init();

    /* Initialize key mutex */
    keyupdate_init();

    /* Initialize manager */
    manager_init(0);

    /* Create Active Response forwarder thread */
    if (CreateThread(AR_Forward, (void *)NULL) != 0) {
        ErrorExit(THREAD_ERROR, ARGV0);
    }

    /* Create wait_for_msgs thread */
    if (CreateThread(wait_for_msgs, (void *)NULL) != 0) {
        ErrorExit(THREAD_ERROR, ARGV0);
    }

    /* Connect to the message queue
     * Exit if it fails.
     */
    if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
        ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
    }

    verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS);

    /* Read authentication keys */
    verbose(ENC_READ, ARGV0);

    OS_ReadKeys(&keys);


    OS_StartCounter(&keys);


    /* Set up peer size */
    peer_size = sizeof(peer_info);
    logr.peer_size = sizeof(peer_info);

    /* Initialize some variables */
    memset(buffer, '\0', OS_MAXSTR + 1);
    memset(cleartext_msg, '\0', OS_MAXSTR + 1);
    memset(srcmsg, '\0', OS_FLSIZE + 1);
    tmp_msg = NULL;

    while (1) {
        /* Receive message  */
        recv_b = recvfrom(logr.sock, buffer, OS_MAXSTR, 0,
                          (struct sockaddr *)&peer_info, &peer_size);

        /* Nothing received */
        if (recv_b <= 0) {
            continue;
        }

        /* Set the source IP */
        strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE);
        srcip[IPSIZE] = '\0';

        /* Get a valid agent id */
        if (buffer[0] == '!') {
            tmp_msg = buffer;
            tmp_msg++;

            /* We need to make sure that we have a valid id
             * and that we reduce the recv buffer size
             */
            while (isdigit((int)*tmp_msg)) {
                tmp_msg++;
                recv_b--;
            }

            if (*tmp_msg != '!') {
                merror(ENCFORMAT_ERROR, __local_name, srcip);
                continue;
            }

            *tmp_msg = '\0';
            tmp_msg++;
            recv_b -= 2;

            agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);

            if (agentid == -1) {
                if (check_keyupdate()) {
                    agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip);
                    if (agentid == -1) {
                        merror(ENC_IP_ERROR, ARGV0, srcip);
                        continue;
                    }
                } else {
                    merror(ENC_IP_ERROR, ARGV0, srcip);
                    continue;
                }
            }
        } else {
            agentid = OS_IsAllowedIP(&keys, srcip);

            if (agentid < 0) {
                if (check_keyupdate()) {
                    agentid = OS_IsAllowedIP(&keys, srcip);
                    if (agentid == -1) {
                        merror(DENYIP_WARN, ARGV0, srcip);
                        continue;
                    }
                } else {
                    merror(DENYIP_WARN, ARGV0, srcip);
                    continue;
                }
            }
            tmp_msg = buffer;

        }

        /* Decrypt the message */
        tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg,
                             agentid, recv_b - 1);

        if (tmp_msg == NULL) {

            /* If duplicated, a warning was already generated */
            continue;
        }


        /* Check if it is a control message */
        if (IsValidHeader(tmp_msg)) {
            /* We need to save the peerinfo if it is a control msg */
            memcpy(&keys.keyentries[agentid]->peer_info, &peer_info, peer_size);
            keys.keyentries[agentid]->rcvd = time(0);

            save_controlmsg((unsigned)agentid, tmp_msg);

            continue;
        }

        /* Generate srcmsg */
        snprintf(srcmsg, OS_FLSIZE, "(%s) %s", keys.keyentries[agentid]->name,
                 keys.keyentries[agentid]->ip->ip);

        /* If we can't send the message, try to connect to the
         * socket again. If it not exit.
         */
        if (SendMSG(logr.m_queue, tmp_msg, srcmsg,
                    SECURE_MQ) < 0) {
            merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));

            if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) {
                ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE);
            }
        }
    }
}