From e1b99e6b6630a81ffd3287bc11533707332d2dda Mon Sep 17 00:00:00 2001 From: James Yonan Date: Sun, 20 Mar 2011 04:12:26 +0000 Subject: Extended "client-kill" management interface command (server-side) to accept an optional message string. The message string format is: RESTART|HALT, RESTART will tell the client to restart (i.e. SIGUSR1). HALT will tell the client to exit (i.e. SIGTERM). On the client, human-readable-message will be communicated via management interface: >NOTIFY,,," Version 2.1.3m git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7063 e7ae566f-a301-0410-adde-c780ea21d3b5 --- forward.c | 11 +++++++++-- manage.c | 17 ++++++++++++----- manage.h | 4 +++- multi.c | 5 +++-- push.c | 29 +++++++++++++++++++++++------ push.h | 4 ++-- version.m4 | 2 +- 7 files changed, 53 insertions(+), 19 deletions(-) diff --git a/forward.c b/forward.c index ce0a7c4..65b8f0c 100644 --- a/forward.c +++ b/forward.c @@ -155,7 +155,9 @@ check_incoming_control_channel_dowork (struct context *c) else if (buf_string_match_head_str (&buf, "PUSH_")) incoming_push_message (c, &buf); else if (buf_string_match_head_str (&buf, "RESTART")) - server_pushed_restart (c, &buf); + server_pushed_signal (c, &buf, true, 7); + else if (buf_string_match_head_str (&buf, "HALT")) + server_pushed_signal (c, &buf, false, 4); else msg (D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR (&buf)); } @@ -237,7 +239,12 @@ send_control_channel_string (struct context *c, const char *str, int msglevel) /* buffered cleartext write onto TLS control channel */ stat = tls_send_payload (c->c2.tls_multi, (uint8_t*) str, strlen (str) + 1); - /* reschedule tls_multi_process */ + /* + * Reschedule tls_multi_process. + * NOTE: in multi-client mode, usually the below two statements are + * insufficient to reschedule the client instance object unless + * multi_schedule_context_wakeup(m, mi) is also called. + */ interval_action (&c->c2.tmp_int); context_immediate_reschedule (c); /* ZERO-TIMEOUT */ diff --git a/manage.c b/manage.c index 0939105..67f87d6 100644 --- a/manage.c +++ b/manage.c @@ -96,7 +96,7 @@ man_help () msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID"); msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason"); msg (M_CLIENT, " text R and optional client reason text CR"); - msg (M_CLIENT, "client-kill CID : Kill client instance CID"); + msg (M_CLIENT, "client-kill CID [M] : Kill client instance CID with message M (def=RESTART)"); msg (M_CLIENT, "env-filter [level] : Set env-var filter level"); #ifdef MANAGEMENT_PF msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)"); @@ -947,14 +947,14 @@ man_client_deny (struct management *man, const char *cid_str, const char *kid_st } static void -man_client_kill (struct management *man, const char *cid_str) +man_client_kill (struct management *man, const char *cid_str, const char *kill_msg) { unsigned long cid = 0; if (parse_cid (cid_str, &cid)) { if (man->persist.callback.kill_by_cid) { - const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid); + const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid, kill_msg); if (status) { msg (M_CLIENT, "SUCCESS: client-kill command succeeded"); @@ -1265,8 +1265,8 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch #ifdef MANAGEMENT_DEF_AUTH else if (streq (p[0], "client-kill")) { - if (man_need (man, p, 1, 0)) - man_client_kill (man, p[1]); + if (man_need (man, p, 1, MN_AT_LEAST)) + man_client_kill (man, p[1], p[2]); } else if (streq (p[0], "client-deny")) { @@ -2190,6 +2190,7 @@ management_open (struct management *man, void management_close (struct management *man) { + man_output_list_push_finalize (man); /* flush output queue */ man_connection_close (man); man_settings_close (&man->settings); man_persist_close (&man->persist); @@ -2332,6 +2333,12 @@ management_up_down(struct management *man, const char *updown, const struct env_ } } +void +management_notify(struct management *man, const char *severity, const char *type, const char *text) +{ + msg (M_CLIENT, ">NOTIFY:%s,%s,%s", severity, type, text); +} + #ifdef MANAGEMENT_DEF_AUTH static bool diff --git a/manage.h b/manage.h index 18b1564..5e0696b 100644 --- a/manage.h +++ b/manage.h @@ -156,7 +156,7 @@ struct management_callback void (*delete_event) (void *arg, event_t event); int (*n_clients) (void *arg); #ifdef MANAGEMENT_DEF_AUTH - bool (*kill_by_cid) (void *arg, const unsigned long cid); + bool (*kill_by_cid) (void *arg, const unsigned long cid, const char *kill_msg); bool (*client_auth) (void *arg, const unsigned long cid, const unsigned int mda_key_id, @@ -375,6 +375,8 @@ void management_event_loop_n_seconds (struct management *man, int sec); void management_up_down(struct management *man, const char *updown, const struct env_set *es); +void management_notify(struct management *man, const char *severity, const char *type, const char *text); + #ifdef MANAGEMENT_DEF_AUTH void management_notify_client_needing_auth (struct management *management, const unsigned int auth_id, diff --git a/multi.c b/multi.c index df96ba5..4ab1e72 100644 --- a/multi.c +++ b/multi.c @@ -2544,13 +2544,14 @@ lookup_by_cid (struct multi_context *m, const unsigned long cid) } static bool -management_kill_by_cid (void *arg, const unsigned long cid) +management_kill_by_cid (void *arg, const unsigned long cid, const char *kill_msg) { struct multi_context *m = (struct multi_context *) arg; struct multi_instance *mi = lookup_by_cid (m, cid); if (mi) { - send_restart (&mi->context); /* was: multi_signal_instance (m, mi, SIGTERM); */ + send_restart (&mi->context, kill_msg); /* was: multi_signal_instance (m, mi, SIGTERM); */ + multi_schedule_context_wakeup(m, mi); return true; } else diff --git a/push.c b/push.c index f7b7d17..2e8aa55 100644 --- a/push.c +++ b/push.c @@ -87,13 +87,30 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) * Act on received restart message from server */ void -server_pushed_restart (struct context *c, const struct buffer *buffer) +server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv) { if (c->options.pull) { - msg (D_STREAM_ERRORS, "Connection reset command was pushed by server"); - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ - c->sig->signal_text = "server-pushed-connection-reset"; + struct buffer buf = *buffer; + const char *m = ""; + if (buf_advance (&buf, adv) && buf_read_u8 (&buf) == ',' && BLEN (&buf)) + m = BSTR (&buf); + if (restart) + { + msg (D_STREAM_ERRORS, "Connection reset command was pushed by server ('%s')", m); + c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ + c->sig->signal_text = "server-pushed-connection-reset"; + } + else + { + msg (D_STREAM_ERRORS, "Halt command was pushed by server ('%s')", m); + c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- server-pushed halt */ + c->sig->signal_text = "server-pushed-halt"; + } +#ifdef ENABLE_MANAGEMENT + if (management) + management_notify (management, "info", c->sig->signal_text, m); +#endif } } @@ -130,10 +147,10 @@ send_auth_failed (struct context *c, const char *client_reason) * Send restart message from server to client. */ void -send_restart (struct context *c) +send_restart (struct context *c, const char *kill_msg) { schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); - send_control_channel_string (c, "RESTART", D_PUSH); + send_control_channel_string (c, kill_msg ? kill_msg : "RESTART", D_PUSH); } #endif diff --git a/push.h b/push.h index b5d1fbf..8c3f157 100644 --- a/push.h +++ b/push.h @@ -50,7 +50,7 @@ bool send_push_request (struct context *c); void receive_auth_failed (struct context *c, const struct buffer *buffer); -void server_pushed_restart (struct context *c, const struct buffer *buffer); +void server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv); #if P2MP_SERVER @@ -67,7 +67,7 @@ void remove_iroutes_from_push_route_list (struct options *o); void send_auth_failed (struct context *c, const char *client_reason); -void send_restart (struct context *c); +void send_restart (struct context *c, const char *kill_msg); #endif #endif diff --git a/version.m4 b/version.m4 index e3825f2..f3e7a8d 100644 --- a/version.m4 +++ b/version.m4 @@ -1,5 +1,5 @@ dnl define the OpenVPN version -define(PRODUCT_VERSION,[2.1.3k]) +define(PRODUCT_VERSION,[2.1.3m]) dnl define the TAP version define(PRODUCT_TAP_ID,[tap0901]) define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9]) -- cgit v1.2.3