For more info, see management/management-notes.txt, and look for
references to "client-reason-text".
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5012 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -94,7 +94,8 @@ man_help () |
| 94 | 94 |
#ifdef MANAGEMENT_DEF_AUTH |
| 95 | 95 |
msg (M_CLIENT, "client-auth CID KID : Authenticate client-id/key-id CID/KID (MULTILINE)"); |
| 96 | 96 |
msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID"); |
| 97 |
- msg (M_CLIENT, "client-deny CID KID R : Deny auth client-id/key-id CID/KID with reason text R"); |
|
| 97 |
+ msg (M_CLIENT, "client-deny CID KID R [CR] : Deny auth client-id/key-id CID/KID with log reason"); |
|
| 98 |
+ msg (M_CLIENT, " text R and optional client reason text CR"); |
|
| 98 | 99 |
msg (M_CLIENT, "client-kill CID : Kill client instance CID"); |
| 99 | 100 |
#ifdef MANAGEMENT_PF |
| 100 | 101 |
msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)"); |
| ... | ... |
@@ -801,6 +802,7 @@ in_extra_dispatch (struct management *man) |
| 801 | 801 |
man->connection.in_extra_kid, |
| 802 | 802 |
true, |
| 803 | 803 |
NULL, |
| 804 |
+ NULL, |
|
| 804 | 805 |
man->connection.in_extra); |
| 805 | 806 |
man->connection.in_extra = NULL; |
| 806 | 807 |
if (status) |
| ... | ... |
@@ -862,7 +864,7 @@ man_client_auth (struct management *man, const char *cid_str, const char *kid_st |
| 862 | 862 |
} |
| 863 | 863 |
|
| 864 | 864 |
static void |
| 865 |
-man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason) |
|
| 865 |
+man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason, const char *client_reason) |
|
| 866 | 866 |
{
|
| 867 | 867 |
unsigned long cid = 0; |
| 868 | 868 |
unsigned int kid = 0; |
| ... | ... |
@@ -876,6 +878,7 @@ man_client_deny (struct management *man, const char *cid_str, const char *kid_st |
| 876 | 876 |
kid, |
| 877 | 877 |
false, |
| 878 | 878 |
reason, |
| 879 |
+ client_reason, |
|
| 879 | 880 |
NULL); |
| 880 | 881 |
if (status) |
| 881 | 882 |
{
|
| ... | ... |
@@ -1160,8 +1163,8 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch |
| 1160 | 1160 |
} |
| 1161 | 1161 |
else if (streq (p[0], "client-deny")) |
| 1162 | 1162 |
{
|
| 1163 |
- if (man_need (man, p, 3, 0)) |
|
| 1164 |
- man_client_deny (man, p[1], p[2], p[3]); |
|
| 1163 |
+ if (man_need (man, p, 3, MN_AT_LEAST)) |
|
| 1164 |
+ man_client_deny (man, p[1], p[2], p[3], p[4]); |
|
| 1165 | 1165 |
} |
| 1166 | 1166 |
else if (streq (p[0], "client-auth-nt")) |
| 1167 | 1167 |
{
|
| ... | ... |
@@ -308,6 +308,12 @@ COMMAND -- password and username |
| 308 | 308 |
|
| 309 | 309 |
>PASSWORD:Verification Failed: 'Auth' |
| 310 | 310 |
|
| 311 |
+ Example 5: The --auth-user-pass username/password failed, |
|
| 312 |
+ and the server provided a custom client-reason-text string |
|
| 313 |
+ using the client-deny server-side management interface command. |
|
| 314 |
+ |
|
| 315 |
+ >PASSWORD:Verification Failed: 'custom server-generated string' |
|
| 316 |
+ |
|
| 311 | 317 |
COMMAND -- forget-passwords |
| 312 | 318 |
--------------------------- |
| 313 | 319 |
|
| ... | ... |
@@ -535,7 +541,7 @@ COMMAND -- client-deny (OpenVPN 2.1 or higher) |
| 535 | 535 |
|
| 536 | 536 |
Deny a ">CLIENT:CONNECT" or ">CLIENT:REAUTH" request. |
| 537 | 537 |
|
| 538 |
- client-deny {CID} {KID} "reason-text"
|
|
| 538 |
+ client-deny {CID} {KID} "reason-text" ["client-reason-text"]
|
|
| 539 | 539 |
|
| 540 | 540 |
CID,KID -- client ID and Key ID. See documentation for ">CLIENT:" |
| 541 | 541 |
notification for more info. |
| ... | ... |
@@ -544,6 +550,9 @@ reason-text: a human-readable message explaining why the authentication |
| 544 | 544 |
request was denied. This message will be output to the OpenVPN log |
| 545 | 545 |
file or syslog. |
| 546 | 546 |
|
| 547 |
+client-reason-text: a message that will be sent to the client as |
|
| 548 |
+part of the AUTH_FAILED message. |
|
| 549 |
+ |
|
| 547 | 550 |
Note that client-deny denies a specific Key ID (pertaining to a |
| 548 | 551 |
TLS renegotiation). A client-deny command issued in response to |
| 549 | 552 |
an initial TLS key negotiation (notified by ">CLIENT:CONNECT") will |
| ... | ... |
@@ -2552,6 +2552,7 @@ management_client_auth (void *arg, |
| 2552 | 2552 |
const unsigned int mda_key_id, |
| 2553 | 2553 |
const bool auth, |
| 2554 | 2554 |
const char *reason, |
| 2555 |
+ const char *client_reason, |
|
| 2555 | 2556 |
struct buffer_list *cc_config) /* ownership transferred */ |
| 2556 | 2557 |
{
|
| 2557 | 2558 |
struct multi_context *m = (struct multi_context *) arg; |
| ... | ... |
@@ -2561,7 +2562,7 @@ management_client_auth (void *arg, |
| 2561 | 2561 |
|
| 2562 | 2562 |
if (mi) |
| 2563 | 2563 |
{
|
| 2564 |
- ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth); |
|
| 2564 |
+ ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth, client_reason); |
|
| 2565 | 2565 |
if (ret) |
| 2566 | 2566 |
{
|
| 2567 | 2567 |
if (auth && !mi->connection_established_flag) |
| ... | ... |
@@ -2570,7 +2571,7 @@ management_client_auth (void *arg, |
| 2570 | 2570 |
cc_config_owned = false; |
| 2571 | 2571 |
} |
| 2572 | 2572 |
if (!auth && reason) |
| 2573 |
- msg (D_MULTI_LOW, "MULTI: connection rejected: %s", reason); |
|
| 2573 |
+ msg (D_MULTI_LOW, "MULTI: connection rejected: %s, CLI:%s", reason, np(client_reason)); |
|
| 2574 | 2574 |
} |
| 2575 | 2575 |
} |
| 2576 | 2576 |
if (cc_config_owned && cc_config) |
| ... | ... |
@@ -61,7 +61,13 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) |
| 61 | 61 |
c->sig->signal_text = "auth-failure"; |
| 62 | 62 |
#ifdef ENABLE_MANAGEMENT |
| 63 | 63 |
if (management) |
| 64 |
- management_auth_failure (management, UP_TYPE_AUTH); |
|
| 64 |
+ {
|
|
| 65 |
+ const char *reason = UP_TYPE_AUTH; |
|
| 66 |
+ struct buffer buf = *buffer; |
|
| 67 |
+ if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf)) |
|
| 68 |
+ reason = BSTR (&buf); |
|
| 69 |
+ management_auth_failure (management, reason); |
|
| 70 |
+ } |
|
| 65 | 71 |
#endif |
| 66 | 72 |
} |
| 67 | 73 |
} |
| ... | ... |
@@ -71,10 +77,27 @@ receive_auth_failed (struct context *c, const struct buffer *buffer) |
| 71 | 71 |
* Send auth failed message from server to client. |
| 72 | 72 |
*/ |
| 73 | 73 |
void |
| 74 |
-send_auth_failed (struct context *c) |
|
| 74 |
+send_auth_failed (struct context *c, const char *client_reason) |
|
| 75 | 75 |
{
|
| 76 |
+ struct gc_arena gc = gc_new (); |
|
| 77 |
+ static const char auth_failed[] = "AUTH_FAILED"; |
|
| 78 |
+ size_t len; |
|
| 79 |
+ |
|
| 76 | 80 |
schedule_exit (c, c->options.scheduled_exit_interval); |
| 77 |
- send_control_channel_string (c, "AUTH_FAILED", D_PUSH); |
|
| 81 |
+ |
|
| 82 |
+ len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed); |
|
| 83 |
+ if (len > TLS_CHANNEL_BUF_SIZE) |
|
| 84 |
+ len = TLS_CHANNEL_BUF_SIZE; |
|
| 85 |
+ |
|
| 86 |
+ {
|
|
| 87 |
+ struct buffer buf = alloc_buf_gc (len, &gc); |
|
| 88 |
+ buf_printf (&buf, auth_failed); |
|
| 89 |
+ if (client_reason) |
|
| 90 |
+ buf_printf (&buf, ",%s", client_reason); |
|
| 91 |
+ send_control_channel_string (c, BSTR (&buf), D_PUSH); |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ gc_free (&gc); |
|
| 78 | 95 |
} |
| 79 | 96 |
#endif |
| 80 | 97 |
|
| ... | ... |
@@ -258,7 +281,8 @@ process_incoming_push_msg (struct context *c, |
| 258 | 258 |
{
|
| 259 | 259 |
if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED) |
| 260 | 260 |
{
|
| 261 |
- send_auth_failed (c); |
|
| 261 |
+ const char *client_reason = tls_client_reason (c->c2.tls_multi); |
|
| 262 |
+ send_auth_failed (c, client_reason); |
|
| 262 | 263 |
ret = PUSH_MSG_AUTH_FAILURE; |
| 263 | 264 |
} |
| 264 | 265 |
else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED) |
| ... | ... |
@@ -62,7 +62,7 @@ bool send_push_reply (struct context *c); |
| 62 | 62 |
|
| 63 | 63 |
void remove_iroutes_from_push_route_list (struct options *o); |
| 64 | 64 |
|
| 65 |
-void send_auth_failed (struct context *c); |
|
| 65 |
+void send_auth_failed (struct context *c, const char *client_reason); |
|
| 66 | 66 |
|
| 67 | 67 |
#endif |
| 68 | 68 |
#endif |
| ... | ... |
@@ -908,6 +908,18 @@ tls_lock_common_name (struct tls_multi *multi) |
| 908 | 908 |
#endif |
| 909 | 909 |
|
| 910 | 910 |
#ifdef MANAGEMENT_DEF_AUTH |
| 911 |
+static void |
|
| 912 |
+man_def_auth_set_client_reason (struct tls_multi *multi, const char *client_reason) |
|
| 913 |
+{
|
|
| 914 |
+ if (multi->client_reason) |
|
| 915 |
+ {
|
|
| 916 |
+ free (multi->client_reason); |
|
| 917 |
+ multi->client_reason = NULL; |
|
| 918 |
+ } |
|
| 919 |
+ if (client_reason && strlen (client_reason)) |
|
| 920 |
+ multi->client_reason = string_alloc (client_reason, NULL); |
|
| 921 |
+} |
|
| 922 |
+ |
|
| 911 | 923 |
static inline unsigned int |
| 912 | 924 |
man_def_auth_test (const struct key_state *ks) |
| 913 | 925 |
{
|
| ... | ... |
@@ -1077,12 +1089,13 @@ tls_authentication_status (struct tls_multi *multi, const int latency) |
| 1077 | 1077 |
|
| 1078 | 1078 |
#ifdef MANAGEMENT_DEF_AUTH |
| 1079 | 1079 |
bool |
| 1080 |
-tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth) |
|
| 1080 |
+tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason) |
|
| 1081 | 1081 |
{
|
| 1082 | 1082 |
bool ret = false; |
| 1083 | 1083 |
if (multi) |
| 1084 | 1084 |
{
|
| 1085 | 1085 |
int i; |
| 1086 |
+ man_def_auth_set_client_reason (multi, client_reason); |
|
| 1086 | 1087 |
for (i = 0; i < KEY_SCAN_SIZE; ++i) |
| 1087 | 1088 |
{
|
| 1088 | 1089 |
struct key_state *ks = multi->key_scan[i]; |
| ... | ... |
@@ -2397,6 +2410,10 @@ tls_multi_free (struct tls_multi *multi, bool clear) |
| 2397 | 2397 |
|
| 2398 | 2398 |
ASSERT (multi); |
| 2399 | 2399 |
|
| 2400 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 2401 |
+ man_def_auth_set_client_reason(multi, NULL); |
|
| 2402 |
+#endif |
|
| 2403 |
+ |
|
| 2400 | 2404 |
if (multi->locked_cn) |
| 2401 | 2405 |
free (multi->locked_cn); |
| 2402 | 2406 |
|
| ... | ... |
@@ -594,6 +594,11 @@ struct tls_multi |
| 594 | 594 |
char *locked_cn; |
| 595 | 595 |
|
| 596 | 596 |
#ifdef ENABLE_DEF_AUTH |
| 597 |
+ /* |
|
| 598 |
+ * An error message to send to client on AUTH_FAILED |
|
| 599 |
+ */ |
|
| 600 |
+ char *client_reason; |
|
| 601 |
+ |
|
| 597 | 602 |
/* Time of last call to tls_authentication_status */ |
| 598 | 603 |
time_t tas_last; |
| 599 | 604 |
#endif |
| ... | ... |
@@ -695,7 +700,7 @@ int tls_authentication_status (struct tls_multi *multi, const int latency); |
| 695 | 695 |
void tls_deauthenticate (struct tls_multi *multi); |
| 696 | 696 |
|
| 697 | 697 |
#ifdef MANAGEMENT_DEF_AUTH |
| 698 |
-bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth); |
|
| 698 |
+bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason); |
|
| 699 | 699 |
#endif |
| 700 | 700 |
|
| 701 | 701 |
/* |
| ... | ... |
@@ -738,6 +743,16 @@ tls_set_single_session (struct tls_multi *multi) |
| 738 | 738 |
multi->opt.single_session = true; |
| 739 | 739 |
} |
| 740 | 740 |
|
| 741 |
+static inline const char * |
|
| 742 |
+tls_client_reason (struct tls_multi *multi) |
|
| 743 |
+{
|
|
| 744 |
+#ifdef ENABLE_DEF_AUTH |
|
| 745 |
+ return multi->client_reason; |
|
| 746 |
+#else |
|
| 747 |
+ return NULL; |
|
| 748 |
+#endif |
|
| 749 |
+} |
|
| 750 |
+ |
|
| 741 | 751 |
#ifdef ENABLE_PF |
| 742 | 752 |
|
| 743 | 753 |
static inline bool |