]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Added --management-client option to connect as a client to
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 23 Jan 2006 14:08:27 +0000 (14:08 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 23 Jan 2006 14:08:27 +0000 (14:08 +0000)
management GUI app rather than be connected to as a server.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@884 e7ae566f-a301-0410-adde-c780ea21d3b5

ChangeLog
configure.ac
init.c
manage.c
manage.h
options.c
options.h
sig.c
sig.h
socket.c
socket.h

index d7f14d57207651450d2a3c40ac517049e3cb92ba..a9a0d0eecda97383baa67bba8aeefd0de47dbc52 100644 (file)
--- 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
index 9090b2bc6557e264fc64b4dc29b50bba8aa2077e..aeb7237674c8549cf56d1032af7f9b28887554f2 100644 (file)
@@ -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 3b9931a30ded67d77dfa1dca8cae26476e094824..97bf9ecc94cf2211036229c01989857fc11ce97b 100644 (file)
--- 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,
index 127e933b5a3bcdc531fa9373025e13776e5e3bc9..935b18a46e6848b646fedb5376558c8f6f4c3c0d 100644 (file)
--- 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)
     {
@@ -1168,6 +1228,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
        */
@@ -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
        {
index c4928663610bb839eb52ae287bb36415531d5b48..873bb4226b366cbb5588d29dd47396a4c105afc9 100644 (file)
--- 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);
index 903cb7dc99567b9995e0391d8e1e05f992c3fa9d..45d0023eb5c5b193770bf617b2f4c4d717ccac7a 100644 (file)
--- 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;
index 644d7cb31a6661f009fb8e4a57a1b75c27e3aee0..ca04cabaca8314c744cd82d7219dfb502c322966 100644 (file)
--- 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 7279b829dce65f823d5b543545cc745cdd9f4b04..7eb120e49b6ea61172b9f1598eee654537929224 100644 (file)
--- 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 dd17c4065a494455ab9f4262491969541fda435f..5c32df6ed4a631756cbd7bf518df51eeb791bf20 100644 (file)
--- 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);
index 6bc8530ec866069217870e5ccf069f25ac0dda68..38b0c1597dcac07a70d574599acb5f3cbecbfc4f 100644 (file)
--- 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,
index b1a4aaa5065c17bb6f1fac89d273df000f76e391..79f06b5a24a9ba2f3f3320e155a36e7d5ac65e11 100644 (file)
--- 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.
  */