Browse code

Added feature to --management-client to confirm connection by writing IP addr and port to a file.

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

james authored on 2006/02/03 18:04:52
Showing 10 changed files
... ...
@@ -98,6 +98,9 @@ typedef unsigned long in_addr_t;
98 98
 /* Dimension size to use for empty array declaration */
99 99
 #define EMPTY_ARRAY_SIZE 0
100 100
 
101
+/* Define to 1 if you have the `getsockname' function. */
102
+#define HAVE_GETSOCKNAME 1
103
+
101 104
 /* Define to 1 if you have the <openssl/engine.h> header file. */
102 105
 #define HAVE_OPENSSL_ENGINE_H 1
103 106
 
... ...
@@ -378,7 +378,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl
378 378
 	       getpass strerror syslog openlog mlockall getgrnam setgid dnl
379 379
 	       setgroups stat flock readv writev setsockopt getsockopt dnl
380 380
 	       setsid chdir gettimeofday putenv getpeername unlink dnl
381
-               poll chsize ftruncate sendmsg recvmsg)
381
+               poll chsize ftruncate sendmsg recvmsg getsockname)
382 382
 AC_CACHE_SAVE
383 383
 
384 384
 dnl Required library functions
... ...
@@ -705,6 +705,15 @@ msg_flags_string (const unsigned int flags, struct gc_arena *gc)
705 705
   return BSTR (&out);
706 706
 }
707 707
 
708
+#ifdef ENABLE_DEBUG
709
+void
710
+crash (void)
711
+{
712
+  char *null = NULL;
713
+  *null = 0;
714
+}
715
+#endif
716
+
708 717
 #ifdef WIN32
709 718
 
710 719
 const char *
... ...
@@ -195,6 +195,10 @@ FILE *msg_fp(void);
195 195
 
196 196
 void assert_failed (const char *filename, int line);
197 197
 
198
+#ifdef ENABLE_DEBUG
199
+void crash (void); // force a segfault (debugging only)
200
+#endif
201
+
198 202
 /* Inline functions */
199 203
 
200 204
 static inline bool
... ...
@@ -2393,7 +2393,8 @@ open_management (struct context *c)
2393 2393
 			       c->options.management_echo_buffer_size,
2394 2394
 			       c->options.management_state_buffer_size,
2395 2395
 			       c->options.management_hold,
2396
-			       c->options.management_client))
2396
+			       c->options.management_client,
2397
+			       c->options.management_write_peer_info_file))
2397 2398
 	    {
2398 2399
 	      management_set_state (management,
2399 2400
 				    OPENVPN_STATE_CONNECTING,
... ...
@@ -2665,7 +2666,8 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int
2665 2665
   return;
2666 2666
 
2667 2667
  sig:
2668
-  c->sig->signal_text = "init_instance";
2668
+  if (!c->sig->signal_text)
2669
+    c->sig->signal_text = "init_instance";
2669 2670
   close_context (c, -1, flags);
2670 2671
   return;
2671 2672
 }
... ...
@@ -187,7 +187,10 @@ man_output_list_push (struct management *man, const char *str)
187 187
 	output_list_push (man->connection.out, (const unsigned char *) str);
188 188
       man_update_io_state (man);
189 189
       if (!man->persist.standalone_disabled)
190
-	man_output_standalone (man, NULL);
190
+	{
191
+	  volatile int signal_received = 0;
192
+	  man_output_standalone (man, &signal_received);
193
+	}
191 194
     }
192 195
 }
193 196
 
... ...
@@ -792,6 +795,46 @@ man_stop_ne32 (struct management *man)
792 792
 #endif
793 793
 
794 794
 static void
795
+man_record_peer_info (struct management *man)
796
+{
797
+  struct gc_arena gc = gc_new ();
798
+  if (man->settings.write_peer_info_file)
799
+    {
800
+      bool success = false;
801
+#ifdef HAVE_GETSOCKNAME
802
+      if (socket_defined (man->connection.sd_cli))
803
+	{
804
+	  struct sockaddr_in addr;
805
+	  socklen_t addrlen = sizeof (addr);
806
+	  int status;
807
+
808
+	  CLEAR (addr);
809
+	  status = getsockname (man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen);
810
+	  if (!status && addrlen == sizeof (addr))
811
+	    {
812
+	      const in_addr_t a = ntohl (addr.sin_addr.s_addr);
813
+	      const int p = ntohs (addr.sin_port);
814
+	      FILE *fp = fopen (man->settings.write_peer_info_file, "w");
815
+	      if (fp)
816
+		{
817
+		  fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p);
818
+		  if (!fclose (fp))
819
+		    success = true;
820
+		}
821
+	    }
822
+	}
823
+#endif
824
+      if (!success)
825
+	{
826
+	  msg (D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file %s",
827
+	       man->settings.write_peer_info_file);
828
+	  throw_signal_soft (SIGTERM, "management-connect-failed");
829
+	}
830
+    }
831
+  gc_free (&gc);
832
+}
833
+
834
+static void
795 835
 man_connection_settings_reset (struct management *man)
