Esempio n. 1
0
static pid_t
get_running_pid(const fko_srv_options_t *opts)
{
    int     op_fd;
    char    buf[PID_BUFLEN] = {0};
    pid_t   rpid            = 0;


    verify_file_perms_ownership(opts->config[CONF_FWKNOP_PID_FILE]);

    op_fd = open(opts->config[CONF_FWKNOP_PID_FILE], O_RDONLY);

    if(op_fd > 0)
    {
        if (read(op_fd, buf, PID_BUFLEN) > 0)
        {
            buf[PID_BUFLEN-1] = '\0';
            rpid = (pid_t)atoi(buf);
        }

        close(op_fd);
    }

    return(rpid);
}
Esempio n. 2
0
/* Show the last command that was executed
*/
static int
show_last_command(const char * const args_save_file)
{
    char args_str[MAX_LINE_LEN] = {0};
    FILE *args_file_ptr = NULL;

    if(verify_file_perms_ownership(args_save_file) != 1)
        return 0;

    if ((args_file_ptr = fopen(args_save_file, "r")) == NULL) {
        log_msg(LOG_VERBOSITY_ERROR, "Could not open args file: %s",
            args_save_file);
        return 0;
    }

    if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL) {
        log_msg(LOG_VERBOSITY_NORMAL,
                "Last fwknop client command line: %s", args_str);
    } else {
        log_msg(LOG_VERBOSITY_NORMAL,
                "Could not read line from file: %s", args_save_file);
        fclose(args_file_ptr);
        return 0;
    }
    fclose(args_file_ptr);

    return 1;
}
Esempio n. 3
0
/* Get the command line arguments from the previous invocation
*/
static int
run_last_args(fko_cli_options_t *options, const char * const args_save_file)
{
    FILE           *args_file_ptr = NULL;
    int             argc_new = 0, args_broken = 0;
    char            args_str[MAX_LINE_LEN] = {0};
    char           *argv_new[MAX_CMDLINE_ARGS];  /* should be way more than enough */

    memset(argv_new, 0x0, sizeof(argv_new));

    if(verify_file_perms_ownership(args_save_file) != 1)
        return 0;

    if ((args_file_ptr = fopen(args_save_file, "r")) == NULL)
    {
        log_msg(LOG_VERBOSITY_ERROR, "Could not open args file: %s",
                args_save_file);
        return 0;
    }
    if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL)
    {
        args_str[MAX_LINE_LEN-1] = '\0';
        if (options->verbose)
            log_msg(LOG_VERBOSITY_NORMAL, "Executing: %s", args_str);
        if(strtoargv(args_str, argv_new, &argc_new, options) != 1)
        {
            args_broken = 1;
        }
    }
    fclose(args_file_ptr);

    if(args_broken)
        return 0;

    /* Reset the options index so we can run through them again.
    */
    optind = 0;

    config_init(options, argc_new, argv_new);

    /* Since we passed in our own copies, free up malloc'd memory
    */
    free_argv(argv_new, &argc_new);

    return 1;
}
Esempio n. 4
0
static pid_t
get_running_pid(const fko_srv_options_t *opts)
{
    int     op_fd, is_err, bytes_read = 0;
    char    buf[PID_BUFLEN] = {0};
    pid_t   rpid            = 0;


    if(verify_file_perms_ownership(opts->config[CONF_FWKNOP_PID_FILE]) != 1)
    {
        fprintf(stderr, "verify_file_perms_ownership() error\n");
        return(rpid);
    }

    op_fd = open(opts->config[CONF_FWKNOP_PID_FILE], O_RDONLY);

    if(op_fd == -1)
    {
        if((opts->foreground != 0) && (opts->verbose != 0))
            perror("Error trying to open PID file: ");
        return(rpid);
    }

    bytes_read = read(op_fd, buf, PID_BUFLEN);
    if (bytes_read > 0)
    {
        buf[PID_BUFLEN-1] = '\0';
        /* max pid value is configurable on Linux
        */
        rpid = (pid_t) strtol_wrapper(buf, 0, (2 << 30),
                NO_EXIT_UPON_ERR, &is_err);
        if(is_err != FKO_SUCCESS)
            rpid = 0;
    }
    else if (bytes_read < 0)
        perror("Error trying to read() PID file: ");

    close(op_fd);

    return(rpid);
}
Esempio n. 5
0
static int
replay_file_cache_init(fko_srv_options_t *opts)
{
    FILE           *digest_file_ptr = NULL;
    unsigned int    num_lines = 0, digest_ctr = 0;
    char            line_buf[MAX_LINE_LEN]    = {0};
    char            src_ip[INET_ADDRSTRLEN+1] = {0};
    char            dst_ip[INET_ADDRSTRLEN+1] = {0};
    long int        time_tmp;
    int             digest_file_fd = -1;
    char            digest_header[] = "# <digest> <proto> <src_ip> <src_port> <dst_ip> <dst_port> <time>\n";

    struct digest_cache_list *digest_elm = NULL;

    /* if the file exists, import the previous SPA digests into
     * the cache list
    */
    if (access(opts->config[CONF_DIGEST_FILE], F_OK) == 0)
    {
        /* Check permissions
        */
        if (access(opts->config[CONF_DIGEST_FILE], R_OK|W_OK) != 0)
        {
            log_msg(LOG_WARNING, "Digest file '%s' exists but: '%s'",
                opts->config[CONF_DIGEST_FILE], strerror(errno));
            return(-1);
        }
    }
    else
    {
        /* the file does not exist yet, so it will be created when the first
         * successful SPA packet digest is written to disk
        */
        digest_file_fd = open(opts->config[CONF_DIGEST_FILE],
                O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);

        if (digest_file_fd == -1)
        {
            log_msg(LOG_WARNING, "Could not create digest cache: %s: %s",
                opts->config[CONF_DIGEST_FILE], strerror(errno));
            return(-1);
        }
        else
        {
            if(write(digest_file_fd, digest_header, strlen(digest_header))
                    != strlen(digest_header)) {
                log_msg(LOG_WARNING,
                    "Did not write expected number of bytes to digest cache: %s",
                    opts->config[CONF_DIGEST_FILE]);
            }
            close(digest_file_fd);

            return(0);
        }
    }

    if(verify_file_perms_ownership(opts->config[CONF_DIGEST_FILE]) != 1)
        return(-1);

    /* File exists, and we have access - create in-memory digest cache
    */
    if ((digest_file_ptr = fopen(opts->config[CONF_DIGEST_FILE], "r")) == NULL)
    {
        log_msg(LOG_WARNING, "Could not open digest cache: %s: %s",
            opts->config[CONF_DIGEST_FILE], strerror(errno));
        return(-1);
    }

    /* Line format:
     * <digest> <proto> <src_ip> <src_port> <dst_ip> <dst_port> <time>
     * Example:
     * 7XgadOyqv0tF5xG8uhg2iIrheeNKglCWKmxQDgYP1dY 17 127.0.0.1 40305 127.0.0.1 62201 1313283481
    */
    while ((fgets(line_buf, MAX_LINE_LEN, digest_file_ptr)) != NULL)
    {
        num_lines++;
        line_buf[MAX_LINE_LEN-1] = '\0';

        if(IS_EMPTY_LINE(line_buf[0]))
            continue;

        /* Initialize a digest cache list element, and add it into the list if
         * valid.
        */
        if ((digest_elm = calloc(1, sizeof(struct digest_cache_list))) == NULL)
        {
            log_msg(LOG_ERR, "[*] Could not allocate digest list element");
            continue;
        }
        if ((digest_elm->cache_info.digest = calloc(1, MAX_DIGEST_SIZE+1)) == NULL)
        {
            free(digest_elm);
            log_msg(LOG_ERR, "[*] Could not allocate digest string");
            continue;
        }
        src_ip[0] = '\0';
        dst_ip[0] = '\0';

        if(sscanf(line_buf, "%64s %hhu %16s %hu %16s %hu %ld",
            digest_elm->cache_info.digest,  /* %64s, buffer size is MAX_DIGEST_SIZE+1 */
            &(digest_elm->cache_info.proto),
            src_ip,  /* %16s, buffer size is INET_ADDRSTRLEN+1 */
            &(digest_elm->cache_info.src_port),
            dst_ip,  /* %16s, buffer size is INET_ADDRSTRLEN+1 */
            &(digest_elm->cache_info.dst_port),
            &time_tmp) != 7)
        {
            log_msg(LOG_INFO,
                "*Skipping invalid digest file entry in %s at line %i.\n - %s",
                opts->config[CONF_DIGEST_FILE], num_lines, line_buf
            );
            free(digest_elm->cache_info.digest);
            free(digest_elm);
            continue;
        }
        digest_elm->cache_info.created = time_tmp;


        if (inet_pton(AF_INET, src_ip, &(digest_elm->cache_info.src_ip)) != 1)
        {
            free(digest_elm->cache_info.digest);
            free(digest_elm);
            continue;
        }

        if (inet_pton(AF_INET, dst_ip, &(digest_elm->cache_info.dst_ip)) != 1)
        {
            free(digest_elm->cache_info.digest);
            free(digest_elm);
            continue;
        }

        digest_elm->next   = opts->digest_cache;
        opts->digest_cache = digest_elm;
        digest_ctr++;

        if(opts->verbose > 3)
            log_msg(LOG_DEBUG,
                "DIGEST FILE: %s, VALID LINE: %s",
                opts->config[CONF_DIGEST_FILE], line_buf
            );

    }

    fclose(digest_file_ptr);

    return(digest_ctr);
}
Esempio n. 6
0
/* Get the command line arguments from the previous invocation
*/
static int
run_last_args(fko_cli_options_t *options, const char * const args_save_file)
{
    FILE           *args_file_ptr = NULL;

    int             current_arg_ctr = 0;
    int             argc_new = 0;
    int             i = 0;

    char            args_str[MAX_LINE_LEN] = {0};
    char            arg_tmp[MAX_LINE_LEN]  = {0};
    char           *argv_new[MAX_CMDLINE_ARGS];  /* should be way more than enough */

    if(verify_file_perms_ownership(args_save_file) != 1)
        return 0;

    if ((args_file_ptr = fopen(args_save_file, "r")) == NULL)
    {
        log_msg(LOG_VERBOSITY_ERROR, "Could not open args file: %s",
                args_save_file);
        return 0;
    }
    if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL)
    {
        args_str[MAX_LINE_LEN-1] = '\0';
        if (options->verbose)
            log_msg(LOG_VERBOSITY_NORMAL, "Executing: %s", args_str);
        for (i=0; i < (int)strlen(args_str); i++)
        {
            if (!isspace(args_str[i]))
            {
                arg_tmp[current_arg_ctr] = args_str[i];
                current_arg_ctr++;
            }
            else
            {
                arg_tmp[current_arg_ctr] = '\0';
                argv_new[argc_new] = malloc(strlen(arg_tmp)+1);
                if (argv_new[argc_new] == NULL)
                {
                    log_msg(LOG_VERBOSITY_ERROR, "[*] malloc failure for cmd line arg.");
                    fclose(args_file_ptr);
                    return 0;
                }
                strlcpy(argv_new[argc_new], arg_tmp, strlen(arg_tmp)+1);
                current_arg_ctr = 0;
                argc_new++;
                if(argc_new >= MAX_CMDLINE_ARGS)
                {
                    log_msg(LOG_VERBOSITY_ERROR, "[*] max command line args exceeded.");
                    fclose(args_file_ptr);
                    return 0;
                }
            }
        }
    }
    fclose(args_file_ptr);

    /* Reset the options index so we can run through them again.
    */
    optind = 0;

    config_init(options, argc_new, argv_new);

    /* Since we passed in our own copies, free up malloc'd memory
    */
    for (i=0; i < argc_new; i++)
    {
        if(argv_new[i] == NULL)
            break;
        else
            free(argv_new[i]);
    }

    return 1;
}
Esempio n. 7
0
/* Parse the config file...
*/
static void
parse_config_file(fko_srv_options_t *opts, const char *config_file)
{
    FILE           *cfile_ptr;
    unsigned int    numLines = 0;
    unsigned int    i, good_ent;
    int             cndx;

    char            conf_line_buf[MAX_LINE_LEN] = {0};
    char            var[MAX_LINE_LEN]  = {0};
    char            val[MAX_LINE_LEN]  = {0};
    char            tmp1[MAX_LINE_LEN] = {0};
    char            tmp2[MAX_LINE_LEN] = {0};

    struct stat     st;

    /* Make sure the config file exists.
    */
    if(stat(config_file, &st) != 0)
    {
        log_msg(LOG_ERR, "[*] Config file: '%s' was not found.",
                config_file);
        clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
    }

    if(verify_file_perms_ownership(config_file) != 1)
        clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);

    /* See the comment in the parse_access_file() function regarding security
     * here relative to a TOCTOU bug flagged by Coverity.
    */
    if ((cfile_ptr = fopen(config_file, "r")) == NULL)
    {
        log_msg(LOG_ERR, "[*] Could not open config file: %s",
                config_file);
        perror(NULL);

        clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
    }

    while ((fgets(conf_line_buf, MAX_LINE_LEN, cfile_ptr)) != NULL)
    {
        numLines++;
        conf_line_buf[MAX_LINE_LEN-1] = '\0';

        /* Get past comments and empty lines (note: we only look at the
         * first character.
        */
        if(IS_EMPTY_LINE(conf_line_buf[0]))
            continue;

        if(sscanf(conf_line_buf, "%s %[^;\n\r]", var, val) != 2)
        {
            log_msg(LOG_ERR,
                    "*Invalid config file entry in %s at line %i.\n - '%s'",
                    config_file, numLines, conf_line_buf
                   );
            continue;
        }

        /*
        fprintf(stderr,
            "CONF FILE: %s, LINE: %s\tVar: %s, Val: '%s'\n",
            config_file, conf_line_buf, var, val
        );
        */

        good_ent = 0;
        for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
        {
            if(CONF_VAR_IS(config_map[i], var))
            {
                /* First check to see if we need to do a varable expansion
                 * on this value.  Note: this only supports one expansion and
                 * only if the value starts with the variable.
                */
                if(*val == '$')
                {
                    if(sscanf((val+1), "%[A-Z_]%s", tmp1, tmp2))
                    {
                        if((cndx = config_entry_index(opts, tmp1)) >= 0)
                        {
                            strlcpy(val, opts->config[cndx], sizeof(val));
                            strlcat(val, tmp2, sizeof(val));
                        }
                    }
                }

                set_config_entry(opts, i, val);
                good_ent++;
                break;
            }
        }

        if(good_ent == 0)
            log_msg(LOG_ERR,
                    "[*] Ignoring unknown configuration parameter: '%s' in %s",
                    var, config_file
                   );
    }

    fclose(cfile_ptr);

    return;
}
Esempio n. 8
0
/* Process (create if necessary) the users ~/.fwknoprc file.
*/
static void
process_rc(fko_cli_options_t *options)
{
    FILE    *rc;
    int     line_num = 0;
    int     rcf_offset;
    char    line[MAX_LINE_LEN];
    char    rcfile[MAX_PATH_LEN];
    char    curr_stanza[MAX_LINE_LEN] = {0};
    char    var[MAX_LINE_LEN]  = {0};
    char    val[MAX_LINE_LEN]  = {0};

    char    *ndx, *emark, *homedir;

#ifdef WIN32
    homedir = getenv("USERPROFILE");
#else
    homedir = getenv("HOME");
#endif

    if(homedir == NULL)
    {
        fprintf(stderr, "Warning: Unable to determine HOME directory.\n"
            " No .fwknoprc file processed.\n");
        return;
    }

    memset(rcfile, 0x0, MAX_PATH_LEN);

    strlcpy(rcfile, homedir, MAX_PATH_LEN);

    rcf_offset = strlen(rcfile);

    /* Sanity check the path to .fwknoprc.
     * The preceeding path plus the path separator and '.fwknoprc' = 11
     * cannot exceed MAX_PATH_LEN.
    */
    if(rcf_offset > (MAX_PATH_LEN - 11))
    {
        fprintf(stderr, "Warning: Path to .fwknoprc file is too long.\n"
            " No .fwknoprc file processed.\n");
        return;
    }

    rcfile[rcf_offset] = PATH_SEP;
    strlcat(rcfile, ".fwknoprc", MAX_PATH_LEN);

    /* Check rc file permissions - if anything other than user read/write,
     * then throw a warning.  This change was made to help ensure that the
     * client consumes a proper rc file with strict permissions set (thanks
     * to Fernando Arnaboldi from IOActive for pointing this out).
    */
    verify_file_perms_ownership(rcfile);

    /* Open the rc file for reading, if it does not exist, then create
     * an initial .fwknoprc file with defaults and go on.
    */
    if ((rc = fopen(rcfile, "r")) == NULL)
    {
        if(errno == ENOENT)
        {
            if(create_fwknoprc(rcfile) != 0)
                return;
        }
        else
            fprintf(stderr, "Unable to open rc file: %s: %s\n",
                rcfile, strerror(errno));

        return;
    }

    /* Read in and parse the rc file parameters.
    */
    while ((fgets(line, MAX_LINE_LEN, rc)) != NULL)
    {
        line_num++;
        line[MAX_LINE_LEN-1] = '\0';

        ndx = line;

        /* Skip any leading whitespace.
        */
        while(isspace(*ndx))
            ndx++;

        /* Get past comments and empty lines (note: we only look at the
         * first character.
        */
        if(IS_EMPTY_LINE(line[0]))
            continue;

        if(*ndx == '[')
        {
            ndx++;
            emark = strchr(ndx, ']');
            if(emark == NULL)
            {
                fprintf(stderr, "Unterminated stanza line: '%s'.  Skipping.\n",
                    line);
                continue;
            }

            *emark = '\0';

            strlcpy(curr_stanza, ndx, MAX_LINE_LEN);

            if(options->verbose > 3)
                fprintf(stderr,
                    "RC FILE: %s, LINE: %s\tSTANZA: %s:\n",
                    rcfile, line, curr_stanza
                );

            continue;
        }

        if(sscanf(line, "%s %[^ ;\t\n\r#]", var, val) != 2)
        {
            fprintf(stderr,
                "*Invalid entry in %s at line %i.\n - '%s'",
                rcfile, line_num, line
            );
            continue;
        }

        /* Remove any colon that may be on the end of the var
        */
        if((ndx = strrchr(var, ':')) != NULL)
            *ndx = '\0';

        if(options->verbose > 3)
            fprintf(stderr,
                "RC FILE: %s, LINE: %s\tVar: %s, Val: '%s'\n",
                rcfile, line, var, val
            );

        /* We do not proceed with parsing until we know we are in
         * a stanza.
        */
        if(strlen(curr_stanza) < 1)
            continue;

        /* Process the values. We assume we will see the default stanza
         * first, then if a named-stanza is specified, we process its
         * entries as well.
        */
        if(strcasecmp(curr_stanza, "default") == 0)
        {
            if(parse_rc_param(options, var, val) < 0)
                fprintf(stderr, "Parameter error in %s, line %i: var=%s, val=%s\n",
                    rcfile, line_num, var, val);
        }
        else if(options->use_rc_stanza[0] != '\0'
          && strncasecmp(curr_stanza, options->use_rc_stanza, MAX_LINE_LEN)==0)
        {
            options->got_named_stanza = 1;
            if(parse_rc_param(options, var, val) < 0)
                fprintf(stderr,
                    "Parameter error in %s, stanza: %s, line %i: var=%s, val=%s\n",
                    rcfile, curr_stanza, line_num, var, val);
        }

    } /* end while fgets rc */
    fclose(rc);
}