0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 20:03:13 +02:00

plugins, down-root: Code style clean-up

The coding style was somewhat chaotic.  Cleaning it up using the astyle
tool.  The style parameters are coherent to what was agreed upon at the
Munich Hackathon 2014 [1].

     astyle --style=allman --indent=spaces=4 -c

Also included a "Local variables" section which some editors may pick
up automatically.

Signed-off-by: David Sommerseth <davids@redhat.com>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1418078751-3614-1-git-send-email-openvpn.list@topphemmelig.net>
URL: http://article.gmane.org/gmane.network.openvpn.devel/9331
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
David Sommerseth 2014-12-08 23:45:51 +01:00 committed by Gert Doering
parent 706283d376
commit e2e9a69c1e

View File

@ -66,17 +66,17 @@ static void down_root_server (const int fd, char * const * argv, char * const *e
*/ */
struct down_root_context struct down_root_context
{ {
/* Foreground's socket to background process */ /* Foreground's socket to background process */
int foreground_fd; int foreground_fd;
/* Process ID of background process */ /* Process ID of background process */
pid_t background_pid; pid_t background_pid;
/* Verbosity level of OpenVPN */ /* Verbosity level of OpenVPN */
int verb; int verb;
/* down command */ /* down command */
char **command; char **command;
}; };
/* /*
@ -87,21 +87,21 @@ struct down_root_context
static const char * static const char *
get_env (const char *name, const char *envp[]) get_env (const char *name, const char *envp[])
{ {
if (envp) if (envp)
{ {
int i; int i;
const int namelen = strlen (name); const int namelen = strlen (name);
for (i = 0; envp[i]; ++i) for (i = 0; envp[i]; ++i)
{ {
if (!strncmp (envp[i], name, namelen)) if (!strncmp (envp[i], name, namelen))
{ {
const char *cp = envp[i] + namelen; const char *cp = envp[i] + namelen;
if (*cp == '=') if (*cp == '=')
return cp + 1; return cp + 1;
} }
} }
} }
return NULL; return NULL;
} }
/* /*
@ -110,13 +110,13 @@ get_env (const char *name, const char *envp[])
static int static int
string_array_len (const char *array[]) string_array_len (const char *array[])
{ {
int i = 0; int i = 0;
if (array) if (array)
{ {
while (array[i]) while (array[i])
++i; ++i;
} }
return i; return i;
} }
/* /*
@ -126,23 +126,23 @@ string_array_len (const char *array[])
static int static int
recv_control (int fd) recv_control (int fd)
{ {
unsigned char c; unsigned char c;
const ssize_t size = read (fd, &c, sizeof (c)); const ssize_t size = read (fd, &c, sizeof (c));
if (size == sizeof (c)) if (size == sizeof (c))
return c; return c;
else else
return -1; return -1;
} }
static int static int
send_control (int fd, int code) send_control (int fd, int code)
{ {
unsigned char c = (unsigned char) code; unsigned char c = (unsigned char) code;
const ssize_t size = write (fd, &c, sizeof (c)); const ssize_t size = write (fd, &c, sizeof (c));
if (size == sizeof (c)) if (size == sizeof (c))
return (int) size; return (int) size;
else else
return -1; return -1;
} }
/* /*
@ -153,22 +153,22 @@ send_control (int fd, int code)
static void static void
daemonize (const char *envp[]) daemonize (const char *envp[])
{ {
const char *daemon_string = get_env ("daemon", envp); const char *daemon_string = get_env ("daemon", envp);
if (daemon_string && daemon_string[0] == '1') if (daemon_string && daemon_string[0] == '1')
{ {
const char *log_redirect = get_env ("daemon_log_redirect", envp); const char *log_redirect = get_env ("daemon_log_redirect", envp);
int fd = -1; int fd = -1;
if (log_redirect && log_redirect[0] == '1') if (log_redirect && log_redirect[0] == '1')
fd = dup (2); fd = dup (2);
if (daemon (0, 0) < 0) if (daemon (0, 0) < 0)
{ {
warn ("DOWN-ROOT: daemonization failed"); warn ("DOWN-ROOT: daemonization failed");
} }
else if (fd >= 3) else if (fd >= 3)
{ {
dup2 (fd, 2); dup2 (fd, 2);
close (fd); close (fd);
} }
} }
} }
@ -185,12 +185,12 @@ daemonize (const char *envp[])
static void static void
close_fds_except (int keep) close_fds_except (int keep)
{ {
int i; int i;
closelog (); closelog ();
for (i = 3; i <= 100; ++i) for (i = 3; i <= 100; ++i)
{ {
if (i != keep) if (i != keep)
close (i); close (i);
} }
} }
@ -201,26 +201,26 @@ close_fds_except (int keep)
static void static void
set_signals (void) set_signals (void)
{ {
signal (SIGTERM, SIG_DFL); signal (SIGTERM, SIG_DFL);
signal (SIGINT, SIG_IGN); signal (SIGINT, SIG_IGN);
signal (SIGHUP, SIG_IGN); signal (SIGHUP, SIG_IGN);
signal (SIGUSR1, SIG_IGN); signal (SIGUSR1, SIG_IGN);
signal (SIGUSR2, SIG_IGN); signal (SIGUSR2, SIG_IGN);
signal (SIGPIPE, SIG_IGN); signal (SIGPIPE, SIG_IGN);
} }
static void static void
free_context (struct down_root_context *context) free_context (struct down_root_context *context)
{ {
if (context) if (context)
{ {
if (context->command) if (context->command)
{ {
free (context->command); free (context->command);
} }
free (context); free (context);
} }
} }
@ -229,226 +229,233 @@ free_context (struct down_root_context *context)
* calling execve() * calling execve()
*/ */
static int static int
run_script(char * const *argv, char * const *envp) { run_script(char * const *argv, char * const *envp)
pid_t pid; {
int ret = 0; pid_t pid;
int ret = 0;
pid = fork(); pid = fork();
if (pid == (pid_t)0) { /* child side */ if (pid == (pid_t)0) /* child side */
execve(argv[0], argv, envp); {
/* If execve() fails to run, exit child with exit code 127 */ execve(argv[0], argv, envp);
err(127, "DOWN-ROOT: Failed execute: %s", argv[0]); /* If execve() fails to run, exit child with exit code 127 */
} else if (pid < (pid_t)0 ){ err(127, "DOWN-ROOT: Failed execute: %s", argv[0]);
warn ("DOWN-ROOT: Failed to fork child to run %s", argv[0]);
return -1;
} else { /* parent side */
if( waitpid (pid, &ret, 0) != pid ) {
/* waitpid does not return error information via errno */
fprintf(stderr, "DOWN-ROOT: waitpid() failed, don't know exit code of child (%s)\n", argv[0]);
return -1;
} }
} else if (pid < (pid_t)0 )
return ret; {
warn ("DOWN-ROOT: Failed to fork child to run %s", argv[0]);
return -1;
}
else /* parent side */
{
if( waitpid (pid, &ret, 0) != pid )
{
/* waitpid does not return error information via errno */
fprintf(stderr, "DOWN-ROOT: waitpid() failed, don't know exit code of child (%s)\n", argv[0]);
return -1;
}
}
return ret;
} }
OPENVPN_EXPORT openvpn_plugin_handle_t OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[])
{ {
struct down_root_context *context; struct down_root_context *context;
int i = 0; int i = 0;
/* /*
* Allocate our context * Allocate our context
*/ */
context = (struct down_root_context *) calloc (1, sizeof (struct down_root_context)); context = (struct down_root_context *) calloc (1, sizeof (struct down_root_context));
if (!context) if (!context)
{ {
warn ("DOWN-ROOT: Could not allocate memory for plug-in context"); warn ("DOWN-ROOT: Could not allocate memory for plug-in context");
goto error; goto error;
} }
context->foreground_fd = -1; context->foreground_fd = -1;
/* /*
* Intercept the --up and --down callbacks * Intercept the --up and --down callbacks
*/ */
*type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN); *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_DOWN);
/* /*
* Make sure we have two string arguments: the first is the .so name, * Make sure we have two string arguments: the first is the .so name,
* the second is the script command. * the second is the script command.
*/ */
if (string_array_len (argv) < 2) if (string_array_len (argv) < 2)
{ {
fprintf (stderr, "DOWN-ROOT: need down script command\n"); fprintf (stderr, "DOWN-ROOT: need down script command\n");
goto error; goto error;
} }
/* /*
* Save the arguments in our context * Save the arguments in our context
*/ */
context->command = calloc(string_array_len(argv), sizeof(char *)); context->command = calloc(string_array_len(argv), sizeof(char *));
if (!context->command) if (!context->command)
{ {
warn ("DOWN-ROOT: Could not allocate memory for command array"); warn ("DOWN-ROOT: Could not allocate memory for command array");
goto error; goto error;
} }
/* Ignore argv[0], as it contains just the plug-in file name */ /* Ignore argv[0], as it contains just the plug-in file name */
for (i = 1; i < string_array_len(argv); i++) for (i = 1; i < string_array_len(argv); i++)
{ {
context->command[i-1] = (char *) argv[i]; context->command[i-1] = (char *) argv[i];
} }
/* /*
* Get verbosity level from environment * Get verbosity level from environment
*/ */
{ {
const char *verb_string = get_env ("verb", envp); const char *verb_string = get_env ("verb", envp);
if (verb_string) if (verb_string)
context->verb = atoi (verb_string); context->verb = atoi (verb_string);
} }
return (openvpn_plugin_handle_t) context; return (openvpn_plugin_handle_t) context;
error: error:
free_context (context); free_context (context);
return NULL; return NULL;
} }
OPENVPN_EXPORT int OPENVPN_EXPORT int
openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[])
{ {
struct down_root_context *context = (struct down_root_context *) handle; struct down_root_context *context = (struct down_root_context *) handle;
if (type == OPENVPN_PLUGIN_UP && context->foreground_fd == -1) /* fork off a process to hold onto root */ if (type == OPENVPN_PLUGIN_UP && context->foreground_fd == -1) /* fork off a process to hold onto root */
{ {
pid_t pid; pid_t pid;
int fd[2]; int fd[2];
/* /*
* Make a socket for foreground and background processes * Make a socket for foreground and background processes
* to communicate. * to communicate.
*/ */
if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd) == -1) if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
{ {
warn ("DOWN-ROOT: socketpair call failed"); warn ("DOWN-ROOT: socketpair call failed");
return OPENVPN_PLUGIN_FUNC_ERROR; return OPENVPN_PLUGIN_FUNC_ERROR;
} }
/* /*
* Fork off the privileged process. It will remain privileged * Fork off the privileged process. It will remain privileged
* even after the foreground process drops its privileges. * even after the foreground process drops its privileges.
*/ */
pid = fork (); pid = fork ();
if (pid) if (pid)
{ {
int status; int status;
/* /*
* Foreground Process * Foreground Process
*/ */
context->background_pid = pid; context->background_pid = pid;
/* close our copy of child's socket */ /* close our copy of child's socket */
close (fd[1]); close (fd[1]);
/* don't let future subprocesses inherit child socket */ /* don't let future subprocesses inherit child socket */
if (fcntl (fd[0], F_SETFD, FD_CLOEXEC) < 0) if (fcntl (fd[0], F_SETFD, FD_CLOEXEC) < 0)
{ {
warn ("DOWN-ROOT: Set FD_CLOEXEC flag on socket file descriptor failed"); warn ("DOWN-ROOT: Set FD_CLOEXEC flag on socket file descriptor failed");
} }
/* wait for background child process to initialize */ /* wait for background child process to initialize */
status = recv_control (fd[0]); status = recv_control (fd[0]);
if (status == RESPONSE_INIT_SUCCEEDED) if (status == RESPONSE_INIT_SUCCEEDED)
{ {
context->foreground_fd = fd[0]; context->foreground_fd = fd[0];
return OPENVPN_PLUGIN_FUNC_SUCCESS; return OPENVPN_PLUGIN_FUNC_SUCCESS;
} }
} }
else else
{ {
/* /*
* Background Process * Background Process
*/ */
/* close all parent fds except our socket back to parent */ /* close all parent fds except our socket back to parent */
close_fds_except (fd[1]); close_fds_except (fd[1]);
/* Ignore most signals (the parent will receive them) */ /* Ignore most signals (the parent will receive them) */
set_signals (); set_signals ();
/* Daemonize if --daemon option is set. */ /* Daemonize if --daemon option is set. */
daemonize (envp); daemonize (envp);
/* execute the event loop */ /* execute the event loop */
down_root_server (fd[1], context->command, (char * const *) envp, context->verb); down_root_server (fd[1], context->command, (char * const *) envp, context->verb);
close (fd[1]); close (fd[1]);
exit (0); exit (0);
return 0; /* NOTREACHED */ return 0; /* NOTREACHED */
} }
} }
else if (type == OPENVPN_PLUGIN_DOWN && context->foreground_fd >= 0) else if (type == OPENVPN_PLUGIN_DOWN && context->foreground_fd >= 0)
{ {
if (send_control (context->foreground_fd, COMMAND_RUN_SCRIPT) == -1) if (send_control (context->foreground_fd, COMMAND_RUN_SCRIPT) == -1)
{ {
warn ("DOWN-ROOT: Error sending script execution signal to background process"); warn ("DOWN-ROOT: Error sending script execution signal to background process");
} }
else else
{ {
const int status = recv_control (context->foreground_fd); const int status = recv_control (context->foreground_fd);
if (status == RESPONSE_SCRIPT_SUCCEEDED) if (status == RESPONSE_SCRIPT_SUCCEEDED)
return OPENVPN_PLUGIN_FUNC_SUCCESS; return OPENVPN_PLUGIN_FUNC_SUCCESS;
if (status == -1) if (status == -1)
{ {
warn ("DOWN-ROOT: Error receiving script execution confirmation from background process"); warn ("DOWN-ROOT: Error receiving script execution confirmation from background process");
} }
} }
} }
return OPENVPN_PLUGIN_FUNC_ERROR; return OPENVPN_PLUGIN_FUNC_ERROR;
} }
OPENVPN_EXPORT void OPENVPN_EXPORT void
openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
{ {
struct down_root_context *context = (struct down_root_context *) handle; struct down_root_context *context = (struct down_root_context *) handle;
if (DEBUG (context->verb)) if (DEBUG (context->verb))
fprintf (stderr, "DOWN-ROOT: close\n"); fprintf (stderr, "DOWN-ROOT: close\n");
if (context->foreground_fd >= 0) if (context->foreground_fd >= 0)
{ {
/* tell background process to exit */ /* tell background process to exit */
if (send_control (context->foreground_fd, COMMAND_EXIT) == -1) if (send_control (context->foreground_fd, COMMAND_EXIT) == -1)
{ {
warn ("DOWN-ROOT: Error signalling background process to exit"); warn ("DOWN-ROOT: Error signalling background process to exit");
} }
/* wait for background process to exit */ /* wait for background process to exit */
if (context->background_pid > 0) if (context->background_pid > 0)
waitpid (context->background_pid, NULL, 0); waitpid (context->background_pid, NULL, 0);
close (context->foreground_fd); close (context->foreground_fd);
context->foreground_fd = -1; context->foreground_fd = -1;
} }
free_context (context); free_context (context);
} }
OPENVPN_EXPORT void OPENVPN_EXPORT void
openvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle) openvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle)
{ {
struct down_root_context *context = (struct down_root_context *) handle; struct down_root_context *context = (struct down_root_context *) handle;
if (context && context->foreground_fd >= 0) if (context && context->foreground_fd >= 0)
{ {
/* tell background process to exit */ /* tell background process to exit */
send_control (context->foreground_fd, COMMAND_EXIT); send_control (context->foreground_fd, COMMAND_EXIT);
close (context->foreground_fd); close (context->foreground_fd);
context->foreground_fd = -1; context->foreground_fd = -1;
} }
} }
@ -458,74 +465,83 @@ openvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle)
static void static void
down_root_server (const int fd, char * const *argv, char * const *envp, const int verb) down_root_server (const int fd, char * const *argv, char * const *envp, const int verb)
{ {
/* /*
* Do initialization * Do initialization
*/ */
if (DEBUG (verb)) if (DEBUG (verb))
fprintf (stderr, "DOWN-ROOT: BACKGROUND: INIT command='%s'\n", argv[0]); fprintf (stderr, "DOWN-ROOT: BACKGROUND: INIT command='%s'\n", argv[0]);
/* /*
* Tell foreground that we initialized successfully * Tell foreground that we initialized successfully
*/ */
if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1) if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1)
{ {
warn ("DOWN-ROOT: BACKGROUND: write error on response socket [1]"); warn ("DOWN-ROOT: BACKGROUND: write error on response socket [1]");
goto done; goto done;
} }
/* /*
* Event loop * Event loop
*/ */
while (1) while (1)
{ {
int command_code; int command_code;
int exit_code = -1; int exit_code = -1;
/* get a command from foreground process */ /* get a command from foreground process */
command_code = recv_control (fd); command_code = recv_control (fd);
if (DEBUG (verb)) if (DEBUG (verb))
fprintf (stderr, "DOWN-ROOT: BACKGROUND: received command code: %d\n", command_code); fprintf (stderr, "DOWN-ROOT: BACKGROUND: received command code: %d\n", command_code);
switch (command_code) switch (command_code)
{ {
case COMMAND_RUN_SCRIPT: case COMMAND_RUN_SCRIPT:
if ( (exit_code = run_script(argv, envp)) == 0 ) /* Succeeded */ if ( (exit_code = run_script(argv, envp)) == 0 ) /* Succeeded */
{ {
if (send_control (fd, RESPONSE_SCRIPT_SUCCEEDED) == -1) if (send_control (fd, RESPONSE_SCRIPT_SUCCEEDED) == -1)
{ {
warn ("DOWN-ROOT: BACKGROUND: write error on response socket [2]"); warn ("DOWN-ROOT: BACKGROUND: write error on response socket [2]");
goto done; goto done;
} }
} }
else /* Failed */ else /* Failed */
{ {
fprintf(stderr, "DOWN-ROOT: BACKGROUND: %s exited with exit code %i\n", argv[0], exit_code); fprintf(stderr, "DOWN-ROOT: BACKGROUND: %s exited with exit code %i\n", argv[0], exit_code);
if (send_control (fd, RESPONSE_SCRIPT_FAILED) == -1) if (send_control (fd, RESPONSE_SCRIPT_FAILED) == -1)
{ {
warn ("DOWN-ROOT: BACKGROUND: write error on response socket [3]"); warn ("DOWN-ROOT: BACKGROUND: write error on response socket [3]");
goto done; goto done;
} }
} }
break; break;
case COMMAND_EXIT: case COMMAND_EXIT:
goto done; goto done;
case -1: case -1:
warn ("DOWN-ROOT: BACKGROUND: read error on command channel"); warn ("DOWN-ROOT: BACKGROUND: read error on command channel");
goto done; goto done;
default: default:
fprintf (stderr, "DOWN-ROOT: BACKGROUND: unknown command code: code=%d, exiting\n", fprintf (stderr, "DOWN-ROOT: BACKGROUND: unknown command code: code=%d, exiting\n",
command_code); command_code);
goto done; goto done;
} }
} }
done: done:
if (DEBUG (verb)) if (DEBUG (verb))
fprintf (stderr, "DOWN-ROOT: BACKGROUND: EXIT\n"); fprintf (stderr, "DOWN-ROOT: BACKGROUND: EXIT\n");
return; return;
} }
/*
Local variables:
c-file-style: "bsd"
c-basic-offset: 4
indent-tabs-mode: nil
End:
*/