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;
}
/** main **/
int main(int argc, char **argv)
{
    char *dir = DEFAULTDIR;
    char *group = GROUPGLOBAL;
    char *user = USER;
    char *agent_id = NULL;
    char *ip_address = NULL;
    char *ar = NULL;

    int arq = 0;
    int gid = 0;
    int uid = 0;
    int c = 0, restart_syscheck = 0, restart_all_agents = 0, list_agents = 0;
    int info_agent = 0, agt_id = 0, active_only = 0, csv_output = 0;
    int list_responses = 0, end_time = 0, restart_agent = 0;

    char shost[512];

    keystore keys;



    /* Setting the name */
    OS_SetName(ARGV0);


    /* user arguments */
    if(argc < 2)
    {
        helpmsg();
    }


    while((c = getopt(argc, argv, "VehdlLcsaru:i:b:f:R:")) != -1)
    {
        switch(c){
            case 'V':
                print_version();
                break;
            case 'h':
                helpmsg();
                break;
            case 'd':
                nowDebug();
                break;
            case 'L':
                list_responses = 1;
                break;
            case 'e':
                end_time = 1;
                break;
            case 'r':
                restart_syscheck = 1;
                break;
            case 'l':
                list_agents++;
                break;
            case 's':
                csv_output = 1;
                break;
            case 'c':
                active_only++;
                break;
            case 'i':
                info_agent++;
            case 'u':
                if(!optarg)
                {
                    merror("%s: -u needs an argument",ARGV0);
                    helpmsg();
                }
                agent_id = optarg;
                break;
            case 'b':
                if(!optarg)
                {
                    merror("%s: -b needs an argument",ARGV0);
                    helpmsg();
                }
                ip_address = optarg;
                break;
            case 'f':
                if(!optarg)
                {
                    merror("%s: -e needs an argument",ARGV0);
                    helpmsg();
                }
                ar = optarg;
                break;
            case 'R':
                if(!optarg)
                {
                    merror("%s: -R needs an argument",ARGV0);
                    helpmsg();
                }
                agent_id = optarg;
                restart_agent = 1;
            case 'a':
                restart_all_agents = 1;
                break;
            default:
                helpmsg();
                break;
        }

    }


    /* Getting the group name */
    gid = Privsep_GetGroup(group);
    uid = Privsep_GetUser(user);
    if(gid < 0)
    {
	    ErrorExit(USER_ERROR, ARGV0, user, group);
    }
	

    /* Setting the group */
    if(Privsep_SetGroup(gid) < 0)
    {
	    ErrorExit(SETGID_ERROR,ARGV0, group);
    }


    /* Chrooting to the default directory */
    if(Privsep_Chroot(dir) < 0)
    {
        ErrorExit(CHROOT_ERROR, ARGV0, dir);
    }


    /* Inside chroot now */
    nowChroot();


    /* Setting the user */
    if(Privsep_SetUser(uid) < 0)
    {
        ErrorExit(SETUID_ERROR, ARGV0, user);
    }



    /* Getting servers hostname */
    memset(shost, '\0', 512);
    if(gethostname(shost, 512 -1) != 0)
    {
        strncpy(shost, "localhost", 32);
        return(0);
    }


    /* Listing responses. */
    if(list_responses)
    {
        FILE *fp;
        if(!csv_output)
        {
            printf("\nOSSEC HIDS %s. Available active responses:\n", ARGV0);
        }

        fp = fopen(DEFAULTAR, "r");
        if(fp)
        {
            char buffer[256];

            while(fgets(buffer, 255, fp) != NULL)
            {
                char *r_name;
                char *r_cmd;
                char *r_timeout;

                r_name = buffer;
                r_cmd = strchr(buffer, ' ');
                if(!r_cmd)
                    continue;

                *r_cmd = '\0';
                r_cmd++;
                if(*r_cmd == '-')
                    r_cmd++;
                if(*r_cmd == ' ')
                    r_cmd++;

                r_timeout = strchr(r_cmd, ' ');
                if(!r_timeout)
                    continue;
                *r_timeout = '\0';

                if(strcmp(r_name, "restart-ossec0") == 0)
                {
                    continue;
                }
                printf("\n   Response name: %s, command: %s", r_name, r_cmd);
            }

            printf("\n\n");
            fclose(fp);
        }
        else
        {
            printf("\n   No active response available.\n\n");
        }

        exit(0);
    }


    /* Listing available agents. */
    if(list_agents)
    {
        if(!csv_output)
        {
            printf("\nOSSEC HIDS %s. List of available agents:",
                    ARGV0);
            printf("\n   ID: 000, Name: %s (server), IP: 127.0.0.1, Active/Local\n",
                    shost);
        }
        else
        {
            printf("000,%s (server),127.0.0.1,Active/Local,\n", shost);
        }
        print_agents(1, active_only, csv_output);
        printf("\n");
        exit(0);
    }



    /* Checking if the provided ID is valid. */
    if(agent_id != NULL)
    {
        if(strcmp(agent_id, "000") != 0)
        {
            OS_ReadKeys(&keys);

            agt_id = OS_IsAllowedID(&keys, agent_id);
            if(agt_id < 0)
            {
                printf("\n** Invalid agent id '%s'.\n", agent_id);
                helpmsg();
            }
        }
        else
        {
            /* server. */
            agt_id = -1;
        }
    }



    /* Printing information from an agent. */
    if(info_agent)
    {
        int agt_status = 0;
        char final_ip[IPSIZE + 4];
        agent_info *agt_info;

        final_ip[(sizeof final_ip) - 1] = '\0';


        if(!csv_output)
            printf("\nOSSEC HIDS %s. Agent information:", ARGV0);

        if(agt_id != -1)
        {
            agt_status = get_agent_status(keys.keyentries[agt_id]->name,
                                          keys.keyentries[agt_id]->ip->ip);

            agt_info = get_agent_info(keys.keyentries[agt_id]->name,
                                      keys.keyentries[agt_id]->ip->ip);

            /* Getting full address/prefix length from ip. */
            snprintf(final_ip, sizeof final_ip, "%s/%u",
                     keys.keyentries[agt_id]->ip->ip,
                     keys.keyentries[agt_id]->ip->prefixlength);


            if(!csv_output)
            {
                printf("\n   Agent ID:   %s\n", keys.keyentries[agt_id]->id);
                printf("   Agent Name: %s\n", keys.keyentries[agt_id]->name);
                printf("   IP address: %s\n", final_ip);
                printf("   Status:     %s\n\n",print_agent_status(agt_status));
            }
            else
            {
                printf("%s,%s,%s,%s,",
                       keys.keyentries[agt_id]->id,
                       keys.keyentries[agt_id]->name,
                       final_ip,
                       print_agent_status(agt_status));
            }
        }
        else
        {
            agt_status = get_agent_status(NULL, NULL);
            agt_info = get_agent_info(NULL, "127.0.0.1");

            if(!csv_output)
            {
            printf("\n   Agent ID:   000 (local instance)\n");
            printf("   Agent Name: %s\n", shost);
            printf("   IP address: 127.0.0.1\n");
            printf("   Status:     %s/Local\n\n",print_agent_status(agt_status));
            }

            else
            {
                printf("000,%s,127.0.0.1,%s/Local,",
                        shost,
                        print_agent_status(agt_status));

            }
        }


        if(!csv_output)
        {
        printf("   Operating system:    %s\n", agt_info->os);
        printf("   Client version:      %s\n", agt_info->version);
        printf("   Last keep alive:     %s\n\n", agt_info->last_keepalive);


        if(end_time)
        {
        printf("   Syscheck last started at:  %s\n", agt_info->syscheck_time);
        printf("   Syscheck last ended   at:  %s\n", agt_info->syscheck_endtime);
        printf("   Rootcheck last started at: %s\n", agt_info->rootcheck_time);
        printf("   Rootcheck last ended   at: %s\n\n", agt_info->rootcheck_endtime);
        }
        else
        {
        printf("   Syscheck last started  at: %s\n", agt_info->syscheck_time);
        printf("   Rootcheck last started at: %s\n", agt_info->rootcheck_time);
        }
        }
        else
        {
            printf("%s,%s,%s,%s,%s,\n",
                   agt_info->os,
                   agt_info->version,
                   agt_info->last_keepalive,
                   agt_info->syscheck_time,
                   agt_info->rootcheck_time);
        }

        exit(0);
    }



    /* Restarting syscheck every where. */
    if(restart_all_agents && restart_syscheck)
    {

        /* Connecting to remoted. */
        debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
        arq = connect_to_remoted();
        if(arq < 0)
        {
            printf("\n** Unable to connect to remoted.\n");
            exit(1);
        }
        debug1("%s: DEBUG: Connected...", ARGV0);


        /* Sending restart message to all agents. */
        if(send_msg_to_agent(arq, HC_SK_RESTART, NULL, NULL) == 0)
        {
            printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on all agents.",
                    ARGV0);
        }
        else
        {
            printf("\n** Unable to restart syscheck on all agents.\n");
            exit(1);
        }

        exit(0);
    }



    if(restart_syscheck && agent_id)
    {

        /* Restart on the server. */
        if(strcmp(agent_id, "000") == 0)
        {
            os_set_restart_syscheck();

            printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck "
                   "locally.\n", ARGV0);

            exit(0);
        }



        /* Connecting to remoted. */
        debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
        arq = connect_to_remoted();
        if(arq < 0)
        {
            printf("\n** Unable to connect to remoted.\n");
            exit(1);
        }
        debug1("%s: DEBUG: Connected...", ARGV0);


        if(send_msg_to_agent(arq, HC_SK_RESTART, agent_id, NULL) == 0)
        {
            printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on agent: %s\n",
                    ARGV0, agent_id);
        }
        else
        {
            printf("\n** Unable to restart syscheck on agent: %s\n", agent_id);
            exit(1);
        }

        exit(0);
    }


    if(restart_agent && agent_id)
    {
        /* Connecting to remoted. */
        debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
        arq = connect_to_remoted();
        if(arq < 0)
        {
            printf("\n** Unable to connect to remoted.\n");
            exit(1);
        }
        debug1("%s: DEBUG: Connected...", ARGV0);


        if(send_msg_to_agent(arq, "restart-ossec0", agent_id, "null") == 0)
        {
            printf("\nOSSEC HIDS %s: Restarting agent: %s\n",
                    ARGV0, agent_id);
        }
        else
        {
            printf("\n** Unable to restart agent: %s\n", agent_id);
            exit(1);
        }

        exit(0);
    }


    /* running active response on the specified agent id. */
    if(ip_address && ar && agent_id)
    {
        /* Connecting to remoted. */
        debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
        arq = connect_to_remoted();
        if(arq < 0)
        {
            printf("\n** Unable to connect to remoted.\n");
            exit(1);
        }
        debug1("%s: DEBUG: Connected...", ARGV0);


        if(send_msg_to_agent(arq, ar, agent_id, ip_address) == 0)
        {
            printf("\nOSSEC HIDS %s: Running active response '%s' on: %s\n",
                    ARGV0, ar, agent_id);
        }
        else
        {
            printf("\n** Unable to restart syscheck on agent: %s\n", agent_id);
            exit(1);
        }

        exit(0);
    }


    printf("\n** Invalid argument combination.\n");
    helpmsg();


    return(0);
}
Esempio n. 3
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);

}