Browse code

auth-gen-token: Generate an auth-token per client

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

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

David Sommerseth authored on 2016/10/29 04:48:42
Showing 3 changed files
... ...
@@ -1194,6 +1194,12 @@ tls_multi_free (struct tls_multi *multi, bool clear)
1194 1194
 
1195 1195
   cert_hash_free (multi->locked_cert_hash_set);
1196 1196
 
1197
+  if (multi->auth_token)
1198
+    {
1199
+      memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
1200
+      free (multi->auth_token);
1201
+    }
1202
+
1197 1203
   for (i = 0; i < TM_SIZE; ++i)
1198 1204
     tls_session_free (&multi->session[i], false);
1199 1205
 
... ...
@@ -351,6 +351,9 @@ struct tls_options
351 351
 /** @} name Index of key_state objects within a tls_session structure */
352 352
 /** @} addtogroup control_processor */
353 353
 
354
+#define AUTH_TOKEN_SIZE 32      /**< Size of server side generated auth tokens.
355
+                                 *   32 bytes == 256 bits
356
+                                 */
354 357
 
355 358
 /**
356 359
  * Security parameter state of a single session within a VPN tunnel.
... ...
@@ -525,6 +528,11 @@ struct tls_multi
525 525
   uint32_t peer_id;
526 526
   bool use_peer_id;
527 527
 
528
+  char *auth_token;      /**< If server sends a generated auth-token,
529
+                          *   this is the token to use for future
530
+                          *   user/pass authentications in this session.
531
+                          */
532
+  time_t auth_token_tstamp; /**< timestamp of the generated token */
528 533
   /*
529 534
    * Our session objects.
530 535
    */
... ...
@@ -39,6 +39,8 @@
39 39
 
40 40
 #include "misc.h"
41 41
 #include "manage.h"
42
+#include "otime.h"
43
+#include "base64.h"
42 44
 #include "ssl_verify.h"
43 45
 #include "ssl_verify_backend.h"
44 46
 
... ...
@@ -1174,6 +1176,43 @@ verify_user_pass(struct user_pass *up, struct tls_multi *multi,
1174 1174
       if (man_def_auth != KMDA_UNDEF)
1175 1175
 	ks->auth_deferred = true;
1176 1176
 #endif
1177
+
1178
+      if ((session->opt->auth_token_generate) && (NULL == multi->auth_token))
1179
+	{
1180
+	  /* Server is configured with --auth-gen-token but no token has yet
1181
+	   * been generated for this client.  Generate one and save it.
1182
+	   */
1183
+	  uint8_t tok[AUTH_TOKEN_SIZE];
1184
+
1185
+	  if (!rand_bytes(tok, AUTH_TOKEN_SIZE))
1186
+	    {
1187
+	      msg( M_FATAL, "Failed to get enough randomness for "
1188
+                   "authentication token");
1189
+	    }
1190
+
1191
+	  /* The token should be longer than the input when
1192
+           * being base64 encoded
1193
+           */
1194
+	  if( openvpn_base64_encode(tok, AUTH_TOKEN_SIZE,
1195
+                                    &multi->auth_token) < AUTH_TOKEN_SIZE)
1196
+	    {
1197
+	      msg(D_TLS_ERRORS, "BASE64 encoding of token failed. "
1198
+                  "No auth-token will be activated now");
1199
+	      if (multi->auth_token)
1200
+		{
1201
+		  memset (multi->auth_token, 0, AUTH_TOKEN_SIZE);
1202
+		  free (multi->auth_token);
1203
+		  multi->auth_token = NULL;
1204
+		}
1205
+	    }
1206
+	  else
1207
+	    {
1208
+	      multi->auth_token_tstamp = now;
1209
+	      dmsg (D_SHOW_KEYS, "Generated token for client: %s",
1210
+                    multi->auth_token);
1211
+	    }
1212
+	}
1213
+
1177 1214
       if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME))
1178 1215
 	set_common_name (session, up->username);
1179 1216
 #ifdef ENABLE_DEF_AUTH