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:
---
#!/bin/sh
prompt="$1"
exec kdialog --title "vpnc" --password "$prompt";
---
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
---
config.c | 7 +++
config.h | 1 +
vpnc.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 132 insertions(+), 1 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/vpnc.c b/vpnc.c
index 206e6a9..6ab10eb 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;
@@ -2298,6 +2407,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: ",
@@ -2306,7 +2416,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@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/
for password and echo result to stdout.
Settings:
---
Password Program /home/alonbl/vpnc/vpnc-getpass
Xauth interactive
---
vpn-getpass script for KDE:
---
#!/bin/sh
prompt="$1"
exec kdialog --title "vpnc" --password "$prompt";
---
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
---
config.c | 7 +++
config.h | 1 +
vpnc.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 132 insertions(+), 1 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/vpnc.c b/vpnc.c
index 206e6a9..6ab10eb 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;
@@ -2298,6 +2407,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: ",
@@ -2306,7 +2416,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@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/