summaryrefslogtreecommitdiff
path: root/src/plugins/auth-pam
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
commit3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (patch)
treef29063da5bec4caf3853d49a22a09c8619eebd21 /src/plugins/auth-pam
parentd53dba59e78da865c4fe820386ff2f4f76925f3b (diff)
New upstream version 2.4.0upstream/2.4.0
Diffstat (limited to 'src/plugins/auth-pam')
-rw-r--r--src/plugins/auth-pam/Makefile.in6
-rw-r--r--src/plugins/auth-pam/auth-pam.c1028
-rw-r--r--src/plugins/auth-pam/pamdl.c113
-rw-r--r--src/plugins/auth-pam/pamdl.h6
-rw-r--r--src/plugins/auth-pam/utils.c102
-rw-r--r--src/plugins/auth-pam/utils.h6
6 files changed, 680 insertions, 581 deletions
diff --git a/src/plugins/auth-pam/Makefile.in b/src/plugins/auth-pam/Makefile.in
index 3a3c656..90d5058 100644
--- a/src/plugins/auth-pam/Makefile.in
+++ b/src/plugins/auth-pam/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -494,14 +494,14 @@ distclean-compile:
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/plugins/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c
index 5ad3ec8..d3e2c89 100644
--- a/src/plugins/auth-pam/auth-pam.c
+++ b/src/plugins/auth-pam/auth-pam.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -68,14 +68,14 @@
*/
struct auth_pam_context
{
- /* Foreground's socket to background process */
- int foreground_fd;
+ /* Foreground's socket to background process */
+ int foreground_fd;
- /* Process ID of background process */
- pid_t background_pid;
+ /* Process ID of background process */
+ pid_t background_pid;
- /* Verbosity level of OpenVPN */
- int verb;
+ /* Verbosity level of OpenVPN */
+ int verb;
};
/*
@@ -90,13 +90,13 @@ struct auth_pam_context
#define N_NAME_VALUE 16
struct name_value {
- const char *name;
- const char *value;
+ const char *name;
+ const char *value;
};
struct name_value_list {
- int len;
- struct name_value data[N_NAME_VALUE];
+ int len;
+ struct name_value data[N_NAME_VALUE];
};
/*
@@ -104,17 +104,17 @@ struct name_value_list {
* to the PAM conversation function.
*/
struct user_pass {
- int verb;
+ int verb;
- char username[128];
- char password[128];
- char common_name[128];
+ char username[128];
+ char password[128];
+ char common_name[128];
- const struct name_value_list *name_value_list;
+ const struct name_value_list *name_value_list;
};
/* Background process function */
-static void pam_server (int fd, const char *service, int verb, const struct name_value_list *name_value_list);
+static void pam_server(int fd, const char *service, int verb, const struct name_value_list *name_value_list);
/*
@@ -122,54 +122,66 @@ static void pam_server (int fd, const char *service, int verb, const struct name
*/
static int
-recv_control (int fd)
+recv_control(int fd)
{
- unsigned char c;
- const ssize_t size = read (fd, &c, sizeof (c));
- if (size == sizeof (c))
- return c;
- else
+ unsigned char c;
+ const ssize_t size = read(fd, &c, sizeof(c));
+ if (size == sizeof(c))
{
- /*fprintf (stderr, "AUTH-PAM: DEBUG recv_control.read=%d\n", (int)size);*/
- return -1;
+ return c;
+ }
+ else
+ {
+ /*fprintf (stderr, "AUTH-PAM: DEBUG recv_control.read=%d\n", (int)size);*/
+ return -1;
}
}
static int
-send_control (int fd, int code)
+send_control(int fd, int code)
{
- unsigned char c = (unsigned char) code;
- const ssize_t size = write (fd, &c, sizeof (c));
- if (size == sizeof (c))
- return (int) size;
- else
- return -1;
+ unsigned char c = (unsigned char) code;
+ const ssize_t size = write(fd, &c, sizeof(c));
+ if (size == sizeof(c))
+ {
+ return (int) size;
+ }
+ else
+ {
+ return -1;
+ }
}
static int
-recv_string (int fd, char *buffer, int len)
+recv_string(int fd, char *buffer, int len)
{
- if (len > 0)
+ if (len > 0)
{
- ssize_t size;
- memset (buffer, 0, len);
- size = read (fd, buffer, len);
- buffer[len-1] = 0;
- if (size >= 1)
- return (int)size;
+ ssize_t size;
+ memset(buffer, 0, len);
+ size = read(fd, buffer, len);
+ buffer[len-1] = 0;
+ if (size >= 1)
+ {
+ return (int)size;
+ }
}
- return -1;
+ return -1;
}
static int
-send_string (int fd, const char *string)
+send_string(int fd, const char *string)
{
- const int len = strlen (string) + 1;
- const ssize_t size = write (fd, string, len);
- if (size == len)
- return (int) size;
- else
- return -1;
+ const int len = strlen(string) + 1;
+ const ssize_t size = write(fd, string, len);
+ if (size == len)
+ {
+ return (int) size;
+ }
+ else
+ {
+ return -1;
+ }
}
#ifdef DO_DAEMONIZE
@@ -180,28 +192,30 @@ send_string (int fd, const char *string)
* "daemon_log_redirect" env var is true.
*/
static void
-daemonize (const char *envp[])
+daemonize(const char *envp[])
{
- const char *daemon_string = get_env ("daemon", envp);
- if (daemon_string && daemon_string[0] == '1')
- {
- const char *log_redirect = get_env ("daemon_log_redirect", envp);
- int fd = -1;
- if (log_redirect && log_redirect[0] == '1')
- fd = dup (2);
- if (daemon (0, 0) < 0)
- {
- fprintf (stderr, "AUTH-PAM: daemonization failed\n");
- }
- else if (fd >= 3)
- {
- dup2 (fd, 2);
- close (fd);
- }
+ const char *daemon_string = get_env("daemon", envp);
+ if (daemon_string && daemon_string[0] == '1')
+ {
+ const char *log_redirect = get_env("daemon_log_redirect", envp);
+ int fd = -1;
+ if (log_redirect && log_redirect[0] == '1')
+ {
+ fd = dup(2);
+ }
+ if (daemon(0, 0) < 0)
+ {
+ fprintf(stderr, "AUTH-PAM: daemonization failed\n");
+ }
+ else if (fd >= 3)
+ {
+ dup2(fd, 2);
+ close(fd);
+ }
}
}
-#endif
+#endif /* ifdef DO_DAEMONIZE */
/*
* Close most of parent's fds.
@@ -214,14 +228,16 @@ daemonize (const char *envp[])
* fds from crossing a fork().
*/
static void
-close_fds_except (int keep)
+close_fds_except(int keep)
{
- int i;
- closelog ();
- for (i = 3; i <= 100; ++i)
+ int i;
+ closelog();
+ for (i = 3; i <= 100; ++i)
{
- if (i != keep)
- close (i);
+ if (i != keep)
+ {
+ close(i);
+ }
}
}
@@ -230,243 +246,263 @@ close_fds_except (int keep)
* deal with them.
*/
static void
-set_signals (void)
+set_signals(void)
{
- signal (SIGTERM, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
- signal (SIGINT, SIG_IGN);
- signal (SIGHUP, SIG_IGN);
- signal (SIGUSR1, SIG_IGN);
- signal (SIGUSR2, SIG_IGN);
- signal (SIGPIPE, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGUSR1, SIG_IGN);
+ signal(SIGUSR2, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
}
/*
* Return 1 if query matches match.
*/
static int
-name_value_match (const char *query, const char *match)
+name_value_match(const char *query, const char *match)
{
- while (!isalnum (*query))
+ while (!isalnum(*query))
{
- if (*query == '\0')
- return 0;
- ++query;
+ if (*query == '\0')
+ {
+ return 0;
+ }
+ ++query;
}
- return strncasecmp (match, query, strlen (match)) == 0;
+ return strncasecmp(match, query, strlen(match)) == 0;
}
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[])
{
- pid_t pid;
- int fd[2];
-
- struct auth_pam_context *context;
- struct name_value_list name_value_list;
-
- const int base_parms = 2;
-
- /*
- * Allocate our context
- */
- context = (struct auth_pam_context *) calloc (1, sizeof (struct auth_pam_context));
- if (!context)
- goto error;
- context->foreground_fd = -1;
-
- /*
- * Intercept the --auth-user-pass-verify callback.
- */
- *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);
+ pid_t pid;
+ int fd[2];
+
+ struct auth_pam_context *context;
+ struct name_value_list name_value_list;
- /*
- * Make sure we have two string arguments: the first is the .so name,
- * the second is the PAM service type.
- */
- if (string_array_len (argv) < base_parms)
+ const int base_parms = 2;
+
+ /*
+ * Allocate our context
+ */
+ context = (struct auth_pam_context *) calloc(1, sizeof(struct auth_pam_context));
+ if (!context)
{
- fprintf (stderr, "AUTH-PAM: need PAM service parameter\n");
- goto error;
+ goto error;
}
-
- /*
- * See if we have optional name/value pairs to match against
- * PAM module queried fields in the conversation function.
- */
- name_value_list.len = 0;
- if (string_array_len (argv) > base_parms)
+ context->foreground_fd = -1;
+
+ /*
+ * Intercept the --auth-user-pass-verify callback.
+ */
+ *type_mask = OPENVPN_PLUGIN_MASK(OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);
+
+ /*
+ * Make sure we have two string arguments: the first is the .so name,
+ * the second is the PAM service type.
+ */
+ if (string_array_len(argv) < base_parms)
{
- const int nv_len = string_array_len (argv) - base_parms;
- int i;
-
- if ((nv_len & 1) == 1 || (nv_len / 2) > N_NAME_VALUE)
- {
- fprintf (stderr, "AUTH-PAM: bad name/value list length\n");
- goto error;
- }
-
- name_value_list.len = nv_len / 2;
- for (i = 0; i < name_value_list.len; ++i)
- {
- const int base = base_parms + i * 2;
- name_value_list.data[i].name = argv[base];
- name_value_list.data[i].value = argv[base+1];
- }
+ fprintf(stderr, "AUTH-PAM: need PAM service parameter\n");
+ goto error;
}
- /*
- * Get verbosity level from environment
- */
- {
- const char *verb_string = get_env ("verb", envp);
- if (verb_string)
- context->verb = atoi (verb_string);
- }
-
- /*
- * Make a socket for foreground and background processes
- * to communicate.
- */
- if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
+ /*
+ * See if we have optional name/value pairs to match against
+ * PAM module queried fields in the conversation function.
+ */
+ name_value_list.len = 0;
+ if (string_array_len(argv) > base_parms)
{
- fprintf (stderr, "AUTH-PAM: socketpair call failed\n");
- goto error;
+ const int nv_len = string_array_len(argv) - base_parms;
+ int i;
+
+ if ((nv_len & 1) == 1 || (nv_len / 2) > N_NAME_VALUE)
+ {
+ fprintf(stderr, "AUTH-PAM: bad name/value list length\n");
+ goto error;
+ }
+
+ name_value_list.len = nv_len / 2;
+ for (i = 0; i < name_value_list.len; ++i)
+ {
+ const int base = base_parms + i * 2;
+ name_value_list.data[i].name = argv[base];
+ name_value_list.data[i].value = argv[base+1];
+ }
}
- /*
- * Fork off the privileged process. It will remain privileged
- * even after the foreground process drops its privileges.
- */
- pid = fork ();
-
- if (pid)
+ /*
+ * Get verbosity level from environment
+ */
{
- int status;
-
- /*
- * Foreground Process
- */
-
- context->background_pid = pid;
+ const char *verb_string = get_env("verb", envp);
+ if (verb_string)
+ {
+ context->verb = atoi(verb_string);
+ }
+ }
- /* close our copy of child's socket */
- close (fd[1]);
+ /*
+ * Make a socket for foreground and background processes
+ * to communicate.
+ */
+ if (socketpair(PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: socketpair call failed\n");
+ goto error;
+ }
- /* don't let future subprocesses inherit child socket */
- if (fcntl (fd[0], F_SETFD, FD_CLOEXEC) < 0)
- fprintf (stderr, "AUTH-PAM: Set FD_CLOEXEC flag on socket file descriptor failed\n");
+ /*
+ * Fork off the privileged process. It will remain privileged
+ * even after the foreground process drops its privileges.
+ */
+ pid = fork();
- /* wait for background child process to initialize */
- status = recv_control (fd[0]);
- if (status == RESPONSE_INIT_SUCCEEDED)
- {
- context->foreground_fd = fd[0];
- return (openvpn_plugin_handle_t) context;
- }
+ if (pid)
+ {
+ int status;
+
+ /*
+ * Foreground Process
+ */
+
+ context->background_pid = pid;
+
+ /* close our copy of child's socket */
+ close(fd[1]);
+
+ /* don't let future subprocesses inherit child socket */
+ if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0)
+ {
+ fprintf(stderr, "AUTH-PAM: Set FD_CLOEXEC flag on socket file descriptor failed\n");
+ }
+
+ /* wait for background child process to initialize */
+ status = recv_control(fd[0]);
+ if (status == RESPONSE_INIT_SUCCEEDED)
+ {
+ context->foreground_fd = fd[0];
+ return (openvpn_plugin_handle_t) context;
+ }
}
- else
+ else
{
- /*
- * Background Process
- */
+ /*
+ * Background Process
+ */
- /* close all parent fds except our socket back to parent */
- close_fds_except (fd[1]);
+ /* close all parent fds except our socket back to parent */
+ close_fds_except(fd[1]);
- /* Ignore most signals (the parent will receive them) */
- set_signals ();
+ /* Ignore most signals (the parent will receive them) */
+ set_signals();
#ifdef DO_DAEMONIZE
- /* Daemonize if --daemon option is set. */
- daemonize (envp);
+ /* Daemonize if --daemon option is set. */
+ daemonize(envp);
#endif
- /* execute the event loop */
- pam_server (fd[1], argv[1], context->verb, &name_value_list);
+ /* execute the event loop */
+ pam_server(fd[1], argv[1], context->verb, &name_value_list);
- close (fd[1]);
+ close(fd[1]);
- exit (0);
- return 0; /* NOTREACHED */
+ exit(0);
+ return 0; /* NOTREACHED */
}
- error:
- if (context)
- free (context);
- return NULL;
+error:
+ if (context)
+ {
+ free(context);
+ }
+ return NULL;
}
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 auth_pam_context *context = (struct auth_pam_context *) handle;
-
- if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY && context->foreground_fd >= 0)
- {
- /* get username/password from envp string array */
- const char *username = get_env ("username", envp);
- const char *password = get_env ("password", envp);
- const char *common_name = get_env ("common_name", envp) ? get_env ("common_name", envp) : "";
-
- if (username && strlen (username) > 0 && password)
- {
- if (send_control (context->foreground_fd, COMMAND_VERIFY) == -1
- || send_string (context->foreground_fd, username) == -1
- || send_string (context->foreground_fd, password) == -1
- || send_string (context->foreground_fd, common_name) == -1)
- {
- fprintf (stderr, "AUTH-PAM: Error sending auth info to background process\n");
- }
- else
- {
- const int status = recv_control (context->foreground_fd);
- if (status == RESPONSE_VERIFY_SUCCEEDED)
- return OPENVPN_PLUGIN_FUNC_SUCCESS;
- if (status == -1)
- fprintf (stderr, "AUTH-PAM: Error receiving auth confirmation from background process\n");
- }
- }
- }
- return OPENVPN_PLUGIN_FUNC_ERROR;
+ struct auth_pam_context *context = (struct auth_pam_context *) handle;
+
+ if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY && context->foreground_fd >= 0)
+ {
+ /* get username/password from envp string array */
+ const char *username = get_env("username", envp);
+ const char *password = get_env("password", envp);
+ const char *common_name = get_env("common_name", envp) ? get_env("common_name", envp) : "";
+
+ if (username && strlen(username) > 0 && password)
+ {
+ if (send_control(context->foreground_fd, COMMAND_VERIFY) == -1
+ || send_string(context->foreground_fd, username) == -1
+ || send_string(context->foreground_fd, password) == -1
+ || send_string(context->foreground_fd, common_name) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: Error sending auth info to background process\n");
+ }
+ else
+ {
+ const int status = recv_control(context->foreground_fd);
+ if (status == RESPONSE_VERIFY_SUCCEEDED)
+ {
+ return OPENVPN_PLUGIN_FUNC_SUCCESS;
+ }
+ if (status == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: Error receiving auth confirmation from background process\n");
+ }
+ }
+ }
+ }
+ return OPENVPN_PLUGIN_FUNC_ERROR;
}
OPENVPN_EXPORT void
-openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
+openvpn_plugin_close_v1(openvpn_plugin_handle_t handle)
{
- struct auth_pam_context *context = (struct auth_pam_context *) handle;
-
- if (DEBUG (context->verb))
- fprintf (stderr, "AUTH-PAM: close\n");
+ struct auth_pam_context *context = (struct auth_pam_context *) handle;
- if (context->foreground_fd >= 0)
+ if (DEBUG(context->verb))
{
- /* tell background process to exit */
- if (send_control (context->foreground_fd, COMMAND_EXIT) == -1)
- fprintf (stderr, "AUTH-PAM: Error signaling background process to exit\n");
-
- /* wait for background process to exit */
- if (context->background_pid > 0)
- waitpid (context->background_pid, NULL, 0);
+ fprintf(stderr, "AUTH-PAM: close\n");
+ }
- close (context->foreground_fd);
- context->foreground_fd = -1;
+ if (context->foreground_fd >= 0)
+ {
+ /* tell background process to exit */
+ if (send_control(context->foreground_fd, COMMAND_EXIT) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: Error signaling background process to exit\n");
+ }
+
+ /* wait for background process to exit */
+ if (context->background_pid > 0)
+ {
+ waitpid(context->background_pid, NULL, 0);
+ }
+
+ close(context->foreground_fd);
+ context->foreground_fd = -1;
}
- free (context);
+ free(context);
}
OPENVPN_EXPORT void
-openvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle)
+openvpn_plugin_abort_v1(openvpn_plugin_handle_t handle)
{
- struct auth_pam_context *context = (struct auth_pam_context *) handle;
+ struct auth_pam_context *context = (struct auth_pam_context *) handle;
- /* tell background process to exit */
- if (context && context->foreground_fd >= 0)
+ /* tell background process to exit */
+ if (context && context->foreground_fd >= 0)
{
- send_control (context->foreground_fd, COMMAND_EXIT);
- close (context->foreground_fd);
- context->foreground_fd = -1;
+ send_control(context->foreground_fd, COMMAND_EXIT);
+ close(context->foreground_fd);
+ context->foreground_fd = -1;
}
}
@@ -474,111 +510,137 @@ openvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle)
* PAM conversation function
*/
static int
-my_conv (int n, const struct pam_message **msg_array,
- struct pam_response **response_array, void *appdata_ptr)
+my_conv(int n, const struct pam_message **msg_array,
+ struct pam_response **response_array, void *appdata_ptr)
{
- const struct user_pass *up = ( const struct user_pass *) appdata_ptr;
- struct pam_response *aresp;
- int i;
- int ret = PAM_SUCCESS;
-
- *response_array = NULL;
-
- if (n <= 0 || n > PAM_MAX_NUM_MSG)
- return (PAM_CONV_ERR);
- if ((aresp = calloc (n, sizeof *aresp)) == NULL)
- return (PAM_BUF_ERR);
-
- /* loop through each PAM-module query */
- for (i = 0; i < n; ++i)
- {
- const struct pam_message *msg = msg_array[i];
- aresp[i].resp_retcode = 0;
- aresp[i].resp = NULL;
-
- if (DEBUG (up->verb))
- {
- fprintf (stderr, "AUTH-PAM: BACKGROUND: my_conv[%d] query='%s' style=%d\n",
- i,
- msg->msg ? msg->msg : "NULL",
- msg->msg_style);
- }
-
- if (up->name_value_list && up->name_value_list->len > 0)
- {
- /* use name/value list match method */
- const struct name_value_list *list = up->name_value_list;
- int j;
-
- /* loop through name/value pairs */
- for (j = 0; j < list->len; ++j)
- {
- const char *match_name = list->data[j].name;
- const char *match_value = list->data[j].value;
-
- if (name_value_match (msg->msg, match_name))
- {
- /* found name/value match */
- aresp[i].resp = NULL;
-
- if (DEBUG (up->verb))
- fprintf (stderr, "AUTH-PAM: BACKGROUND: name match found, query/match-string ['%s', '%s'] = '%s'\n",
- msg->msg,
- match_name,
- match_value);
-
- if (strstr(match_value, "USERNAME"))
- aresp[i].resp = searchandreplace(match_value, "USERNAME", up->username);
- else if (strstr(match_value, "PASSWORD"))
- aresp[i].resp = searchandreplace(match_value, "PASSWORD", up->password);
- else if (strstr(match_value, "COMMONNAME"))
- aresp[i].resp = searchandreplace(match_value, "COMMONNAME", up->common_name);
- else
- aresp[i].resp = strdup (match_value);
-
- if (aresp[i].resp == NULL)
- ret = PAM_CONV_ERR;
- break;
- }
- }
-
- if (j == list->len)
- ret = PAM_CONV_ERR;
- }
- else
- {
- /* use PAM_PROMPT_ECHO_x hints */
- switch (msg->msg_style)
- {
- case PAM_PROMPT_ECHO_OFF:
- aresp[i].resp = strdup (up->password);
- if (aresp[i].resp == NULL)
- ret = PAM_CONV_ERR;
- break;
-
- case PAM_PROMPT_ECHO_ON:
- aresp[i].resp = strdup (up->username);
- if (aresp[i].resp == NULL)
- ret = PAM_CONV_ERR;
- break;
-
- case PAM_ERROR_MSG:
- case PAM_TEXT_INFO:
- break;
-
- default:
- ret = PAM_CONV_ERR;
- break;
- }
- }
- }
-
- if (ret == PAM_SUCCESS)
- *response_array = aresp;
- else
- free(aresp);
-
- return ret;
+ const struct user_pass *up = ( const struct user_pass *) appdata_ptr;
+ struct pam_response *aresp;
+ int i;
+ int ret = PAM_SUCCESS;
+
+ *response_array = NULL;
+
+ if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ {
+ return (PAM_CONV_ERR);
+ }
+ if ((aresp = calloc(n, sizeof *aresp)) == NULL)
+ {
+ return (PAM_BUF_ERR);
+ }
+
+ /* loop through each PAM-module query */
+ for (i = 0; i < n; ++i)
+ {
+ const struct pam_message *msg = msg_array[i];
+ aresp[i].resp_retcode = 0;
+ aresp[i].resp = NULL;
+
+ if (DEBUG(up->verb))
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: my_conv[%d] query='%s' style=%d\n",
+ i,
+ msg->msg ? msg->msg : "NULL",
+ msg->msg_style);
+ }
+
+ if (up->name_value_list && up->name_value_list->len > 0)
+ {
+ /* use name/value list match method */
+ const struct name_value_list *list = up->name_value_list;
+ int j;
+
+ /* loop through name/value pairs */
+ for (j = 0; j < list->len; ++j)
+ {
+ const char *match_name = list->data[j].name;
+ const char *match_value = list->data[j].value;
+
+ if (name_value_match(msg->msg, match_name))
+ {
+ /* found name/value match */
+ aresp[i].resp = NULL;
+
+ if (DEBUG(up->verb))
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: name match found, query/match-string ['%s', '%s'] = '%s'\n",
+ msg->msg,
+ match_name,
+ match_value);
+ }
+
+ if (strstr(match_value, "USERNAME"))
+ {
+ aresp[i].resp = searchandreplace(match_value, "USERNAME", up->username);
+ }
+ else if (strstr(match_value, "PASSWORD"))
+ {
+ aresp[i].resp = searchandreplace(match_value, "PASSWORD", up->password);
+ }
+ else if (strstr(match_value, "COMMONNAME"))
+ {
+ aresp[i].resp = searchandreplace(match_value, "COMMONNAME", up->common_name);
+ }
+ else
+ {
+ aresp[i].resp = strdup(match_value);
+ }
+
+ if (aresp[i].resp == NULL)
+ {
+ ret = PAM_CONV_ERR;
+ }
+ break;
+ }
+ }
+
+ if (j == list->len)
+ {
+ ret = PAM_CONV_ERR;
+ }
+ }
+ else
+ {
+ /* use PAM_PROMPT_ECHO_x hints */
+ switch (msg->msg_style)
+ {
+ case PAM_PROMPT_ECHO_OFF:
+ aresp[i].resp = strdup(up->password);
+ if (aresp[i].resp == NULL)
+ {
+ ret = PAM_CONV_ERR;
+ }
+ break;
+
+ case PAM_PROMPT_ECHO_ON:
+ aresp[i].resp = strdup(up->username);
+ if (aresp[i].resp == NULL)
+ {
+ ret = PAM_CONV_ERR;
+ }
+ break;
+
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ break;
+
+ default:
+ ret = PAM_CONV_ERR;
+ break;
+ }
+ }
+ }
+
+ if (ret == PAM_SUCCESS)
+ {
+ *response_array = aresp;
+ }
+ else
+ {
+ free(aresp);
+ }
+
+ return ret;
}
/*
@@ -587,156 +649,166 @@ my_conv (int n, const struct pam_message **msg_array,
* to be authenticated.
*/
static int
-pam_auth (const char *service, const struct user_pass *up)
+pam_auth(const char *service, const struct user_pass *up)
{
- struct pam_conv conv;
- pam_handle_t *pamh = NULL;
- int status = PAM_SUCCESS;
- int ret = 0;
- const int name_value_list_provided = (up->name_value_list && up->name_value_list->len > 0);
-
- /* Initialize PAM */
- conv.conv = my_conv;
- conv.appdata_ptr = (void *)up;
- status = pam_start (service, name_value_list_provided ? NULL : up->username, &conv, &pamh);
- if (status == PAM_SUCCESS)
- {
- /* Call PAM to verify username/password */
- status = pam_authenticate(pamh, 0);
- if (status == PAM_SUCCESS)
- status = pam_acct_mgmt (pamh, 0);
- if (status == PAM_SUCCESS)
- ret = 1;
-
- /* Output error message if failed */
- if (!ret)
- {
- fprintf (stderr, "AUTH-PAM: BACKGROUND: user '%s' failed to authenticate: %s\n",
- up->username,
- pam_strerror (pamh, status));
- }
-
- /* Close PAM */
- pam_end (pamh, status);
- }
-
- return ret;
+ struct pam_conv conv;
+ pam_handle_t *pamh = NULL;
+ int status = PAM_SUCCESS;
+ int ret = 0;
+ const int name_value_list_provided = (up->name_value_list && up->name_value_list->len > 0);
+
+ /* Initialize PAM */
+ conv.conv = my_conv;
+ conv.appdata_ptr = (void *)up;
+ status = pam_start(service, name_value_list_provided ? NULL : up->username, &conv, &pamh);
+ if (status == PAM_SUCCESS)
+ {
+ /* Call PAM to verify username/password */
+ status = pam_authenticate(pamh, 0);
+ if (status == PAM_SUCCESS)
+ {
+ status = pam_acct_mgmt(pamh, 0);
+ }
+ if (status == PAM_SUCCESS)
+ {
+ ret = 1;
+ }
+
+ /* Output error message if failed */
+ if (!ret)
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: user '%s' failed to authenticate: %s\n",
+ up->username,
+ pam_strerror(pamh, status));
+ }
+
+ /* Close PAM */
+ pam_end(pamh, status);
+ }
+
+ return ret;
}
/*
* Background process -- runs with privilege.
*/
static void
-pam_server (int fd, const char *service, int verb, const struct name_value_list *name_value_list)
+pam_server(int fd, const char *service, int verb, const struct name_value_list *name_value_list)
{
- struct user_pass up;
- int command;
+ struct user_pass up;
+ int command;
#ifdef USE_PAM_DLOPEN
- static const char pam_so[] = "libpam.so";
+ static const char pam_so[] = "libpam.so";
#endif
- /*
- * Do initialization
- */
- if (DEBUG (verb))
- fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service);
+ /*
+ * Do initialization
+ */
+ if (DEBUG(verb))
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service);
+ }
#ifdef USE_PAM_DLOPEN
- /*
- * Load PAM shared object
- */
- if (!dlopen_pam (pam_so))
+ /*
+ * Load PAM shared object
+ */
+ if (!dlopen_pam(pam_so))
{
- fprintf (stderr, "AUTH-PAM: BACKGROUND: could not load PAM lib %s: %s\n", pam_so, dlerror());
- send_control (fd, RESPONSE_INIT_FAILED);
- goto done;
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: could not load PAM lib %s: %s\n", pam_so, dlerror());
+ send_control(fd, RESPONSE_INIT_FAILED);
+ goto done;
}
#endif
- /*
- * Tell foreground that we initialized successfully
- */
- if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1)
+ /*
+ * Tell foreground that we initialized successfully
+ */
+ if (send_control(fd, RESPONSE_INIT_SUCCEEDED) == -1)
{
- fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [1]\n");
- goto done;
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: write error on response socket [1]\n");
+ goto done;
}
- /*
- * Event loop
- */
- while (1)
+ /*
+ * Event loop
+ */
+ while (1)
{
- memset (&up, 0, sizeof (up));
- up.verb = verb;
- up.name_value_list = name_value_list;
-
- /* get a command from foreground process */
- command = recv_control (fd);
-
- if (DEBUG (verb))
- fprintf (stderr, "AUTH-PAM: BACKGROUND: received command code: %d\n", command);
-
- switch (command)
- {
- case COMMAND_VERIFY:
- if (recv_string (fd, up.username, sizeof (up.username)) == -1
- || recv_string (fd, up.password, sizeof (up.password)) == -1
- || recv_string (fd, up.common_name, sizeof (up.common_name)) == -1)
- {
- fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel: code=%d, exiting\n",
- command);
- goto done;
- }
-
- if (DEBUG (verb))
- {
+ memset(&up, 0, sizeof(up));
+ up.verb = verb;
+ up.name_value_list = name_value_list;
+
+ /* get a command from foreground process */
+ command = recv_control(fd);
+
+ if (DEBUG(verb))
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: received command code: %d\n", command);
+ }
+
+ switch (command)
+ {
+ case COMMAND_VERIFY:
+ if (recv_string(fd, up.username, sizeof(up.username)) == -1
+ || recv_string(fd, up.password, sizeof(up.password)) == -1
+ || recv_string(fd, up.common_name, sizeof(up.common_name)) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: read error on command channel: code=%d, exiting\n",
+ command);
+ goto done;
+ }
+
+ if (DEBUG(verb))
+ {
#if 0
- fprintf (stderr, "AUTH-PAM: BACKGROUND: USER/PASS: %s/%s\n",
- up.username, up.password);
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: USER/PASS: %s/%s\n",
+ up.username, up.password);
#else
- fprintf (stderr, "AUTH-PAM: BACKGROUND: USER: %s\n", up.username);
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: USER: %s\n", up.username);
#endif
- }
-
- if (pam_auth (service, &up)) /* Succeeded */
- {
- if (send_control (fd, RESPONSE_VERIFY_SUCCEEDED) == -1)
- {
- fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [2]\n");
- goto done;
- }
- }
- else /* Failed */
- {
- if (send_control (fd, RESPONSE_VERIFY_FAILED) == -1)
- {
- fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [3]\n");
- goto done;
- }
- }
- break;
-
- case COMMAND_EXIT:
- goto done;
-
- case -1:
- fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel\n");
- goto done;
-
- default:
- fprintf (stderr, "AUTH-PAM: BACKGROUND: unknown command code: code=%d, exiting\n",
- command);
- goto done;
- }
- }
- done:
+ }
+
+ if (pam_auth(service, &up)) /* Succeeded */
+ {
+ if (send_control(fd, RESPONSE_VERIFY_SUCCEEDED) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: write error on response socket [2]\n");
+ goto done;
+ }
+ }
+ else /* Failed */
+ {
+ if (send_control(fd, RESPONSE_VERIFY_FAILED) == -1)
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: write error on response socket [3]\n");
+ goto done;
+ }
+ }
+ break;
+
+ case COMMAND_EXIT:
+ goto done;
+
+ case -1:
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: read error on command channel\n");
+ goto done;
+
+ default:
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: unknown command code: code=%d, exiting\n",
+ command);
+ goto done;
+ }
+ }
+done:
#ifdef USE_PAM_DLOPEN
- dlclose_pam ();
+ dlclose_pam();
#endif
- if (DEBUG (verb))
- fprintf (stderr, "AUTH-PAM: BACKGROUND: EXIT\n");
+ if (DEBUG(verb))
+ {
+ fprintf(stderr, "AUTH-PAM: BACKGROUND: EXIT\n");
+ }
- return;
+ return;
}
diff --git a/src/plugins/auth-pam/pamdl.c b/src/plugins/auth-pam/pamdl.c
index 26e9821..02ea71a 100644
--- a/src/plugins/auth-pam/pamdl.c
+++ b/src/plugins/auth-pam/pamdl.c
@@ -21,125 +21,136 @@ static void *libpam_h = NULL;
#define RESOLVE_PAM_FUNCTION(x, y, z, err) \
{ \
- union { const void *tpointer; y (*fn) z ; } fptr; \
- fptr.tpointer = dlsym(libpam_h, #x); real_##x = fptr.fn; \
- if (real_##x == NULL) { \
- fprintf (stderr, "PAMDL: unable to resolve '%s': %s\n", #x, dlerror()); \
- return err; \
- } \
+ union { const void *tpointer; y(*fn) z; } fptr; \
+ fptr.tpointer = dlsym(libpam_h, #x); real_ ## x = fptr.fn; \
+ if (real_ ## x == NULL) { \
+ fprintf(stderr, "PAMDL: unable to resolve '%s': %s\n", #x, dlerror()); \
+ return err; \
+ } \
}
int
-dlopen_pam (const char *so)
+dlopen_pam(const char *so)
{
- if (libpam_h == NULL)
+ if (libpam_h == NULL)
{
- libpam_h = dlopen(so, RTLD_GLOBAL|RTLD_NOW);
+ libpam_h = dlopen(so, RTLD_GLOBAL|RTLD_NOW);
}
- return libpam_h != NULL;
+ return libpam_h != NULL;
}
void
-dlclose_pam (void)
+dlclose_pam(void)
{
- if (libpam_h != NULL)
+ if (libpam_h != NULL)
{
- dlclose(libpam_h);
- libpam_h = NULL;
+ dlclose(libpam_h);
+ libpam_h = NULL;
}
}
-int pam_start(const char *service_name, const char *user,
- const struct pam_conv *pam_conversation,
- pam_handle_t **pamh)
+int
+pam_start(const char *service_name, const char *user,
+ const struct pam_conv *pam_conversation,
+ pam_handle_t **pamh)
{
int (*real_pam_start)(const char *, const char *,
- const struct pam_conv *,
- pam_handle_t **);
+ const struct pam_conv *,
+ pam_handle_t **);
RESOLVE_PAM_FUNCTION(pam_start, int, (const char *, const char *,
- const struct pam_conv *,
- pam_handle_t **), PAM_ABORT);
+ const struct pam_conv *,
+ pam_handle_t **), PAM_ABORT);
return real_pam_start(service_name, user, pam_conversation, pamh);
}
-int pam_end(pam_handle_t *pamh, int pam_status)
+int
+pam_end(pam_handle_t *pamh, int pam_status)
{
int (*real_pam_end)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_end, int, (pam_handle_t *, int), PAM_ABORT);
return real_pam_end(pamh, pam_status);
}
-int pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
+int
+pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
{
int (*real_pam_set_item)(pam_handle_t *, int, const void *);
RESOLVE_PAM_FUNCTION(pam_set_item, int,
- (pam_handle_t *, int, const void *), PAM_ABORT);
+ (pam_handle_t *, int, const void *), PAM_ABORT);
return real_pam_set_item(pamh, item_type, item);
}
-int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
+int
+pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
{
int (*real_pam_get_item)(const pam_handle_t *, int, const void **);
RESOLVE_PAM_FUNCTION(pam_get_item, int,
- (const pam_handle_t *, int, const void **),
- PAM_ABORT);
+ (const pam_handle_t *, int, const void **),
+ PAM_ABORT);
return real_pam_get_item(pamh, item_type, item);
}
-int pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay)
+int
+pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay)
{
int (*real_pam_fail_delay)(pam_handle_t *, unsigned int);
RESOLVE_PAM_FUNCTION(pam_fail_delay, int, (pam_handle_t *, unsigned int),
- PAM_ABORT);
+ PAM_ABORT);
return real_pam_fail_delay(pamh, musec_delay);
}
-typedef const char * const_char_pointer;
+typedef const char *const_char_pointer;
-const_char_pointer pam_strerror(pam_handle_t *pamh, int errnum)
+const_char_pointer
+pam_strerror(pam_handle_t *pamh, int errnum)
{
const_char_pointer (*real_pam_strerror)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_strerror, const_char_pointer,
- (pam_handle_t *, int), NULL);
+ (pam_handle_t *, int), NULL);
return real_pam_strerror(pamh, errnum);
}
-int pam_putenv(pam_handle_t *pamh, const char *name_value)
+int
+pam_putenv(pam_handle_t *pamh, const char *name_value)
{
int (*real_pam_putenv)(pam_handle_t *, const char *);
RESOLVE_PAM_FUNCTION(pam_putenv, int, (pam_handle_t *, const char *),
- PAM_ABORT);
+ PAM_ABORT);
return real_pam_putenv(pamh, name_value);
}
-const_char_pointer pam_getenv(pam_handle_t *pamh, const char *name)
+const_char_pointer
+pam_getenv(pam_handle_t *pamh, const char *name)
{
const_char_pointer (*real_pam_getenv)(pam_handle_t *, const char *);
RESOLVE_PAM_FUNCTION(pam_getenv, const_char_pointer,
- (pam_handle_t *, const char *), NULL);
+ (pam_handle_t *, const char *), NULL);
return real_pam_getenv(pamh, name);
}
-typedef char ** char_ppointer;
-char_ppointer pam_getenvlist(pam_handle_t *pamh)
+typedef char **char_ppointer;
+char_ppointer
+pam_getenvlist(pam_handle_t *pamh)
{
char_ppointer (*real_pam_getenvlist)(pam_handle_t *);
RESOLVE_PAM_FUNCTION(pam_getenvlist, char_ppointer, (pam_handle_t *),
- NULL);
+ NULL);
return real_pam_getenvlist(pamh);
}
/* Authentication management */
-int pam_authenticate(pam_handle_t *pamh, int flags)
+int
+pam_authenticate(pam_handle_t *pamh, int flags)
{
int (*real_pam_authenticate)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_authenticate, int, (pam_handle_t *, int),
- PAM_ABORT);
+ PAM_ABORT);
return real_pam_authenticate(pamh, flags);
}
-int pam_setcred(pam_handle_t *pamh, int flags)
+int
+pam_setcred(pam_handle_t *pamh, int flags)
{
int (*real_pam_setcred)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_setcred, int, (pam_handle_t *, int), PAM_ABORT);
@@ -148,7 +159,8 @@ int pam_setcred(pam_handle_t *pamh, int flags)
/* Account Management API's */
-int pam_acct_mgmt(pam_handle_t *pamh, int flags)
+int
+pam_acct_mgmt(pam_handle_t *pamh, int flags)
{
int (*real_pam_acct_mgmt)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_acct_mgmt, int, (pam_handle_t *, int), PAM_ABORT);
@@ -157,28 +169,31 @@ int pam_acct_mgmt(pam_handle_t *pamh, int flags)
/* Session Management API's */
-int pam_open_session(pam_handle_t *pamh, int flags)
+int
+pam_open_session(pam_handle_t *pamh, int flags)
{
int (*real_pam_open_session)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_open_session, int, (pam_handle_t *, int),
- PAM_ABORT);
+ PAM_ABORT);
return real_pam_open_session(pamh, flags);
}
-int pam_close_session(pam_handle_t *pamh, int flags)
+int
+pam_close_session(pam_handle_t *pamh, int flags)
{
int (*real_pam_close_session)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_close_session, int, (pam_handle_t *, int),
- PAM_ABORT);
+ PAM_ABORT);
return real_pam_close_session(pamh, flags);
}
/* Password Management API's */
-int pam_chauthtok(pam_handle_t *pamh, int flags)
+int
+pam_chauthtok(pam_handle_t *pamh, int flags)
{
int (*real_pam_chauthtok)(pam_handle_t *, int);
RESOLVE_PAM_FUNCTION(pam_chauthtok, int, (pam_handle_t *, int), PAM_ABORT);
return real_pam_chauthtok(pamh, flags);
}
-#endif
+#endif /* ifdef USE_PAM_DLOPEN */
diff --git a/src/plugins/auth-pam/pamdl.h b/src/plugins/auth-pam/pamdl.h
index 12ba068..15ca85e 100644
--- a/src/plugins/auth-pam/pamdl.h
+++ b/src/plugins/auth-pam/pamdl.h
@@ -1,5 +1,7 @@
#ifdef USE_PAM_DLOPEN
/* Dynamically load and unload the PAM library */
-int dlopen_pam (const char *so);
-void dlclose_pam (void);
+int dlopen_pam(const char *so);
+
+void dlclose_pam(void);
+
#endif
diff --git a/src/plugins/auth-pam/utils.c b/src/plugins/auth-pam/utils.c
index 4f2bec1..4f8fb0a 100644
--- a/src/plugins/auth-pam/utils.c
+++ b/src/plugins/auth-pam/utils.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -43,71 +43,81 @@
char *
searchandreplace(const char *tosearch, const char *searchfor, const char *replacewith)
{
- if (!tosearch || !searchfor || !replacewith) return NULL;
+ if (!tosearch || !searchfor || !replacewith)
+ {
+ return NULL;
+ }
- size_t tosearchlen = strlen(tosearch);
- size_t replacewithlen = strlen(replacewith);
- size_t templen = tosearchlen * replacewithlen;
+ size_t tosearchlen = strlen(tosearch);
+ size_t replacewithlen = strlen(replacewith);
+ size_t templen = tosearchlen * replacewithlen;
- if (tosearchlen == 0 || strlen(searchfor) == 0 || replacewithlen == 0) {
- return NULL;
- }
+ if (tosearchlen == 0 || strlen(searchfor) == 0 || replacewithlen == 0)
+ {
+ return NULL;
+ }
- bool is_potential_integer_overflow = (templen == SIZE_MAX) || (templen / tosearchlen != replacewithlen);
+ bool is_potential_integer_overflow = (templen == SIZE_MAX) || (templen / tosearchlen != replacewithlen);
- if (is_potential_integer_overflow) {
- return NULL;
- }
+ if (is_potential_integer_overflow)
+ {
+ return NULL;
+ }
- // state: all parameters are valid
+ /* state: all parameters are valid */
- const char *searching=tosearch;
- char *scratch;
+ const char *searching = tosearch;
+ char *scratch;
- char temp[templen+1];
- temp[0]=0;
+ char temp[templen+1];
+ temp[0] = 0;
- scratch = strstr(searching,searchfor);
- if (!scratch) return strdup(tosearch);
+ scratch = strstr(searching,searchfor);
+ if (!scratch)
+ {
+ return strdup(tosearch);
+ }
- while (scratch) {
- strncat(temp,searching,scratch-searching);
- strcat(temp,replacewith);
+ while (scratch) {
+ strncat(temp,searching,scratch-searching);
+ strcat(temp,replacewith);
- searching=scratch+strlen(searchfor);
- scratch = strstr(searching,searchfor);
- }
- return strdup(temp);
+ searching = scratch+strlen(searchfor);
+ scratch = strstr(searching,searchfor);
+ }
+ return strdup(temp);
}
const char *
-get_env (const char *name, const char *envp[])
+get_env(const char *name, const char *envp[])
{
- if (envp)
+ if (envp)
{
- int i;
- const int namelen = strlen (name);
- for (i = 0; envp[i]; ++i)
- {
- if (!strncmp (envp[i], name, namelen))
- {
- const char *cp = envp[i] + namelen;
- if (*cp == '=')
- return cp + 1;
- }
- }
+ int i;
+ const int namelen = strlen(name);
+ for (i = 0; envp[i]; ++i)
+ {
+ if (!strncmp(envp[i], name, namelen))
+ {
+ const char *cp = envp[i] + namelen;
+ if (*cp == '=')
+ {
+ return cp + 1;
+ }
+ }
+ }
}
- return NULL;
+ return NULL;
}
int
-string_array_len (const char *array[])
+string_array_len(const char *array[])
{
- int i = 0;
- if (array)
+ int i = 0;
+ if (array)
{
- while (array[i])
- ++i;
+ while (array[i])
+ ++i;
}
- return i;
+ return i;
}
diff --git a/src/plugins/auth-pam/utils.h b/src/plugins/auth-pam/utils.h
index 2f72040..fbc9705 100644
--- a/src/plugins/auth-pam/utils.h
+++ b/src/plugins/auth-pam/utils.h
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -52,7 +52,7 @@ searchandreplace(const char *tosearch, const char *searchfor, const char *replac
* @return Returns a pointer to the value of the enviroment variable if found, otherwise NULL is returned.
*/
const char *
-get_env (const char *name, const char *envp[]);
+get_env(const char *name, const char *envp[]);
/**
* Return the length of a string array
@@ -61,6 +61,6 @@ get_env (const char *name, const char *envp[]);
*
*/
int
-string_array_len (const char *array[]);
+string_array_len(const char *array[]);
#endif