#ifdef MANAGEMENT_DEF_AUTH
msg (M_CLIENT, "client-auth CID KID : Authenticate client-id/key-id CID/KID (MULTILINE)");
msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID");
- msg (M_CLIENT, "client-deny CID KID R : Deny auth client-id/key-id CID/KID with reason text R");
+ 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");
#ifdef MANAGEMENT_PF
msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)");
man->connection.in_extra_kid,
true,
NULL,
+ NULL,
man->connection.in_extra);
man->connection.in_extra = NULL;
if (status)
}
static void
-man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason)
+man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason, const char *client_reason)
{
unsigned long cid = 0;
unsigned int kid = 0;
kid,
false,
reason,
+ client_reason,
NULL);
if (status)
{
}
else if (streq (p[0], "client-deny"))
{
- if (man_need (man, p, 3, 0))
- man_client_deny (man, p[1], p[2], p[3]);
+ if (man_need (man, p, 3, MN_AT_LEAST))
+ man_client_deny (man, p[1], p[2], p[3], p[4]);
}
else if (streq (p[0], "client-auth-nt"))
{
const unsigned int mda_key_id,
const bool auth,
const char *reason,
+ const char *client_reason,
struct buffer_list *cc_config); /* ownership transferred */
#endif
#ifdef MANAGEMENT_PF
>PASSWORD:Verification Failed: 'Auth'
+ Example 5: The --auth-user-pass username/password failed,
+ and the server provided a custom client-reason-text string
+ using the client-deny server-side management interface command.
+
+ >PASSWORD:Verification Failed: 'custom server-generated string'
+
COMMAND -- forget-passwords
---------------------------
Deny a ">CLIENT:CONNECT" or ">CLIENT:REAUTH" request.
- client-deny {CID} {KID} "reason-text"
+ client-deny {CID} {KID} "reason-text" ["client-reason-text"]
CID,KID -- client ID and Key ID. See documentation for ">CLIENT:"
notification for more info.
request was denied. This message will be output to the OpenVPN log
file or syslog.
+client-reason-text: a message that will be sent to the client as
+part of the AUTH_FAILED message.
+
Note that client-deny denies a specific Key ID (pertaining to a
TLS renegotiation). A client-deny command issued in response to
an initial TLS key negotiation (notified by ">CLIENT:CONNECT") will
const unsigned int mda_key_id,
const bool auth,
const char *reason,
+ const char *client_reason,
struct buffer_list *cc_config) /* ownership transferred */
{
struct multi_context *m = (struct multi_context *) arg;
if (mi)
{
- ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth);
+ ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth, client_reason);
if (ret)
{
if (auth && !mi->connection_established_flag)
cc_config_owned = false;
}
if (!auth && reason)
- msg (D_MULTI_LOW, "MULTI: connection rejected: %s", reason);
+ msg (D_MULTI_LOW, "MULTI: connection rejected: %s, CLI:%s", reason, np(client_reason));
}
}
if (cc_config_owned && cc_config)
c->sig->signal_text = "auth-failure";
#ifdef ENABLE_MANAGEMENT
if (management)
- management_auth_failure (management, UP_TYPE_AUTH);
+ {
+ const char *reason = UP_TYPE_AUTH;
+ struct buffer buf = *buffer;
+ if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf))
+ reason = BSTR (&buf);
+ management_auth_failure (management, reason);
+ }
#endif
}
}
* Send auth failed message from server to client.
*/
void
-send_auth_failed (struct context *c)
+send_auth_failed (struct context *c, const char *client_reason)
{
+ struct gc_arena gc = gc_new ();
+ static const char auth_failed[] = "AUTH_FAILED";
+ size_t len;
+
schedule_exit (c, c->options.scheduled_exit_interval);
- send_control_channel_string (c, "AUTH_FAILED", D_PUSH);
+
+ len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
+ if (len > TLS_CHANNEL_BUF_SIZE)
+ len = TLS_CHANNEL_BUF_SIZE;
+
+ {
+ struct buffer buf = alloc_buf_gc (len, &gc);
+ buf_printf (&buf, auth_failed);
+ if (client_reason)
+ buf_printf (&buf, ",%s", client_reason);
+ send_control_channel_string (c, BSTR (&buf), D_PUSH);
+ }
+
+ gc_free (&gc);
}
#endif
{
if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED)
{
- send_auth_failed (c);
+ const char *client_reason = tls_client_reason (c->c2.tls_multi);
+ send_auth_failed (c, client_reason);
ret = PUSH_MSG_AUTH_FAILURE;
}
else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
void remove_iroutes_from_push_route_list (struct options *o);
-void send_auth_failed (struct context *c);
+void send_auth_failed (struct context *c, const char *client_reason);
#endif
#endif
#endif
#ifdef MANAGEMENT_DEF_AUTH
+static void
+man_def_auth_set_client_reason (struct tls_multi *multi, const char *client_reason)
+{
+ if (multi->client_reason)
+ {
+ free (multi->client_reason);
+ multi->client_reason = NULL;
+ }
+ if (client_reason && strlen (client_reason))
+ multi->client_reason = string_alloc (client_reason, NULL);
+}
+
static inline unsigned int
man_def_auth_test (const struct key_state *ks)
{
#ifdef MANAGEMENT_DEF_AUTH
bool
-tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth)
+tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason)
{
bool ret = false;
if (multi)
{
int i;
+ man_def_auth_set_client_reason (multi, client_reason);
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
ASSERT (multi);
+#ifdef MANAGEMENT_DEF_AUTH
+ man_def_auth_set_client_reason(multi, NULL);
+#endif
+
if (multi->locked_cn)
free (multi->locked_cn);
char *locked_cn;
#ifdef ENABLE_DEF_AUTH
+ /*
+ * An error message to send to client on AUTH_FAILED
+ */
+ char *client_reason;
+
/* Time of last call to tls_authentication_status */
time_t tas_last;
#endif
void tls_deauthenticate (struct tls_multi *multi);
#ifdef MANAGEMENT_DEF_AUTH
-bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth);
+bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason);
#endif
/*
multi->opt.single_session = true;
}
+static inline const char *
+tls_client_reason (struct tls_multi *multi)
+{
+#ifdef ENABLE_DEF_AUTH
+ return multi->client_reason;
+#else
+ return NULL;
+#endif
+}
+
#ifdef ENABLE_PF
static inline bool