Skip to contentSkip to conversation

New feature: --auth-gen-token

PATCH In review David Sommerseth 2 participants 14 messages Oct 28, 2016 – Oct 31, 2016

lore
Share & tools
lore
#0 lore raw

v2 cover New feature: --auth-gen-token

This is an updated patch-set of the --auth-gen-token feature. A couple of patches have already been sent to the previous mail thread [1], but I thought it would be easier to do the final ACK round when everything was collected into the same thread.

As the previous PATCH 1/5 got ACKed and is already applied to the master branch, this patch is excluded from this updated thread.

[1] <https://www.mail-archive.com/[email protected]/msg12701.html>

Quick recap
===========

This patch-set adds a new --auth-gen-token option with an optional lifetime argument. This allows existing authentication modules to let clients store a temporary authentication token for the session instead of caching passwords locally. This also have the benefit of allowing Two Factor Authentication (2FA) implementations to work properly with the --reneg-* options enabled without any further modifications. This feature can be used against any OpenVPN v2.3.0 client and newer.

What has changed since the first patche-set
===========================================

- Changes.rst have been updated
- man page have been improved
- Ensuring the feature has a consistent naming scheme in the code
- Ensuring the code don't exceed 80 chars line length
- Various improvements to comments

David Sommerseth (4):
auth-gen-token: Add --auth-gen-token option
auth-gen-token: Generate an auth-token per client
auth-gen-token: Push generated auth-tokens to the client
auth-gen-token: Authenticate generated auth-tokens when client
re-authenticates

 Changes.rst              | 15 ++++++++
 doc/openvpn.8            | 22 +++++++++++
 src/openvpn/init.c       |  2 +
 src/openvpn/misc.c       |  9 +++++
 src/openvpn/options.c    | 16 ++++++++
 src/openvpn/options.h    |  2 +
 src/openvpn/push.c       | 12 +++++-
 src/openvpn/ssl.c        |  6 +++
 src/openvpn/ssl_common.h | 13 +++++++
 src/openvpn/ssl_verify.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 193 insertions(+), 1 deletion(-)
Signature · 1 line
1.8.3.1
#1 lore raw

PATCH v2 1/4 auth-gen-token: Add --auth-gen-token option

This sets the flag if the OpenVPN server should create authentication tokens on-the-fly on successful --auth-user-pass-verify or --plugin with OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY processing.

If an OpenVPN server is running without this option, it should behave as before. Next patches will implement the auth-token generation and passing it on to the clients.

The --auth-gen-token can be given an optional integer argument which defines the lifetime of generated tokens. The lifetime argument must be given in number of seconds.

v2 - Update Changes.rst
- Improve man page in regards to lifetime argument
- Rename struct member auth_generate_token to auth_token_generate to have a consistent naming scheme

---
 Changes.rst              | 15 +++++++++++++++
 doc/openvpn.8            | 22 ++++++++++++++++++++++
 src/openvpn/init.c       |  2 ++
 src/openvpn/options.c    | 16 ++++++++++++++++
 src/openvpn/options.h    |  2 ++
 src/openvpn/ssl_common.h |  3 +++
 6 files changed, 60 insertions(+)
Changes.rst +15 -0
index 0118e78..8fd5859 100644
@@ -79,6 +79,21 @@ Windows version
     Windows version is detected, logged and possibly signalled to server
     (IV_PLAT_VER=<nn> if ``--push-peer-info`` is set on client)
 
+Authentication tokens
+    In situations where it is not suitable to save users passwords on the client
+    OpenVPN have since v2.3 had support for --auth-token.  This option is
+    pushed from the server to the client with a token value to be used instead
+    of the users password.  For this to work, the authentication plug-in would
+    need to implement this support as well.  In OpenVPN 2.4 --auth-gen-token
+    is introduced, which will allow the OpenVPN server to generate a random
+    token and push it to the client without any changes to the authentication
+    modules.  When the clients need to re-authenticate the OpenVPN server will
+    instead of sending the re-authentication request to the authentication
+    module do the authentication internally.  This feature is especially
+    useful in configurations which adds One Time Password (OTP) authentication
+    schemes, as this allows the tunnel to be renegotiated regularly without
+    any need to supply new OTP codes.
+
 keying-material-exporter
     Keying Material Exporter [RFC-5705] allow additional keying material to be
     derived from existing TLS channel.
doc/openvpn.8 +22 -0
index 0ac8184..e73517a 100644
@@ -3583,6 +3583,28 @@ For a sample script that performs PAM authentication, see
 in the OpenVPN source distribution.
 .\"*********************************************************
 .TP
+.B \-\-auth\-gen\-token [lifetime]
+After successful user/password authentication, the OpenVPN
+server will with this option generate a temporary
+authentication token and push that to client.  On the following
+renegotiations, the OpenVPN client will pass this token instead
+of the users password.  On the server side the server will do
+the token authentication internally and it will NOT do any
+additional authentications against configured external
+user/password authentication mechanisms.
+
+The
+.B lifetime
+argument defines how long the generated token is valid.  The
+lifetime is defined in seconds.  If lifetime is not set
+or it is set to 0, the token will never expire.
+
+This feature is useful for environments which is configured
+to use One Time Passwords (OTP) as part of the user/password
+authentications and that authentication mechanism does not
+implement any auth-token support.
+.\"*********************************************************
+.TP
 .B \-\-opt\-verify
 Clients that connect with options that are incompatible
 with those of the server will be disconnected.
src/openvpn/init.c +2 -0
index 73f8c6d..3ec3b18 100644
@@ -2421,6 +2421,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
   if (options->ccd_exclusive)
     to.client_config_dir_exclusive = options->client_config_dir;
   to.auth_user_pass_file = options->auth_user_pass_file;
+  to.auth_token_generate = options->auth_token_generate;
+  to.auth_token_lifetime = options->auth_token_lifetime;
 #endif
 
   to.x509_track = options->x509_track;
src/openvpn/options.c +16 -0
index 996c26e..f88e94d 100644
@@ -444,6 +444,11 @@ static const char usage_message[] =
   "                  run command cmd to verify.  If method='via-env', pass\n"
   "                  user/pass via environment, if method='via-file', pass\n"
   "                  user/pass via temporary file.\n"
+  "--auth-gen-token  [lifetime] Generate a random authentication token which is pushed\n"
+  "                  to each client, replacing the password.  Usefull when\n"
+  "                  OTP based two-factor auth mechanisms are in use and\n"
+  "                  --reneg-* options are enabled. Optionally a lifetime in seconds\n"
+  "                  for generated tokens can be set.\n"
   "--opt-verify    : Clients that connect with options that are incompatible\n"
   "                  with those of the server will be disconnected.\n"
   "--auth-user-pass-optional : Allow connections by clients that don't\n"
