diff --git a/cli-runopts.c b/cli-runopts.c index e42ef57..ca58899 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -355,8 +355,7 @@ void cli_getopts(int argc, char ** argv) { } } if (keepalive_arg) { - opts.keepalive_secs = strtoul(keepalive_arg, NULL, 10); - if (opts.keepalive_secs == 0 && errno == EINVAL) { + if (m_str_to_uint(keepalive_arg, &opts.keepalive_secs) == DROPBEAR_FAILURE) { dropbear_exit("Bad keepalive '%s'", keepalive_arg); } } @@ -499,8 +498,7 @@ static void add_netcat(const char* origstr) { goto fail; } - cli_opts.netcat_port = strtoul(portstr, NULL, 10); - if (errno != 0) { + if (m_str_to_uint(portstr, &cli_opts.netcat_port) == DROPBEAR_FAILURE) { TRACE(("bad netcat port")) goto fail; } @@ -571,15 +569,13 @@ static void addforward(const char* origstr, struct TCPFwdList** fwdlist) { /* Now we check the ports - note that the port ints are unsigned, * the check later only checks for >= MAX_PORT */ - newfwd->listenport = strtoul(listenport, NULL, 10); - if (errno != 0) { - TRACE(("bad listenport strtol")) + if (m_str_to_uint(listenport, &newfwd->listenport) == DROPBEAR_FAILURE) { + TRACE(("bad listenport strtoul")) goto fail; } - newfwd->connectport = strtoul(connectport, NULL, 10); - if (errno != 0) { - TRACE(("bad connectport strtol")) + if (m_str_to_uint(connectport, &newfwd->connectport) == DROPBEAR_FAILURE) { + TRACE(("bad connectport strtoul")) goto fail; } diff --git a/dbutil.c b/dbutil.c index 45915be..b016dc1 100644 --- a/dbutil.c +++ b/dbutil.c @@ -504,7 +504,7 @@ void run_shell_command(const char* cmd, unsigned int maxfd, char* usershell) { if (cmd != NULL) { argv[1] = "-c"; - argv[2] = cmd; + argv[2] = (char*)cmd; argv[3] = NULL; } else { /* construct a shell of the form "-bash" etc */ @@ -835,3 +835,17 @@ void disallow_core() { lim.rlim_cur = lim.rlim_max = 0; setrlimit(RLIMIT_CORE, &lim); } + +/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE, with the result in *val */ +int m_str_to_uint(const char* str, unsigned int *val) { + errno = 0; + *val = strtoul(str, NULL, 10); + /* The c99 spec doesn't actually seem to define EINVAL, but most platforms + * I've looked at mention it in their manpage */ + if ((*val == 0 && errno == EINVAL) + || (*val == ULONG_MAX && errno == ERANGE)) { + return DROPBEAR_FAILURE; + } else { + return DROPBEAR_SUCCESS; + } +} diff --git a/dbutil.h b/dbutil.h index a70ed46..706f35e 100644 --- a/dbutil.h +++ b/dbutil.h @@ -67,6 +67,7 @@ void __m_free(void* ptr); void m_burn(void* data, unsigned int len); void setnonblocking(int fd); void disallow_core(); +int m_str_to_uint(const char* str, unsigned int *val); /* Used to force mp_ints to be initialised */ #define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL} diff --git a/runopts.h b/runopts.h index 1be82a6..e9d2363 100644 --- a/runopts.h +++ b/runopts.h @@ -37,7 +37,7 @@ typedef struct runopts { int listen_fwd_all; #endif unsigned int recv_window; - time_t keepalive_secs; + unsigned int keepalive_secs; } runopts; diff --git a/svr-runopts.c b/svr-runopts.c index 83c75c3..c8b6585 100644 --- a/svr-runopts.c +++ b/svr-runopts.c @@ -284,16 +284,13 @@ void svr_getopts(int argc, char ** argv) { if (recv_window_arg) { opts.recv_window = atol(recv_window_arg); - if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW) - { + if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW) { dropbear_exit("Bad recv window '%s'", recv_window_arg); } } if (keepalive_arg) { - opts.keepalive_secs = strtoul(keepalive_arg, NULL, 10); - if (opts.keepalive_secs == 0 && errno == EINVAL) - { + if (m_str_to_uint(keepalive_arg, &opts.keepalive_secs) == DROPBEAR_FAILURE) { dropbear_exit("Bad keepalive '%s'", keepalive_arg); } }