Added strtol_wrapper() libfko utility function for atoi() replacement (#21)
authorMichael Rash <mbr@cipherdyne.org>
Tue, 19 Feb 2013 00:32:53 +0000 (19:32 -0500)
committerMichael Rash <mbr@cipherdyne.org>
Tue, 19 Feb 2013 00:32:53 +0000 (19:32 -0500)
This commit replaces most atoi() calls (which don't report errors) with a strtol()
wrapper function for stronger string -> integer conversion validation.

15 files changed:
client/config_init.c
client/fwknop.c
client/http_resolve_host.c
client/spa_comm.c
common/Makefile.am
lib/fko.h
lib/fko_decode.c
lib/fko_util.c
lib/fko_util.h
server/config_init.c
server/fw_util_iptables.c
server/fwknopd.c
server/incoming_spa.c
server/pcap_capture.c
server/tcp_server.c

index 8cc4388..d7232d5 100644 (file)
@@ -106,6 +106,7 @@ parse_time_offset(const char *offset_str)
     int offset      = 0;
     int offset_type = TIME_OFFSET_SECONDS;
     int os_len      = strlen(offset_str);
+    int is_err;
 
     char offset_digits[MAX_TIME_STR_LEN];
 
@@ -138,12 +139,7 @@ parse_time_offset(const char *offset_str)
         exit(EXIT_FAILURE);
     }
 
-    offset = atoi(offset_digits);
-
-    if (offset < 0) {
-        fprintf(stderr, "Invalid time offset: %s", offset_str);
-        exit(EXIT_FAILURE);
-    }
+    offset = strtol_wrapper(offset_digits, 0, (2 << 15), EXIT_UPON_ERR, &is_err);
 
     /* Apply the offset_type value
     */
@@ -262,7 +258,7 @@ create_fwknoprc(const char *rcfile)
 static int
 parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
 {
-    int     tmpint;
+    int     tmpint, is_err;
 
     /* Digest Type */
     if(CONF_VAR_IS(var, "DIGEST_TYPE"))
@@ -285,29 +281,30 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
     /* Server port */
     else if(CONF_VAR_IS(var, "SPA_SERVER_PORT"))
     {
-        tmpint = atoi(val);
-        if(tmpint < 0 || tmpint > MAX_PORT)
-            return(-1);
-        else
+        tmpint = strtol_wrapper(val, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+        if(is_err == FKO_SUCCESS)
             options->spa_dst_port = tmpint;
+        else
+            return(-1);
     }
     /* Source port */
     else if(CONF_VAR_IS(var, "SPA_SOURCE_PORT"))
     {
-        tmpint = atoi(val);
-        if(tmpint < 0 || tmpint > MAX_PORT)
-            return(-1);
-        else
+        tmpint = strtol_wrapper(val, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+        if(is_err == FKO_SUCCESS)
             options->spa_src_port = tmpint;
+        else
+            return(-1);
     }
     /* Firewall rule timeout */
     else if(CONF_VAR_IS(var, "FW_TIMEOUT"))
     {
-        tmpint = atoi(val);
-        if(tmpint < 0)
-            return(-1);
-        else
+        tmpint = strtol_wrapper(val, 0, (2 << 15), NO_EXIT_UPON_ERR, &is_err);
+        if(is_err == FKO_SUCCESS)
             options->fw_timeout = tmpint;
+        else
+            return(-1);
+
     }
     /* Allow IP */
     else if(CONF_VAR_IS(var, "ALLOW_IP"))
@@ -475,11 +472,11 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
     /* NAT port */
     else if(CONF_VAR_IS(var, "NAT_PORT"))
     {
-        tmpint = atoi(val);
-        if(tmpint < 0 || tmpint > MAX_PORT)
-            return(-1);
-        else
+        tmpint = strtol_wrapper(val, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+        if(is_err == FKO_SUCCESS)
             options->nat_port = tmpint;
+        else
+            return(-1);
     }
 
     return(0);
@@ -764,7 +761,7 @@ set_defaults(fko_cli_options_t *options)
 void
 config_init(fko_cli_options_t *options, int argc, char **argv)
 {
-    int       cmd_arg, index;
+    int       cmd_arg, index, is_err;
 
     /* Zero out options and opts_track.
     */
@@ -833,8 +830,10 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 strlcpy(options->args_save_file, optarg, MAX_PATH_LEN);
                 break;
             case 'f':
-                options->fw_timeout = atoi(optarg);
-                if (options->fw_timeout < 0) {
+                options->fw_timeout = strtol_wrapper(optarg, 0,
+                        (2 << 15), NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
+                {
                     fprintf(stderr, "--fw-timeout must be >= 0\n");
                     exit(EXIT_FAILURE);
                 }
@@ -860,16 +859,18 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 options->key_gen = 1;
                 strlcpy(options->key_gen_file, optarg, MAX_PATH_LEN);
             case SPA_ICMP_TYPE:
-                options->spa_icmp_type = atoi(optarg);
-                if (options->spa_icmp_type < 0 || options->spa_icmp_type > MAX_ICMP_TYPE)
+                options->spa_icmp_type = strtol_wrapper(optarg, 0,
+                        MAX_ICMP_TYPE, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
                 {
                     fprintf(stderr, "Unrecognized icmp type value: %s\n", optarg);
                     exit(EXIT_FAILURE);
                 }
                 break;
             case SPA_ICMP_CODE:
-                options->spa_icmp_code = atoi(optarg);
-                if (options->spa_icmp_code < 0 || options->spa_icmp_code > MAX_ICMP_CODE)
+                options->spa_icmp_code = strtol_wrapper(optarg, 0,
+                        MAX_ICMP_CODE, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
                 {
                     fprintf(stderr, "Unrecognized icmp code value: %s\n", optarg);
                     exit(EXIT_FAILURE);
@@ -909,8 +910,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 strlcpy(options->nat_access_str, optarg, MAX_LINE_LEN);
                 break;
             case 'p':
-                options->spa_dst_port = atoi(optarg);
-                if (options->spa_dst_port < 0 || options->spa_dst_port > MAX_PORT)
+                options->spa_dst_port = strtol_wrapper(optarg, 0,
+                        MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
                 {
                     fprintf(stderr, "Unrecognized port: %s\n", optarg);
                     exit(EXIT_FAILURE);
@@ -953,8 +955,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 strlcpy(options->allow_ip_str, "0.0.0.0", MAX_IPV4_STR_LEN);
                 break;
             case 'S':
-                options->spa_src_port = atoi(optarg);
-                if (options->spa_src_port < 0 || options->spa_src_port > MAX_PORT)
+                options->spa_src_port = strtol_wrapper(optarg, 0,
+                        MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
                 {
                     fprintf(stderr, "Unrecognized port: %s\n", optarg);
                     exit(EXIT_FAILURE);
@@ -999,8 +1002,8 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 options->nat_rand_port = 1;
                 break;
             case NAT_PORT:
-                options->nat_port = atoi(optarg);
-                if (options->nat_port < 0 || options->nat_port > MAX_PORT)
+                options->nat_port = strtol_wrapper(optarg, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
                 {
                     fprintf(stderr, "Unrecognized port: %s\n", optarg);
                     exit(EXIT_FAILURE);
index 1ef8158..5601594 100644 (file)
@@ -508,6 +508,8 @@ static int
 get_rand_port(fko_ctx_t ctx)
 {
     char *rand_val = NULL;
+    char  port_str[6];
+    int   tmpint, is_err;
     int   port     = 0;
     int   res      = 0;
 
@@ -515,21 +517,35 @@ get_rand_port(fko_ctx_t ctx)
     if(res != FKO_SUCCESS)
     {
         errmsg("get_rand_port(), fko_get_rand_value", res);
+        fko_destroy(ctx);
+        exit(EXIT_FAILURE);
+    }
+
+    strlcpy(port_str, rand_val, 6);
+
+    tmpint = strtol_wrapper(port_str, 0, 0, NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        fprintf(stderr,
+            "[*] get_rand_port(), could not convert rand_val str '%s', to integer",
+            rand_val);
+        fko_destroy(ctx);
         exit(EXIT_FAILURE);
     }
 
     /* Convert to a random value between 1024 and 65535
     */
-    port = (MIN_HIGH_PORT + (abs(atoi(rand_val)) % (MAX_PORT - MIN_HIGH_PORT)));
+    port = (MIN_HIGH_PORT + (tmpint % (MAX_PORT - MIN_HIGH_PORT)));
 
     /* Force libfko to calculate a new random value since we don't want to
-     * given anyone a hint (via the port value) about the contents of the
+     * give anyone a hint (via the port value) about the contents of the
      * encrypted SPA data.
     */
     res = fko_set_rand_value(ctx, NULL);
     if(res != FKO_SUCCESS)
     {
         errmsg("get_rand_port(), fko_get_rand_value", res);
+        fko_destroy(ctx);
         exit(EXIT_FAILURE);
     }
 
index bdde3f2..8abcb37 100644 (file)
@@ -219,7 +219,7 @@ static int
 parse_url(char *res_url, struct url* url)
 {
     char *s_ndx, *e_ndx;
-    int  tlen, tlen_offset, port;
+    int  tlen, tlen_offset, port, is_err;
 
     /* https is not supported.
     */
@@ -241,8 +241,8 @@ parse_url(char *res_url, struct url* url)
     e_ndx = strchr(s_ndx, ':');
     if(e_ndx != NULL)
     {
-        port = atoi(e_ndx+1);
-        if(port < 1 || port > MAX_PORT)
+        port = strtol_wrapper(e_ndx+1, 1, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+        if(is_err != FKO_SUCCESS)
         {
             fprintf(stderr, "resolve-url port value is invalid.\n");
             return(-1);
index 0716b70..2c703a4 100644 (file)
@@ -509,11 +509,12 @@ send_spa_packet_http(const char *spa_data, const int sd_len,
 {
     char http_buf[HTTP_MAX_REQUEST_LEN], *spa_data_copy = NULL;
     char *ndx = options->http_proxy;
-    int  i, proxy_port = 0;
+    int  i, proxy_port = 0, is_err;
 
     spa_data_copy = malloc(sd_len+1);
     if (spa_data_copy == NULL)
     {
+        fprintf(stderr, "[*] Fatal, could not allocate memory.\n");
         exit(EXIT_FAILURE);
     }
     memcpy(spa_data_copy, spa_data, sd_len+1);
@@ -557,7 +558,12 @@ send_spa_packet_http(const char *spa_data, const int sd_len,
         if(ndx)
         {
             *ndx = '\0';
-            proxy_port = atoi(ndx+1);
+            proxy_port = strtol_wrapper(ndx+1, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+            if(is_err != FKO_SUCCESS)
+            {
+                fprintf(stderr, "proxy port value is invalid.\n");
+                return 0;
+            }
         }
 
         /* If we have a valid port value, use it.
index 4924f53..dbd89ed 100644 (file)
@@ -1,6 +1,6 @@
 noinst_LIBRARIES               = libfko_util.a
 
-libfko_util_source_files       = ../lib/strlcpy.c ../lib/strlcat.c ../lib/fko_util.h
+libfko_util_source_files       = ../lib/strlcpy.c ../lib/strlcat.c ../lib/fko_util.c ../lib/fko_util.h
 
 libfko_util_a_SOURCES          = $(libfko_util_source_files)
 
index 9a75dc8..b3efe88 100644 (file)
--- a/lib/fko.h
+++ b/lib/fko.h
@@ -202,6 +202,11 @@ typedef enum {
 #define B64_GPG_PREFIX "hQ"
 #define B64_GPG_PREFIX_STR_LEN 2
 
+/* Specify whether libfko is allowed to call exit()
+*/
+#define EXIT_UPON_ERR 1
+#define NO_EXIT_UPON_ERR 0
+
 /* The context holds the global state and config options, as
  * well as some intermediate results during processing. This
  * is an opaque pointer.
index 336a1b8..d645741 100644 (file)
@@ -40,7 +40,7 @@ int
 fko_decode_spa_data(fko_ctx_t ctx)
 {
     char       *tbuf, *ndx, *tmp;
-    int         t_size, i;
+    int         t_size, i, is_err;
 
     if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
         return(FKO_ERROR_INVALID_DATA);
@@ -227,7 +227,13 @@ fko_decode_spa_data(fko_ctx_t ctx)
 
     strlcpy(tbuf, ndx, t_size+1);
 
-    ctx->timestamp = (unsigned int)atoi(tbuf);
+    ctx->timestamp = (unsigned int) strtol_wrapper(tbuf,
+            0, 0, NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        free(tbuf);
+        return(FKO_ERROR_INVALID_DATA);
+    }
 
     /* Extract the version string.
     */
@@ -270,9 +276,9 @@ fko_decode_spa_data(fko_ctx_t ctx)
 
     strlcpy(tbuf, ndx, t_size+1);
 
-    ctx->message_type = (unsigned int)atoi(tbuf);
-
-    if(ctx->message_type < 0 || ctx->message_type >= FKO_LAST_MSG_TYPE)
+    ctx->message_type = strtol_wrapper(tbuf, 0,
+            FKO_LAST_MSG_TYPE, NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
     {
         free(tbuf);
         return(FKO_ERROR_INVALID_DATA);
@@ -477,7 +483,13 @@ fko_decode_spa_data(fko_ctx_t ctx)
                 return(FKO_ERROR_INVALID_DATA);
             }
 
-            ctx->client_timeout = (unsigned int)atoi(ndx);
+            ctx->client_timeout = (unsigned int) strtol_wrapper(ndx, 0,
+                    (2 << 15), NO_EXIT_UPON_ERR, &is_err);
+            if(is_err != FKO_SUCCESS)
+            {
+                free(tbuf);
+                return(FKO_ERROR_INVALID_DATA);
+            }
         }
     }
 
index 638b6e8..c4fccda 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Author:  Michael Rash
  *
- * Purpose: Set/Get the current username.
+ * Purpose: Provide a set of common utility functions that fwknop can use.
  *
  * Copyright 2012 Michael Rash (mbr@cipherdyne.org)
  *
@@ -30,6 +30,7 @@
 */
 #include "fko_common.h"
 #include "fko.h"
+#include <errno.h>
 
 /* Validate encoded message length
 */
@@ -77,4 +78,53 @@ is_valid_digest_len(const int len)
     return(1);
 }
 
+int
+strtol_wrapper(const char * const str, const int min,
+    const int max, const int exit_upon_err, int *err)
+{
+    int val;
+
+    errno = 0;
+    *err = FKO_SUCCESS;
+
+    val = strtol(str, (char **) NULL, 10);
+
+    if ((errno == ERANGE || (errno != 0 && val == 0)))
+    {
+        *err = errno;
+        if(exit_upon_err == EXIT_UPON_ERR)
+        {
+            perror("strtol");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    if(val < min)
+    {
+        *err = FKO_ERROR_INVALID_DATA;
+        if(exit_upon_err == EXIT_UPON_ERR)
+        {
+            fprintf(stderr, "[*] Value %d out of range %d - %d\n",
+                val, min, max);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    /* allow max==0 to be an exception where we don't care about the
+     * maximum - note that the ERANGE check is still in place above
+    */
+    if((max > 0) && (val > max))
+    {
+        *err = FKO_ERROR_INVALID_DATA;
+        if(exit_upon_err == EXIT_UPON_ERR)
+        {
+            fprintf(stderr, "[*] Value %d out of range %d - %d\n",
+                val, min, max);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    return val;
+}
+
 /***EOF***/
index 5b980a0..e0017b2 100644 (file)
@@ -38,6 +38,8 @@
 int is_valid_encoded_msg_len(const int len);
 int is_valid_pt_msg_len(const int len);
 int is_valid_digest_len(const int len);
+int strtol_wrapper(const char * const str, const int min,
+    const int max, const int exit_upon_err, int *is_err);
 
 size_t strlcat(char *dst, const char *src, size_t siz);
 size_t strlcpy(char *dst, const char *src, size_t siz);
index a218066..6cb27f2 100644 (file)
 static void
 range_check(fko_srv_options_t *opts, char *var, char *val, int low, int high)
 {
-    if (low > atoi(val) || high < atoi(val))
+    int     is_err;
+
+    strtol_wrapper(val, low, high, NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
     {
         fprintf(stderr, "[*] var %s value '%s' not in the range %d-%d\n",
             var, val, low, high);
         clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
     }
+
     return;
 }
 
@@ -128,6 +132,8 @@ free_configs(fko_srv_options_t *opts)
 static void
 validate_int_var_ranges(fko_srv_options_t *opts)
 {
+    int     is_err = FKO_SUCCESS;
+
     range_check(opts, "PCAP_LOOP_SLEEP", opts->config[CONF_PCAP_LOOP_SLEEP],
         1, RCHK_MAX_PCAP_LOOP_SLEEP);
     range_check(opts, "MAX_SPA_PACKET_AGE", opts->config[CONF_MAX_SPA_PACKET_AGE],
@@ -153,10 +159,14 @@ validate_int_var_ranges(fko_srv_options_t *opts)
     /* Make sure the active and expire sets are not identical whenever
      * they are non-zero
     */
-    if((atoi(opts->config[CONF_IPFW_ACTIVE_SET_NUM]) > 0
-            && atoi(opts->config[CONF_IPFW_EXPIRE_SET_NUM]) > 0)
-            && atoi(opts->config[CONF_IPFW_ACTIVE_SET_NUM])
-                == atoi(opts->config[CONF_IPFW_EXPIRE_SET_NUM]))
+    if((strtol_wrapper(opts->config[CONF_IPFW_ACTIVE_SET_NUM],
+                    0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err) > 0
+            && strtol_wrapper(opts->config[CONF_IPFW_EXPIRE_SET_NUM],
+                0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err) > 0)
+            && strtol_wrapper(opts->config[CONF_IPFW_ACTIVE_SET_NUM],
+                0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err)
+                == strtol_wrapper(opts->config[CONF_IPFW_EXPIRE_SET_NUM],
+                    0, RCHK_MAX_IPFW_SET_NUM, NO_EXIT_UPON_ERR, &is_err))
     {
         fprintf(stderr,
                 "[*] Cannot set identical ipfw active and expire sets.\n");
@@ -169,6 +179,12 @@ validate_int_var_ranges(fko_srv_options_t *opts)
 
 #endif /* FIREWALL type */
 
+    if(is_err != FKO_SUCCESS)
+    {
+        fprintf(stderr, "[*] invalid integer conversion error.\n");
+        clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
+    }
+
     return;
 }
 
@@ -631,7 +647,7 @@ set_preconfig_entries(fko_srv_options_t *opts)
 void
 config_init(fko_srv_options_t *opts, int argc, char **argv)
 {
-    int             cmd_arg, index;
+    int             cmd_arg, index, is_err;
     unsigned char   got_conf_file = 0, got_override_config = 0;
 
     char            override_file[MAX_LINE_LEN];
@@ -753,7 +769,15 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
                 /* This was handled earlier */
                 break;
             case 'C':
-                opts->packet_ctr_limit = atoi(optarg);
+                opts->packet_ctr_limit = strtol_wrapper(optarg,
+                        0, (2 << 31), NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
+                {
+                    fprintf(stderr,
+                        "[*] invalid -C packet count limit '%s'\n",
+                        optarg);
+                    clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
+                }
                 break;
             case 'd':
 #if USE_FILE_CACHE
index 9e77cc2..5569c7a 100644 (file)
@@ -434,7 +434,7 @@ create_fw_chains(const fko_srv_options_t * const opts)
 static void
 set_fw_chain_conf(const int type, const char * const conf_str)
 {
-    int i, j;
+    int i, j, is_err;
     char tbuf[1024]     = {0};
     const char *ndx     = conf_str;
 
@@ -491,14 +491,27 @@ set_fw_chain_conf(const int type, const char * const conf_str)
     strlcpy(chain->from_chain, chain_fields[2], MAX_CHAIN_NAME_LEN);
 
     /* Pull and set Jump_rule_position */
-    chain->jump_rule_pos = atoi(chain_fields[3]);
+    chain->jump_rule_pos = strtol_wrapper(chain_fields[3],
+            0, (2 << 15), NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] invalid jump rule position in Line: %s\n",
+            conf_str);
+        exit(EXIT_FAILURE);
+    }
 
     /* Pull and set To_chain */
     strlcpy(chain->to_chain, chain_fields[4], MAX_CHAIN_NAME_LEN);
 
-    /* Pull and set Jump_rule_position */
-    chain->rule_pos = atoi(chain_fields[5]);
-
+    /* Pull and set to_chain rule position */
+    chain->rule_pos = strtol_wrapper(chain_fields[5],
+            0, (2 << 15), NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] invalid to_chain rule position in Line: %s\n",
+            conf_str);
+        exit(EXIT_FAILURE);
+    }
 }
 
 void
@@ -686,7 +699,7 @@ process_spa_request(const fko_srv_options_t * const opts,
     struct fw_chain * const dnat_chain = &(opts->fw_config->chain[IPT_DNAT_ACCESS]);
     struct fw_chain *snat_chain; /* We assign this later (if we need to). */
 
-    int             res = 0;
+    int             res = 0, is_err;
     time_t          now;
     unsigned int    exp_ts;
 
@@ -804,7 +817,6 @@ process_spa_request(const fko_srv_options_t * const opts,
                     }
                 }
             }
-
             ple = ple->next;
         }
     }
@@ -828,7 +840,13 @@ process_spa_request(const fko_srv_options_t * const opts,
             if(ndx != NULL)
             {
                 strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1);
-                nat_port = atoi(ndx+1);
+                nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
+                {
+                    log_msg(LOG_INFO, "Invalid NAT port in SPA message");
+                    free_acc_port_list(port_list);
+                    return res;
+                }
             }
         }
 
@@ -1024,7 +1042,7 @@ check_firewall_rules(const fko_srv_options_t * const opts)
     char             rule_num_str[6];
     char            *ndx, *rn_start, *rn_end, *tmp_mark;
 
-    int             i, res, rn_offset;
+    int             i, res, rn_offset, rule_num, is_err;
     time_t          now, rule_exp, min_exp = 0;
 
     struct fw_chain *ch = opts->fw_config->chain;
@@ -1141,16 +1159,28 @@ check_firewall_rules(const fko_srv_options_t * const opts)
 
                 strlcpy(rule_num_str, rn_start, (rn_end - rn_start)+1);
 
+                rule_num = strtol_wrapper(rule_num_str, rn_offset, (2 << 15),
+                        NO_EXIT_UPON_ERR, &is_err);
+                if(is_err != FKO_SUCCESS)
+                {
+                    log_msg(LOG_ERR,
+                        "Rule parse error while finding rule number in chain %i", i);
+
+                    if (ch[i].active_rules > 0)
+                        ch[i].active_rules--;
+
+                    break;
+                }
+
                 zero_cmd_buffers();
 
                 snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_DEL_RULE_ARGS,
                     opts->fw_config->fw_command,
                     ch[i].table,
                     ch[i].to_chain,
-                    atoi(rule_num_str) - rn_offset
+                    rule_num - rn_offset
                 );
 
-
                 res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
 
                 if (opts->verbose)
index 47fe910..1b3d6dd 100644 (file)
@@ -52,7 +52,7 @@ static pid_t get_running_pid(const fko_srv_options_t *opts);
 int
 main(int argc, char **argv)
 {
-    int                 res, last_sig, rp_cache_count;
+    int                 res, last_sig, rp_cache_count, is_err;
     char               *locale;
     pid_t               old_pid;
 
@@ -282,16 +282,18 @@ main(int argc, char **argv)
         */
         if(strncasecmp(opts.config[CONF_ENABLE_TCP_SERVER], "Y", 1) == 0)
         {
-            if(atoi(opts.config[CONF_TCPSERV_PORT]) <= 0
-              || atoi(opts.config[CONF_TCPSERV_PORT]) > MAX_PORT)
+
+            strtol_wrapper(opts.config[CONF_TCPSERV_PORT],
+                    1, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+            if(is_err == FKO_SUCCESS)
             {
-                log_msg(LOG_WARNING,
-                    "WARNING: ENABLE_TCP_SERVER is set, but TCPSERV_PORT is not valid. TCP server not started!"
-                );
+                run_tcp_server(&opts);
             }
             else
             {
-                run_tcp_server(&opts);
+                log_msg(LOG_WARNING,
+                    "WARNING: ENABLE_TCP_SERVER is set, but TCPSERV_PORT is not valid. TCP server not started!"
+                );
             }
         }
 
@@ -673,7 +675,7 @@ write_pid_file(fko_srv_options_t *opts)
 static pid_t
 get_running_pid(const fko_srv_options_t *opts)
 {
-    int     op_fd;
+    int     op_fd, is_err;
     char    buf[PID_BUFLEN] = {0};
     pid_t   rpid            = 0;
 
@@ -687,7 +689,12 @@ get_running_pid(const fko_srv_options_t *opts)
         if (read(op_fd, buf, PID_BUFLEN) > 0)
         {
             buf[PID_BUFLEN-1] = '\0';
-            rpid = (pid_t)atoi(buf);
+            /* max pid value is configurable on Linux
+            */
+            rpid = (pid_t) strtol_wrapper(buf, 0, (2 << 31),
+                    NO_EXIT_UPON_ERR, &is_err);
+            if(is_err != FKO_SUCCESS)
+                rpid = 0;
         }
 
         close(op_fd);
index afc6624..561c237 100644 (file)
@@ -256,6 +256,8 @@ incoming_spa(fko_srv_options_t *opts)
     time_t          now_ts;
     int             res, status, ts_diff, enc_type, stanza_num=0;
     int             added_replay_digest = 0, pkt_data_len=0;
+    int             is_err;
+    int             conf_pkt_age = 0;
 
     spa_pkt_info_t *spa_pkt = &(opts->spa_pkt);
 
@@ -290,6 +292,17 @@ incoming_spa(fko_srv_options_t *opts)
         hex_dump(spa_pkt->packet_data, pkt_data_len);
     }
 
+    if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0)
+    {
+        conf_pkt_age = strtol_wrapper(opts->config[CONF_MAX_SPA_PACKET_AGE],
+                0, (2 << 31), NO_EXIT_UPON_ERR, &is_err);
+        if(is_err != FKO_SUCCESS)
+        {
+            log_msg(LOG_ERR, "[*] invalid MAX_SPA_PACKET_AGE\n");
+            return;
+        }
+    }
+
     if (is_src_match(opts->acc_stanzas, ntohl(spa_pkt->packet_src_ip)))
     {
         if(strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
@@ -568,7 +581,7 @@ incoming_spa(fko_srv_options_t *opts)
 
             ts_diff = abs(now_ts - spadat.timestamp);
 
-            if(ts_diff > atoi(opts->config[CONF_MAX_SPA_PACKET_AGE]))
+            if(ts_diff > conf_pkt_age)
             {
                 log_msg(LOG_WARNING, "(stanza #%d) SPA data time difference is too great (%i seconds).",
                     stanza_num, ts_diff);
index 64d49fb..d78cf64 100644 (file)
@@ -60,13 +60,30 @@ pcap_capture(fko_srv_options_t *opts)
     int                 pcap_file_mode = 0;
     int                 status;
     int                 useconds;
+    int                 pcap_dispatch_count;
+    int                 max_sniff_bytes;
+    int                 is_err;
     pid_t               child_pid;
 
 #if FIREWALL_IPFW
     time_t              now;
 #endif
 
-    useconds = atoi(opts->config[CONF_PCAP_LOOP_SLEEP]);
+    useconds = strtol_wrapper(opts->config[CONF_PCAP_LOOP_SLEEP],
+            0, (2 << 31), NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] invalid PCAP_LOOP_SLEEP_value\n");
+        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
+    }
+
+    max_sniff_bytes = strtol_wrapper(opts->config[CONF_MAX_SNIFF_BYTES],
+            0, (2 << 14), NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] invalid MAX_SNIFF_BYTES\n");
+        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
+    }
 
     /* Set promiscuous mode if ENABLE_PCAP_PROMISC is set to 'Y'.
     */
@@ -95,10 +112,8 @@ pcap_capture(fko_srv_options_t *opts)
         log_msg(LOG_INFO, "Sniffing interface: %s",
             opts->config[CONF_PCAP_INTF]);
 
-        pcap = pcap_open_live(
-            opts->config[CONF_PCAP_INTF],
-            atoi(opts->config[CONF_MAX_SNIFF_BYTES]),
-            promisc, 100, errstr
+        pcap = pcap_open_live(opts->config[CONF_PCAP_INTF],
+            max_sniff_bytes, promisc, 100, errstr
         );
 
         if(pcap == NULL)
@@ -180,6 +195,14 @@ pcap_capture(fko_srv_options_t *opts)
         clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
     }
 
+    pcap_dispatch_count = strtol_wrapper(opts->config[CONF_PCAP_DISPATCH_COUNT],
+            0, (2 << 31), NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] invalid PCAP_DISPATCH_COUNT\n");
+        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
+    }
+
     /* Initialize our signal handlers. You can check the return value for
      * the number of signals that were *not* set.  Those that were not set
      * will be listed in the log/stderr output.
@@ -222,7 +245,6 @@ pcap_capture(fko_srv_options_t *opts)
             got_sigchld = 0;
         }
 
-
         /* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
         */
         if(got_signal != 0)
@@ -243,7 +265,7 @@ pcap_capture(fko_srv_options_t *opts)
                 got_signal = 0;
         }
 
-        res = pcap_dispatch(pcap, atoi(opts->config[CONF_PCAP_DISPATCH_COUNT]),
+        res = pcap_dispatch(pcap, pcap_dispatch_count,
             (pcap_handler)&process_packet, (unsigned char *)opts);
 
         /* Count processed packets
index b3bedb7..48f0f88 100644 (file)
@@ -56,14 +56,21 @@ run_tcp_server(fko_srv_options_t *opts)
 {
     pid_t               pid, ppid;
     int                 s_sock, c_sock, sfd_flags, clen, selval;
-    int                 reuse_addr = 1;
+    int                 reuse_addr = 1, is_err;
     fd_set              sfd_set;
     struct sockaddr_in  saddr, caddr;
     struct timeval      tv;
     char                sipbuf[MAX_IPV4_STR_LEN];
 
-    unsigned short      port = atoi(opts->config[CONF_TCPSERV_PORT]);
+    unsigned short      port;
 
+    port = strtol_wrapper(opts->config[CONF_TCPSERV_PORT],
+            0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
+    if(is_err != FKO_SUCCESS)
+    {
+        log_msg(LOG_ERR, "[*] Invalid max TCPSERV_PORT value.\n");
+        exit(EXIT_FAILURE);
+    }
     log_msg(LOG_INFO, "Kicking off TCP server to listen on port %i.", port);
 
     /* Fork off a child process to run the command and provide its outputs.