64 buf_printf(&out,
"disallowed by script-security setting");
69 buf_printf(&out,
"external program did not execute -- ");
78 buf_printf(&out,
"external program fork failed");
84 buf_printf(&out,
"external program did not exit normally");
91 buf_printf(&out,
"external program exited normally");
95 buf_printf(&out,
"could not execute external program");
105 return (
const char *)out.
data;
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);
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.
int len
Length in bytes of the actual content within 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)