summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/openvpn/Makefile.am1
-rw-r--r--src/openvpn/console.c238
-rw-r--r--src/openvpn/console.h33
-rw-r--r--src/openvpn/misc.c125
-rw-r--r--src/openvpn/misc.h3
-rw-r--r--src/openvpn/openvpn.vcproj8
-rw-r--r--src/openvpn/pkcs11.c1
-rw-r--r--src/openvpn/win32.c87
-rw-r--r--src/openvpn/win32.h5
9 files changed, 286 insertions, 215 deletions
diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am
index e170380..333eebc 100644
--- a/src/openvpn/Makefile.am
+++ b/src/openvpn/Makefile.am
@@ -58,6 +58,7 @@ openvpn_SOURCES = \
mbuf.c mbuf.h \
memdbg.h \
misc.c misc.h \
+ console.c console.h \
mroute.c mroute.h \
mss.c mss.h \
mstats.c mstats.h \
diff --git a/src/openvpn/console.c b/src/openvpn/console.c
new file mode 100644
index 0000000..2464e7e
--- /dev/null
+++ b/src/openvpn/console.c
@@ -0,0 +1,238 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 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
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#include "syshead.h"
+#include "console.h"
+#include "error.h"
+#include "buffer.h"
+#include "misc.h"
+
+#ifdef WIN32
+
+#include "win32.h"
+
+/*
+ * Get input from console.
+ *
+ * Return false on input error, or if service
+ * exit event is signaled.
+ */
+
+static bool
+get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ HANDLE in = INVALID_HANDLE_VALUE;
+ HANDLE err = INVALID_HANDLE_VALUE;
+ DWORD len = 0;
+
+ ASSERT (prompt);
+ ASSERT (input);
+ ASSERT (capacity > 0);
+
+ input[0] = '\0';
+
+ in = GetStdHandle (STD_INPUT_HANDLE);
+ err = get_orig_stderr ();
+
+ if (in != INVALID_HANDLE_VALUE
+ && err != INVALID_HANDLE_VALUE
+ && !win32_service_interrupt (&win32_signal)
+ && WriteFile (err, prompt, strlen (prompt), &len, NULL))
+ {
+ bool is_console = (GetFileType (in) == FILE_TYPE_CHAR);
+ DWORD flags_save = 0;
+ int status = 0;
+ WCHAR *winput;
+
+ if (is_console)
+ {
+ if (GetConsoleMode (in, &flags_save))
+ {
+ DWORD flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ if (echo)
+ flags |= ENABLE_ECHO_INPUT;
+ SetConsoleMode (in, flags);
+ }
+ else
+ is_console = 0;
+ }
+
+ if (is_console)
+ {
+ winput = malloc (capacity * sizeof (WCHAR));
+ if (winput == NULL)
+ return false;
+
+ status = ReadConsoleW (in, winput, capacity, &len, NULL);
+ WideCharToMultiByte (CP_UTF8, 0, winput, len, input, capacity, NULL, NULL);
+ free (winput);
+ }
+ else
+ status = ReadFile (in, input, capacity, &len, NULL);
+
+ string_null_terminate (input, (int)len, capacity);
+ chomp (input);
+
+ if (!echo)
+ WriteFile (err, "\r\n", 2, &len, NULL);
+ if (is_console)
+ SetConsoleMode (in, flags_save);
+ if (status && !win32_service_interrupt (&win32_signal))
+ return true;
+ }
+
+ return false;
+}
+
+#endif
+
+#ifdef HAVE_GETPASS
+
+static FILE *
+open_tty (const bool write)
+{
+ FILE *ret;
+ ret = fopen ("/dev/tty", write ? "w" : "r");
+ if (!ret)
+ ret = write ? stderr : stdin;
+ return ret;
+}
+
+static void
+close_tty (FILE *fp)
+{
+ if (fp != stderr && fp != stdin)
+ fclose (fp);
+}
+
+#endif
+
+#ifdef ENABLE_SYSTEMD
+
+/*
+ * is systemd running
+ */
+
+static bool
+check_systemd_running ()
+{
+ struct stat a, b;
+
+ /* We simply test whether the systemd cgroup hierarchy is
+ * mounted */
+
+ return (lstat("/sys/fs/cgroup", &a) == 0)
+ && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
+ && (a.st_dev != b.st_dev);
+
+}
+
+static bool
+get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ int std_out;
+ bool ret = false;
+ struct argv argv;
+
+ argv_init (&argv);
+ argv_printf (&argv, "/bin/systemd-ask-password");
+ argv_printf_cat (&argv, "%s", prompt);
+
+ if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
+ return false;
+ }
+ CLEAR (*input);
+ if (read (std_out, input, capacity) != 0)
+ {
+ chomp (input);
+ ret = true;
+ }
+ close (std_out);
+
+ argv_reset (&argv);
+
+ return ret;
+}
+
+
+#endif
+
+/*
+ * Get input from console
+ */
+bool
+get_console_input (const char *prompt, const bool echo, char *input, const int capacity)
+{
+ bool ret = false;
+ ASSERT (prompt);
+ ASSERT (input);
+ ASSERT (capacity > 0);
+ input[0] = '\0';
+
+#ifdef ENABLE_SYSTEMD
+ if (check_systemd_running ())
+ return get_console_input_systemd (prompt, echo, input, capacity);
+#endif
+
+#if defined(WIN32)
+ return get_console_input_win32 (prompt, echo, input, capacity);
+#elif defined(HAVE_GETPASS)
+ if (echo)
+ {
+ FILE *fp;
+
+ fp = open_tty (true);
+ fprintf (fp, "%s", prompt);
+ fflush (fp);
+ close_tty (fp);
+
+ fp = open_tty (false);
+ if (fgets (input, capacity, fp) != NULL)
+ {
+ chomp (input);
+ ret = true;
+ }
+ close_tty (fp);
+ }
+ else
+ {
+ char *gp = getpass (prompt);
+ if (gp)
+ {
+ strncpynt (input, gp, capacity);
+ memset (gp, 0, strlen (gp));
+ ret = true;
+ }
+ }
+#else
+ msg (M_FATAL, "Sorry, but I can't get console input on this OS");
+#endif
+ return ret;
+}
diff --git a/src/openvpn/console.h b/src/openvpn/console.h
new file mode 100644
index 0000000..268f3fe
--- /dev/null
+++ b/src/openvpn/console.h
@@ -0,0 +1,33 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2010 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
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+#include "basic.h"
+
+bool
+get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
+
+#endif
diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index 07beaf0..2571194 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -41,6 +41,7 @@
#include "manage.h"
#include "crypto.h"
#include "route.h"
+#include "console.h"
#include "win32.h"
#include "memdbg.h"
@@ -1373,130 +1374,6 @@ absolute_pathname (const char *pathname)
return false;
}
-#ifdef HAVE_GETPASS
-
-static FILE *
-open_tty (const bool write)
-{
- FILE *ret;
- ret = fopen ("/dev/tty", write ? "w" : "r");
- if (!ret)
- ret = write ? stderr : stdin;
- return ret;
-}
-
-static void
-close_tty (FILE *fp)
-{
- if (fp != stderr && fp != stdin)
- fclose (fp);
-}
-
-#endif
-
-/*
- * is systemd running
- */
-
-#if defined(TARGET_LINUX) && defined(ENABLE_SYSTEMD)
-bool
-check_systemd_running ()
-{
- struct stat a, b;
-
- /* We simply test whether the systemd cgroup hierarchy is
- * mounted */
-
- return (lstat("/sys/fs/cgroup", &a) == 0)
- && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
- && (a.st_dev != b.st_dev);
-
-}
-
-bool
-get_console_input_systemd (const char *prompt, const bool echo, char *input, const int capacity)
-{
- int std_out;
- char cmd[256];
- bool ret = false;
- struct argv argv;
-
- argv_init (&argv);
- argv_printf (&argv, "/bin/systemd-ask-password");
- argv_printf_cat (&argv, "%s", prompt);
-
- if ((std_out = openvpn_popen (&argv, NULL)) < 0) {
- return false;
- }
- CLEAR (*input);
- if (read (std_out, input, capacity) != 0)
- {
- chomp (input);
- ret = true;
- }
- close (std_out);
-
- argv_reset (&argv);
-
- return ret;
-}
-
-
-#endif
-
-/*
- * Get input from console
- */
-bool
-get_console_input (const char *prompt, const bool echo, char *input, const int capacity)
-{
- bool ret = false;
- ASSERT (prompt);
- ASSERT (input);
- ASSERT (capacity > 0);
- input[0] = '\0';
-
-#if defined(TARGET_LINUX) && defined(ENABLE_SYSTEMD)
- if (check_systemd_running ())
- return get_console_input_systemd (prompt, echo, input, capacity);
-#endif
-
-#if defined(WIN32)
- return get_console_input_win32 (prompt, echo, input, capacity);
-#elif defined(HAVE_GETPASS)
- if (echo)
- {
- FILE *fp;
-
- fp = open_tty (true);
- fprintf (fp, "%s", prompt);
- fflush (fp);
- close_tty (fp);
-
- fp = open_tty (false);
- if (fgets (input, capacity, fp) != NULL)
- {
- chomp (input);
- ret = true;
- }
- close_tty (fp);
- }
- else
- {
- char *gp = getpass (prompt);
- if (gp)
- {
- strncpynt (input, gp, capacity);
- memset (gp, 0, strlen (gp));
- ret = true;
- }
- }
-#else
- msg (M_FATAL, "Sorry, but I can't get console input on this OS");
-#endif
- return ret;
-}
-
/*
* Get and store a username/password
*/
diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
index 9bb2fa2..12a8f71 100644
--- a/src/openvpn/misc.h
+++ b/src/openvpn/misc.h
@@ -128,6 +128,7 @@ bool system_executed (int stat);
const char *system_error_message (int, struct gc_arena *gc);
/* wrapper around the execve() call */
+int openvpn_popen (const struct argv *a, const struct env_set *es);
int openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags);
bool openvpn_execve_check (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message);
bool openvpn_execve_allowed (const unsigned int flags);
@@ -322,8 +323,6 @@ struct auth_challenge_info {};
struct static_challenge_info {};
#endif
-bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
-
/*
* Flags for get_user_pass and management_query_user_pass
*/
diff --git a/src/openvpn/openvpn.vcproj b/src/openvpn/openvpn.vcproj
index 45c0a77..6c19621 100644
--- a/src/openvpn/openvpn.vcproj
+++ b/src/openvpn/openvpn.vcproj
@@ -191,6 +191,10 @@
>
</File>
<File
+ RelativePath=".\console.c"
+ >
+ </File>
+ <File
RelativePath=".\crypto.c"
>
</File>
@@ -457,6 +461,10 @@
>
</File>
<File
+ RelativePath=".\console.h"
+ >
+ </File>
+ <File
RelativePath=".\crypto.h"
>
</File>
diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c
index 2189208..fd609d4 100644
--- a/src/openvpn/pkcs11.c
+++ b/src/openvpn/pkcs11.c
@@ -40,6 +40,7 @@
#include "pkcs11.h"
#include "misc.h"
#include "otime.h"
+#include "console.h"
#include "pkcs11_backend.h"
static
diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c
index d7bf514..e94343b 100644
--- a/src/openvpn/win32.c
+++ b/src/openvpn/win32.c
@@ -514,7 +514,7 @@ win32_signal_close (struct win32_signal *ws)
/*
* Return true if interrupt occurs in service mode.
*/
-static bool
+bool
win32_service_interrupt (struct win32_signal *ws)
{
if (ws->mode == WSO_MODE_SERVICE)
@@ -740,91 +740,6 @@ netcmd_semaphore_release (void)
}
/*
- * Get input from console.
- *
- * Return false on input error, or if service
- * exit event is signaled.
- */
-
-bool
-get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity)
-{
- HANDLE in = INVALID_HANDLE_VALUE;
- HANDLE err = INVALID_HANDLE_VALUE;
- DWORD len = 0;
-
- ASSERT (prompt);
- ASSERT (input);
- ASSERT (capacity > 0);
-
- input[0] = '\0';
-
- in = GetStdHandle (STD_INPUT_HANDLE);
- err = get_orig_stderr ();
-
- if (in != INVALID_HANDLE_VALUE
- && err != INVALID_HANDLE_VALUE
- && !win32_service_interrupt (&win32_signal)
- && WriteFile (err, prompt, strlen (prompt), &len, NULL))
- {
- bool is_console = (GetFileType (in) == FILE_TYPE_CHAR);
- DWORD flags_save = 0;
- int status = 0;
- WCHAR *winput;
-
- if (is_console)
- {
- if (GetConsoleMode (in, &flags_save))
- {
- DWORD flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
- if (echo)
- flags |= ENABLE_ECHO_INPUT;
- SetConsoleMode (in, flags);
- }
- else
- is_console = 0;
- }
-
- if (is_console)
- {
- winput = malloc (capacity * sizeof (WCHAR));
- if (winput == NULL)
- return false;
-
- status = ReadConsoleW (in, winput, capacity, &len, NULL);
- WideCharToMultiByte (CP_UTF8, 0, winput, len, input, capacity, NULL, NULL);
- free (winput);
- }
- else
- status = ReadFile (in, input, capacity, &len, NULL);
-
- string_null_terminate (input, (int)len, capacity);
- chomp (input);
-
- if (!echo)
- WriteFile (err, "\r\n", 2, &len, NULL);
- if (is_console)
- SetConsoleMode (in, flags_save);
- if (status && !win32_service_interrupt (&win32_signal))
- return true;
- }
-
- return false;
-}
-
-/* get password from console */
-
-char *
-getpass (const char *prompt)
-{
- static char line[256];
- if (get_console_input_win32 (prompt, false, line, sizeof (line)))
- return line;
- else
- return NULL;
-}
-
-/*
* Return true if filename is safe to be used on Windows,
* by avoiding the following reserved names:
*
diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h
index d87e987..cc18f02 100644
--- a/src/openvpn/win32.h
+++ b/src/openvpn/win32.h
@@ -166,6 +166,8 @@ int win32_signal_get (struct win32_signal *ws);
void win32_pause (struct win32_signal *ws);
+bool win32_service_interrupt (struct win32_signal *ws);
+
/*
* Set the text on the window title bar
*/
@@ -246,9 +248,6 @@ void netcmd_semaphore_close (void);
void netcmd_semaphore_lock (void);
void netcmd_semaphore_release (void);
-bool get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity);
-char *getpass (const char *prompt);
-
/* Set Win32 security attributes structure to allow all access */
bool init_security_attributes_allow_all (struct security_attributes *obj);