コード例 #1
0
ファイル: main-server.c プロジェクト: Ar0xA/ossec-hids
int main(int argc, char **argv)
{
    FILE *fp;
    // Bucket to keep pids in.
    int process_pool[POOL_SIZE];
    // Count of pids we are wait()ing on.
    int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0;
    int gid = 0, client_sock = 0, sock = 0, port = 1515, ret = 0;
    char *dir  = DEFAULTDIR;
    char *user = USER;
    char *group = GROUPGLOBAL;
    // TODO: implement or delete
    char *cfg __attribute__((unused)) = DEFAULTCPATH;
    char buf[4096 +1];
    SSL_CTX *ctx;
    SSL *ssl;
    char srcip[IPSIZE +1];
    struct sockaddr_in _nc;
    socklen_t _ncl;


    /* Initializing some variables */
    memset(srcip, '\0', IPSIZE + 1);
    memset(process_pool, 0x0, POOL_SIZE);

    bio_err = 0;


    /* Setting the name */
    OS_SetName(ARGV0);
    /* add an option to use the ip on the socket to tie the name to a
       specific address */
    while((c = getopt(argc, argv, "Vdhiu:g:D:c:m:p:")) != -1)
    {
        switch(c){
            case 'V':
                print_version();
                break;
            case 'h':
                report_help();
                break;
            case 'd':
                nowDebug();
                break;
            case 'i':
                use_ip_address = 1;
                break;
            case 'u':
                if(!optarg)
                    ErrorExit("%s: -u needs an argument",ARGV0);
                user = optarg;
                break;
            case 'g':
                if(!optarg)
                    ErrorExit("%s: -g needs an argument",ARGV0);
                group = optarg;
                break;
            case 'D':
                if(!optarg)
                    ErrorExit("%s: -D needs an argument",ARGV0);
                dir = optarg;
                break;
            case 'c':
                if(!optarg)
                    ErrorExit("%s: -c needs an argument",ARGV0);
                cfg = optarg;
                break;
            case 't':
                test_config = 1;
                break;
            case 'p':
               if(!optarg)
                    ErrorExit("%s: -%c needs an argument",ARGV0, c);
                port = atoi(optarg);
                if(port <= 0 || port >= 65536)
                {
                    ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
                }
                break;
            default:
                report_help();
                break;
        }

    }

    /* Starting daemon -- NB: need to double fork and setsid */
    debug1(STARTED_MSG,ARGV0);

    /* Check if the user/group given are valid */
    gid = Privsep_GetGroup(group);
    if(gid < 0)
        ErrorExit(USER_ERROR,ARGV0,user,group);



    /* Exit here if test config is set */
    if(test_config)
        exit(0);


    /* Privilege separation */
    if(Privsep_SetGroup(gid) < 0)
        ErrorExit(SETGID_ERROR,ARGV0,group);


    /* chrooting -- TODO: this isn't a chroot. Should also close
       unneeded open file descriptors (like stdin/stdout)*/
    chdir(dir);



    /* Signal manipulation */
    StartSIG(ARGV0);


    /* Creating PID files */
    if(CreatePID(ARGV0, getpid()) < 0)
        ErrorExit(PID_ERROR,ARGV0);

    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());


    fp = fopen(KEYSFILE_PATH,"a");
    if(!fp)
    {
        merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
        exit(1);
    }


    /* Starting SSL */
    ctx = os_ssl_keys(0, dir);
    if(!ctx)
    {
        merror("%s: ERROR: SSL error. Exiting.", ARGV0);
        exit(1);
    }


    /* Connecting via TCP */
    sock = OS_Bindporttcp(port, NULL, 0);
    if(sock <= 0)
    {
        merror("%s: Unable to bind to port %d", ARGV0, port);
        exit(1);
    }
    fcntl(sock, F_SETFL, O_NONBLOCK);

    debug1("%s: DEBUG: Going into listening mode.", ARGV0);
    while(1)
    {

        // no need to completely pin the cpu, 100ms should be fast enough
        usleep(100*1000);

        // Only check process-pool if we have active processes
        if(active_processes > 0){
            for (i = 0; i < POOL_SIZE; i++)
            {
                int rv = 0;
                status = 0;
                if (process_pool[i])
                {
                    rv = waitpid(process_pool[i], &status, WNOHANG);
                    if (rv != 0){
                        debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]);
                        process_pool[i] = 0;
                        active_processes = active_processes - 1;
                    }
                }
            }
        }
        memset(&_nc, 0, sizeof(_nc));
        _ncl = sizeof(_nc);

        if((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0){
            if (active_processes >= POOL_SIZE)
            {
                merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0);
                break;
            }
            pid = fork();
            if(pid)
            {
                active_processes = active_processes + 1;
                close(client_sock);
                for (i = 0; i < POOL_SIZE; i++)
                {
                    if (! process_pool[i])
                    {
                        process_pool[i] = pid;
                        break;
                    }
                }
            }
            else
            {
                strncpy(srcip, inet_ntoa(_nc.sin_addr),IPSIZE -1);
                char *agentname = NULL;
                ssl = SSL_new(ctx);
                SSL_set_fd(ssl, client_sock);

                do
                {
                    ret = SSL_accept(ssl);

                    if (ssl_error(ssl, ret))
                        clean_exit(ctx, client_sock);

                } while (ret <= 0);

                verbose("%s: INFO: New connection from %s", ARGV0, srcip);

                do
                {
                    ret = SSL_read(ssl, buf, sizeof(buf));

                    if (ssl_error(ssl, ret))
                        clean_exit(ctx, client_sock);

                } while (ret <= 0);

                int parseok = 0;
                if(strncmp(buf, "OSSEC A:'", 9) == 0)
                {
                    char *tmpstr = buf;
                    agentname = tmpstr + 9;
                    tmpstr += 9;
                    while(*tmpstr != '\0')
                    {
                        if(*tmpstr == '\'')
                        {
                            *tmpstr = '\0';
                            verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip);
                            parseok = 1;
                            break;
                        }
                        tmpstr++;
                    }
                }
                if(parseok == 0)
                {
                    merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip);
                }
                else
                {
                    int acount = 2;
                    char fname[2048 +1];
                    char response[2048 +1];
                    char *finalkey = NULL;
                    response[2048] = '\0';
                    fname[2048] = '\0';
                    if(!OS_IsValidName(agentname))
                    {
                        merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip);
                        snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                        ret = SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        ret = SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }


                    /* Checking for a duplicated names. */
                    strncpy(fname, agentname, 2048);
                    while(NameExist(fname))
                    {
                        snprintf(fname, 2048, "%s%d", agentname, acount);
                        acount++;
                        if(acount > 256)
                        {
                            merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname);
                            snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                            ret = SSL_write(ssl, response, strlen(response));
                            snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                            ret = SSL_write(ssl, response, strlen(response));
                            sleep(1);
                            exit(0);
                        }
                    }
                    agentname = fname;


                    /* Adding the new agent. */
                    if (use_ip_address)
                    {
                        finalkey = OS_AddNewAgent(agentname, srcip, NULL, NULL);
                    }
                    else
                    {
                        finalkey = OS_AddNewAgent(agentname, NULL, NULL, NULL);
                    }
                    if(!finalkey)
                    {
                        merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname);
                        snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname);
                        ret = SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        ret = SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }


                    snprintf(response, 2048,"OSSEC K:'%s'\n\n", finalkey);
                    verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip);
                    ret = SSL_write(ssl, response, strlen(response));
                    if(ret < 0)
                    {
                        merror("%s: ERROR: SSL write error (%d)", ARGV0, ret);
                        merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname);
                        ERR_print_errors_fp(stderr);
                    }
                    else
                    {
                        verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip);
                    }
                }

                clean_exit(ctx, client_sock);
            }
        }
    }


    /* Shutdown the socket */
    clean_exit(ctx, sock);

    return (0);
}
コード例 #2
0
ファイル: manage_keys.c プロジェクト: Defensative/ossec-hids
/* Bulk generate client keys from file */
int k_bulkload(const char *cmdbulk)
{
    int i = 1;
    FILE *fp, *infp;
    char str1[STR_SIZE + 1];
    char str2[STR_SIZE + 1];

    os_md5 md1;
    os_md5 md2;
    char line[FILE_SIZE + 1];
    char name[FILE_SIZE + 1];
    char id[FILE_SIZE + 1];
    char ip[FILE_SIZE + 1];
    char delims[] = ",";
    char *token = NULL;

    /* Check if we can open the input file */
    printf("Opening: [%s]\n", cmdbulk);
    infp = fopen(cmdbulk, "r");
    if (!infp) {
        perror("Failed.");
        ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno));
    }

    /* Check if we can open the auth_file */
    fp = fopen(AUTH_FILE, "a");
    if (!fp) {
        ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
    }
    fclose(fp);

    while (fgets(line, FILE_SIZE - 1, infp) != NULL) {
        os_ip c_ip;
        c_ip.ip = NULL;

        if (1 >= strlen(trimwhitespace(line))) {
            continue;
        }

        memset(ip, '\0', FILE_SIZE + 1);
        token = strtok(line, delims);
        strncpy(ip, trimwhitespace(token), FILE_SIZE - 1);

        memset(name, '\0', FILE_SIZE + 1);
        token = strtok(NULL, delims);
        strncpy(name, trimwhitespace(token), FILE_SIZE - 1);

#ifndef WIN32
        if (chmod(AUTH_FILE, 0440) == -1) {
            ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
        }
#endif

        /* Set time 2 */
        time2 = time(0);

        srandom_init();
        rand1 = random();

        /* Zero strings */
        memset(str1, '\0', STR_SIZE + 1);
        memset(str2, '\0', STR_SIZE + 1);

        /* Check the name */
        if (!OS_IsValidName(name)) {
            printf(INVALID_NAME, name);
            continue;
        }

        /* Search for name  -- no duplicates */
        if (NameExist(name)) {
            printf(ADD_ERROR_NAME, name);
            continue;
        }

        if (!OS_IsValidIP(ip, &c_ip)) {
            printf(IP_ERROR, ip);
            continue;
        }

        /* Default ID */
        i = MAX_AGENTS + 32512;
        snprintf(id, 8, "%03d", i);
        while (!IDExist(id)) {
            i--;
            snprintf(id, 8, "%03d", i);

            /* No key present, use id 0 */
            if (i <= 0) {
                i = 0;
                break;
            }
        }
        snprintf(id, 8, "%03d", i + 1);

        if (!OS_IsValidID(id)) {
            printf(INVALID_ID, id);
            goto cleanup;
        }

        /* Search for ID KEY  -- no duplicates */
        if (IDExist(id)) {
            printf(NO_DEFAULT, i + 1);
            goto cleanup;
        }

        printf(AGENT_INFO, id, name, ip);
        fflush(stdout);

        time3 = time(0);
        rand2 = random();

        fp = fopen(AUTH_FILE, "a");
        if (!fp) {
            ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno));
        }