@@ -864,6 +869,7 @@ init_options (struct options *o, const bool init_gc)
 #ifdef ENABLE_PKCS11
   o->pkcs11_pin_cache_period = -1;
 #endif			/* ENABLE_PKCS11 */
+  o->auth_token_generate = false;
 
 /* tmp is only used in P2MP server context */
 #if P2MP_SERVER
@@ -1264,6 +1270,8 @@ show_p2mp_parms (const struct options *o)
   SHOW_INT (max_routes_per_client);
   SHOW_STR (auth_user_pass_verify_script);
   SHOW_BOOL (auth_user_pass_verify_script_via_file);
+  SHOW_BOOL (auth_token_generate);
+  SHOW_INT (auth_token_lifetime);
 #if PORT_SHARE
   SHOW_STR (port_share_host);
   SHOW_STR (port_share_port);
@@ -2186,6 +2194,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
              "tcp-nodelay in the server configuration instead.");
       if (options->auth_user_pass_verify_script)
 	msg (M_USAGE, "--auth-user-pass-verify requires --mode server");
+      if (options->auth_token_generate)
+	msg (M_USAGE, "--auth-gen-token requires --mode server");
 #if PORT_SHARE
       if (options->port_share_host || options->port_share_port)
 	msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
@@ -5965,6 +5975,12 @@ add_option (struct options *options,
 		       &options->auth_user_pass_verify_script,
 		       p[1], "auth-user-pass-verify", true);
     }
+  else if (streq (p[0], "auth-gen-token"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->auth_token_generate = true;
+      options->auth_token_lifetime = p[1] ? positive_atoi (p[1]) : 0;
+    }
   else if (streq (p[0], "client-connect") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_SCRIPT);
src/openvpn/options.h +2 -0
index b7453a0..2f91a52 100644
@@ -442,6 +442,8 @@ struct options
 
   const char *auth_user_pass_verify_script;
   bool auth_user_pass_verify_script_via_file;
+  bool auth_token_generate;
+  unsigned int auth_token_lifetime;
 #if PORT_SHARE
   char *port_share_host;
   char *port_share_port;
src/openvpn/ssl_common.h +3 -0
index eb2ad6f..50c4a9c 100644
@@ -289,6 +289,9 @@ struct tls_options
   bool auth_user_pass_verify_script_via_file;
   const char *tmp_dir;
   const char *auth_user_pass_file;
+  bool auth_token_generate;     /**< Generate auth-tokens on successful user/pass auth,
+                                 *   set via options->auth_token_generate. */
+  unsigned int auth_token_lifetime;
 
   /* use the client-config-dir as a positive authenticator */
   const char *client_config_dir_exclusive;
Signature · 1 line
1.8.3.1
#2 lore raw

Re: [Openvpn-devel] [PATCH v2 1/4] auth-gen-token: Add --auth-gen-token option

Quoted 172 lines · David Sommerseth

This sets the flag if the OpenVPN server should create authentication tokens on-the-fly on successful --auth-user-pass-verify or --plugin with OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY processing.

If an OpenVPN server is running without this option, it should behave as before. Next patches will implement the auth-token generation and passing it on to the clients.

The --auth-gen-token can be given an optional integer argument which defines the lifetime of generated tokens. The lifetime argument must be given in number of seconds.

v2 - Update Changes.rst
- Improve man page in regards to lifetime argument
- Rename struct member auth_generate_token to auth_token_generate to have a consistent naming scheme

---
 Changes.rst              | 15 +++++++++++++++
 doc/openvpn.8            | 22 ++++++++++++++++++++++
 src/openvpn/init.c       |  2 ++
 src/openvpn/options.c    | 16 ++++++++++++++++
 src/openvpn/options.h    |  2 ++
 src/openvpn/ssl_common.h |  3 +++
 6 files changed, 60 insertions(+)
Changes.rst +15 -0
index 0118e78..8fd5859 100644
@@ -79,6 +79,21 @@ Windows version
     Windows version is detected, logged and possibly signalled to server
     (IV_PLAT_VER=<nn> if ``--push-peer-info`` is set on client)
 
+Authentication tokens
+    In situations where it is not suitable to save users passwords on the client
+    OpenVPN have since v2.3 had support for --auth-token.  This option is
+    pushed from the server to the client with a token value to be used instead
+    of the users password.  For this to work, the authentication plug-in would
+    need to implement this support as well.  In OpenVPN 2.4 --auth-gen-token
+    is introduced, which will allow the OpenVPN server to generate a random
+    token and push it to the client without any changes to the authentication
+    modules.  When the clients need to re-authenticate the OpenVPN server will
+    instead of sending the re-authentication request to the authentication
+    module do the authentication internally.  This feature is especially
+    useful in configurations which adds One Time Password (OTP) authentication
+    schemes, as this allows the tunnel to be renegotiated regularly without
+    any need to supply new OTP codes.
+
 keying-material-exporter
     Keying Material Exporter [RFC-5705] allow additional keying material to be
     derived from existing TLS channel.
doc/openvpn.8 +22 -0
index 0ac8184..e73517a 100644
@@ -3583,6 +3583,28 @@ For a sample script that performs PAM authentication, see
 in the OpenVPN source distribution.
 .\"*********************************************************
 .TP
+.B \-\-auth\-gen\-token [lifetime]
+After successful user/password authentication, the OpenVPN
+server will with this option generate a temporary
+authentication token and push that to client.  On the following
+renegotiations, the OpenVPN client will pass this token instead
+of the users password.  On the server side the server will do
+the token authentication internally and it will NOT do any
+additional authentications against configured external
+user/password authentication mechanisms.
+
+The
+.B lifetime
+argument defines how long the generated token is valid.  The
+lifetime is defined in seconds.  If lifetime is not set
+or it is set to 0, the token will never expire.
+
+This feature is useful for environments which is configured
+to use One Time Passwords (OTP) as part of the user/password
+authentications and that authentication mechanism does not
+implement any auth-token support.
+.\"*********************************************************
+.TP
 .B \-\-opt\-verify
 Clients that connect with options that are incompatible
 with those of the server will be disconnected.
src/openvpn/init.c +2 -0
index 73f8c6d..3ec3b18 100644
@@ -2421,6 +2421,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
   if (options->ccd_exclusive)
     to.client_config_dir_exclusive = options->client_config_dir;
   to.auth_user_pass_file = options->auth_user_pass_file;
+  to.auth_token_generate = options->auth_token_generate;
+  to.auth_token_lifetime = options->auth_token_lifetime;
 #endif
 
   to.x509_track = options->x509_track;
src/openvpn/options.c +16 -0
index 996c26e..f88e94d 100644
@@ -444,6 +444,11 @@ static const char usage_message[] =
   "                  run command cmd to verify.  If method='via-env', pass\n"
   "                  user/pass via environment, if method='via-file', pass\n"
   "                  user/pass via temporary file.\n"
+  "--auth-gen-token  [lifetime] Generate a random authentication token which is pushed\n"
+  "                  to each client, replacing the password.  Usefull when\n"
+  "                  OTP based two-factor auth mechanisms are in use and\n"
+  "                  --reneg-* options are enabled. Optionally a lifetime in seconds\n"
+  "                  for generated tokens can be set.\n"
   "--opt-verify    : Clients that connect with options that are incompatible\n"
   "                  with those of the server will be disconnected.\n"
   "--auth-user-pass-optional : Allow connections by clients that don't\n"
@@ -864,6 +869,7 @@ init_options (struct options *o, const bool init_gc)
 #ifdef ENABLE_PKCS11
   o->pkcs11_pin_cache_period = -1;
 #endif                 /* ENABLE_PKCS11 */
+  o->auth_token_generate = false;
 
 /* tmp is only used in P2MP server context */
 #if P2MP_SERVER
@@ -1264,6 +1270,8 @@ show_p2mp_parms (const struct options *o)
   SHOW_INT (max_routes_per_client);
   SHOW_STR (auth_user_pass_verify_script);
   SHOW_BOOL (auth_user_pass_verify_script_via_file);
+  SHOW_BOOL (auth_token_generate);
+  SHOW_INT (auth_token_lifetime);
 #if PORT_SHARE
   SHOW_STR (port_share_host);
   SHOW_STR (port_share_port);
@@ -2186,6 +2194,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
              "tcp-nodelay in the server configuration instead.");
       if (options->auth_user_pass_verify_script)
        msg (M_USAGE, "--auth-user-pass-verify requires --mode server");
