
alon.barlev at gmail
Jul 3, 2012, 12:42 PM
Post #2 of 9
(711 views)
Permalink
|
Allows to integrate UI, similar to ssh-askpass, program prompt user for password and echo result to stdout. Settings: --- Password Program /home/alonbl/vpnc/vpnc-getpass Xauth interactive --- vpn-getpass script for KDE: --- prompt="$1" exec kdialog --title "vpnc" --password "$prompt"; --- Signed-off-by: Alon Bar-Lev <alon.barlev [at] gmail> --- config.c | 7 +++ config.h | 1 + tunip.c | 2 +- vpnc.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/config.c b/config.c index fae2799..4485063 100644 --- a/config.c +++ b/config.c @@ -469,6 +469,13 @@ static const struct config_names_s { "Target network in dotted decimal or CIDR notation\n", config_def_target_network }, { + CONFIG_PASSWORD_PROGRAM, 1, 1, + "--password-program", + "Password Program ", + "<executable>", + "path to password program\n", + NULL + }, { 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; diff --git a/config.h b/config.h index a065a58..2016e0b 100644 --- a/config.h +++ b/config.h @@ -59,6 +59,7 @@ enum config_enum { CONFIG_AUTH_MODE, CONFIG_CA_FILE, CONFIG_CA_DIR, + CONFIG_PASSWORD_PROGRAM, LAST_CONFIG }; diff --git a/tunip.c b/tunip.c index d0bc971..ae68b34 100644 --- a/tunip.c +++ b/tunip.c @@ -1049,7 +1049,7 @@ void vpnc_doit(struct sa_block *s) setsid(); } else { printf("VPNC started in background (pid: %d)...\n", (int)pid); - exit(0); + _exit(0); } openlog("vpnc", LOG_PID | LOG_PERROR, LOG_DAEMON); logmsg = syslog; diff --git a/vpnc.c b/vpnc.c index f8f0828..f72d8ec 100644 --- a/vpnc.c +++ b/vpnc.c @@ -37,6 +37,7 @@ #include <poll.h> #include <sys/ioctl.h> #include <sys/utsname.h> +#include <sys/wait.h> #include <gcrypt.h> @@ -161,6 +162,114 @@ const struct vid_element vid_list[] = { static uint8_t r_packet[8192]; static ssize_t r_length; +static int +getpass_program(const char * const program, const char *const prompt, + char *const input, const size_t input_size) +{ + int status; + pid_t pid = -1; + int fds[2] = {-1, -1}; + int r = 0; + int rc; + + /* + * Make sure we don't reuse input + */ + if (input) + memset(input, 0, input_size); + + if (program == NULL) { + rc = -EINVAL; + goto out; + } + + if (pipe(fds) == -1) { + rc = -errno; + goto out; + } + + if ((pid = fork()) == -1) { + rc = -errno; + goto out; + } + + if (pid == 0) { + close (fds[0]); + fds[0] = -1; + + if (dup2(fds[1], 1) == -1) { + exit (1); + } + + close(fds[1]); + fds[1] = -1; + + execl(program, program, prompt, NULL); + + exit(1); + } + + close(fds[1]); + fds[1] = -1; + + while ( + (r=waitpid(pid, &status, 0)) == 0 || + (r == -1 && errno == EINTR) + ); + + if (r == -1) { + rc = -errno; + goto out; + } + + if (!WIFEXITED(status)) { + rc = -EFAULT; + goto out; + } + + if (WEXITSTATUS(status) != 0) { + rc = -EIO; + goto out; + } + + if (input != NULL) { + ssize_t bytes; + + if ((bytes = read (fds[0], input, input_size)) == -1) { + rc = -errno; + goto out; + } + + input[bytes] = '\0'; + + if (strlen (input) > 0 && input[(int)strlen (input)-1] == '\n') + input[(int)strlen (input)-1] = '\0'; + /* DOS cygwin */ + if (strlen (input) > 0 && input[(int)strlen (input)-1] == '\r') + input[(int)strlen (input)-1] = '\0'; + } + + rc = 0; + +out: + if (rc != 0) { + if (input) + memset(input, 0, input_size); + } + + if (fds[0] != -1) { + close(fds[0]); + fds[0] = -1; + } + + if (fds[1] != -1) { + close(fds[1]); + fds[1] = -1; + } + + return rc; +} + void print_vid(const unsigned char *vid, uint16_t len) { int vid_index = 0; @@ -2310,6 +2419,7 @@ static int do_phase2_xauth(struct sa_block *s) phase2_fatal(s, "noninteractive can't reuse password", reject); error(2, 0, "authentication failed (requires interactive mode)"); } else if (seen_answer || passwd_used || config[CONFIG_XAUTH_INTERACTIVE]) { + char _pass[1024]; char *pass, *prompt = NULL; asprintf(&prompt, "%s for VPN %s@%s: ", @@ -2318,7 +2428,20 @@ static int do_phase2_xauth(struct sa_block *s) (ap->type == ISAKMP_XAUTH_06_ATTRIB_USER_PASSWORD) ? "Password" : "Passcode", config[CONFIG_XAUTH_USERNAME], ntop_buf); - pass = getpass(prompt); + if (config[CONFIG_PASSWORD_PROGRAM] == NULL) { + pass = getpass(prompt); + } else { + if (getpass_program( + config[CONFIG_PASSWORD_PROGRAM], + prompt, + _pass, + sizeof(_pass)) != 0 + ) { + free(prompt); + error(2, 0, "authentication unsuccessful"); + } + pass = _pass; + } free(prompt); na = new_isakmp_attribute(ap->type, NULL); -- 1.7.8.6 _______________________________________________ vpnc-devel mailing list vpnc-devel [at] unix-ag https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel http://www.unix-ag.uni-kl.de/~massar/vpnc/
|