diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2020-04-10 23:10:07 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2020-04-10 23:10:07 +0200 |
commit | 4f3065b441a19ac8661a487a1f87c25d7173ac03 (patch) | |
tree | ccf4fa15d6322e1c080d29500261cc7dc0be042a /src/openvpn/misc.c | |
parent | a351f71e82badcc71a2ce881bbb97eccfcebc06b (diff) | |
parent | 8a3450ef8682b9085637d7b94afc5c7e6f92e64b (diff) |
Update upstream source from tag 'upstream/2.4.8'
Update to upstream version '2.4.8'
with Debian dir 00c9c7e7fdd8b0a1729f9102507c151f67ca8c5d
Diffstat (limited to 'src/openvpn/misc.c')
-rw-r--r-- | src/openvpn/misc.c | 93 |
1 files changed, 56 insertions, 37 deletions
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 581a890..f44c65f 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -99,44 +99,57 @@ save_inetd_socket_descriptor(void) } /* - * Print an error message based on the status code returned by system(). + * Generate an error message based on the status code returned by openvpn_execve(). */ const char * system_error_message(int stat, struct gc_arena *gc) { struct buffer out = alloc_buf_gc(256, gc); -#ifdef _WIN32 - if (stat == -1) + + switch (stat) { - buf_printf(&out, "external program did not execute -- "); - } - buf_printf(&out, "returned error code %d", stat); + case OPENVPN_EXECVE_NOT_ALLOWED: + buf_printf(&out, "disallowed by script-security setting"); + break; + +#ifdef _WIN32 + case OPENVPN_EXECVE_ERROR: + buf_printf(&out, "external program did not execute -- "); + /* fall through */ + + default: + buf_printf(&out, "returned error code %d", stat); + break; #else /* ifdef _WIN32 */ - if (stat == -1) - { - buf_printf(&out, "external program fork failed"); - } - else if (!WIFEXITED(stat)) - { - buf_printf(&out, "external program did not exit normally"); - } - else - { - const int cmd_ret = WEXITSTATUS(stat); - if (!cmd_ret) - { - buf_printf(&out, "external program exited normally"); - } - else if (cmd_ret == 127) - { - buf_printf(&out, "could not execute external program"); - } - else - { - buf_printf(&out, "external program exited with error status: %d", cmd_ret); - } - } + + case OPENVPN_EXECVE_ERROR: + buf_printf(&out, "external program fork failed"); + break; + + default: + if (!WIFEXITED(stat)) + { + buf_printf(&out, "external program did not exit normally"); + } + else + { + const int cmd_ret = WEXITSTATUS(stat); + if (!cmd_ret) + { + buf_printf(&out, "external program exited normally"); + } + else if (cmd_ret == OPENVPN_EXECVE_FAILURE) + { + buf_printf(&out, "could not execute external program"); + } + else + { + buf_printf(&out, "external program exited with error status: %d", cmd_ret); + } + } + break; #endif /* ifdef _WIN32 */ + } return (const char *)out.data; } @@ -186,12 +199,14 @@ openvpn_execve_allowed(const unsigned int flags) * Run execve() inside a fork(). Designed to replicate the semantics of system() but * in a safer way that doesn't require the invocation of a shell or the risks * assocated with formatting and parsing a command line. + * Returns the exit status of child, OPENVPN_EXECVE_NOT_ALLOWED if openvpn_execve_allowed() + * returns false, or OPENVPN_EXECVE_ERROR on other errors. */ int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags) { struct gc_arena gc = gc_new(); - int ret = -1; + int ret = OPENVPN_EXECVE_ERROR; static bool warn_shown = false; if (a && a->argv[0]) @@ -208,7 +223,7 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in if (pid == (pid_t)0) /* child side */ { execve(cmd, argv, envp); - exit(127); + exit(OPENVPN_EXECVE_FAILURE); } else if (pid < (pid_t)0) /* fork failed */ { @@ -218,14 +233,18 @@ openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned in { if (waitpid(pid, &ret, 0) != pid) { - ret = -1; + ret = OPENVPN_EXECVE_ERROR; } } } - else if (!warn_shown && (script_security < SSEC_SCRIPTS)) + else { - msg(M_WARN, SCRIPT_SECURITY_WARNING); - warn_shown = true; + ret = OPENVPN_EXECVE_NOT_ALLOWED; + if (!warn_shown && (script_security < SSEC_SCRIPTS)) + { + msg(M_WARN, SCRIPT_SECURITY_WARNING); + warn_shown = true; + } } #else /* if defined(ENABLE_FEATURE_EXECVE) */ msg(M_WARN, "openvpn_execve: execve function not available"); @@ -272,7 +291,7 @@ openvpn_popen(const struct argv *a, const struct env_set *es) close(pipe_stdout[0]); /* Close read end */ dup2(pipe_stdout[1],1); execve(cmd, argv, envp); - exit(127); + exit(OPENVPN_EXECVE_FAILURE); } else if (pid > (pid_t)0) /* parent side */ { |