Browse code

Added --management-client option to connect as a client to 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

james authored on 2006/01/23 23:08:27
Showing 11 changed files
... ...
@@ -3,6 +3,12 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
3 3
 
4 4
 $Id$
5 5
 
6
+2006.01.xx -- Version 2.1-beta9
7
+
8
+* Added --management-client option to connect as a client
9
+  to management GUI app rather than be connected to as a
10
+  server.
11
+
6 12
 2006.01.03 -- Version 2.1-beta8
7 13
 
8 14
 * --remap-usr1 will now also remap signals thrown during
... ...
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
25 25
 
26 26
 AC_PREREQ(2.50)
27 27
 
28
-AC_INIT([OpenVPN], [2.1_beta8], [openvpn-users@lists.sourceforge.net], [openvpn])
28
+AC_INIT([OpenVPN], [2.1_beta8a], [openvpn-users@lists.sourceforge.net], [openvpn])
29 29
 AM_CONFIG_HEADER(config.h)
30 30
 AC_CONFIG_SRCDIR(syshead.h)
31 31
 
... ...
@@ -2392,7 +2392,8 @@ open_management (struct context *c)
2392 2392
 			       c->options.management_log_history_cache,
2393 2393
 			       c->options.management_echo_buffer_size,
2394 2394
 			       c->options.management_state_buffer_size,
2395
-			       c->options.management_hold))
2395
+			       c->options.management_hold,
2396
+			       c->options.management_client))
2396 2397
 	    {
2397 2398
 	      management_set_state (management,
2398 2399
 				    OPENVPN_STATE_CONNECTING,
... ...
@@ -59,7 +59,7 @@ struct management *management; /* GLOBAL */
59 59
 
60 60
 /* static forward declarations */
61 61
 static void man_output_standalone (struct management *man, volatile int *signal_received);
62
-static void man_reset_client_socket (struct management *man, const bool listen);
62
+static void man_reset_client_socket (struct management *man, const bool exiting);
63 63
 
64 64
 static void
65 65
 man_help ()
... ...
@@ -259,7 +259,7 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s
259 259
 	      if (out)
260 260
 		{
261 261
 		  man_output_list_push (man, out);
262
-		  man_reset_client_socket (man, false);
262
+		  man_reset_client_socket (man, true);
263 263
 		}
264 264
 	    }
265 265
 	}
... ...
@@ -792,9 +792,48 @@ man_stop_ne32 (struct management *man)
792 792
 #endif
793 793
 
794 794
 static void
795
-man_accept (struct management *man)
795
+man_connection_settings_reset (struct management *man)
796
+{
797
+  man->connection.state_realtime = false;
798
+  man->connection.log_realtime = false;
799
+  man->connection.echo_realtime = false;
800
+  man->connection.password_verified = false;
801
+  man->connection.password_tries = 0;
802
+  man->connection.halt = false;
803
+  man->connection.state = MS_CC_WAIT_WRITE;
804
+}
805
+
806
+static void
807
+man_new_connection_post (struct management *man, const char *description)
796 808
 {
797 809
   struct gc_arena gc = gc_new ();
810
+
811
+  set_nonblock (man->connection.sd_cli);
812
+  set_cloexec (man->connection.sd_cli);
813
+
814
+  man_connection_settings_reset (man);
815
+
816
+#ifdef WIN32
817
+  man_start_ne32 (man);
818
+#endif
819
+
820
+  msg (D_MANAGEMENT, "MANAGEMENT: %s %s",
821
+       description,
822
+       print_sockaddr (&man->settings.local, &gc));
823
+
824
+  output_list_reset (man->connection.out);
825
+
826
+  if (!man_password_needed (man))
827
+    man_welcome (man);
828
+  man_prompt (man);
829
+  man_update_io_state (man);
830
+
831
+  gc_free (&gc);
832
+}
833
+
834
+static void
835
+man_accept (struct management *man)
836
+{
798 837
   struct link_socket_actual act;
799 838
 
800 839
   /*
... ...
@@ -812,36 +851,8 @@ man_accept (struct management *man)
812 812
 #endif
813 813
 	}
814 814
 
815
-      /*
816
-       * Set misc socket properties
817
-       */
818
-      set_nonblock (man->connection.sd_cli);
819
-      set_cloexec (man->connection.sd_cli);
820
-
821
-      man->connection.state_realtime = false;
822
-      man->connection.log_realtime = false;
823
-      man->connection.echo_realtime = false;
824
-      man->connection.password_verified = false;
825
-      man->connection.password_tries = 0;
826
-      man->connection.halt = false;
827
-      man->connection.state = MS_CC_WAIT_WRITE;
828
-
829
-#ifdef WIN32
830
-      man_start_ne32 (man);
831
-#endif
832
-
833
-      msg (D_MANAGEMENT, "MANAGEMENT: Client connected from %s",
834
-	   print_sockaddr (&man->settings.local, &gc));
835
-
836
-      output_list_reset (man->connection.out);
837
-
838
-      if (!man_password_needed (man))
839
-	man_welcome (man);
840
-      man_prompt (man);
841
-      man_update_io_state (man);
815
+      man_new_connection_post (man, "Client connected from");
842 816
     }
