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... | ... |
@@ -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; |
... | ... |
@@ -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 |
*/ |