From: james Date: Fri, 3 Feb 2006 09:04:52 +0000 (+0000) Subject: Added feature to --management-client to confirm connection X-Git-Tag: v2.1_rc1~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d33c060282fedc26d46e02aeee98fb751330adb;p=thirdparty%2Fopenvpn.git 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 --- diff --git a/config-win32.h.in b/config-win32.h.in index 3ea4d8582..502c6aebc 100644 --- a/config-win32.h.in +++ b/config-win32.h.in @@ -98,6 +98,9 @@ typedef unsigned long in_addr_t; /* Dimension size to use for empty array declaration */ #define EMPTY_ARRAY_SIZE 0 +/* Define to 1 if you have the `getsockname' function. */ +#define HAVE_GETSOCKNAME 1 + /* Define to 1 if you have the header file. */ #define HAVE_OPENSSL_ENGINE_H 1 diff --git a/configure.ac b/configure.ac index aeb723767..13d7d321e 100644 --- a/configure.ac +++ b/configure.ac @@ -378,7 +378,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl getpass strerror syslog openlog mlockall getgrnam setgid dnl setgroups stat flock readv writev setsockopt getsockopt dnl setsid chdir gettimeofday putenv getpeername unlink dnl - poll chsize ftruncate sendmsg recvmsg) + poll chsize ftruncate sendmsg recvmsg getsockname) AC_CACHE_SAVE dnl Required library functions diff --git a/error.c b/error.c index f01dd8fc8..6191cb393 100644 --- a/error.c +++ b/error.c @@ -705,6 +705,15 @@ msg_flags_string (const unsigned int flags, struct gc_arena *gc) return BSTR (&out); } +#ifdef ENABLE_DEBUG +void +crash (void) +{ + char *null = NULL; + *null = 0; +} +#endif + #ifdef WIN32 const char * diff --git a/error.h b/error.h index bfe5ec32f..62926ccfb 100644 --- a/error.h +++ b/error.h @@ -195,6 +195,10 @@ FILE *msg_fp(void); void assert_failed (const char *filename, int line); +#ifdef ENABLE_DEBUG +void crash (void); // force a segfault (debugging only) +#endif + /* Inline functions */ static inline bool diff --git a/init.c b/init.c index 97bf9ecc9..b1ef03433 100644 --- a/init.c +++ b/init.c @@ -2393,7 +2393,8 @@ open_management (struct context *c) c->options.management_echo_buffer_size, c->options.management_state_buffer_size, c->options.management_hold, - c->options.management_client)) + c->options.management_client, + c->options.management_write_peer_info_file)) { management_set_state (management, OPENVPN_STATE_CONNECTING, @@ -2665,7 +2666,8 @@ init_instance (struct context *c, const struct env_set *env, const unsigned int return; sig: - c->sig->signal_text = "init_instance"; + if (!c->sig->signal_text) + c->sig->signal_text = "init_instance"; close_context (c, -1, flags); return; } diff --git a/manage.c b/manage.c index 935b18a46..9c2a178bd 100644 --- a/manage.c +++ b/manage.c @@ -187,7 +187,10 @@ man_output_list_push (struct management *man, const char *str) output_list_push (man->connection.out, (const unsigned char *) str); man_update_io_state (man); if (!man->persist.standalone_disabled) - man_output_standalone (man, NULL); + { + volatile int signal_received = 0; + man_output_standalone (man, &signal_received); + } } } @@ -791,6 +794,46 @@ man_stop_ne32 (struct management *man) #endif +static void +man_record_peer_info (struct management *man) +{ + struct gc_arena gc = gc_new (); + if (man->settings.write_peer_info_file) + { + bool success = false; +#ifdef HAVE_GETSOCKNAME + if (socket_defined (man->connection.sd_cli)) + { + struct sockaddr_in addr; + socklen_t addrlen = sizeof (addr); + int status; + + CLEAR (addr); + status = getsockname (man->connection.sd_cli, (struct sockaddr *)&addr, &addrlen); + if (!status && addrlen == sizeof (addr)) + { + const in_addr_t a = ntohl (addr.sin_addr.s_addr); + const int p = ntohs (addr.sin_port); + FILE *fp = fopen (man->settings.write_peer_info_file, "w"); + if (fp) + { + fprintf (fp, "%s\n%d\n", print_in_addr_t (a, 0, &gc), p); + if (!fclose (fp)) + success = true; + } + } + } +#endif + if (!success) + { + msg (D_MANAGEMENT, "MANAGEMENT: failed to write peer info to file %s", + man->settings.write_peer_info_file); + throw_signal_soft (SIGTERM, "management-connect-failed"); + } + } + gc_free (&gc); +} + static void man_connection_settings_reset (struct management *man) { @@ -937,6 +980,7 @@ man_connect (struct management *man) goto done; } + man_record_peer_info (man); man_new_connection_post (man, "Connected to management server at"); done: @@ -960,7 +1004,10 @@ man_reset_client_socket (struct management *man, const bool exiting) if (!exiting) { if (man->settings.connect_as_client) - throw_signal_soft (SIGTERM, "management-exit"); + { + msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit"); + throw_signal_soft (SIGTERM, "management-exit"); + } else man_listen (man); } @@ -1199,7 +1246,8 @@ man_settings_init (struct man_settings *ms, const int echo_buffer_size, const int state_buffer_size, const bool hold, - const bool connect_as_client) + const bool connect_as_client, + const char *write_peer_info_file) { if (!ms->defined) { @@ -1233,6 +1281,7 @@ man_settings_init (struct man_settings *ms, * rather than a server? */ ms->connect_as_client = connect_as_client; + ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL); /* * Initialize socket address @@ -1269,6 +1318,7 @@ man_settings_init (struct man_settings *ms, static void man_settings_close (struct man_settings *ms) { + free (ms->write_peer_info_file); CLEAR (*ms); } @@ -1360,7 +1410,8 @@ management_open (struct management *man, const int echo_buffer_size, const int state_buffer_size, const bool hold, - const bool connect_as_client) + const bool connect_as_client, + const char *write_peer_info_file) { bool ret = false; @@ -1378,7 +1429,8 @@ management_open (struct management *man, echo_buffer_size, state_buffer_size, hold, - connect_as_client); + connect_as_client, + write_peer_info_file); /* * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE, @@ -1678,6 +1730,18 @@ man_standalone_ok (const struct management *man) return !man->settings.management_over_tunnel && man->connection.state != MS_INITIAL; } +static bool +man_check_for_signals (volatile int *signal_received) +{ + if (signal_received) + { + get_signal (signal_received); + if (*signal_received) + return true; + } + return false; +} + /* * Wait for socket I/O when outside primary event loop */ @@ -1696,16 +1760,17 @@ man_block (struct management *man, volatile int *signal_received, const time_t e management_socket_set (man, man->connection.es, NULL, NULL); tv.tv_usec = 0; tv.tv_sec = 1; + if (man_check_for_signals (signal_received)) + { + status = -1; + break; + } status = event_wait (man->connection.es, &tv, &esr, 1); update_time (); - if (signal_received) + if (man_check_for_signals (signal_received)) { - get_signal (signal_received); - if (*signal_received) - { - status = -1; - break; - } + status = -1; + break; } /* set SIGINT signal if expiration time exceeded */ if (expire && now >= expire) diff --git a/manage.h b/manage.h index 873bb4226..d7ed79c42 100644 --- a/manage.h +++ b/manage.h @@ -201,6 +201,7 @@ struct man_settings { bool server; bool hold; bool connect_as_client; + char *write_peer_info_file; }; /* up_query modes */ @@ -267,8 +268,8 @@ bool management_open (struct management *man, const int echo_buffer_size, const int state_buffer_size, const bool hold, - const bool connect_as_client); - + const bool connect_as_client, + const char *write_peer_info_file); void management_close (struct management *man); diff --git a/options.c b/options.c index 45d0023eb..2c9dbcbb4 100644 --- a/options.c +++ b/options.c @@ -1184,6 +1184,7 @@ show_settings (const struct options *o) SHOW_BOOL (management_query_passwords); SHOW_BOOL (management_hold); SHOW_BOOL (management_client); + SHOW_STR (management_write_peer_info_file); #endif #ifdef ENABLE_PLUGIN if (o->plugin_list) @@ -1498,7 +1499,8 @@ options_postprocess (struct options *options, bool first_time) */ #ifdef ENABLE_MANAGEMENT if (!options->management_addr && - (options->management_query_passwords || options->management_hold || options->management_client + (options->management_query_passwords || options->management_hold + || options->management_client || options->management_write_peer_info_file || 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 @@ -3129,6 +3131,7 @@ add_option (struct options *options, { VERIFY_PERMISSION (OPT_P_GENERAL); options->management_client = true; + options->management_write_peer_info_file = p[1]; } else if (streq (p[0], "management-log-cache") && p[1]) { diff --git a/options.h b/options.h index ca04cabac..9f8f08a79 100644 --- a/options.h +++ b/options.h @@ -280,6 +280,7 @@ struct options bool management_query_passwords; bool management_hold; bool management_client; + const char *management_write_peer_info_file; #endif #ifdef ENABLE_PLUGIN diff --git a/service-win32/service.patch b/service-win32/service.patch index b4b2063d4..8de38eb02 100755 --- a/service-win32/service.patch +++ b/service-win32/service.patch @@ -1,5 +1,5 @@ ---- service.c.orig Mon Sep 5 14:38:41 2005 -+++ service.c Tue Sep 6 13:58:52 2005 +--- service.c.orig Mon Jan 30 10:03:35 2006 ++++ service.c Mon Jan 30 10:16:33 2006 @@ -16,6 +16,7 @@ service_main(DWORD dwArgc, LPTSTR *lpszArgv); CmdInstallService(); @@ -221,9 +221,9 @@ + + schService = OpenService( + schSCManager, // SCM database -+ "MeetrixService", // service name ++ SZSERVICENAME, // service name + SERVICE_ALL_ACCESS); -+ ++ + if (schService == NULL) { + _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256)); + ret = 1; @@ -319,8 +319,8 @@ } if ( lpszTemp ) ---- service.h.orig Mon Sep 5 14:38:41 2005 -+++ service.h Tue Sep 6 13:58:59 2005 +--- service.h.orig Mon Jan 30 10:03:35 2006 ++++ service.h Mon Jan 30 10:03:35 2006 @@ -62,13 +62,13 @@ //// todo: change to desired strings ////