843
-
844
-  gc_free (&gc);
845 817
 }
846 818
 
847 819
 static void
... ...
@@ -891,7 +902,49 @@ man_listen (struct management *man)
891 891
 }
892 892
 
893 893
 static void
894
-man_reset_client_socket (struct management *man, const bool listen)
894
+man_connect (struct management *man)
895
+{
896
+  struct gc_arena gc = gc_new ();
897
+  int status;
898
+  int signal_received = 0;
899
+
900
+  /*
901
+   * Initialize state
902
+   */
903
+  man->connection.state = MS_INITIAL;
904
+  man->connection.sd_top = SOCKET_UNDEFINED;
905
+
906
+  man->connection.sd_cli = create_socket_tcp ();
907
+
908
+  status = openvpn_connect (man->connection.sd_cli,
909
+			    &man->settings.local,
910
+			    5,
911
+			    &signal_received);
912
+
913
+  if (signal_received)
914
+    {
915
+      throw_signal (signal_received);
916
+      goto done;
917
+    }
918
+
919
+  if (status)
920
+    {
921
+      msg (D_LINK_ERRORS,
922
+	   "MANAGEMENT: connect to %s failed: %s",
923
+	   print_sockaddr (&man->settings.local, &gc),
924
+	   strerror_ts (status, &gc));
925
+      throw_signal_soft (SIGTERM, "management-connect-failed");
926
+      goto done;
927
+    }
928
+
929
+  man_new_connection_post (man, "Connected to management server at");
930
+
931
+ done:
932
+  gc_free (&gc);
933
+}
934
+
935
+static void
936
+man_reset_client_socket (struct management *man, const bool exiting)
895 937
 {
896 938
   if (socket_defined (man->connection.sd_cli))
897 939
     {
... ...
@@ -900,11 +953,17 @@ man_reset_client_socket (struct management *man, const bool listen)
900 900
       man_stop_ne32 (man);
901 901
 #endif
902 902
       man_close_socket (man, man->connection.sd_cli);
903
+      man->connection.sd_cli = SOCKET_UNDEFINED;
903 904
       command_line_reset (man->connection.in);
904 905
       output_list_reset (man->connection.out);
905 906
     }
906
-  if (listen)
907
-    man_listen (man);
907
+  if (!exiting)
908
+    {
909
+      if (man->settings.connect_as_client)
910
+	throw_signal_soft (SIGTERM, "management-exit");
911
+      else
912
+	man_listen (man);
913
+    }
908 914
 }
909 915
 
910 916
 static void
... ...
@@ -978,7 +1037,7 @@ man_read (struct management *man)
978 978
   len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
979 979
   if (len == 0)
980 980
     {
981
-      man_reset_client_socket (man, true);
981
+      man_reset_client_socket (man, false);
982 982
     }
983 983
   else if (len > 0)
984 984
     {
... ...
@@ -1012,7 +1071,7 @@ man_read (struct management *man)
1012 1012
        */
1013 1013
       if (man->connection.halt)
1014 1014
 	{
1015
-	  man_reset_client_socket (man, true);
1015
+	  man_reset_client_socket (man, false);
1016 1016
 	  len = 0;
1017 1017
 	}
1018 1018
       else
... ...
@@ -1025,7 +1084,7 @@ man_read (struct management *man)
1025 1025
   else /* len < 0 */
1026 1026
     {
1027 1027
       if (man_io_error (man, "recv"))
1028
-	man_reset_client_socket (man, true);
1028
+	man_reset_client_socket (man, false);
1029 1029
     }
1030 1030
   return len;
1031 1031
 }