+      if (options->auth_token_generate)
+       msg (M_USAGE, "--auth-gen-token requires --mode server");
 #if PORT_SHARE
       if (options->port_share_host || options->port_share_port)
        msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
@@ -5965,6 +5975,12 @@ add_option (struct options *options,
                       &options->auth_user_pass_verify_script,
                       p[1], "auth-user-pass-verify", true);
     }
+  else if (streq (p[0], "auth-gen-token"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->auth_token_generate = true;
+      options->auth_token_lifetime = p[1] ? positive_atoi (p[1]) : 0;
+    }
   else if (streq (p[0], "client-connect") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_SCRIPT);
src/openvpn/options.h +2 -0
index b7453a0..2f91a52 100644
@@ -442,6 +442,8 @@ struct options
 
   const char *auth_user_pass_verify_script;
   bool auth_user_pass_verify_script_via_file;
+  bool auth_token_generate;
+  unsigned int auth_token_lifetime;
 #if PORT_SHARE
   char *port_share_host;
   char *port_share_port;
src/openvpn/ssl_common.h +0 -0
index eb2ad6f..50c4a9c 100644

src/openvpn/ssl_common.h struct tls_options · line 297

Quoted 9 lines
src/openvpn/ssl_common.h +3 -0
@@ -289,6 +289,9 @@ struct tls_options
   bool auth_user_pass_verify_script_via_file;
   const char *tmp_dir;
   const char *auth_user_pass_file;
+  bool auth_token_generate;     /**< Generate auth-tokens on successful user/pass auth,
+                                 *   set via options->auth_token_generate. */
+  unsigned int auth_token_lifetime;
 
   /* use the client-config-dir as a positive authenticator */
   const char *client_config_dir_exclusive;

ACK - all my previous nagging points are resolved now.

-Steffan

#3 lore raw

Re: [Openvpn-devel] [PATCH applied] auth-gen-token: Add --auth-gen-token option

In reply to David Sommerseth

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Your patch has been applied to the master branch.

commit 58066d04036bf29107f67ca38c6e964ec11f9dfd

Author: David Sommerseth
Date:   Fri Oct 28 21:48:40 2016 +0200
     auth-gen-token: Add --auth-gen-token option

     Signed-off-by: David Sommerseth <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg12825.html

- --
kind regards,

David Sommerseth

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJYFyWOAAoJEIbPlEyWcf3yqgwP/3YOTkCnYq6ip1Ax/wXcH/43 BfPY5q1HaOj1m7yGGdz0SgU9nUueN70px6qm2QSSJl87zP3buBJnd/5vYvyeXn/W CIZgAW2zosFdWEOLQruXIr9SR5i5VvZcfio1aTM6uF3i8KY0bj7KODh2/g744UXn fypjs97NUj6RindYV7oOA44UFKcwkYoxuVD1jfqZPHhyhMh+qyKaoC1FfN8S1Mzz 8eGFNlEnuvhiSeus2UYCU68qm+KnvLFP/0Eyb0cTAfkMXDuBSJxehaammcu+Kzj5 HiPrSRank/rnbKn28dZEjotn3XLezANlmtDB0NeoEg+ZqO7iIb/m5EzFKPPyMRza tnkWmDVc2urjKnYQU+aayJZapB0DxHGUIa1vua+Fl2aRhDo3XNNTweE5UNODznmF 0owg4CECkrs2g0FYC/mv6XXREm54tK/Q8kQtuTgs+n4oRDrCtu4g8wAX857CdnJH +UCDZAcQA0qGnHRiEkXzTb1qGLysRFZLEunDPN7fBxL7M2FhXR7Kx59/wrQePhTX ViqkIflR00gWJR4b6nZBUKXnfsT9k6+1wKqmrKI6jYzXYBi5HNS8TsJyhKfh6+rE 5mBlrJsCNTwMctatLNy8EOe80Q1aMZqwr0N+8zUKAqdOv2B/AIWixnsQfIGt/XWm Dpovhe4bBlJpY3XPxun3
=bd8d
-----END PGP SIGNATURE-----

#4 lore raw

PATCH v2 1/4 auth-gen-token: Add --auth-gen-token option

In reply to David Sommerseth

This sets the flag if the OpenVPN server should create authentication tokens on-the-fly on successful --auth-user-pass-verify or --plugin with OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY processing.

If an OpenVPN server is running without this option, it should behave as before. Next patches will implement the auth-token generation and passing it on to the clients.

The --auth-gen-token can be given an optional integer argument which defines the lifetime of generated tokens. The lifetime argument must be given in number of seconds.

v2 - Update Changes.rst
- Improve man page in regards to lifetime argument
- Rename struct member auth_generate_token to auth_token_generate to have a consistent naming scheme

---
 Changes.rst              | 15 +++++++++++++++
 doc/openvpn.8            | 22 ++++++++++++++++++++++
 src/openvpn/init.c       |  2 ++
 src/openvpn/options.c    | 16 ++++++++++++++++
 src/openvpn/options.h    |  2 ++
 src/openvpn/ssl_common.h |  3 +++
 6 files changed, 60 insertions(+)
Changes.rst +15 -0
index 0118e78..8fd5859 100644
@@ -79,6 +79,21 @@ Windows version
     Windows version is detected, logged and possibly signalled to server
     (IV_PLAT_VER=<nn> if ``--push-peer-info`` is set on client)
 
+Authentication tokens
+    In situations where it is not suitable to save users passwords on the client
+    OpenVPN have since v2.3 had support for --auth-token.  This option is
+    pushed from the server to the client with a token value to be used instead
+    of the users password.  For this to work, the authentication plug-in would
+    need to implement this support as well.  In OpenVPN 2.4 --auth-gen-token
+    is introduced, which will allow the OpenVPN server to generate a random
+    token and push it to the client without any changes to the authentication
+    modules.  When the clients need to re-authenticate the OpenVPN server will
+    instead of sending the re-authentication request to the authentication
+    module do the authentication internally.  This feature is especially
+    useful in configurations which adds One Time Password (OTP) authentication
+    schemes, as this allows the tunnel to be renegotiated regularly without
+    any need to supply new OTP codes.
+
 keying-material-exporter
     Keying Material Exporter [RFC-5705] allow additional keying material to be
     derived from existing TLS channel.
doc/openvpn.8 +22 -0
index 0ac8184..e73517a 100644
@@ -3583,6 +3583,28 @@ For a sample script that performs PAM authentication, see
 in the OpenVPN source distribution.
 .\"*********************************************************
 .TP
+.B \-\-auth\-gen\-token [lifetime]
+After successful user/password authentication, the OpenVPN
+server will with this option generate a temporary
+authentication token and push that to client.  On the following
+renegotiations, the OpenVPN client will pass this token instead
+of the users password.  On the server side the server will do
+the token authentication internally and it will NOT do any
+additional authentications against configured external
+user/password authentication mechanisms.
+
+The
+.B lifetime
+argument defines how long the generated token is valid.  The
+lifetime is defined in seconds.  If lifetime is not set
+or it is set to 0, the token will never expire.
+
+This feature is useful for environments which is configured
+to use One Time Passwords (OTP) as part of the user/password
+authentications and that authentication mechanism does not
+implement any auth-token support.
+.\"*********************************************************
+.TP
 .B \-\-opt\-verify
 Clients that connect with options that are incompatible
 with those of the server will be disconnected.
src/openvpn/init.c +2 -0
index 73f8c6d..3ec3b18 100644
@@ -2421,6 +2421,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
   if (options->ccd_exclusive)
     to.client_config_dir_exclusive = options->client_config_dir;
   to.auth_user_pass_file = options->auth_user_pass_file;
+  to.auth_token_generate = options->auth_token_generate;
+  to.auth_token_lifetime = options->auth_token_lifetime;
 #endif
 
   to.x509_track = options->x509_track;
src/openvpn/options.c +16 -0
index 996c26e..f88e94d 100644
@@ -444,6 +444,11 @@ static const char usage_message[] =
   "                  run command cmd to verify.  If method='via-env', pass\n"
   "                  user/pass via environment, if method='via-file', pass\n"
   "                  user/pass via temporary file.\n"
+  "--auth-gen-token  [lifetime] Generate a random authentication token which is pushed\n"
+  "                  to each client, replacing the password.  Usefull when\n"
+  "                  OTP based two-factor auth mechanisms are in use and\n"
+  "                  --reneg-* options are enabled. Optionally a lifetime in seconds\n"
+  "                  for generated tokens can be set.\n"
   "--opt-verify    : Clients that connect with options that are incompatible\n"
   "                  with those of the server will be disconnected.\n"
   "--auth-user-pass-optional : Allow connections by clients that don't\n"
@@ -864,6 +869,7 @@ init_options (struct options *o, const bool init_gc)
 #ifdef ENABLE_PKCS11
   o->pkcs11_pin_cache_period = -1;
 #endif			/* ENABLE_PKCS11 */
+  o->auth_token_generate = false;
 
 /* tmp is only used in P2MP server context */
 #if P2MP_SERVER
@@ -1264,6 +1270,8 @@ show_p2mp_parms (const struct options *o)
   SHOW_INT (max_routes_per_client);
   SHOW_STR (auth_user_pass_verify_script);
   SHOW_BOOL (auth_user_pass_verify_script_via_file);
+  SHOW_BOOL (auth_token_generate);
+  SHOW_INT (auth_token_lifetime);
 #if PORT_SHARE
   SHOW_STR (port_share_host);
   SHOW_STR (port_share_port);
@@ -2186,6 +2194,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
              "tcp-nodelay in the server configuration instead.");
       if (options->auth_user_pass_verify_script)
 	msg (M_USAGE, "--auth-user-pass-verify requires --mode server");
