(such as tls-verify, auth-user-pass-verify, or client-connect), then
every module and script must return success (:code:`0`) in order for the
connection to be authenticated.
+
+ **WARNING**:
+ Plug-ins may do deferred execution, meaning the plug-in will
+ return the control back to the main OpenVPN process and provide
+ the plug-in result later on via a different thread or process.
+ OpenVPN does **NOT** support multiple authentication plug-ins
+ **where more than one plugin** tries to do deferred authentication.
+ If this behaviour is detected, OpenVPN will shut down upon first
+ authentication.
const char **envp;
const int n = plugin_n(pl);
bool error = false;
- bool deferred = false;
+ bool deferred_auth_done = false;
setenv_del(es, "script_type");
envp = make_env_array(es, false, &gc);
break;
case OPENVPN_PLUGIN_FUNC_DEFERRED:
- deferred = true;
+ if ((type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
+ && deferred_auth_done)
+ {
+ /*
+ * Do not allow deferred auth if a deferred auth has
+ * already been started. This should allow a single
+ * deferred auth call to happen, with one or more
+ * auth calls with an instant authentication result.
+ *
+ * The plug-in API is not designed for multiple
+ * deferred authentications to happen, as the
+ * auth_control_file file will be shared across all
+ * the plug-ins.
+ *
+ * Since this is considered a critical configuration
+ * error, we bail out and exit the OpenVPN process.
+ */
+ error = true;
+ msg(M_FATAL,
+ "Exiting due to multiple authentication plug-ins "
+ "performing deferred authentication. Only one "
+ "authentication plug-in doing deferred auth is "
+ "allowed. Ignoring the result and stopping now, "
+ "the current authentication result is not to be "
+ "trusted.");
+ break;
+ }
+ deferred_auth_done = true;
break;
default:
{
return OPENVPN_PLUGIN_FUNC_ERROR;
}
- else if (deferred)
+ else if (deferred_auth_done)
{
return OPENVPN_PLUGIN_FUNC_DEFERRED;
}