Re: [Openvpn-devel] [PATCH v6] Implement deferred auth for scripts
Hi, On 07/04/2021 17:49, Arne Schwabe wrote: > This patch also refactors the if condition that checks the result of > the authentication since that has become quite unreadable. It renames > s1/s2 and extracts some parts of the condition into individual variables > to make the condition better understandle > > Patch v2: add refactoring of the if condition > Patch v4: fix documentation not mentioning method as 2nd line > Patch v5: fix deferred auth used by both plugin and script not working > Patch v6: Add missing async inotify for script deferred auth > > Signed-off-by: Arne Schwabe Very nice feature! deferred auth made easy! Thanks Arne :) > --- > Changes.rst | 10 +++ > doc/man-sections/script-options.rst | 14 +++- > src/openvpn/multi.c | 6 ++ > src/openvpn/ssl.c | 1 + > src/openvpn/ssl_common.h| 1 + > src/openvpn/ssl_verify.c| 105 > 6 files changed, 106 insertions(+), 31 deletions(-) > > diff --git a/Changes.rst b/Changes.rst > index 457dfc07e..9185b55f7 100644 > --- a/Changes.rst > +++ b/Changes.rst > @@ -30,6 +30,16 @@ TLS mode with self-signed certificates > become optional. This allows for small OpenVPN setups without setting up > a PKI with Easy-RSA or similar software. > > +Deferred auth support for scripts > +The ``--auth-user-pass-verify`` script supports now deferred > authentication. > + > +Pending auth support for plugins and scripts > +Both auth plugin and script can now signal pending authentication to > +the client when using deferred authentication. The new > ``client-crresponse`` > +script option and ``OPENVPN_PLUGIN_CLIENT_CRRESPONSE`` plugin function > can > +be used to parse a client response to a ``CR_TEXT`` two factor challenge. > + > +See ``sample/sample-scripts/totpauth.py`` for an example. > > Deprecated features > --- > diff --git a/doc/man-sections/script-options.rst > b/doc/man-sections/script-options.rst > index 03b3dd77b..22990f4f4 100644 > --- a/doc/man-sections/script-options.rst > +++ b/doc/man-sections/script-options.rst > @@ -90,7 +90,19 @@ SCRIPT HOOKS > >The script should examine the username and password, returning a success >exit code (:code:`0`) if the client's authentication request is to be > - accepted, or a failure code (:code:`1`) to reject the client. > + accepted, a failure code (:code:`1`) to reject the client, or a that typ0: "or a that" -> "or that" ? > + the authentication is deferred (:code:`2`). If the authentication is > + deferred, the script must fork/start a background or another non-blocking > + operation to continue the authentication in the background. When finshing > + the authentication, a :code:`1` or :code:`0` must be written to the > + file specified by the :code:`auth_control_file`. > + > + When deferred authentication is in use, the script can also request > + pending authentication by writing to the file specified by the > + :code:`auth_pending_file`. The first line must be the timeout in > + seconds, the required method on the second line (e.g. crtext) and > + third line must be the EXTRA as documented in the > + ``client-pending-auth`` section of `doc/management.txt`. > >This directive is designed to enable a plugin-style interface for >extending OpenVPN's authentication capabilities. > diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c > index 7c9500f3e..e5e466631 100644 > --- a/src/openvpn/multi.c > +++ b/src/openvpn/multi.c > @@ -2990,6 +2990,12 @@ multi_process_post(struct multi_context *m, struct > multi_instance *mi, const uns > add_inotify_file_watch(m, mi, m->top.c2.inotify_fd, > ks->plugin_auth.auth_control_file); > } > +if (ks && ks->script_auth.auth_control_file && was_unauthenticated > +&& (ks->authenticated == KS_AUTH_DEFERRED)) > +{ > +add_inotify_file_watch(m, mi, m->top.c2.inotify_fd, > + ks->script_auth.auth_control_file); > +} > #endif > > if (!IS_SIG(>context)) > diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c > index d8662d000..b27a78b3d 100644 > --- a/src/openvpn/ssl.c > +++ b/src/openvpn/ssl.c > @@ -994,6 +994,7 @@ key_state_free(struct key_state *ks, bool clear) > packet_id_free(>crypto_options.packet_id); > > key_state_rm_auth_control_files(>plugin_auth); > +key_state_rm_auth_control_files(>script_auth); > > if (clear) > { > diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h > index b2fa44e56..acb815955 100644 > --- a/src/openvpn/ssl_common.h > +++ b/src/openvpn/ssl_common.h > @@ -222,6 +222,7 @@ struct key_state > time_t acf_last_mod; > > struct auth_deferred_status plugin_auth; > +struct auth_deferred_status script_auth; > }; > > /** Control channel wrapping
[Openvpn-devel] [PATCH v6] Implement deferred auth for scripts
This patch also refactors the if condition that checks the result of the authentication since that has become quite unreadable. It renames s1/s2 and extracts some parts of the condition into individual variables to make the condition better understandle Patch v2: add refactoring of the if condition Patch v4: fix documentation not mentioning method as 2nd line Patch v5: fix deferred auth used by both plugin and script not working Patch v6: Add missing async inotify for script deferred auth Signed-off-by: Arne Schwabe --- Changes.rst | 10 +++ doc/man-sections/script-options.rst | 14 +++- src/openvpn/multi.c | 6 ++ src/openvpn/ssl.c | 1 + src/openvpn/ssl_common.h| 1 + src/openvpn/ssl_verify.c| 105 6 files changed, 106 insertions(+), 31 deletions(-) diff --git a/Changes.rst b/Changes.rst index 457dfc07e..9185b55f7 100644 --- a/Changes.rst +++ b/Changes.rst @@ -30,6 +30,16 @@ TLS mode with self-signed certificates become optional. This allows for small OpenVPN setups without setting up a PKI with Easy-RSA or similar software. +Deferred auth support for scripts +The ``--auth-user-pass-verify`` script supports now deferred authentication. + +Pending auth support for plugins and scripts +Both auth plugin and script can now signal pending authentication to +the client when using deferred authentication. The new ``client-crresponse`` +script option and ``OPENVPN_PLUGIN_CLIENT_CRRESPONSE`` plugin function can +be used to parse a client response to a ``CR_TEXT`` two factor challenge. + +See ``sample/sample-scripts/totpauth.py`` for an example. Deprecated features --- diff --git a/doc/man-sections/script-options.rst b/doc/man-sections/script-options.rst index 03b3dd77b..22990f4f4 100644 --- a/doc/man-sections/script-options.rst +++ b/doc/man-sections/script-options.rst @@ -90,7 +90,19 @@ SCRIPT HOOKS The script should examine the username and password, returning a success exit code (:code:`0`) if the client's authentication request is to be - accepted, or a failure code (:code:`1`) to reject the client. + accepted, a failure code (:code:`1`) to reject the client, or a that + the authentication is deferred (:code:`2`). If the authentication is + deferred, the script must fork/start a background or another non-blocking + operation to continue the authentication in the background. When finshing + the authentication, a :code:`1` or :code:`0` must be written to the + file specified by the :code:`auth_control_file`. + + When deferred authentication is in use, the script can also request + pending authentication by writing to the file specified by the + :code:`auth_pending_file`. The first line must be the timeout in + seconds, the required method on the second line (e.g. crtext) and + third line must be the EXTRA as documented in the + ``client-pending-auth`` section of `doc/management.txt`. This directive is designed to enable a plugin-style interface for extending OpenVPN's authentication capabilities. diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 7c9500f3e..e5e466631 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2990,6 +2990,12 @@ multi_process_post(struct multi_context *m, struct multi_instance *mi, const uns add_inotify_file_watch(m, mi, m->top.c2.inotify_fd, ks->plugin_auth.auth_control_file); } +if (ks && ks->script_auth.auth_control_file && was_unauthenticated +&& (ks->authenticated == KS_AUTH_DEFERRED)) +{ +add_inotify_file_watch(m, mi, m->top.c2.inotify_fd, + ks->script_auth.auth_control_file); +} #endif if (!IS_SIG(>context)) diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index d8662d000..b27a78b3d 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -994,6 +994,7 @@ key_state_free(struct key_state *ks, bool clear) packet_id_free(>crypto_options.packet_id); key_state_rm_auth_control_files(>plugin_auth); +key_state_rm_auth_control_files(>script_auth); if (clear) { diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index b2fa44e56..acb815955 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -222,6 +222,7 @@ struct key_state time_t acf_last_mod; struct auth_deferred_status plugin_auth; +struct auth_deferred_status script_auth; }; /** Control channel wrapping (--tls-auth/--tls-crypt) context */ diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 7608155cd..7c02d46ce 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -1102,20 +1102,25 @@ tls_authentication_status(struct tls_multi *multi, const int latency) } else { -unsigned int s1 =