@@ -1354,10 +1354,8 @@ tls_multi_free(struct tls_multi *multi, bool clear)
ASSERT(multi);
-#ifdef MANAGEMENT_DEF_AUTH
- man_def_auth_set_client_reason(multi, NULL);
+ set_client_reason(multi, NULL);
-#endif
#if P2MP_SERVER
free(multi->peer_info);
#endif
@@ -515,13 +515,13 @@ struct tls_multi
char *locked_cn;
char *locked_username;
struct cert_hash_set *locked_cert_hash_set;
-
-#ifdef ENABLE_DEF_AUTH
+
/*
* An error message to send to client on AUTH_FAILED
*/
char *client_reason;
+#ifdef ENABLE_DEF_AUTH
/* Time of last call to tls_authentication_status */
time_t tas_last;
#endif
@@ -837,21 +837,6 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
#endif
#ifdef MANAGEMENT_DEF_AUTH
-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))
- {
- /* FIXME: Last alloc will never be freed */
- multi->client_reason = string_alloc(client_reason, NULL);
- }
-}
-
static inline unsigned int
man_def_auth_test(const struct key_state *ks)
{
@@ -1055,7 +1040,7 @@ tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, con
if (multi)
{
int i;
- man_def_auth_set_client_reason(multi, client_reason);
+ set_client_reason(multi, client_reason);
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
@@ -1081,6 +1066,21 @@ tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, con
* this is the place to start.
*************************************************************************** */
+
+void
+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);
+ }
+}
+
/*
* Verify the user name and password using a script
*/
@@ -1166,7 +1166,7 @@ verify_user_pass_script(struct tls_session *session, const struct user_pass *up)
* Verify the username and password using a plugin
*/
static int
-verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up, const char *raw_username)
+verify_user_pass_plugin(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up, const char *raw_username)
{
int retval = OPENVPN_PLUGIN_FUNC_ERROR;
#ifdef PLUGIN_DEF_AUTH
@@ -1176,6 +1176,9 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up,
/* Is username defined? */
if ((session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL) || strlen(up->username))
{
+ struct plugin_return pr, prfetch;
+ plugin_return_init(&pr);
+
/* set username/password in private env space */
setenv_str(session->opt->es, "username", (raw_username ? raw_username : up->username));
setenv_str(session->opt->es, "password", up->password);
@@ -1197,7 +1200,23 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up,
#endif
/* call command */
- retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es);
+ retval = plugin_call(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, &pr, session->opt->es);
+
+ /* Fetch client reason */
+ plugin_return_get_column(&pr, &prfetch, "client_reason");
+ if (plugin_return_defined(&prfetch))
+ {
+ int i;
+ for (i = 0; i < prfetch.n; ++i)
+ {
+ if (prfetch.list[i] && prfetch.list[i]->value)
+ {
+ set_client_reason(multi, prfetch.list[i]->value);
+ }
+ }
+ }
+
+ plugin_return_free(&pr);
#ifdef PLUGIN_DEF_AUTH
/* purge auth control filename (and file itself) for non-deferred returns */
@@ -1378,7 +1397,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
#endif
if (plugin_defined(session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY))
{
- s1 = verify_user_pass_plugin(session, up, raw_username);
+ s1 = verify_user_pass_plugin(session, multi, up, raw_username);
}
if (session->opt->auth_user_pass_verify_script)
{
@@ -1462,7 +1481,16 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
if (multi->connection_established)
{
/* Notify the client */
- send_push_reply_auth_failed(multi, "SESSION:Auth failed");
+ const char *client_reason;
+ if (multi->client_reason != NULL)
+ {
+ client_reason = multi->client_reason;
+ }
+ else
+ {
+ client_reason = "SESSION:Auth failed";
+ }
+ send_push_reply_auth_failed(multi, client_reason);
}
msg(D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
@@ -171,6 +171,8 @@ tls_common_name_hash(const struct tls_multi *multi, const char **cn, uint32_t *c
#endif
+void set_client_reason(struct tls_multi *multi, const char *client_reason);
+
/**
* Verify the given username and password, using either an external script, a
* plugin, or the management interface.
@@ -225,19 +227,12 @@ struct x509_track
*/
#ifdef MANAGEMENT_DEF_AUTH
bool tls_authenticate_key(struct tls_multi *multi, const unsigned int mda_key_id, const bool auth, const char *client_reason);
-
-void man_def_auth_set_client_reason(struct tls_multi *multi, const char *client_reason);
-
#endif
static inline const char *
tls_client_reason(struct tls_multi *multi)
{
-#ifdef ENABLE_DEF_AUTH
return multi->client_reason;
-#else
- return NULL;
-#endif
}
/** Remove any X509_ env variables from env_set es */