... ...
@@ -1048,7 +1107,7 @@ man_write (struct management *man)
1048 1048
       else if (sent < 0)
1049 1049
 	{
1050 1050
 	  if (man_io_error (man, "send"))
1051
-	    man_reset_client_socket (man, true);
1051
+	    man_reset_client_socket (man, false);
1052 1052
 	}
1053 1053
     }
1054 1054
 
... ...
@@ -1139,7 +1198,8 @@ man_settings_init (struct man_settings *ms,
1139 1139
 		   const int log_history_cache,
1140 1140
 		   const int echo_buffer_size,
1141 1141
 		   const int state_buffer_size,
1142
-		   const bool hold)
1142
+		   const bool hold,
1143
+		   const bool connect_as_client)
1143 1144
 {
1144 1145
   if (!ms->defined)
1145 1146
     {
... ...
@@ -1169,6 +1229,12 @@ man_settings_init (struct man_settings *ms,
1169 1169
       ms->hold = hold;
1170 1170
 
1171 1171
       /*
1172
+       * Should OpenVPN connect to management interface as a client
1173
+       * rather than a server?
1174
+       */
1175
+      ms->connect_as_client = connect_as_client;
1176
+
1177
+      /*
1172 1178
        * Initialize socket address
1173 1179
        */
1174 1180
       ms->local.sa.sin_family = AF_INET;
... ...
@@ -1179,7 +1245,7 @@ man_settings_init (struct man_settings *ms,
1179 1179
        * Run management over tunnel, or
1180 1180
        * separate channel?
1181 1181
        */
1182
-      if (streq (addr, "tunnel"))
1182
+      if (streq (addr, "tunnel") && !connect_as_client)
1183 1183
 	{
1184 1184
 	  ms->management_over_tunnel = true;
1185 1185
 	}
... ...
@@ -1237,9 +1303,12 @@ man_connection_init (struct management *man)
1237 1237
       }
1238 1238
 
1239 1239
       /*
1240
-       * Listen on socket
1240
+       * Listen/connect socket
1241 1241
        */
1242
-      man_listen (man);
1242
+      if (man->settings.connect_as_client)
1243
+	man_connect (man);
1244
+      else
1245
+	man_listen (man);
1243 1246
     }
1244 1247
 }
1245 1248
 
... ...
@@ -1290,7 +1359,8 @@ management_open (struct management *man,
1290 1290
 		 const int log_history_cache,
1291 1291
 		 const int echo_buffer_size,
1292 1292
 		 const int state_buffer_size,
1293
-		 const bool hold)
1293
+		 const bool hold,
1294
+		 const bool connect_as_client)
1294 1295
 {
1295 1296
   bool ret = false;
1296 1297
 
... ...
@@ -1307,7 +1377,8 @@ management_open (struct management *man,
1307 1307
 		     log_history_cache,
1308 1308
 		     echo_buffer_size,
1309 1309
 		     state_buffer_size,
1310
-		     hold);
1310
+		     hold,
1311
+		     connect_as_client);
1311 1312
 
1312 1313
   /*
1313 1314
    * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
... ...
@@ -1510,7 +1581,7 @@ management_io (struct management *man)
1510 1510
 
1511 1511
       if (net_events & FD_CLOSE)
1512 1512
 	{
1513
-	  man_reset_client_socket (man, true);
1513
+	  man_reset_client_socket (man, false);
1514 1514
 	}
1515 1515
       else
1516 1516
 	{
... ...
@@ -200,6 +200,7 @@ struct man_settings {
200 200
   int state_buffer_size;
201 201
   bool server;
202 202
   bool hold;
203
+  bool connect_as_client;
203 204
 };
204 205
 
205 206
 /* up_query modes */
... ...
@@ -265,7 +266,8 @@ bool management_open (struct management *man,
265 265
 		      const int log_history_cache,
266 266
 		      const int echo_buffer_size,
267 267
 		      const int state_buffer_size,
268
-		      const bool hold);
268
+		      const bool hold,
269
+		      const bool connect_as_client);
269 270
 
270 271
 
271 272
 void management_close (struct management *man);
... ...
@@ -299,6 +299,8 @@ static const char usage_message[] =
299 299
   "--management ip port [pass] : Enable a TCP server on ip:port to handle\n"
300 300
   "                  management functions.  pass is a password file\n"
301 301
   "                  or 'stdin' to prompt from console.\n"
