summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac2
-rw-r--r--init.c3
-rw-r--r--manage.c163
-rw-r--r--manage.h4
-rw-r--r--options.c10
-rw-r--r--options.h1
-rw-r--r--sig.c8
-rw-r--r--sig.h1
-rw-r--r--socket.c4
-rw-r--r--socket.h5
11 files changed, 155 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index d7f14d5..a9a0d0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
$Id$
+2006.01.xx -- Version 2.1-beta9
+
+* Added --management-client option to connect as a client
+ to management GUI app rather than be connected to as a
+ server.
+
2006.01.03 -- Version 2.1-beta8
* --remap-usr1 will now also remap signals thrown during
diff --git a/configure.ac b/configure.ac
index 9090b2b..aeb7237 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
-AC_INIT([OpenVPN], [2.1_beta8], [openvpn-users@lists.sourceforge.net], [openvpn])
+AC_INIT([OpenVPN], [2.1_beta8a], [openvpn-users@lists.sourceforge.net], [openvpn])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR(syshead.h)
diff --git a/init.c b/init.c
index 3b9931a..97bf9ec 100644
--- a/init.c
+++ b/init.c
@@ -2392,7 +2392,8 @@ open_management (struct context *c)
c->options.management_log_history_cache,
c->options.management_echo_buffer_size,
c->options.management_state_buffer_size,
- c->options.management_hold))
+ c->options.management_hold,
+ c->options.management_client))
{
management_set_state (management,
OPENVPN_STATE_CONNECTING,
diff --git a/manage.c b/manage.c
index 127e933..935b18a 100644
--- a/manage.c
+++ b/manage.c
@@ -59,7 +59,7 @@ struct management *management; /* GLOBAL */
/* static forward declarations */
static void man_output_standalone (struct management *man, volatile int *signal_received);
-static void man_reset_client_socket (struct management *man, const bool listen);
+static void man_reset_client_socket (struct management *man, const bool exiting);
static void
man_help ()
@@ -259,7 +259,7 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s
if (out)
{
man_output_list_push (man, out);
- man_reset_client_socket (man, false);
+ man_reset_client_socket (man, true);
}
}
}
@@ -792,9 +792,48 @@ man_stop_ne32 (struct management *man)
#endif
static void
-man_accept (struct management *man)
+man_connection_settings_reset (struct management *man)
+{
+ man->connection.state_realtime = false;
+ man->connection.log_realtime = false;
+ man->connection.echo_realtime = false;
+ man->connection.password_verified = false;
+ man->connection.password_tries = 0;
+ man->connection.halt = false;
+ man->connection.state = MS_CC_WAIT_WRITE;
+}
+
+static void
+man_new_connection_post (struct management *man, const char *description)
{
struct gc_arena gc = gc_new ();
+
+ set_nonblock (man->connection.sd_cli);
+ set_cloexec (man->connection.sd_cli);
+
+ man_connection_settings_reset (man);
+
+#ifdef WIN32
+ man_start_ne32 (man);
+#endif
+
+ msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
+ description,
+ print_sockaddr (&man->settings.local, &gc));
+
+ output_list_reset (man->connection.out);
+
+ if (!man_password_needed (man))
+ man_welcome (man);
+ man_prompt (man);
+ man_update_io_state (man);
+
+ gc_free (&gc);
+}
+
+static void
+man_accept (struct management *man)
+{
struct link_socket_actual act;
/*
@@ -812,36 +851,8 @@ man_accept (struct management *man)
#endif
}
- /*
- * Set misc socket properties
- */
- set_nonblock (man->connection.sd_cli);
- set_cloexec (man->connection.sd_cli);
-
- man->connection.state_realtime = false;
- man->connection.log_realtime = false;
- man->connection.echo_realtime = false;
- man->connection.password_verified = false;
- man->connection.password_tries = 0;
- man->connection.halt = false;
- man->connection.state = MS_CC_WAIT_WRITE;
-
-#ifdef WIN32
- man_start_ne32 (man);
-#endif
-
- msg (D_MANAGEMENT, "MANAGEMENT: Client connected from %s",
- print_sockaddr (&man->settings.local, &gc));
-
- output_list_reset (man->connection.out);
-
- if (!man_password_needed (man))
- man_welcome (man);
- man_prompt (man);
- man_update_io_state (man);
+ man_new_connection_post (man, "Client connected from");
}
-
- gc_free (&gc);
}
static void
@@ -891,7 +902,49 @@ man_listen (struct management *man)
}
static void
-man_reset_client_socket (struct management *man, const bool listen)
+man_connect (struct management *man)
+{
+ struct gc_arena gc = gc_new ();
+ int status;
+ int signal_received = 0;
+
+ /*
+ * Initialize state
+ */
+ man->connection.state = MS_INITIAL;
+ man->connection.sd_top = SOCKET_UNDEFINED;
+
+ man->connection.sd_cli = create_socket_tcp ();
+
+ status = openvpn_connect (man->connection.sd_cli,
+ &man->settings.local,
+ 5,
+ &signal_received);
+
+ if (signal_received)
+ {
+ throw_signal (signal_received);
+ goto done;
+ }
+
+ if (status)
+ {
+ msg (D_LINK_ERRORS,
+ "MANAGEMENT: connect to %s failed: %s",
+ print_sockaddr (&man->settings.local, &gc),
+ strerror_ts (status, &gc));
+ throw_signal_soft (SIGTERM, "management-connect-failed");
+ goto done;
+ }
+
+ man_new_connection_post (man, "Connected to management server at");
+
+ done:
+ gc_free (&gc);
+}
+
+static void
+man_reset_client_socket (struct management *man, const bool exiting)
{
if (socket_defined (man->connection.sd_cli))
{
@@ -900,11 +953,17 @@ man_reset_client_socket (struct management *man, const bool listen)
man_stop_ne32 (man);
#endif
man_close_socket (man, man->connection.sd_cli);
+ man->connection.sd_cli = SOCKET_UNDEFINED;
command_line_reset (man->connection.in);
output_list_reset (man->connection.out);
}
- if (listen)
- man_listen (man);
+ if (!exiting)
+ {
+ if (man->settings.connect_as_client)
+ throw_signal_soft (SIGTERM, "management-exit");
+ else
+ man_listen (man);
+ }
}
static void
@@ -978,7 +1037,7 @@ man_read (struct management *man)
len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
if (len == 0)
{
- man_reset_client_socket (man, true);
+ man_reset_client_socket (man, false);
}
else if (len > 0)
{
@@ -1012,7 +1071,7 @@ man_read (struct management *man)
*/
if (man->connection.halt)
{
- man_reset_client_socket (man, true);
+ man_reset_client_socket (man, false);
len = 0;
}
else
@@ -1025,7 +1084,7 @@ man_read (struct management *man)
else /* len < 0 */
{
if (man_io_error (man, "recv"))
- man_reset_client_socket (man, true);
+ man_reset_client_socket (man, false);
}
return len;
}
@@ -1048,7 +1107,7 @@ man_write (struct management *man)
else if (sent < 0)
{
if (man_io_error (man, "send"))
- man_reset_client_socket (man, true);
+ man_reset_client_socket (man, false);
}
}
@@ -1139,7 +1198,8 @@ man_settings_init (struct man_settings *ms,
const int log_history_cache,
const int echo_buffer_size,
const int state_buffer_size,
- const bool hold)
+ const bool hold,
+ const bool connect_as_client)
{
if (!ms->defined)
{
@@ -1169,6 +1229,12 @@ man_settings_init (struct man_settings *ms,
ms->hold = hold;
/*
+ * Should OpenVPN connect to management interface as a client
+ * rather than a server?
+ */
+ ms->connect_as_client = connect_as_client;
+
+ /*
* Initialize socket address
*/
ms->local.sa.sin_family = AF_INET;
@@ -1179,7 +1245,7 @@ man_settings_init (struct man_settings *ms,
* Run management over tunnel, or
* separate channel?
*/
- if (streq (addr, "tunnel"))
+ if (streq (addr, "tunnel") && !connect_as_client)
{
ms->management_over_tunnel = true;
}
@@ -1237,9 +1303,12 @@ man_connection_init (struct management *man)
}
/*
- * Listen on socket
+ * Listen/connect socket
*/
- man_listen (man);
+ if (man->settings.connect_as_client)
+ man_connect (man);
+ else
+ man_listen (man);
}
}
@@ -1290,7 +1359,8 @@ management_open (struct management *man,
const int log_history_cache,
const int echo_buffer_size,
const int state_buffer_size,
- const bool hold)
+ const bool hold,
+ const bool connect_as_client)
{
bool ret = false;
@@ -1307,7 +1377,8 @@ management_open (struct management *man,
log_history_cache,
echo_buffer_size,
state_buffer_size,
- hold);
+ hold,
+ connect_as_client);
/*
* The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
@@ -1510,7 +1581,7 @@ management_io (struct management *man)
if (net_events & FD_CLOSE)
{
- man_reset_client_socket (man, true);
+ man_reset_client_socket (man, false);
}
else
{
diff --git a/manage.h b/manage.h
index c492866..873bb42 100644
--- a/manage.h
+++ b/manage.h
@@ -200,6 +200,7 @@ struct man_settings {
int state_buffer_size;
bool server;
bool hold;
+ bool connect_as_client;
};
/* up_query modes */
@@ -265,7 +266,8 @@ bool management_open (struct management *man,
const int log_history_cache,
const int echo_buffer_size,
const int state_buffer_size,
- const bool hold);
+ const bool hold,
+ const bool connect_as_client);
void management_close (struct management *man);
diff --git a/options.c b/options.c
index 903cb7d..45d0023 100644
--- a/options.c
+++ b/options.c
@@ -299,6 +299,8 @@ static const char usage_message[] =
"--management ip port [pass] : Enable a TCP server on ip:port to handle\n"
" management functions. pass is a password file\n"
" or 'stdin' to prompt from console.\n"
+ "--management-client : Management interface will connect as a TCP client to\n"
+ " ip/port rather than listen as a TCP server.\n"
"--management-query-passwords : Query management channel for private key\n"
" and auth-user-pass passwords.\n"
"--management-hold : Start " PACKAGE_NAME " in a hibernating state, until a client\n"
@@ -1181,6 +1183,7 @@ show_settings (const struct options *o)
SHOW_INT (management_echo_buffer_size);
SHOW_BOOL (management_query_passwords);
SHOW_BOOL (management_hold);
+ SHOW_BOOL (management_client);
#endif
#ifdef ENABLE_PLUGIN
if (o->plugin_list)
@@ -1495,7 +1498,7 @@ options_postprocess (struct options *options, bool first_time)
*/
#ifdef ENABLE_MANAGEMENT
if (!options->management_addr &&
- (options->management_query_passwords || options->management_hold
+ (options->management_query_passwords || options->management_hold || options->management_client
|| options->management_log_history_cache != defaults.management_log_history_cache))
msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified");
#endif
@@ -3122,6 +3125,11 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->management_hold = true;
}
+ else if (streq (p[0], "management-client"))
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->management_client = true;
+ }
else if (streq (p[0], "management-log-cache") && p[1])
{
int cache;
diff --git a/options.h b/options.h
index 644d7cb..ca04cab 100644
--- a/options.h
+++ b/options.h
@@ -279,6 +279,7 @@ struct options
int management_state_buffer_size;
bool management_query_passwords;
bool management_hold;
+ bool management_client;
#endif
#ifdef ENABLE_PLUGIN
diff --git a/sig.c b/sig.c
index 7279b82..7eb120e 100644
--- a/sig.c
+++ b/sig.c
@@ -100,6 +100,14 @@ throw_signal (const int signum)
siginfo_static.hard = true;
}
+void
+throw_signal_soft (const int signum, const char *signal_text)
+{
+ siginfo_static.signal_received = signum;
+ siginfo_static.hard = false;
+ siginfo_static.signal_text = signal_text;
+}
+
static void
signal_reset (struct signal_info *si)
{
diff --git a/sig.h b/sig.h
index dd17c40..5c32df6 100644
--- a/sig.h
+++ b/sig.h
@@ -49,6 +49,7 @@ int parse_signal (const char *signame);
const char *signal_name (const int sig, const bool upper);
const char *signal_description (const int signum, const char *sigtext);
void throw_signal (const int signum);
+void throw_signal_soft (const int signum, const char *signal_text);
void pre_init_signal_catch (void);
void post_init_signal_catch (void);
diff --git a/socket.c b/socket.c
index 6bc8530..38b0c15 100644
--- a/socket.c
+++ b/socket.c
@@ -712,7 +712,7 @@ socket_bind (socket_descriptor_t sd,
gc_free (&gc);
}
-static int
+int
openvpn_connect (socket_descriptor_t sd,
struct openvpn_sockaddr *remote,
int connect_timeout,
@@ -785,7 +785,7 @@ openvpn_connect (socket_descriptor_t sd,
return status;
}
-static void
+void
socket_connect (socket_descriptor_t *sd,
struct openvpn_sockaddr *local,
bool bind_local,
diff --git a/socket.h b/socket.h
index b1a4aaa..79f06b5 100644
--- a/socket.h
+++ b/socket.h
@@ -272,6 +272,11 @@ void socket_bind (socket_descriptor_t sd,
struct openvpn_sockaddr *local,
const char *prefix);
+int openvpn_connect (socket_descriptor_t sd,
+ struct openvpn_sockaddr *remote,
+ int connect_timeout,
+ volatile int *signal_received);
+
/*
* Initialize link_socket object.
*/