64 buf_printf(&out,
"disallowed by script-security setting");
69 buf_printf(&out,
"external program did not execute -- ");
73 buf_printf(&out,
"returned error code %d", stat);
78 buf_printf(&out,
"external program fork failed");
84 buf_printf(&out,
"external program did not exit normally");
88 const int cmd_ret = WEXITSTATUS(stat);
91 buf_printf(&out,
"external program exited normally");
95 buf_printf(&out,
"could not execute external program");
99 buf_printf(&out,
"external program exited with error status: %d", cmd_ret);
105 return (
const char *)out.
data;
117 pid_t pidret = waitpid(pid, &
status, WNOHANG);
125 int exitcode = WEXITSTATUS(
status);
129 msg(msglevel,
"%scould not execute external program (exit code 127)", msg_prefix);
133 msg(msglevel,
"%sexternal program exited with error status: %d", msg_prefix, exitcode);
136 else if (WIFSIGNALED(
status))
138 msg(msglevel,
"%sexternal program received signal %d", msg_prefix, WTERMSIG(
status));
172 static bool warn_shown =
false;
176#if defined(ENABLE_FEATURE_EXECVE)
181 const pid_t pid = fork();
184 const char *cmd = a->
argv[0];
186 execve(cmd,
argv, envp);
189 else if (pid < (pid_t)0)
191 msg(
M_ERR,
"openvpn_execve: unable to fork");
199 if (waitpid(pid, &ret, 0) != pid)
215 msg(
M_WARN,
"openvpn_execve: execve function not available");
220 msg(
M_FATAL,
"openvpn_execve: called with empty argv");
233 const char *error_message)
281#if defined(ENABLE_FEATURE_EXECVE)
282 static bool warn_shown =
false;
286 const char *cmd = a->
argv[0];
289 if (pipe(pipe_stdout) == 0)
291 const pid_t pid = fork();
296 close(pipe_stdout[0]);
297 dup2(pipe_stdout[1], 1);
298 execve(cmd,
argv, envp);
301 else if (pid > (pid_t)0)
305 close(pipe_stdout[1]);
307 ret = pipe_stdout[0];
311 close(pipe_stdout[0]);
312 close(pipe_stdout[1]);
313 msg(
M_ERR,
"openvpn_popen: unable to fork %s", cmd);
318 msg(
M_WARN,
"openvpn_popen: unable to create stdout pipe for %s", cmd);
328 msg(
M_WARN,
"openvpn_popen: execve function not available");
333 msg(
M_FATAL,
"openvpn_popen: called with empty argv");
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Buffer management functions and garbage collection.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
#define SCRIPT_SECURITY_WARNING
const char ** make_env_array(const struct env_set *es, const bool check_allowed, struct gc_arena *gc)
static SERVICE_STATUS status
bool openvpn_execve_allowed(const unsigned int flags)
void script_security_set(int level)
int openvpn_popen(const struct argv *a, const struct env_set *es)
static const char * system_error_message(int stat, struct gc_arena *gc)
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
int script_security(void)
bool openvpn_waitpid_check(pid_t pid, const char *msg_prefix, msglvl_t msglevel)
Checks if a running process is still running.
static int script_security_level
#define SSEC_SCRIPTS
allow calling of built-in programs and user-defined scripts
#define S_EXITCODE
Instead of returning 1/0 for success/fail, return exit code when between 0 and 255 and -1 otherwise.
#define OPENVPN_EXECVE_ERROR
#define OPENVPN_EXECVE_NOT_ALLOWED
#define S_NOWAITPID
instead of waiting for child process to exit and report the status, return the pid of the child proce...
#define SSEC_BUILT_IN
only call built-in programs such as ifconfig, route, netsh, etc.
#define OPENVPN_EXECVE_FAILURE
Wrapper structure for dynamically allocated memory.
uint8_t * data
Pointer to the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)