302
+  "--management-client : Management interface will connect as a TCP client to\n"
303
+  "                      ip/port rather than listen as a TCP server.\n"
302 304
   "--management-query-passwords : Query management channel for private key\n"
303 305
   "                  and auth-user-pass passwords.\n"
304 306
   "--management-hold : Start " PACKAGE_NAME " in a hibernating state, until a client\n"
... ...
@@ -1181,6 +1183,7 @@ show_settings (const struct options *o)
1181 1181
   SHOW_INT (management_echo_buffer_size);
1182 1182
   SHOW_BOOL (management_query_passwords);
1183 1183
   SHOW_BOOL (management_hold);
1184
+  SHOW_BOOL (management_client);
1184 1185
 #endif
1185 1186
 #ifdef ENABLE_PLUGIN
1186 1187
   if (o->plugin_list)
... ...
@@ -1495,7 +1498,7 @@ options_postprocess (struct options *options, bool first_time)
1495 1495
    */
1496 1496
 #ifdef ENABLE_MANAGEMENT
1497 1497
   if (!options->management_addr &&
1498
-      (options->management_query_passwords || options->management_hold
1498
+      (options->management_query_passwords || options->management_hold || options->management_client
1499 1499
        || options->management_log_history_cache != defaults.management_log_history_cache))
1500 1500
     msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified");
1501 1501
 #endif
... ...
@@ -3122,6 +3125,11 @@ add_option (struct options *options,
3122 3122
       VERIFY_PERMISSION (OPT_P_GENERAL);
3123 3123
       options->management_hold = true;
3124 3124
     }
3125
+  else if (streq (p[0], "management-client"))
3126
+    {
3127
+      VERIFY_PERMISSION (OPT_P_GENERAL);
3128
+      options->management_client = true;
3129
+    }
3125 3130
   else if (streq (p[0], "management-log-cache") && p[1])
3126 3131
     {
3127 3132
       int cache;
... ...
@@ -279,6 +279,7 @@ struct options
279 279
   int management_state_buffer_size;
280 280
   bool management_query_passwords;
281 281
   bool management_hold;
282
+  bool management_client;
282 283
 #endif
283 284
 
284 285
 #ifdef ENABLE_PLUGIN
... ...
@@ -100,6 +100,14 @@ throw_signal (const int signum)
100 100
   siginfo_static.hard = true;
101 101
 }
102 102
 
103
+void
104
+throw_signal_soft (const int signum, const char *signal_text)
105
+{
106
+  siginfo_static.signal_received = signum;
107
+  siginfo_static.hard = false;
108
+  siginfo_static.signal_text = signal_text;
109
+}
110
+
103 111
 static void
104 112
 signal_reset (struct signal_info *si)
105 113
 {
... ...
@@ -49,6 +49,7 @@ int parse_signal (const char *signame);
49 49
 const char *signal_name (const int sig, const bool upper);
50 50
 const char *signal_description (const int signum, const char *sigtext);
51 51
 void throw_signal (const int signum);
52
+void throw_signal_soft (const int signum, const char *signal_text);
52 53
 
53 54
 void pre_init_signal_catch (void);
54 55
 void post_init_signal_catch (void);
... ...
@@ -712,7 +712,7 @@ socket_bind (socket_descriptor_t sd,
712 712
   gc_free (&gc);
713 713
 }
714 714
 
715
-static int
715
+int
716 716
 openvpn_connect (socket_descriptor_t sd,
717 717
 		 struct openvpn_sockaddr *remote,
718 718
 		 int connect_timeout,
... ...
@@ -785,7 +785,7 @@ openvpn_connect (socket_descriptor_t sd,
785 785
   return status;
786 786
 }
787 787
 
788
-static void
788
+void
789 789
 socket_connect (socket_descriptor_t *sd,
790 790
                 struct openvpn_sockaddr *local,
791 791
                 bool bind_local,
... ...
@@ -272,6 +272,11 @@ void socket_bind (socket_descriptor_t sd,
272 272
 		  struct openvpn_sockaddr *local,
273 273
 		  const char *prefix);
274 274
 
275
+int openvpn_connect (socket_descriptor_t sd,
276
+		     struct openvpn_sockaddr *remote,
277
+		     int connect_timeout,
278
+		     volatile int *signal_received);
279
+
275 280
 /*
276 281
  * Initialize link_socket object.
277 282
  */