796 836
 {
797 837
   man->connection.state_realtime = false;
... ...
@@ -937,6 +980,7 @@ man_connect (struct management *man)
937 937
       goto done;
938 938
     }
939 939
 
940
+  man_record_peer_info (man);
940 941
   man_new_connection_post (man, "Connected to management server at");
941 942
 
942 943
  done:
... ...
@@ -960,7 +1004,10 @@ man_reset_client_socket (struct management *man, const bool exiting)
960 960
   if (!exiting)
961 961
     {
962 962
       if (man->settings.connect_as_client)
963
-	throw_signal_soft (SIGTERM, "management-exit");
963
+	{
964
+	  msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit");
965
+	  throw_signal_soft (SIGTERM, "management-exit");
966
+	}
964 967
       else
965 968
 	man_listen (man);
966 969
     }
... ...
@@ -1199,7 +1246,8 @@ man_settings_init (struct man_settings *ms,
1199 1199
 		   const int echo_buffer_size,
1200 1200
 		   const int state_buffer_size,
1201 1201
 		   const bool hold,
1202
-		   const bool connect_as_client)
1202
+		   const bool connect_as_client,
1203
+		   const char *write_peer_info_file)
1203 1204
 {
1204 1205
   if (!ms->defined)
1205 1206
     {
... ...
@@ -1233,6 +1281,7 @@ man_settings_init (struct man_settings *ms,
1233 1233
        * rather than a server?
1234 1234
        */
1235 1235
       ms->connect_as_client = connect_as_client;
1236
+      ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL);
1236 1237
 
1237 1238
       /*
1238 1239
        * Initialize socket address
... ...
@@ -1269,6 +1318,7 @@ man_settings_init (struct man_settings *ms,
1269 1269
 static void
1270 1270
 man_settings_close (struct man_settings *ms)
1271 1271
 {
1272
+  free (ms->write_peer_info_file);
1272 1273
   CLEAR (*ms);
1273 1274
 }
1274 1275
 
... ...
@@ -1360,7 +1410,8 @@ management_open (struct management *man,
1360 1360
 		 const int echo_buffer_size,
1361 1361
 		 const int state_buffer_size,
1362 1362
 		 const bool hold,
1363
-		 const bool connect_as_client)
1363
+		 const bool connect_as_client,
1364
+		 const char *write_peer_info_file)
1364 1365
 {
1365 1366
   bool ret = false;
1366 1367
 
... ...
@@ -1378,7 +1429,8 @@ management_open (struct management *man,
1378 1378
 		     echo_buffer_size,
1379 1379
 		     state_buffer_size,
1380 1380
 		     hold,
1381
-		     connect_as_client);
1381
+		     connect_as_client,
1382
+		     write_peer_info_file);
1382 1383
 
1383 1384
   /*
1384 1385
    * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE,
... ...
@@ -1678,6 +1730,18 @@ man_standalone_ok (const struct management *man)
1678 1678
   return !man->settings.management_over_tunnel && man->connection.state != MS_INITIAL;
1679 1679
 }
1680 1680
 
1681
+static bool
1682
+man_check_for_signals (volatile int *signal_received)
1683
+{
1684
+  if (signal_received)
1685
+    {
1686
+      get_signal (signal_received);
1687
+      if (*signal_received)
1688
+	return true;
1689
+    }
1690
+  return false;
1691
+}
1692
+
1681 1693
 /*
1682 1694
  * Wait for socket I/O when outside primary event loop
1683 1695
  */
... ...
@@ -1696,16 +1760,17 @@ man_block (struct management *man, volatile int *signal_received, const time_t e
1696 1696
 	  management_socket_set (man, man->connection.es, NULL, NULL);
1697 1697
 	  tv.tv_usec = 0;
1698 1698
 	  tv.tv_sec = 1;
1699
+	  if (man_check_for_signals (signal_received))
1700
+	    {
1701
+	      status = -1;
1702
+	      break;
1703
+	    }
1699 1704
 	  status = event_wait (man->connection.es, &tv, &esr, 1);
1700 1705
 	  update_time ();
1701
-	  if (signal_received)
1706
+	  if (man_check_for_signals (signal_received))
1702 1707
 	    {
1703
-	      get_signal (signal_received);
1704
-	      if (*signal_received)
1705
-		{
1706
-		  status = -1;
1707
-		  break;
1708
-		}
1708
+	      status = -1;
1709
+	      break;
1709 1710
 	    }
1710 1711
 	  /* set SIGINT signal if expiration time exceeded */
1711 1712
 	  if (expire && now >= expire)
... ...
@@ -201,6 +201,7 @@ struct man_settings {
201 201
   bool server;
202 202
   bool hold;
203 203
   bool connect_as_client;
204
+  char *write_peer_info_file;
204 205
 };
205 206
 
206 207
 /* up_query modes */
... ...
@@ -267,8 +268,8 @@ bool management_open (struct management *man,
267 267
 		      const int echo_buffer_size,
268 268
 		      const int state_buffer_size,
269 269
 		      const bool hold,
270
-		      const bool connect_as_client);
271
-
270
+		      const bool connect_as_client,
271
+		      const char *write_peer_info_file);
272 272
 
273 273
 void management_close (struct management *man);
274 274
 
... ...
@@ -1184,6 +1184,7 @@ show_settings (const struct options *o)
1184 1184
   SHOW_BOOL (management_query_passwords);
1185 1185
   SHOW_BOOL (management_hold);
1186 1186
   SHOW_BOOL (management_client);
1187
+  SHOW_STR (management_write_peer_info_file);
1187 1188
 #endif
1188 1189
 #ifdef ENABLE_PLUGIN
1189 1190
   if (o->plugin_list)
... ...
@@ -1498,7 +1499,8 @@ options_postprocess (struct options *options, bool first_time)
1498 1498
    */
1499 1499
 #ifdef ENABLE_MANAGEMENT
1500 1500
   if (!options->management_addr &&
1501
-      (options->management_query_passwords || options->management_hold || options->management_client
1501
+      (options->management_query_passwords || options->management_hold
1502
+       || options->management_client || options->management_write_peer_info_file
1502 1503
        || options->management_log_history_cache != defaults.management_log_history_cache))
1503 1504
     msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified");
1504 1505
 #endif
... ...
@@ -3129,6 +3131,7 @@ add_option (struct options *options,
3129 3129
     {
3130 3130
       VERIFY_PERMISSION (OPT_P_GENERAL);
3131 3131
       options->management_client = true;
3132
+      options->management_write_peer_info_file = p[1];
3132 3133
     }
3133 3134
   else if (streq (p[0], "management-log-cache") && p[1])
3134 3135
     {
... ...
@@ -280,6 +280,7 @@ struct options
280 280
   bool management_query_passwords;
281 281
   bool management_hold;
282 282
   bool management_client;
283
+  const char *management_write_peer_info_file;
283 284
 #endif
284 285
 
285 286
 #ifdef ENABLE_PLUGIN
... ...
@@ -1,5 +1,5 @@
1
-+++ service.c	Tue Sep  6 13:58:52 2005
1
+--- service.c.orig	Mon Jan 30 10:03:35 2006
2 2
 @@ -16,6 +16,7 @@
3 3
    service_main(DWORD dwArgc, LPTSTR *lpszArgv);
4 4
    CmdInstallService();
... ...
@@ -221,9 +221,9 @@
221 221
 +
222 222
 +    schService = OpenService( 
223 223
 +        schSCManager,          // SCM database 
224
-+        "MeetrixService",     // service name
224
++        SZSERVICENAME,         // service name
225 225
 +        SERVICE_ALL_ACCESS); 
226
-+ 
226
++
227 227
 +    if (schService == NULL) {
228 228
 +      _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
229 229
 +       ret = 1;
... ...
@@ -319,8 +319,8 @@
319 319
     }
320 320
  
321 321
     if ( lpszTemp )
322
-+++ service.h	Tue Sep  6 13:58:59 2005
322
+--- service.h.orig	Mon Jan 30 10:03:35 2006
323 323
 @@ -62,13 +62,13 @@
324 324
  //// todo: change to desired strings
325 325
  ////