+      if (options->auth_token_generate)
+	msg (M_USAGE, "--auth-gen-token requires --mode server");
 #if PORT_SHARE
       if (options->port_share_host || options->port_share_port)
 	msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
@@ -5965,6 +5975,12 @@ add_option (struct options *options,
 		       &options->auth_user_pass_verify_script,
 		       p[1], "auth-user-pass-verify", true);
     }
+  else if (streq (p[0], "auth-gen-token"))
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->auth_token_generate = true;
+      options->auth_token_lifetime = p[1] ? positive_atoi (p[1]) : 0;
+    }
   else if (streq (p[0], "client-connect") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_SCRIPT);
src/openvpn/options.h +2 -0
index b7453a0..2f91a52 100644
@@ -442,6 +442,8 @@ struct options
 
   const char *auth_user_pass_verify_script;
   bool auth_user_pass_verify_script_via_file;
+  bool auth_token_generate;
+  unsigned int auth_token_lifetime;
 #if PORT_SHARE
   char *port_share_host;
   char *port_share_port;
src/openvpn/ssl_common.h +3 -0
index eb2ad6f..50c4a9c 100644
@@ -289,6 +289,9 @@ struct tls_options
   bool auth_user_pass_verify_script_via_file;
   const char *tmp_dir;
   const char *auth_user_pass_file;
+  bool auth_token_generate;     /**< Generate auth-tokens on successful user/pass auth,
+                                 *   set via options->auth_token_generate. */
+  unsigned int auth_token_lifetime;
 
   /* use the client-config-dir as a positive authenticator */
   const char *client_config_dir_exclusive;
Signature · 1 line
1.8.3.1
#5 lore raw

PATCH v2 2/4 auth-gen-token: Generate an auth-token per client

In reply to David Sommerseth

When --auth-gen-token is used a random token key is generated for each client after a successful user/password authentication. This token is expected to be returned in the password field on the following authentications.

The token is 256 bits long and BASE64 encoded before it is stored.

v2 - Fix Doxygen comment typo
- Don't exceed 80 chars line length

---
 src/openvpn/ssl.c        |  6 ++++++
 src/openvpn/ssl_common.h |  8 ++++++++
 src/openvpn/ssl_verify.c | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
src/openvpn/ssl.c +6 -0
index cbe925f..4a0cd6f 100644
@@ -1194,6 +1194,12 @@ tls_multi_free (struct tls_multi *multi, bool clear)
 
   cert_hash_free (multi->locked_cert_hash_set);
 
+  if (multi->auth_token)
+    {
+      memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+      free (multi->auth_token);
+    }
+
   for (i = 0; i < TM_SIZE; ++i)
     tls_session_free (&multi->session[i], false);
 
src/openvpn/ssl_common.h +8 -0
index 50c4a9c..9b63a12 100644
@@ -351,6 +351,9 @@ struct tls_options
 /** @} name Index of key_state objects within a tls_session structure */
 /** @} addtogroup control_processor */
 
+#define AUTH_TOKEN_SIZE 32      /**< Size of server side generated auth tokens.
+                                 *   32 bytes == 256 bits
+                                 */
 
 /**
  * Security parameter state of a single session within a VPN tunnel.
@@ -525,6 +528,11 @@ struct tls_multi
   uint32_t peer_id;
   bool use_peer_id;
 
+  char *auth_token;      /**< If server sends a generated auth-token,
+                          *   this is the token to use for future
+                          *   user/pass authentications in this session.
+                          */
+  time_t auth_token_tstamp; /**< timestamp of the generated token */
   /*
    * Our session objects.
    */
src/openvpn/ssl_verify.c +39 -0
index d0c22b8..0ac5689 100644
@@ -39,6 +39,8 @@
 
 #include "misc.h"
 #include "manage.h"
+#include "otime.h"
+#include "base64.h"
 #include "ssl_verify.h"
 #include "ssl_verify_backend.h"
 
@@ -1174,6 +1176,43 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
       if (man_def_auth != KMDA_UNDEF)
 	ks->auth_deferred = true;
 #endif
+
+      if ((session->opt->auth_token_generate) && (NULL == multi->auth_token))
+	{
+	  /* Server is configured with --auth-gen-token but no token has yet
+	   * been generated for this client.  Generate one and save it.
+	   */
+	  uint8_t tok[AUTH_TOKEN_SIZE];
+
+	  if (!rand_bytes(tok, AUTH_TOKEN_SIZE))
+	    {
+	      msg( M_FATAL, "Failed to get enough randomness for "
+                   "authentication token");
+	    }
+
+	  /* The token should be longer than the input when
+           * being base64 encoded
+           */
+	  if( openvpn_base64_encode(tok, AUTH_TOKEN_SIZE,
+                                    &multi->auth_token) < AUTH_TOKEN_SIZE)
+	    {
+	      msg(D_TLS_ERRORS, "BASE64 encoding of token failed. "
+                  "No auth-token will be activated now");
+	      if (multi->auth_token)
+		{
+		  memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+		  free (multi->auth_token);
+		  multi->auth_token = NULL;
+		}
+	    }
+	  else
+	    {
+	      multi->auth_token_tstamp = now;
+	      dmsg (D_SHOW_KEYS, "Generated token for client: %s",
+                    multi->auth_token);
+	    }
+	}
+
       if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
 	set_common_name (session, up->username);
 #ifdef ENABLE_DEF_AUTH
Signature · 1 line
1.8.3.1
#6 lore raw

Re: [Openvpn-devel] [PATCH v2 2/4] auth-gen-token: Generate an auth-token per client

Quoted 107 lines · David Sommerseth

When --auth-gen-token is used a random token key is generated for each client after a successful user/password authentication. This token is expected to be returned in the password field on the following authentications.

The token is 256 bits long and BASE64 encoded before it is stored.

v2 - Fix Doxygen comment typo
- Don't exceed 80 chars line length

---
 src/openvpn/ssl.c        |  6 ++++++
 src/openvpn/ssl_common.h |  8 ++++++++
 src/openvpn/ssl_verify.c | 39 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
src/openvpn/ssl.c +6 -0
index cbe925f..4a0cd6f 100644
@@ -1194,6 +1194,12 @@ tls_multi_free (struct tls_multi *multi, bool clear)
 
   cert_hash_free (multi->locked_cert_hash_set);
 
+  if (multi->auth_token)
+    {
+      memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+      free (multi->auth_token);
+    }
+
   for (i = 0; i < TM_SIZE; ++i)
     tls_session_free (&multi->session[i], false);
 
src/openvpn/ssl_common.h +8 -0
index 50c4a9c..9b63a12 100644
@@ -351,6 +351,9 @@ struct tls_options
 /** @} name Index of key_state objects within a tls_session structure */
 /** @} addtogroup control_processor */
 
+#define AUTH_TOKEN_SIZE 32      /**< Size of server side generated auth tokens.
+                                 *   32 bytes == 256 bits
+                                 */
 
 /**
  * Security parameter state of a single session within a VPN tunnel.
@@ -525,6 +528,11 @@ struct tls_multi
   uint32_t peer_id;
   bool use_peer_id;
 
+  char *auth_token;      /**< If server sends a generated auth-token,
+                          *   this is the token to use for future
+                          *   user/pass authentications in this session.
+                          */
+  time_t auth_token_tstamp; /**< timestamp of the generated token */
   /*
    * Our session objects.
    */
src/openvpn/ssl_verify.c +32 -0
index d0c22b8..0ac5689 100644
@@ -39,6 +39,8 @@
 
 #include "misc.h"
 #include "manage.h"
+#include "otime.h"
+#include "base64.h"
 #include "ssl_verify.h"
 #include "ssl_verify_backend.h"
 
@@ -1174,6 +1176,43 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
       if (man_def_auth != KMDA_UNDEF)
        ks->auth_deferred = true;
 #endif
+
+      if ((session->opt->auth_token_generate) && (NULL == multi->auth_token))
+       {
+         /* Server is configured with --auth-gen-token but no token has yet
+          * been generated for this client.  Generate one and save it.
+          */
+         uint8_t tok[AUTH_TOKEN_SIZE];
+
+         if (!rand_bytes(tok, AUTH_TOKEN_SIZE))
+           {
+             msg( M_FATAL, "Failed to get enough randomness for "
+                   "authentication token");
+           }
+
+         /* The token should be longer than the input when
+           * being base64 encoded
+           */
+         if( openvpn_base64_encode(tok, AUTH_TOKEN_SIZE,
+                                    &multi->auth_token) < AUTH_TOKEN_SIZE)
+           {
+             msg(D_TLS_ERRORS, "BASE64 encoding of token failed. "
+                  "No auth-token will be activated now");
+             if (multi->auth_token)
+               {
+                 memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+                 free (multi->auth_token);
+                 multi->auth_token = NULL;
+               }
+           }
+         else

src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1218

Quoted 10 lines
src/openvpn/ssl_verify.c +7 -0
+           {
+             multi->auth_token_tstamp = now;
+             dmsg (D_SHOW_KEYS, "Generated token for client: %s",
+                    multi->auth_token);
+           }
+       }
+
       if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
        set_common_name (session, up->username);
 #ifdef ENABLE_DEF_AUTH

ACK - all my previous nagging points are resolved now.

-Steffan

#7 lore raw

Re: [Openvpn-devel] [PATCH applied] auth-gen-token: Generate an auth-token per client

In reply to David Sommerseth

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Your patch has been applied to the master branch.

commit 270dc91164013eb7ace34d7b098fa11a97aef847

Author: David Sommerseth
Date:   Fri Oct 28 21:48:42 2016 +0200
     auth-gen-token: Generate an auth-token per client

     Signed-off-by: David Sommerseth <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg12820.html

- --
kind regards,

David Sommerseth

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJYFyWpAAoJEIbPlEyWcf3yRVAQAIyfTA0RHdD/4Fo0ylIpuByL dE3Flhyfo8ebXSjmrVaI68hFxo+UztdVSfrd/3VsobjSyzbYo200fINOdoZF9pUe EQ8da0Fn26URFdD26h47vgpyO1McK1kY3S7bhbn/uCi1b89eZNbb1dnKTSf927AP 4zJFl8A1I25taDMh2qsq7rl2ydi1NcT2sT1m7tnvHlaGKRvJpnFcaMdzgiwSsYoq o6Ltcy+neAqLgt7fpa1p/nLJaYXi19W7RekHIWkQGexoe990pWzdLDYTZVGgjRIa zwQ5UvZb8ZpmNvpy2LSadejuTMhhul5Q5+rE/wHiZTTUGEiOsoupIIuE6MNceeXu +j485smCYUBCATocgHa0XpOQ75fuNKl15PghitjOpCpIcfStsXhetwSlxjR+aNsS U9Dgg2m4n20CDNLc8ez2OUQoN+W33OEbn0hOmz02Iy+Z1ezNNsPCmyPaapVBPJ45 1aToU8DQeyfwUz73ynhLn/u1WqetG/H8H/5HYvPDVC8zxKfKe7iMiylEN6s/2A5n DoV3j4S0I9TpYYC10ncTXBMhgbKRR1jM2v63OTHw19eFA09P/jKqi8z6+mnBO0FX acmLflI4R9drFO/rwS8X5FfTdSBT9JjjnsBPH1/Xb4nbbbAdggVqxKBBujsogMdk LcDiHhxSCH6b6RWfj7Ry
=fPuy
-----END PGP SIGNATURE-----

#8 lore raw

PATCH v2 3/4 auth-gen-token: Push generated auth-tokens to the client

In reply to David Sommerseth

If --auth-gen-token has been enabled and a token has been generated, ensure this token is pushed to the client using the 'auth-token' option.

This patch will also remove the logging of auth-token values being pushed, unless --verb level is 7 or higher.

v2 - Don't exceed 80 chars line length
- Clarify the magic in sanitize_control_message()
- Relocate auth_token_sent struct member slightly

---
 src/openvpn/misc.c       |  9 +++++++++
 src/openvpn/push.c       | 12 +++++++++++-
 src/openvpn/ssl_common.h |  2 ++
 3 files changed, 22 insertions(+), 1 deletion(-)
src/openvpn/misc.c +9 -0
index 225f0bf..b06d446 100644
@@ -2073,6 +2073,15 @@ sanitize_control_message(const char *src, struct gc_arena *gc)
 	  skip = 4;
 	  redact = true;
 	}
+      else if (!check_debug_level(D_SHOW_KEYS)
+               && (c == 'a' && !strncmp(src, "auth-token ", 11)))
+	{
+          /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
+           * the auth-token value coming in the src string
+           */
+	  skip = 10;
+	  redact = true;
+	}
 
       if (c == ',') /* end of redacted item? */
 	{
src/openvpn/push.c +11 -1
index 4f24b58..f86bdd3 100644
@@ -309,7 +309,7 @@ prepare_push_reply (struct context *c, struct gc_arena *gc,
 		    struct push_list *push_list)
 {
   const char *optstr = NULL;
-  const struct tls_multi *tls_multi = c->c2.tls_multi;
+  struct tls_multi *tls_multi = c->c2.tls_multi;
   const char * const peer_info = tls_multi->peer_info;
   struct options *o = &c->options;
 
@@ -371,6 +371,16 @@ prepare_push_reply (struct context *c, struct gc_arena *gc,
 	  push_option_fmt(gc, push_list, M_USAGE, "cipher %s", o->ciphername);
 	}
     }
+
+  /* If server uses --auth-gen-token and we have an auth token
+   * to send to the client
+   */
+  if (false == tls_multi->auth_token_sent && NULL != tls_multi->auth_token)
+    {
+      push_option_fmt(gc, push_list, M_USAGE,
+                      "auth-token %s", tls_multi->auth_token);
+      tls_multi->auth_token_sent = true;
+    }
   return true;
 }
 
src/openvpn/ssl_common.h +2 -0
index 9b63a12..b04a24c 100644
@@ -533,6 +533,8 @@ struct tls_multi
                           *   user/pass authentications in this session.
                           */
   time_t auth_token_tstamp; /**< timestamp of the generated token */
+  bool auth_token_sent;  /**< If server uses --auth-gen-token and
+                          *   token has been sent to client */
   /*
    * Our session objects.
    */
Signature · 1 line
1.8.3.1
#9 lore raw

Re: [Openvpn-devel] [PATCH v2 3/4] auth-gen-token: Push generated auth-tokens to the client

Quoted 72 lines · David Sommerseth

If --auth-gen-token has been enabled and a token has been generated, ensure this token is pushed to the client using the 'auth-token' option.

This patch will also remove the logging of auth-token values being pushed, unless --verb level is 7 or higher.

v2 - Don't exceed 80 chars line length
- Clarify the magic in sanitize_control_message()
- Relocate auth_token_sent struct member slightly

---
 src/openvpn/misc.c       |  9 +++++++++
 src/openvpn/push.c       | 12 +++++++++++-
 src/openvpn/ssl_common.h |  2 ++
 3 files changed, 22 insertions(+), 1 deletion(-)
src/openvpn/misc.c +9 -0
index 225f0bf..b06d446 100644
@@ -2073,6 +2073,15 @@ sanitize_control_message(const char *src, struct gc_arena *gc)
          skip = 4;
          redact = true;
        }
+      else if (!check_debug_level(D_SHOW_KEYS)
+               && (c == 'a' && !strncmp(src, "auth-token ", 11)))
+       {
+          /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
+           * the auth-token value coming in the src string
+           */
+         skip = 10;
+         redact = true;
+       }
 
       if (c == ',') /* end of redacted item? */
        {
src/openvpn/push.c +11 -1
index 4f24b58..f86bdd3 100644
@@ -309,7 +309,7 @@ prepare_push_reply (struct context *c, struct gc_arena *gc,
                    struct push_list *push_list)
 {
   const char *optstr = NULL;
-  const struct tls_multi *tls_multi = c->c2.tls_multi;
+  struct tls_multi *tls_multi = c->c2.tls_multi;
   const char * const peer_info = tls_multi->peer_info;
   struct options *o = &c->options;
 
@@ -371,6 +371,16 @@ prepare_push_reply (struct context *c, struct gc_arena *gc,
          push_option_fmt(gc, push_list, M_USAGE, "cipher %s", o->ciphername);
        }
     }
+
+  /* If server uses --auth-gen-token and we have an auth token
+   * to send to the client
+   */
+  if (false == tls_multi->auth_token_sent && NULL != tls_multi->auth_token)
+    {
+      push_option_fmt(gc, push_list, M_USAGE,
+                      "auth-token %s", tls_multi->auth_token);
+      tls_multi->auth_token_sent = true;
+    }
   return true;
 }
 
src/openvpn/ssl_common.h +0 -0
index 9b63a12..b04a24c 100644

src/openvpn/ssl_common.h struct tls_multi

Quoted 9 lines
src/openvpn/ssl_common.h +2 -1
@@ -533,6 +533,8 @@ struct tls_multi
                           *   user/pass authentications in this session.
                           */
   time_t auth_token_tstamp; /**< timestamp of the generated token */
+  bool auth_token_sent;  /**< If server uses --auth-gen-token and
+                          *   token has been sent to client */
   /*
    * Our session objects.
    */
--

ACK - all my previous nagging points are resolved now.

-Steffan

#10 lore raw

Re: [Openvpn-devel] [PATCH applied] auth-gen-token: Push generated auth-tokens to the client

In reply to David Sommerseth

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Your patch has been applied to the master branch.

commit 2c0403ac359097bbcb1e97b777120e218e29014f

Author: David Sommerseth
Date:   Fri Oct 28 21:48:43 2016 +0200
     auth-gen-token: Push generated auth-tokens to the client

     Signed-off-by: David Sommerseth <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg12824.html

- --
kind regards,

David Sommerseth

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJYFyW0AAoJEIbPlEyWcf3y0HgP/jhHH6oZwt2I2ckTPfP1Kc0e sHQyEFF5C9h1NPZxM2iN1RhL3QSiqf0SRYhWpc2a2q3XnRtTXMle0ho9eK03CZ37 hs/yRC8GdPkFDl+v4RN288eekILl06MWAVh8ZeqCljd+bhh+t0jTHV/7yTcKoO42 C8ElYdbZ/r4cVTQ2C3HkgqLucqiPrquuO16JJ8f1sLYZ+OnyRtQ8LSTeFRy+l9td ZdUUBkksQG5I0umkRGvKzGeJZ9NJN/h5900gPGM3AYMuHLY/sNfKdW+yAODho/qB oob1Ya8ffsz/Qk4x8UBCr927SVaSNTO4SDBxUiHMSnu54RNKEmbu+IadUmoeghNL v+ktF/fxj3/Vxw9XVxnAdVGe9FO6/a7xukbvoaWBP7/7/+iPpVqfCJ0UH8dbrO1/ qVGx4n9e9TstquFrOuC1dZQNbMti1hrZ/n6WcEmyOD1tLgPMPmbS1LK10mr1lHrw hhAbVwt6LlHCUe9yh/6mPAA5TsocO2gkYqncfHwG1ggFhbjNQs/fNAgWNAyw3RHk 0leSJ3GhtXeIl9sud4BSnwWAjjHdYm1l2RwAVb4xC2m2RuVI+ppQEW3jhjsy04tu Si8vAByudS90uPrRh6x4JSlt6weonHjVU9XOfw91powmgXg07jyWtGnF9DVoaXH1 0RueBWK+pvePzvU2rKeN
=a2gv
-----END PGP SIGNATURE-----

#11 lore raw

PATCH v2 4/4 auth-gen-token: Authenticate generated auth-tokens when client re-authenticates

In reply to David Sommerseth

On a server with --auth-gen-token enabled, the server will have created a random token and pushed it to the client. When the client needs to renegotiate the connection or otherwise reconnect, it will at this point use the auth-token as password.

Here we check if we have a token generated and that it has been pushed to the client, if so, then we check if the token matches the locally stored token. If everything matches, we're done and the connection is still authenticated.

If the auth-token authentication fails, we delete our local copy of the token and changes the connection to not being authenticated. From this moment of, the client needs to do a full reconnect providing the users password again.

This token authentication also considers the token lifetime, if that have been set via --auth-gen-token. If the token have expired, the client is rejected and needs to do a full reconnect with a new authentication using the users password.

v2 - Rename auth_generate_token to auth_token_generate
- Wrap lines exceeding 80 chars
- Improved several comments (rephrasing, grammar)

---
 src/openvpn/ssl_verify.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
src/openvpn/ssl_verify.c +58 -0
index 0ac5689..99a2f70 100644
@@ -1139,6 +1139,63 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
   string_mod_remap_name (up->username, COMMON_NAME_CHAR_CLASS);
   string_mod (up->password, CC_PRINT, CC_CRLF, '_');
 
+  /* If server is configured with --auth-gen-token and we have an
+   * authentication token for this client, this authentication
+   * round will be done internally using the token instead of
+   * calling any external authentication modules.
+   */
+  if (session->opt->auth_token_generate && multi->auth_token_sent
+      && NULL != multi->auth_token)
+    {
+      unsigned int ssl_flags = session->opt->ssl_flags;
+
+      /* Ensure that the username has not changed */
+      if (!tls_lock_username(multi, up->username))
+        {
+          ks->authenticated = false;
+          goto done;
+        }
+
+      /* If auth-token lifetime has been enabled,
+       * ensure the token has not expired
+       */
+      if (session->opt->auth_token_lifetime > 0
+          && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now)
+        {
+          msg (D_HANDSHAKE, "Auth-token for client expired\n");
+          ks->authenticated = false;
+          goto done;
+        }
+
+      /* The core authentication of the token itself */
+      if (memcmp_constant_time(multi->auth_token, up->password,
+                 strlen(multi->auth_token)) != 0)
+        {
+          memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+          free (multi->auth_token);
+          multi->auth_token = NULL;
+          multi->auth_token_sent = false;
+          ks->authenticated = false;
+          tls_deauthenticate (multi);
+
+          msg (D_TLS_ERRORS, "TLS Auth Error: Auth-token verification "
+               "failed for username '%s' %s", up->username,
+               (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+        }
+      else
+        {
+          ks->authenticated = true;
+
+          if (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
+            set_common_name (session, up->username);
+          msg (D_HANDSHAKE, "TLS: Username/auth-token authentication "
+               "succeeded for username '%s' %s",
+               up->username,
+               (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+        }
+      goto done;
+    }
+
   /* call plugin(s) and/or script */
 #ifdef MANAGEMENT_DEF_AUTH
   if (man_def_auth == KMDA_DEF)
@@ -1232,6 +1289,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
       msg (D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
     }
 
+ done:
   gc_free (&gc);
 }
 
Signature · 1 line
1.8.3.1
#12 lore raw

Re: [Openvpn-devel] [PATCH v2 4/4] auth-gen-token: Authenticate generated auth-tokens when client re-authenticates

Quoted 36 lines · David Sommerseth

On a server with --auth-gen-token enabled, the server will have created a random token and pushed it to the client. When the client needs to renegotiate the connection or otherwise reconnect, it will at this point use the auth-token as password.

Here we check if we have a token generated and that it has been pushed to the client, if so, then we check if the token matches the locally stored token. If everything matches, we're done and the connection is still authenticated.

If the auth-token authentication fails, we delete our local copy of the token and changes the connection to not being authenticated. From this moment of, the client needs to do a full reconnect providing the users password again.

This token authentication also considers the token lifetime, if that have been set via --auth-gen-token. If the token have expired, the client is rejected and needs to do a full reconnect with a new authentication using the users password.

v2 - Rename auth_generate_token to auth_token_generate
- Wrap lines exceeding 80 chars
- Improved several comments (rephrasing, grammar)

---
 src/openvpn/ssl_verify.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
src/openvpn/ssl_verify.c +0 -0
index 0ac5689..99a2f70 100644
@@ -1139,6 +1139,63 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
   string_mod_remap_name (up->username, COMMON_NAME_CHAR_CLASS);
   string_mod (up->password, CC_PRINT, CC_CRLF, '_');

src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi, · line 1150

Quoted 10 lines
src/openvpn/ssl_verify.c +9 -0
 
+  /* If server is configured with --auth-gen-token and we have an
+   * authentication token for this client, this authentication
+   * round will be done internally using the token instead of
+   * calling any external authentication modules.
+   */
+  if (session->opt->auth_token_generate && multi->auth_token_sent
+      && NULL != multi->auth_token)
+    {
+      unsigned int ssl_flags = session->opt->ssl_flags;

You could make this a 'const'.

Quoted 52 lines
src/openvpn/ssl_verify.c +48 -0
+
+      /* Ensure that the username has not changed */
+      if (!tls_lock_username(multi, up->username))
+        {
+          ks->authenticated = false;
+          goto done;
+        }
+
+      /* If auth-token lifetime has been enabled,
+       * ensure the token has not expired
+       */
+      if (session->opt->auth_token_lifetime > 0
+          && (multi->auth_token_tstamp + session->opt->auth_token_lifetime) < now)
+        {
+          msg (D_HANDSHAKE, "Auth-token for client expired\n");
+          ks->authenticated = false;
+          goto done;
+        }
+
+      /* The core authentication of the token itself */
+      if (memcmp_constant_time(multi->auth_token, up->password,
+                 strlen(multi->auth_token)) != 0)
+        {
+          memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
+          free (multi->auth_token);
+          multi->auth_token = NULL;
+          multi->auth_token_sent = false;
+          ks->authenticated = false;
+          tls_deauthenticate (multi);
+
+          msg (D_TLS_ERRORS, "TLS Auth Error: Auth-token verification "
+               "failed for username '%s' %s", up->username,
+               (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+        }
+      else
+        {
+          ks->authenticated = true;
+
+          if (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)
+            set_common_name (session, up->username);
+          msg (D_HANDSHAKE, "TLS: Username/auth-token authentication "
+               "succeeded for username '%s' %s",
+               up->username,
+               (ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) ? "[CN SET]" : "");
+        }
+      goto done;
+    }
+
   /* call plugin(s) and/or script */
 #ifdef MANAGEMENT_DEF_AUTH
   if (man_def_auth == KMDA_DEF)

src/openvpn/ssl_verify.c verify_user_pass(struct user_pass *up, struct tls_multi *multi,

Quoted 8 lines
src/openvpn/ssl_verify.c +1 -1
@@ -1232,6 +1289,7 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
       msg (D_TLS_ERRORS, "TLS Auth Error: Auth Username/Password verification failed for peer");
     }
 
+ done:
   gc_free (&gc);
 }
 
--

Whether you decide to add the const or not, ACK. (Knowing that you'll continue with makes this *really* useful by fixing reauthentication is later patches.)

-Steffan

#13 lore raw

Re: [Openvpn-devel] [PATCH applied] auth-gen-token: Authenticate generated auth-tokens when client re-authenticates

In reply to David Sommerseth

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Your patch has been applied to the master branch.

commit 703c9784f4dcd4f77166201074c21c6ea4aeb033

Author: David Sommerseth
Date:   Fri Oct 28 21:48:44 2016 +0200
     auth-gen-token: Authenticate generated auth-tokens when client re-authenticates

     Signed-off-by: David Sommerseth <[email protected]...>
     Acked-by: Steffan Karger <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg12822.html

- --
kind regards,

David Sommerseth

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJYFyXHAAoJEIbPlEyWcf3yRkYQAJgD9V8Gi+3PxtN/d5v7Gr8C hYAu+k2sk5Zty+ywq6s1OjlL67w14URecz8EQ2p1mAiMecd4DEWWHz9N9As2r9u3 94C9/b1eDSKCnyOtngNjM9H4VyZ1RF8mIg9thCTHwSrZ4yl3f2IpYSXpn/Fh6giR Xr1ZCrPQuCCkyRoN7KVvTYoeXZBayTci5hcbYk+m20QDPYsxLeedKwDHwrsvc0Aq bFK9cdmbro5epmlBv77Ov6ZMiRhw0Y6k2iJdoZ2orKYy8m6XOdUvPp4XaTKmwUkz g1tDellYQzfUwICF2d3ZDAiNsAWAvdN+Y8IhfY1HhXPNOQfiPOlS9mkVFem+Fm2l nYj83p7SSBR+EbYYZt48JU+HHJUeXJxlPT3VdmgzQZfRnsDHbsU1mMwniBmt9Wj6 uoFoLYwZvijneE1n1TqX1Mp5ksf+3sF133zP56s/AkT8kPYDODWv41QPlSjwUcuN zsv9h5fRFW0UxwV7ufl0OpaOYwAfSg8xBltZRi8imPreQjg4MjyBYfg4Vgs7+T9T sqzQ378IKFwI0uilqo8OPn2uMoX2vf8DwasV9mTC6POc+1r2hUF4wM0AeEdFr3cR 231LBjjADAVGG/TO+Q5xlMyXa3KNpo7tRknyN1AyfueHkaHviEaOmy8aNnr3GoC5 2GySIEzHogP+dJI7thpl
=xScg
-----END PGP SIGNATURE-----