#ifndef WIN32
        if (chmod(AUTH_FILE, 0440) == -1) {
            ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
        }
#endif

        /* Random 1: Time took to write the agent information
         * Random 2: Time took to choose the action
         * Random 3: All of this + time + pid
         * Random 4: MD5 all of this + the name, key and IP
         * Random 5: Final key
         */

        snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1);
        snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2);

        OS_MD5_Str(str1, md1);
        OS_MD5_Str(str2, md2);

        snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(),
                 (int)time3);
        OS_MD5_Str(str1, md1);

        fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2);
        fclose(fp);

        printf(AGENT_ADD);
        restart_necessary = 1;

cleanup:
        free(c_ip.ip);
    };

    fclose(infp);
    return (0);
}
コード例 #3
0
ファイル: main-server.c プロジェクト: asecurity/ossec-wazuh
int main(int argc, char **argv)
{
    FILE *fp;
    char *authpass = NULL;
    /* Bucket to keep pids in */
    int process_pool[POOL_SIZE];
    /* Count of pids we are wait()ing on */
    int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0;
    int use_pass = 1;
    int force_antiquity = -1;
    char *id_exist;
    gid_t gid;
    int client_sock = 0, sock = 0, port = DEFAULT_PORT, ret = 0;
    const char *dir  = DEFAULTDIR;
    const char *group = GROUPGLOBAL;
    const char *server_cert = NULL;
    const char *server_key = NULL;
    const char *ca_cert = NULL;
    char buf[4096 + 1];
    SSL_CTX *ctx;
    SSL *ssl;
    char srcip[IPSIZE + 1];
    struct sockaddr_in _nc;
    socklen_t _ncl;

    /* Initialize some variables */
    memset(srcip, '\0', IPSIZE + 1);
    memset(process_pool, 0x0, POOL_SIZE * sizeof(*process_pool));
    bio_err = 0;

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

    while ((c = getopt(argc, argv, "Vdhtig:D:m:p:v:x:k:nf:")) != -1) {
        char *end;

        switch (c) {
            case 'V':
                print_version();
                break;
            case 'h':
                help_authd();
                break;
            case 'd':
                nowDebug();
                break;
            case 'i':
                use_ip_address = 1;
                break;
            case 'g':
                if (!optarg) {
                    ErrorExit("%s: -g needs an argument", ARGV0);
                }
                group = optarg;
                break;
            case 'D':
                if (!optarg) {
                    ErrorExit("%s: -D needs an argument", ARGV0);
                }
                dir = optarg;
                break;
            case 't':
                test_config = 1;
                break;
            case 'n':
                use_pass = 0;
                break;
            case 'p':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                port = atoi(optarg);
                if (port <= 0 || port >= 65536) {
                    ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
                }
                break;
            case 'v':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                ca_cert = optarg;
                break;
            case 'x':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                server_cert = optarg;
                break;
            case 'k':
                if (!optarg) {
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                }
                server_key = optarg;
                break;
            case 'f':
                if (!optarg)
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);

                force_antiquity = strtol(optarg, &end, 10);

                if (optarg == end || force_antiquity < 0)
                    ErrorExit("%s: Invalid number for -f", ARGV0);

                break;
            default:
                help_authd();
                break;
        }
    }

    /* Start daemon -- NB: need to double fork and setsid */
    debug1(STARTED_MSG, ARGV0);

    /* Check if the user/group given are valid */
    gid = Privsep_GetGroup(group);
    if (gid == (gid_t) - 1) {
        ErrorExit(USER_ERROR, ARGV0, "", group);
    }

    /* Exit here if test config is set */
    if (test_config) {
        exit(0);
    }

    /* Privilege separation */
    if (Privsep_SetGroup(gid) < 0) {
        ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
    }

    /* chroot -- TODO: this isn't a chroot. Should also close
     * unneeded open file descriptors (like stdin/stdout)
     */
    if (chdir(dir) == -1) {
        ErrorExit(CHDIR_ERROR, ARGV0, dir, errno, strerror(errno));
    }

    /* Signal manipulation */
    StartSIG(ARGV0);

    /* Create PID files */
    if (CreatePID(ARGV0, getpid()) < 0) {
        ErrorExit(PID_ERROR, ARGV0);
    }

    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());

    if (use_pass) {

        /* Checking if there is a custom password file */
        fp = fopen(AUTHDPASS_PATH, "r");
        buf[0] = '\0';
        if (fp) {
            buf[4096] = '\0';
            char *ret = fgets(buf, 4095, fp);

            if (ret && strlen(buf) > 2) {
                /* Remove newline */
                buf[strlen(buf) - 1] = '\0';
                authpass = strdup(buf);
            }

            fclose(fp);
        }

        if (buf[0] != '\0')
            verbose("Accepting connections. Using password specified on file: %s",AUTHDPASS_PATH);
        else {
            /* Getting temporary pass. */
            authpass = __generatetmppass();
            verbose("Accepting connections. Random password chosen for agent authentication: %s", authpass);
        }
    } else
        verbose("Accepting insecure connections. No password required (not recommended)");

    /* Getting SSL cert. */

    fp = fopen(KEYSFILE_PATH, "a");
    if (!fp) {
        merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
        exit(1);
    }
    fclose(fp);

    /* Start SSL */
    ctx = os_ssl_keys(1, dir, server_cert, server_key, ca_cert);
    if (!ctx) {
        merror("%s: ERROR: SSL error. Exiting.", ARGV0);
        exit(1);
    }

    /* Connect via TCP */
    sock = OS_Bindporttcp(port, NULL, 0);
    if (sock <= 0) {
        merror("%s: Unable to bind to port %d", ARGV0, port);
        exit(1);
    }

    fcntl(sock, F_SETFL, O_NONBLOCK);
    debug1("%s: DEBUG: Going into listening mode.", ARGV0);

    /* Setup random */
    srandom_init();

    /* Chroot */
    if (Privsep_Chroot(dir) < 0)
        ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));

    nowChroot();

    while (1) {
        /* No need to completely pin the cpu, 100ms should be fast enough */
        usleep(100 * 1000);

        /* Only check process-pool if we have active processes */
        if (active_processes > 0) {
            for (i = 0; i < POOL_SIZE; i++) {
                int rv = 0;
                status = 0;
                if (process_pool[i]) {
                    rv = waitpid(process_pool[i], &status, WNOHANG);
                    if (rv != 0) {
                        debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]);
                        process_pool[i] = 0;
                        active_processes = active_processes - 1;
                    }
                }
            }
        }
        memset(&_nc, 0, sizeof(_nc));
        _ncl = sizeof(_nc);

        if ((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0) {
            if (active_processes >= POOL_SIZE) {
                merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0);
                break;
            }
            pid = fork();
            if (pid) {
                active_processes = active_processes + 1;
                close(client_sock);
                for (i = 0; i < POOL_SIZE; i++) {
                    if (! process_pool[i]) {
                        process_pool[i] = pid;
                        break;
                    }
                }
            } else {
                strncpy(srcip, inet_ntoa(_nc.sin_addr), IPSIZE - 1);
                char *agentname = NULL;
                ssl = SSL_new(ctx);
                SSL_set_fd(ssl, client_sock);

                do {
                    ret = SSL_accept(ssl);

                    if (ssl_error(ssl, ret)) {
                        clean_exit(ctx, client_sock);
                    }

                } while (ret <= 0);
                verbose("%s: INFO: New connection from %s", ARGV0, srcip);
                buf[0] = '\0';

                do {
                    ret = SSL_read(ssl, buf, sizeof(buf));

                    if (ssl_error(ssl, ret)) {
                        clean_exit(ctx, client_sock);
                    }

                } while (ret <= 0);

                int parseok = 0;
                char *tmpstr = buf;

                /* Checking for shared password authentication. */
                if(authpass) {
                    /* Format is pretty simple: OSSEC PASS: PASS WHATEVERACTION */
                    if (strncmp(tmpstr, "OSSEC PASS: "******"%s: ERROR: Invalid password provided by %s. Closing connection.", ARGV0, srcip);
                        SSL_CTX_free(ctx);
                        close(client_sock);
                        exit(0);
                    }
                }

                /* Checking for action A (add agent) */
                parseok = 0;
                if (strncmp(tmpstr, "OSSEC A:'", 9) == 0) {
                    agentname = tmpstr + 9;
                    tmpstr += 9;
                    while (*tmpstr != '\0') {
                        if (*tmpstr == '\'') {
                            *tmpstr = '\0';
                            verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip);
                            parseok = 1;
                            break;
                        }
                        tmpstr++;
                    }
                }
                if (parseok == 0) {
                    merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip);
                } else {
                    int acount = 2;
                    char fname[2048 + 1];
                    char response[2048 + 1];
                    char *finalkey = NULL;
                    response[2048] = '\0';
                    fname[2048] = '\0';
                    if (!OS_IsValidName(agentname)) {
                        merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip);
                        snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                        SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }

                    /* Check for duplicated names */
                    strncpy(fname, agentname, 2048);
                    while (NameExist(fname)) {
                        snprintf(fname, 2048, "%s%d", agentname, acount);
                        acount++;
                        if (acount > 256) {
                            merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname);
                            snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                            SSL_write(ssl, response, strlen(response));
                            snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                            SSL_write(ssl, response, strlen(response));
                            sleep(1);
                            exit(0);
                        }
                    }
                    agentname = fname;

                    /* Check for duplicated IP */

                    if (use_ip_address) {
                        id_exist = IPExist(srcip);
                        if (id_exist) {
                            if (force_antiquity >= 0) {
                                double antiquity = OS_AgentAntiquity(id_exist);
                                if (antiquity >= force_antiquity || antiquity < 0) {
                                    /* TODO: Backup info-agent, syscheck and rootcheck */
                                    OS_RemoveAgent(id_exist);
                                } else {
                                    /* TODO: Send alert */
                                    merror("%s: ERROR: Duplicated IP %s (another active)", ARGV0, srcip);
                                    snprintf(response, 2048, "ERROR: Duplicated IP: %s\n\n", srcip);
                                    SSL_write(ssl, response, strlen(response));
                                    snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                                    SSL_write(ssl, response, strlen(response));
                                    sleep(1);
                                    exit(0);
                                }

                            } else {
                                merror("%s: ERROR: Duplicated IP %s", ARGV0, srcip);
                                snprintf(response, 2048, "ERROR: Duplicated IP: %s\n\n", srcip);
                                SSL_write(ssl, response, strlen(response));
                                snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                                SSL_write(ssl, response, strlen(response));
                                sleep(1);
                                exit(0);
                            }
                        }
                    }

                    /* Add the new agent */
                    if (use_ip_address)
                        finalkey = OS_AddNewAgent(agentname, srcip, NULL);
                    else
                        finalkey = OS_AddNewAgent(agentname, NULL, NULL);

                    if (!finalkey) {
                        merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname);
                        snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname);
                        SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }

                    snprintf(response, 2048, "OSSEC K:'%s'\n\n", finalkey);
                    verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip);
                    ret = SSL_write(ssl, response, strlen(response));
                    if (ret < 0) {
                        merror("%s: ERROR: SSL write error (%d)", ARGV0, ret);
                        merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname);
                        ERR_print_errors_fp(stderr);
                    } else {
                        verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip);
                    }
                }

                clean_exit(ctx, client_sock);
            }
        }
    }

    /* Shut down the socket */
    clean_exit(ctx, sock);

    return (0);
}
コード例 #4
0
ファイル: manage_agents.c プロジェクト: nixfloyd/ossec-hids
int add_agent()
{
    int i = 1;
    FILE *fp;
    char str1[STR_SIZE + 1];
    char str2[STR_SIZE + 1];

    os_md5 md1;
    os_md5 md2;

    char *user_input;
    char *_name;
    char *_id;
    char *_ip;

    char name[FILE_SIZE + 1];
    char id[FILE_SIZE + 1];
    char ip[FILE_SIZE + 1];
    os_ip *c_ip;

    /* Check if we can open the auth_file */
    fp = fopen(AUTH_FILE, "a");
    if (!fp) {
        ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
    }
    fclose(fp);

    /* Allocate for c_ip */
    os_calloc(1, sizeof(os_ip), c_ip);

#ifndef WIN32
    if (chmod(AUTH_FILE, 0440) == -1) {
        ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
    }
#endif

    /* Set time 2 */
    time2 = time(0);

    rand1 = random();

    /* Zero strings */
    memset(str1, '\0', STR_SIZE + 1);
    memset(str2, '\0', STR_SIZE + 1);

    printf(ADD_NEW);

    /* Get the name */
    memset(name, '\0', FILE_SIZE + 1);

    do {
        printf(ADD_NAME);
        fflush(stdout);
        /* Read the agent's name from user environment. If it is invalid
         * we should force user to provide a name from input device.
         */
        _name = getenv("OSSEC_AGENT_NAME");
        if (_name == NULL || NameExist(_name) || !OS_IsValidName(_name)) {
            _name = read_from_user();
        }

        if (strcmp(_name, QUIT) == 0) {
            return (0);
        }

        strncpy(name, _name, FILE_SIZE - 1);

        /* Check the name */
        if (!OS_IsValidName(name)) {
            printf(INVALID_NAME, name);
        }

        /* Search for name  -- no duplicates */
        if (NameExist(name)) {
            printf(ADD_ERROR_NAME, name);
        }
    } while (NameExist(name) || !OS_IsValidName(name));

    /* Get IP */
    memset(ip, '\0', FILE_SIZE + 1);

    do {
        printf(ADD_IP);
        fflush(stdout);

        /* Read IP address from user's environment. If that IP is invalid,
         * force user to provide IP from input device */
        _ip = getenv("OSSEC_AGENT_IP");
        if (_ip == NULL || !OS_IsValidIP(_ip, c_ip)) {
            _ip = read_from_user();
        }

        /* Quit */
        if (strcmp(_ip, QUIT) == 0) {
            return (0);
        }

        strncpy(ip, _ip, FILE_SIZE - 1);

        if (!OS_IsValidIP(ip, c_ip)) {
            printf(IP_ERROR, ip);
            _ip = NULL;
        }

    } while (!_ip);

    do {
        /* Default ID */
        i = MAX_AGENTS + 32512;
        snprintf(id, 8, "%03d", i);
        while (!IDExist(id)) {
            i--;
            snprintf(id, 8, "%03d", i);

            /* No key present, use id 0 */
            if (i <= 0) {
                i = 0;
                break;
            }
        }
        snprintf(id, 8, "%03d", i + 1);

        /* Get ID */
        printf(ADD_ID, id);
        fflush(stdout);

        /* Get Agent ID from environment. If 0, use default ID. If null,
         * get from user input. If value from environment is invalid,
         * we force user to specify an ID from the terminal. Otherwise,
         * our program goes to infinite loop.
         */
        _id = getenv("OSSEC_AGENT_ID");
        if (_id == NULL || IDExist(_id) || !OS_IsValidID(_id)) {
            _id = read_from_user();
        }

        /* If user specified 0 as Agent ID, he meant use default value.
         * NOTE: a bad condition can cause infinite loop.
         */
        if (strcmp(_id, "0") == 0) {
            strncpy(_id, id, FILE_SIZE - 1);
        }

        /* Quit */
        if (strcmp(_id, QUIT) == 0) {
            return (0);
        }

        if (_id[0] != '\0') {
            strncpy(id, _id, FILE_SIZE - 1);
        }

        if (!OS_IsValidID(id)) {
            printf(INVALID_ID, id);
        }

        /* Search for ID KEY  -- no duplicates */
        if (IDExist(id)) {
            printf(ADD_ERROR_ID, id);
        }

    } while (IDExist(id) || !OS_IsValidID(id));

    printf(AGENT_INFO, id, name, ip);
    fflush(stdout);

    do {
        printf(ADD_CONFIRM);
        /* Confirmation by an environment variable. The valid value is y/Y.
         * If the user provides anything other string, it is considered as
         * n/N; please note that the old code only accepts y/Y/n/N. So if
         * the variable OSSEC_ACTION_CONFIRMED is 'foobar', the program will
         * go into an infinite loop.
         */
        user_input = getenv("OSSEC_ACTION_CONFIRMED");
        if (user_input == NULL) {
            user_input = read_from_user();
        }

        /* If user accepts to add */
        if (user_input[0] == 'y' || user_input[0] == 'Y') {
            time3 = time(0);
            rand2 = random();

            fp = fopen(AUTH_FILE, "a");
            if (!fp) {
                ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno));
            }
#ifndef WIN32
            chmod(AUTH_FILE, 0440);
#endif

            /* Random 1: Time took to write the agent information
             * Random 2: Time took to choose the action
             * Random 3: All of this + time + pid
             * Random 4: Md5 all of this + the name, key and IP
             * Random 5: Final key
             */

            snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1);
            snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2);

            OS_MD5_Str(str1, md1);
            OS_MD5_Str(str2, md2);

            snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(),
                     (int)time3);
            OS_MD5_Str(str1, md1);

            fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip->ip, md1, md2);

            fclose(fp);

            printf(AGENT_ADD);
            restart_necessary = 1;
            break;
        } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */
            printf(ADD_NOT);
            break;
        }
    } while (1);

    return (0);
}