cron2 has submitted this change. ( http://gerrit.openvpn.net/c/openvpn/+/873?usp=email )
Change subject: Print warnings/errors when numerical parameters cannot be parsed ...................................................................... Print warnings/errors when numerical parameters cannot be parsed Using the atoi method is a best effort method that parses as much of the input string as possible as integer and ignores the rest or return 0 if the string cannot be parsed. This is lead to unexpected results. Change the behaviour by printing a warning in these cases instead. When parsing a configuration, these warnings will error out since the msglevel is M_USAGE in this case. Example: ./src/openvpn/openvpn --resolv-retry 198jj Options error: Cannot parse argument '198jj' as non-negative integer Reported-By: Anqi Chen <chen.an...@northeastern.edu> Reported-By: Cristina Nita-Rotaru <c.nitarot...@northeastern.edu> Change-Id: Ie1e2eb54d516b3ae87c5ca56fe8edd77ee2be4de Signed-off-by: Arne Schwabe <a...@rfc2549.org> Acked-by: Gert Doering <g...@greenie.muc.de> Message-Id: <20250127122531.13105-1-g...@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg30627.html Signed-off-by: Gert Doering <g...@greenie.muc.de> --- M src/openvpn/options.c M src/openvpn/options_util.c M src/openvpn/options_util.h 3 files changed, 144 insertions(+), 82 deletions(-) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index bd5c056..4510bea 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -60,6 +60,8 @@ #include "platform.h" #include "xkey_common.h" #include "dco.h" +#include "options_util.h" + #include <ctype.h> #include "memdbg.h" @@ -5014,13 +5016,6 @@ } #endif -static int -positive_atoi(const char *str) -{ - const int i = atoi(str); - return i < 0 ? 0 : i; -} - #ifdef _WIN32 /* This function is only used when compiling on Windows */ static unsigned int atou(const char *str) @@ -6043,7 +6038,7 @@ int cache; VERIFY_PERMISSION(OPT_P_GENERAL); - cache = atoi(p[1]); + cache = atoi_warn(p[1], msglevel); if (cache < 1) { msg(msglevel, "--management-log-cache parameter is out of range"); @@ -6355,7 +6350,7 @@ } else { - options->resolve_retry_seconds = positive_atoi(p[1]); + options->resolve_retry_seconds = positive_atoi(p[1], msglevel); } } else if ((streq(p[0], "preresolve") || streq(p[0], "ip-remote-hint")) && !p[2]) @@ -6372,7 +6367,7 @@ else if (streq(p[0], "connect-retry") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); - options->ce.connect_retry_seconds = positive_atoi(p[1]); + options->ce.connect_retry_seconds = positive_atoi(p[1], msglevel); /* * Limit the base value of retry wait interval to 16 bits to avoid * overflow when scaled up for exponential backoff @@ -6387,19 +6382,19 @@ if (p[2]) { options->ce.connect_retry_seconds_max = - max_int(positive_atoi(p[2]), options->ce.connect_retry_seconds); + max_int(positive_atoi(p[2], msglevel), options->ce.connect_retry_seconds); } } else if ((streq(p[0], "connect-timeout") || streq(p[0], "server-poll-timeout")) && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); - options->ce.connect_timeout = positive_atoi(p[1]); + options->ce.connect_timeout = positive_atoi(p[1], msglevel); } else if (streq(p[0], "connect-retry-max") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); - options->connect_retry_max = positive_atoi(p[1]); + options->connect_retry_max = positive_atoi(p[1], msglevel); } else if (streq(p[0], "ipchange") && p[1]) { @@ -6422,7 +6417,7 @@ else if (streq(p[0], "gremlin") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL); - options->gremlin = positive_atoi(p[1]); + options->gremlin = positive_atoi(p[1], msglevel); } #endif else if (streq(p[0], "chroot") && p[1] && !p[2]) @@ -6554,7 +6549,7 @@ else if (streq(p[0], "verb") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_MESSAGES); - options->verbosity = positive_atoi(p[1]); + options->verbosity = positive_atoi(p[1], msglevel); if (options->verbosity >= (D_TLS_DEBUG_MED & M_DEBUG_LEVEL)) { /* We pass this flag to the SSL library to avoid @@ -6573,7 +6568,7 @@ else if (streq(p[0], "mute") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_MESSAGES); - options->mute = positive_atoi(p[1]); + options->mute = positive_atoi(p[1], msglevel); } else if (streq(p[0], "errors-to-stderr") && !p[1]) { @@ -6586,7 +6581,7 @@ options->status_file = p[1]; if (p[2]) { - options->status_file_update_freq = positive_atoi(p[2]); + options->status_file_update_freq = positive_atoi(p[2], msglevel); } } else if (streq(p[0], "status-version") && p[1] && !p[2]) @@ -6594,7 +6589,7 @@ int version; VERIFY_PERMISSION(OPT_P_GENERAL); - version = atoi(p[1]); + version = atoi_warn(p[1], msglevel); if (version < 1 || version > 3) { msg(msglevel, "--status-version must be 1 to 3"); @@ -6622,17 +6617,17 @@ else if ((streq(p[0], "link-mtu") || streq(p[0], "udp-mtu")) && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); - options->ce.link_mtu = positive_atoi(p[1]); + options->ce.link_mtu = positive_atoi(p[1], msglevel); options->ce.link_mtu_defined = true; } else if (streq(p[0], "tun-mtu") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_PUSH_MTU|OPT_P_CONNECTION); - options->ce.tun_mtu = positive_atoi(p[1]); + options->ce.tun_mtu = positive_atoi(p[1], msglevel); options->ce.tun_mtu_defined = true; if (p[2]) { - options->ce.occ_mtu = positive_atoi(p[2]); + options->ce.occ_mtu = positive_atoi(p[2], msglevel); } else { @@ -6642,7 +6637,7 @@ else if (streq(p[0], "tun-mtu-max") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); - int max_mtu = positive_atoi(p[1]); + int max_mtu = positive_atoi(p[1], msglevel); if (max_mtu < 68 || max_mtu > 65536) { msg(msglevel, "--tun-mtu-max value '%s' is invalid", p[1]); @@ -6655,13 +6650,13 @@ else if (streq(p[0], "tun-mtu-extra") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); - options->ce.tun_mtu_extra = positive_atoi(p[1]); + options->ce.tun_mtu_extra = positive_atoi(p[1], msglevel); options->ce.tun_mtu_extra_defined = true; } else if (streq(p[0], "max-packet-size") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); - int maxmtu = positive_atoi(p[1]); + int maxmtu = positive_atoi(p[1], msglevel); options->ce.tls_mtu = constrain_int(maxmtu, TLS_CHANNEL_MTU_MIN, TLS_CHANNEL_BUF_SIZE); if (maxmtu < TLS_CHANNEL_MTU_MIN || maxmtu > TLS_CHANNEL_BUF_SIZE) @@ -6687,7 +6682,7 @@ else if (streq(p[0], "fragment") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION); - options->ce.fragment = positive_atoi(p[1]); + options->ce.fragment = positive_atoi(p[1], msglevel); if (options->ce.fragment < 68) { @@ -6718,23 +6713,23 @@ else if (streq(p[0], "nice") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_NICE); - options->nice = atoi(p[1]); + options->nice = atoi_warn(p[1], msglevel); } else if (streq(p[0], "rcvbuf") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_SOCKBUF); - options->rcvbuf = positive_atoi(p[1]); + options->rcvbuf = positive_atoi(p[1], msglevel); } else if (streq(p[0], "sndbuf") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_SOCKBUF); - options->sndbuf = positive_atoi(p[1]); + options->sndbuf = positive_atoi(p[1], msglevel); } else if (streq(p[0], "mark") && p[1] && !p[2]) { #if defined(TARGET_LINUX) && HAVE_DECL_SO_MARK VERIFY_PERMISSION(OPT_P_GENERAL); - options->mark = atoi(p[1]); + options->mark = atoi_warn(p[1], msglevel); #endif } else if (streq(p[0], "socket-flags")) @@ -6764,7 +6759,7 @@ { VERIFY_PERMISSION(OPT_P_GENERAL); #ifdef TARGET_LINUX - options->tuntap_options.txqueuelen = positive_atoi(p[1]); + options->tuntap_options.txqueuelen = positive_atoi(p[1], msglevel); #else msg(msglevel, "--txqueuelen not supported on this OS"); goto err; @@ -6775,7 +6770,7 @@ int shaper; VERIFY_PERMISSION(OPT_P_SHAPER); - shaper = atoi(p[1]); + shaper = atoi_warn(p[1], msglevel); if (shaper < SHAPER_MIN || shaper > SHAPER_MAX) { msg(msglevel, "Bad shaper value, must be between %d and %d", @@ -6823,7 +6818,7 @@ else if (streq(p[0], "inactive") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_TIMER); - options->inactivity_timeout = positive_atoi(p[1]); + options->inactivity_timeout = positive_atoi(p[1], msglevel); if (p[2]) { int64_t val = atoll(p[2]); @@ -6841,7 +6836,7 @@ else if (streq(p[0], "session-timeout") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TIMER); - options->session_timeout = positive_atoi(p[1]); + options->session_timeout = positive_atoi(p[1], msglevel); } else if (streq(p[0], "proto") && p[1] && !p[2]) { @@ -7008,24 +7003,24 @@ else if (streq(p[0], "keepalive") && p[1] && p[2] && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL); - options->keepalive_ping = atoi(p[1]); - options->keepalive_timeout = atoi(p[2]); + options->keepalive_ping = atoi_warn(p[1], msglevel); + options->keepalive_timeout = atoi_warn(p[2], msglevel); } else if (streq(p[0], "ping") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TIMER); - options->ping_send_timeout = positive_atoi(p[1]); + options->ping_send_timeout = positive_atoi(p[1], msglevel); } else if (streq(p[0], "ping-exit") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TIMER); - options->ping_rec_timeout = positive_atoi(p[1]); + options->ping_rec_timeout = positive_atoi(p[1], msglevel); options->ping_rec_timeout_action = PING_EXIT; } else if (streq(p[0], "ping-restart") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TIMER); - options->ping_rec_timeout = positive_atoi(p[1]); + options->ping_rec_timeout = positive_atoi(p[1], msglevel); options->ping_rec_timeout_action = PING_RESTART; } else if (streq(p[0], "ping-timer-rem") && !p[1]) @@ -7038,7 +7033,7 @@ VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION|OPT_P_EXPLICIT_NOTIFY); if (p[1]) { - options->ce.explicit_exit_notification = positive_atoi(p[1]); + options->ce.explicit_exit_notification = positive_atoi(p[1], msglevel); } else { @@ -7158,7 +7153,7 @@ else if (streq(p[0], "route-metric") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_ROUTE); - options->route_default_metric = positive_atoi(p[1]); + options->route_default_metric = positive_atoi(p[1], msglevel); } else if (streq(p[0], "route-delay") && !p[3]) { @@ -7166,10 +7161,10 @@ options->route_delay_defined = true; if (p[1]) { - options->route_delay = positive_atoi(p[1]); + options->route_delay = positive_atoi(p[1], msglevel); if (p[2]) { - options->route_delay_window = positive_atoi(p[2]); + options->route_delay_window = positive_atoi(p[2], msglevel); } } else @@ -7334,7 +7329,7 @@ } else if (streq(p[1], "SERVER_POLL_TIMEOUT") && p[2]) { - options->ce.connect_timeout = positive_atoi(p[2]); + options->ce.connect_timeout = positive_atoi(p[2], msglevel); } else { @@ -7366,14 +7361,14 @@ else if (streq(p[0], "script-security") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL); - script_security_set(atoi(p[1])); + script_security_set(atoi_warn(p[1], msglevel)); } else if (streq(p[0], "mssfix") && !p[3]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_CONNECTION); if (p[1]) { - int mssfix = positive_atoi(p[1]); + int mssfix = positive_atoi(p[1], msglevel); /* can be 0, but otherwise it needs to be high enough so we can * substract room for headers. */ if (mssfix != 0 @@ -7556,7 +7551,7 @@ options->ifconfig_pool_persist_filename = p[1]; if (p[2]) { - options->ifconfig_pool_persist_refresh_freq = positive_atoi(p[2]); + options->ifconfig_pool_persist_refresh_freq = positive_atoi(p[2], msglevel); } } else if (streq(p[0], "ifconfig-ipv6-pool") && p[1] && !p[2]) @@ -7588,8 +7583,8 @@ int real, virtual; VERIFY_PERMISSION(OPT_P_GENERAL); - real = atoi(p[1]); - virtual = atoi(p[2]); + real = atoi_warn(p[1], msglevel); + virtual = atoi_warn(p[2], msglevel); if (real < 1 || virtual < 1) { msg(msglevel, "--hash-size sizes must be >= 1 (preferably a power of 2)"); @@ -7603,8 +7598,8 @@ int cf_max, cf_per; VERIFY_PERMISSION(OPT_P_GENERAL); - cf_max = atoi(p[1]); - cf_per = atoi(p[2]); + cf_max = atoi_warn(p[1], msglevel); + cf_per = atoi_warn(p[2], msglevel); if (cf_max < 0 || cf_per < 0) { msg(msglevel, "--connect-freq parms must be > 0"); @@ -7634,7 +7629,7 @@ int max_clients; VERIFY_PERMISSION(OPT_P_GENERAL); - max_clients = atoi(p[1]); + max_clients = atoi_warn(p[1], msglevel); if (max_clients < 0) { msg(msglevel, "--max-clients must be at least 1"); @@ -7650,7 +7645,7 @@ else if (streq(p[0], "max-routes-per-client") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_INHERIT); - options->max_routes_per_client = max_int(atoi(p[1]), 1); + options->max_routes_per_client = max_int(positive_atoi(p[1], msglevel), 1); } else if (streq(p[0], "client-cert-not-required") && !p[1]) { @@ -7734,14 +7729,14 @@ { VERIFY_PERMISSION(OPT_P_GENERAL); options->auth_token_generate = true; - options->auth_token_lifetime = p[1] ? positive_atoi(p[1]) : 0; + options->auth_token_lifetime = p[1] ? positive_atoi(p[1], msglevel) : 0; for (int i = 2; i < MAX_PARMS && p[i] != NULL; i++) { /* the second parameter can be the renewal time */ - if (i == 2 && positive_atoi(p[i])) + if (i == 2 && valid_integer(p[i], true)) { - options->auth_token_renewal = positive_atoi(p[i]); + options->auth_token_renewal = positive_atoi(p[i], msglevel); } else if (streq(p[i], "external-auth")) { @@ -7821,7 +7816,7 @@ int n_bcast_buf; VERIFY_PERMISSION(OPT_P_GENERAL); - n_bcast_buf = atoi(p[1]); + n_bcast_buf = atoi_warn(p[1], msglevel); if (n_bcast_buf < 1) { msg(msglevel, "--bcast-buffers parameter must be > 0"); @@ -7833,7 +7828,7 @@ int tcp_queue_limit; VERIFY_PERMISSION(OPT_P_GENERAL); - tcp_queue_limit = atoi(p[1]); + tcp_queue_limit = atoi_warn(p[1], msglevel); if (tcp_queue_limit < 1) { msg(msglevel, "--tcp-queue-limit parameter must be > 0"); @@ -7964,10 +7959,10 @@ int ageing_time, check_interval; VERIFY_PERMISSION(OPT_P_GENERAL); - ageing_time = atoi(p[1]); + ageing_time = atoi_warn(p[1], msglevel); if (p[2]) { - check_interval = atoi(p[2]); + check_interval = atoi_warn(p[2], msglevel); } else { @@ -7996,7 +7991,7 @@ else if (streq(p[0], "push-continuation") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_PULL_MODE); - options->push_continuation = atoi(p[1]); + options->push_continuation = atoi_warn(p[1], msglevel); } else if (streq(p[0], "auth-user-pass") && !p[2]) { @@ -8021,7 +8016,7 @@ { VERIFY_PERMISSION(OPT_P_GENERAL); options->sc_info.challenge_text = p[1]; - if (atoi(p[2])) + if (atoi_warn(p[2], msglevel)) { options->sc_info.flags |= SC_ECHO; } @@ -8117,7 +8112,7 @@ { if (!streq(p[2], "default")) { - int offset = atoi(p[2]); + int offset = atoi_warn(p[2], msglevel); if (!(offset > -256 && offset < 256)) { @@ -8133,7 +8128,7 @@ { const int min_lease = 30; int lease_time; - lease_time = atoi(p[3]); + lease_time = atoi_warn(p[3], msglevel); if (lease_time < min_lease) { msg(msglevel, "--ip-win32 dynamic [offset] [lease-time]: lease time parameter (%d) must be at least %d seconds", lease_time, min_lease); @@ -8257,7 +8252,7 @@ else if (streq(p[1], "NBT") && p[2] && !p[3]) { int t; - t = atoi(p[2]); + t = atoi_warn(p[2], msglevel); if (!(t == 1 || t == 2 || t == 4 || t == 8)) { msg(msglevel, "--dhcp-option NBT: parameter (%d) must be 1, 2, 4, or 8", t); @@ -8315,7 +8310,7 @@ #if defined(TARGET_ANDROID) else if (streq(p[1], "PROXY_HTTP") && p[3] && !p[4]) { - o->http_proxy_port = atoi(p[3]); + o->http_proxy_port = positiove_atoi(p[3], msglevel); o->http_proxy = p[2]; } #endif @@ -8349,7 +8344,7 @@ { int s; VERIFY_PERMISSION(OPT_P_DHCPDNS); - s = atoi(p[1]); + s = atoi_warn(p[1], msglevel); if (s < 0 || s >= 256) { msg(msglevel, "--tap-sleep parameter must be between 0 and 255"); @@ -8432,7 +8427,7 @@ options->exit_event_name = p[1]; if (p[2]) { - options->exit_event_initial_state = (atoi(p[2]) != 0); + options->exit_event_initial_state = (atoi_warn(p[2], msglevel) != 0); } } else if (streq(p[0], "allow-nonadmin") && !p[2]) @@ -8799,7 +8794,7 @@ { int replay_window; - replay_window = atoi(p[1]); + replay_window = atoi_warn(p[1], msglevel); if (!(MIN_SEQ_BACKTRACK <= replay_window && replay_window <= MAX_SEQ_BACKTRACK)) { msg(msglevel, "replay-window window size parameter (%d) must be between %d and %d", @@ -8814,7 +8809,7 @@ { int replay_time; - replay_time = atoi(p[2]); + replay_time = atoi_warn(p[2], msglevel); if (!(MIN_TIME_BACKTRACK <= replay_time && replay_time <= MAX_TIME_BACKTRACK)) { msg(msglevel, "replay-window time window parameter (%d) must be between %d and %d", @@ -9256,7 +9251,7 @@ else if (streq(p[0], "tls-timeout") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TLS_PARMS); - options->tls_timeout = positive_atoi(p[1]); + options->tls_timeout = positive_atoi(p[1], msglevel); } else if (streq(p[0], "reneg-bytes") && p[1] && !p[2]) { @@ -9285,21 +9280,21 @@ else if (streq(p[0], "reneg-sec") && p[1] && !p[3]) { VERIFY_PERMISSION(OPT_P_TLS_PARMS); - options->renegotiate_seconds = positive_atoi(p[1]); + options->renegotiate_seconds = positive_atoi(p[1], msglevel); if (p[2]) { - options->renegotiate_seconds_min = positive_atoi(p[2]); + options->renegotiate_seconds_min = positive_atoi(p[2], msglevel); } } else if (streq(p[0], "hand-window") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TLS_PARMS); - options->handshake_window = positive_atoi(p[1]); + options->handshake_window = positive_atoi(p[1], msglevel); } else if (streq(p[0], "tran-window") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_TLS_PARMS); - options->transition_window = positive_atoi(p[1]); + options->transition_window = positive_atoi(p[1], msglevel); } else if (streq(p[0], "tls-auth") && p[1] && !p[3]) { @@ -9436,7 +9431,7 @@ else if (streq(p[0], "show-pkcs11-ids") && !p[3]) { char *provider = p[1]; - bool cert_private = (p[2] == NULL ? false : ( atoi(p[2]) != 0 )); + bool cert_private = (p[2] == NULL ? false : (atoi_warn(p[2], msglevel) != 0 )); #ifdef DEFAULT_PKCS11_MODULE if (!provider) @@ -9488,7 +9483,7 @@ for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j) { - options->pkcs11_protected_authentication[j-1] = atoi(p[j]) != 0 ? 1 : 0; + options->pkcs11_protected_authentication[j-1] = atoi_warn(p[j], msglevel) != 0 ? 1 : 0; } } else if (streq(p[0], "pkcs11-private-mode") && p[1]) @@ -9510,13 +9505,13 @@ for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j) { - options->pkcs11_cert_private[j-1] = atoi(p[j]) != 0 ? 1 : 0; + options->pkcs11_cert_private[j-1] = (bool) (atoi_warn(p[j], msglevel)); } } else if (streq(p[0], "pkcs11-pin-cache") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL); - options->pkcs11_pin_cache_period = atoi(p[1]); + options->pkcs11_pin_cache_period = atoi_warn(p[1], msglevel); } else if (streq(p[0], "pkcs11-id") && p[1] && !p[2]) { @@ -9545,12 +9540,12 @@ { VERIFY_PERMISSION(OPT_P_PEER_ID); options->use_peer_id = true; - options->peer_id = atoi(p[1]); + options->peer_id = atoi_warn(p[1], msglevel); } #ifdef HAVE_EXPORT_KEYING_MATERIAL else if (streq(p[0], "keying-material-exporter") && p[1] && p[2]) { - int ekm_length = positive_atoi(p[2]); + int ekm_length = positive_atoi(p[2], msglevel); VERIFY_PERMISSION(OPT_P_GENERAL); @@ -9609,7 +9604,7 @@ else if (streq(p[0], "vlan-pvid") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_GENERAL|OPT_P_INSTANCE); - options->vlan_pvid = positive_atoi(p[1]); + options->vlan_pvid = positive_atoi(p[1], msglevel); if (options->vlan_pvid < OPENVPN_8021Q_MIN_VID || options->vlan_pvid > OPENVPN_8021Q_MAX_VID) { diff --git a/src/openvpn/options_util.c b/src/openvpn/options_util.c index a9e020a..fea4c3d 100644 --- a/src/openvpn/options_util.c +++ b/src/openvpn/options_util.c @@ -98,3 +98,50 @@ gc_free(&gc); return message; } + +bool +valid_integer(const char *str, bool positive) +{ + char *endptr; + long long i = strtoll(str, &endptr, 10); + + if (i < INT_MIN || (positive && i < 0) || *endptr != '\0' || i > INT_MAX) + { + return false; + } + else + { + return true; + } +} + +int +positive_atoi(const char *str, int msglevel) +{ + char *endptr; + long long i = strtoll(str, &endptr, 10); + + if (i < 0 || *endptr != '\0' || i > INT_MAX) + { + msg(msglevel, "Cannot parse argument '%s' as non-negative integer", + str); + i = 0; + } + + return (int) i; +} + +int +atoi_warn(const char *str, int msglevel) +{ + char *endptr; + long long i = strtoll(str, &endptr, 10); + + if (i < INT_MIN || *endptr != '\0' || i > INT_MAX) + { + msg(msglevel, "Cannot parse argument '%s' as integer", str); + i = 0; + } + + return (int) i; +} diff --git a/src/openvpn/options_util.h b/src/openvpn/options_util.h index 29bc9dc..f34d997 100644 --- a/src/openvpn/options_util.h +++ b/src/openvpn/options_util.h @@ -30,4 +30,24 @@ const char * parse_auth_failed_temp(struct options *o, const char *reason); -#endif + +/** Checks if the string is a valid integer by checking if it can be + * converted to an integer */ +bool +valid_integer(const char *str, bool positive); + +/** + * Converts a str to a positive number if the string represents a postive + * integer number. Otherwise print a warning with msglevel and return 0 + */ +int +positive_atoi(const char *str, int msglevel); + +/** + * Converts a str to an integer if the string can be represented as an + * integer number. Otherwise print a warning with msglevel and return 0 + */ +int +atoi_warn(const char *str, int msglevel); + +#endif /* ifndef OPTIONS_UTIL_H_ */ -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/873?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: Ie1e2eb54d516b3ae87c5ca56fe8edd77ee2be4de Gerrit-Change-Number: 873 Gerrit-PatchSet: 9 Gerrit-Owner: plaisthos <arne-open...@rfc2549.org> Gerrit-Reviewer: cron2 <g...@greenie.muc.de> Gerrit-Reviewer: flichtenheld <fr...@lichtenheld.com> Gerrit-Reviewer: plaisthos <arne-open...@rfc2549.org> Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> Gerrit-MessageType: merged
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel