Browse code

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

Signed-off-by: David Sommerseth <davids@openvpn.net>
Acked-by: Steffan Karger <steffan@karger.me>
Message-Id: <1477684124-26083-2-git-send-email-davids@openvpn.net>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg12825.html

David Sommerseth authored on 2016/10/29 04:48:40
Showing 6 changed files
... ...
@@ -79,6 +79,21 @@ Windows version
79 79
     Windows version is detected, logged and possibly signalled to server
80 80
     (IV_PLAT_VER=<nn> if ``--push-peer-info`` is set on client)
81 81
 
82
+Authentication tokens
83
+    In situations where it is not suitable to save users passwords on the client
84
+    OpenVPN have since v2.3 had support for --auth-token.  This option is
85
+    pushed from the server to the client with a token value to be used instead
86
+    of the users password.  For this to work, the authentication plug-in would
87
+    need to implement this support as well.  In OpenVPN 2.4 --auth-gen-token
88
+    is introduced, which will allow the OpenVPN server to generate a random
89
+    token and push it to the client without any changes to the authentication
90
+    modules.  When the clients need to re-authenticate the OpenVPN server will
91
+    instead of sending the re-authentication request to the authentication
92
+    module do the authentication internally.  This feature is especially
93
+    useful in configurations which adds One Time Password (OTP) authentication
94
+    schemes, as this allows the tunnel to be renegotiated regularly without
95
+    any need to supply new OTP codes.
96
+
82 97
 keying-material-exporter
83 98
     Keying Material Exporter [RFC-5705] allow additional keying material to be
84 99
     derived from existing TLS channel.
... ...
@@ -3583,6 +3583,28 @@ For a sample script that performs PAM authentication, see
3583 3583
 in the OpenVPN source distribution.
3584 3584
 .\"*********************************************************
3585 3585
 .TP
3586
+.B \-\-auth\-gen\-token [lifetime]
3587
+After successful user/password authentication, the OpenVPN
3588
+server will with this option generate a temporary
3589
+authentication token and push that to client.  On the following
3590
+renegotiations, the OpenVPN client will pass this token instead
3591
+of the users password.  On the server side the server will do
3592
+the token authentication internally and it will NOT do any
3593
+additional authentications against configured external
3594
+user/password authentication mechanisms.
3595
+
3596
+The
3597
+.B lifetime
3598
+argument defines how long the generated token is valid.  The
3599
+lifetime is defined in seconds.  If lifetime is not set
3600
+or it is set to 0, the token will never expire.
3601
+
3602
+This feature is useful for environments which is configured
3603
+to use One Time Passwords (OTP) as part of the user/password
3604
+authentications and that authentication mechanism does not
3605
+implement any auth-token support.
3606
+.\"*********************************************************
3607
+.TP
3586 3608
 .B \-\-opt\-verify
3587 3609
 Clients that connect with options that are incompatible
3588 3610
 with those of the server will be disconnected.
... ...
@@ -2421,6 +2421,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
2421 2421
   if (options->ccd_exclusive)
2422 2422
     to.client_config_dir_exclusive = options->client_config_dir;
2423 2423
   to.auth_user_pass_file = options->auth_user_pass_file;
2424
+  to.auth_token_generate = options->auth_token_generate;
2425
+  to.auth_token_lifetime = options->auth_token_lifetime;
2424 2426
 #endif
2425 2427
 
2426 2428
   to.x509_track = options->x509_track;
... ...
@@ -444,6 +444,11 @@ static const char usage_message[] =
444 444
   "                  run command cmd to verify.  If method='via-env', pass\n"
445 445
   "                  user/pass via environment, if method='via-file', pass\n"
446 446
   "                  user/pass via temporary file.\n"
447
+  "--auth-gen-token  [lifetime] Generate a random authentication token which is pushed\n"
448
+  "                  to each client, replacing the password.  Usefull when\n"
449
+  "                  OTP based two-factor auth mechanisms are in use and\n"
450
+  "                  --reneg-* options are enabled. Optionally a lifetime in seconds\n"
451
+  "                  for generated tokens can be set.\n"
447 452
   "--opt-verify    : Clients that connect with options that are incompatible\n"
448 453
   "                  with those of the server will be disconnected.\n"
449 454
   "--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)
864 864
 #ifdef ENABLE_PKCS11
865 865
   o->pkcs11_pin_cache_period = -1;
866 866
 #endif			/* ENABLE_PKCS11 */
867
+  o->auth_token_generate = false;
867 868
 
868 869
 /* tmp is only used in P2MP server context */
869 870
 #if P2MP_SERVER
... ...
@@ -1264,6 +1270,8 @@ show_p2mp_parms (const struct options *o)
1264 1264
   SHOW_INT (max_routes_per_client);
1265 1265
   SHOW_STR (auth_user_pass_verify_script);
1266 1266
   SHOW_BOOL (auth_user_pass_verify_script_via_file);
1267
+  SHOW_BOOL (auth_token_generate);
1268
+  SHOW_INT (auth_token_lifetime);
1267 1269
 #if PORT_SHARE
1268 1270
   SHOW_STR (port_share_host);
1269 1271
   SHOW_STR (port_share_port);
... ...
@@ -2186,6 +2194,8 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
2186 2186
              "tcp-nodelay in the server configuration instead.");
2187 2187
       if (options->auth_user_pass_verify_script)
2188 2188
 	msg (M_USAGE, "--auth-user-pass-verify requires --mode server");
2189
+      if (options->auth_token_generate)
2190
+	msg (M_USAGE, "--auth-gen-token requires --mode server");
2189 2191
 #if PORT_SHARE
2190 2192
       if (options->port_share_host || options->port_share_port)
2191 2193
 	msg (M_USAGE, "--port-share requires TCP server mode (--mode server --proto tcp-server)");
... ...
@@ -5965,6 +5975,12 @@ add_option (struct options *options,
5965 5965
 		       &options->auth_user_pass_verify_script,
5966 5966
 		       p[1], "auth-user-pass-verify", true);
5967 5967
     }
5968
+  else if (streq (p[0], "auth-gen-token"))
5969
+    {
5970
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5971
+      options->auth_token_generate = true;
5972
+      options->auth_token_lifetime = p[1] ? positive_atoi (p[1]) : 0;
5973
+    }
5968 5974
   else if (streq (p[0], "client-connect") && p[1])
5969 5975
     {
5970 5976
       VERIFY_PERMISSION (OPT_P_SCRIPT);
... ...
@@ -442,6 +442,8 @@ struct options
442 442
 
443 443
   const char *auth_user_pass_verify_script;
444 444
   bool auth_user_pass_verify_script_via_file;
445
+  bool auth_token_generate;
446
+  unsigned int auth_token_lifetime;
445 447
 #if PORT_SHARE
446 448
   char *port_share_host;
447 449
   char *port_share_port;
... ...
@@ -289,6 +289,9 @@ struct tls_options
289 289
   bool auth_user_pass_verify_script_via_file;
290 290
   const char *tmp_dir;
291 291
   const char *auth_user_pass_file;
292
+  bool auth_token_generate;     /**< Generate auth-tokens on successful user/pass auth,
293
+                                 *   set via options->auth_token_generate. */
294
+  unsigned int auth_token_lifetime;
292 295
 
293 296
   /* use the client-config-dir as a positive authenticator */
294 297
   const char *client_config_dir_exclusive;