OpenVPN
test_auth_token.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2016-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "syshead.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <setjmp.h>
35 #include <cmocka.h>
36 
37 #include "auth_token.c"
38 #include "test_common.h"
39 
40 struct test_context {
41  struct tls_multi multi;
42  struct key_type kt;
43  struct user_pass up;
45 };
46 
47 /* Dummy functions that do nothing to mock the functionality */
48 void
50 {
51 }
52 
53 void
54 auth_set_client_reason(struct tls_multi *multi, const char *reason)
55 {
56 
57 }
58 
59 static const char *now0key0 = "SESS_ID_AT_0123456789abcdefAAAAAAAAAAAAAAAAAAAAAE5JsQJOVfo8jnI3RL3tBaR5NkE4yPfcylFUHmHSc5Bu";
60 
61 static const char *zeroinline = "-----BEGIN OpenVPN auth-token server key-----\n"
62  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
63  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"
64  "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n"
65  "-----END OpenVPN auth-token server key-----";
66 
67 static const char *allx01inline = "-----BEGIN OpenVPN auth-token server key-----\n"
68  "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n"
69  "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n"
70  "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=\n"
71  "-----END OpenVPN auth-token server key-----";
72 
73 static const char *random_key = "-----BEGIN OpenVPN auth-token server key-----\n"
74  "+mmmf7IQ5cymtMVjKYTWk8IOcYanRlpQmV9Tb3EjkHYxueBVDg3yqRgzeBlVGzNLD//rAPiOVhau\n"
75  "3NDBjNOQB8951bfs7Cc2mYfay92Bh2gRJ5XEM/DMfzCWN+7uU6NWoTTHr4FuojnIQtjtqVAj/JS9\n"
76  "w+dTSp/vYHl+c7uHd19uVRu/qLqV85+rm4tUGIjO7FfYuwyPqwmhuIsi3hs9QkSimh888FmBpoKY\n"
77  "/tbKVTJZmSERKti9KEwtV2eVAR0znN5KW7lCB3mHVAhN7bUpcoDjfCzYIFARxwswTFu9gFkwqUMY\n"
78  "I1KUOgIsVNs4llACioeXplYekWETR+YkJwDc/A==\n"
79  "-----END OpenVPN auth-token server key-----";
80 
81 static const char *random_token = "SESS_ID_AT_ThhRItzOKNKrh3dfAAAAAFwzHpwAAAAAXDMenDdrq0RoH3dkA1f7O3wO+7kZcx2DusVZrRmFlWQM9HOb";
82 
83 
84 static int
85 setup(void **state)
86 {
87  struct test_context *ctx = calloc(1, sizeof(*ctx));
88  *state = ctx;
89 
90  struct key_parameters key = { 0 };
91  key.hmac_size = MAX_HMAC_KEY_LENGTH; /* 64 byte of 0 */
92 
93  ctx->kt = auth_token_kt();
94  if (!ctx->kt.digest)
95  {
96  return 0;
97  }
98  ctx->multi.opt.auth_token_generate = true;
99  ctx->multi.opt.auth_token_lifetime = 3000;
100  ctx->session = &ctx->multi.session[TM_ACTIVE];
101 
102  ctx->session->opt = calloc(1, sizeof(struct tls_options));
103  ctx->session->opt->renegotiate_seconds = 240;
104  ctx->session->opt->auth_token_renewal = 120;
105  ctx->session->opt->auth_token_lifetime = 3000;
106 
107  strcpy(ctx->up.username, "test user name");
108  strcpy(ctx->up.password, "ignored");
109 
110  init_key_ctx(&ctx->multi.opt.auth_token_key, &key, &ctx->kt, false, "TEST");
111 
112  now = 0;
113  return 0;
114 }
115 
116 static int
117 teardown(void **state)
118 {
119  struct test_context *ctx = (struct test_context *) *state;
120 
122  wipe_auth_token(&ctx->multi);
123 
124  free(ctx->session->opt);
125  free(ctx);
126 
127  return 0;
128 }
129 
130 static void
132 {
133  struct test_context *ctx = (struct test_context *) *state;
134 
135  generate_auth_token(&ctx->up, &ctx->multi);
136  strcpy(ctx->up.password, ctx->multi.auth_token);
137  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
139 }
140 
141 static void
143 {
144  struct test_context *ctx = (struct test_context *) *state;
145 
146  generate_auth_token(&ctx->up, &ctx->multi);
147  strcpy(ctx->up.password, ctx->multi.auth_token);
148  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
150 
151  /* Change auth-token key */
152  struct key_parameters key;
153  memset(key.hmac, '1', sizeof(key.hmac));
154  key.hmac_size = MAX_HMAC_KEY_LENGTH;
155 
157  init_key_ctx(&ctx->multi.opt.auth_token_key, &key, &ctx->kt, false, "TEST");
158 
159  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session), 0);
160 
161  /* Load original test key again */
162  memset(&key.hmac, 0, sizeof(key.hmac));
164  init_key_ctx(&ctx->multi.opt.auth_token_key, &key, &ctx->kt, false, "TEST");
165  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
167 
168 }
169 
170 static void
172 {
173  struct test_context *ctx = (struct test_context *) *state;
174 
175  now = 100000;
176  generate_auth_token(&ctx->up, &ctx->multi);
177 
178  strcpy(ctx->up.password, ctx->multi.auth_token);
179  free(ctx->multi.auth_token_initial);
180  ctx->multi.auth_token_initial = NULL;
181 
182  /* No time has passed */
183  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
185 
186  /* Token before validity, should be rejected */
187  now = 100000 - 100;
188  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
190 
191  /* Token no valid for renegotiate_seconds but still for renewal_time */
192  now = 100000 + 2*ctx->session->opt->renegotiate_seconds - 20;
193  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
195 
196 
197  now = 100000 + 2*ctx->session->opt->auth_token_renewal - 20;
198  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
200 
201  /* Token past validity, should be rejected */
202  now = 100000 + 2*ctx->session->opt->renegotiate_seconds + 20;
203  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
205 
206  /* But not when we reached our timeout */
207  now = 100000 + ctx->session->opt->auth_token_lifetime + 1;
208  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
210 
211  free(ctx->multi.auth_token_initial);
212  ctx->multi.auth_token_initial = NULL;
213 
214  /* regenerate the token util it hits the expiry */
215  now = 100000;
216  while (now < 100000 + ctx->session->opt->auth_token_lifetime + 1)
217  {
218  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
220  generate_auth_token(&ctx->up, &ctx->multi);
221  strcpy(ctx->up.password, ctx->multi.auth_token);
222  now += ctx->session->opt->auth_token_renewal;
223  }
224 
225 
226  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
228  ctx->multi.opt.auth_token_lifetime = 0;
229 
230  /* Non expiring token should be fine */
231  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
233 }
234 
235 static void
236 zerohmac(char *token)
237 {
238  char *hmacstart = token + AUTH_TOKEN_SESSION_ID_LEN
239  + strlen(SESSION_ID_PREFIX) + 2*sizeof(uint64_t);
240  memset(hmacstart, 0x8d, strlen(hmacstart));
241 }
242 
243 static void
245 {
246  struct test_context *ctx = (struct test_context *) *state;
247 
248  now = 0;
249  /* Preload the session id so the same session id is used here */
250  ctx->multi.auth_token_initial = strdup(now0key0);
251  assert_non_null(ctx->multi.auth_token_initial);
252 
253  /* Zero the hmac part to ensure we have a newly generated token */
255 
256  generate_auth_token(&ctx->up, &ctx->multi);
257 
258  assert_string_equal(now0key0, ctx->multi.auth_token);
259 
260  strcpy(ctx->up.password, ctx->multi.auth_token);
261  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
263 }
264 
265 static const char *lastsesion_statevalue;
266 void
267 setenv_str(struct env_set *es, const char *name, const char *value)
268 {
269  if (streq(name, "session_state"))
270  {
271  lastsesion_statevalue = value;
272  }
273 }
274 
275 void
277 {
278  struct test_context *ctx = (struct test_context *) *state;
279 
280  /* Generate first auth token and check it is correct */
281  generate_auth_token(&ctx->up, &ctx->multi);
282  strcpy(ctx->up.password, ctx->multi.auth_token);
283  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
285 
286  char *token_sessiona = strdup(ctx->multi.auth_token);
287 
288  /* Generate second token */
289  wipe_auth_token(&ctx->multi);
290 
291  generate_auth_token(&ctx->up, &ctx->multi);
292  strcpy(ctx->up.password, ctx->multi.auth_token);
293  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
295 
296  assert_int_not_equal(0, memcmp(ctx->multi.auth_token_initial + strlen(SESSION_ID_PREFIX),
297  token_sessiona + strlen(SESSION_ID_PREFIX),
299 
300  /* The first token is valid but should trigger the invalid response since
301  * the session id is not the same */
302  strcpy(ctx->up.password, token_sessiona);
303  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session), 0);
304  free(token_sessiona);
305 }
306 
307 static void
309 {
310  struct test_context *ctx = (struct test_context *) *state;
311 
312  CLEAR(ctx->up.username);
313  now = 0;
314 
315  generate_auth_token(&ctx->up, &ctx->multi);
316  strcpy(ctx->up.password, ctx->multi.auth_token);
317  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
319 
320  now = 100000;
321  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
323  strcpy(ctx->up.username, "test user name");
324 
325  now = 0;
326  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
328 
329  strcpy(ctx->up.username, "test user name");
330  now = 100000;
331  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
333 
334  zerohmac(ctx->up.password);
335  assert_int_equal(verify_auth_token(&ctx->up, &ctx->multi, ctx->session),
336  0);
337 }
338 
339 static void
340 auth_token_test_env(void **state)
341 {
342  struct test_context *ctx = (struct test_context *) *state;
343 
344  struct key_state *ks = &ctx->multi.session[TM_ACTIVE].key[KS_PRIMARY];
345 
346  ks->auth_token_state_flags = 0;
347  ctx->multi.auth_token = NULL;
348  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
349  assert_string_equal(lastsesion_statevalue, "Initial");
350 
351  ks->auth_token_state_flags = 0;
352  strcpy(ctx->up.password, now0key0);
353  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
354  assert_string_equal(lastsesion_statevalue, "Invalid");
355 
357  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
358  assert_string_equal(lastsesion_statevalue, "Authenticated");
359 
361  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
362  assert_string_equal(lastsesion_statevalue, "Expired");
363 
365  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
366  assert_string_equal(lastsesion_statevalue, "AuthenticatedEmptyUser");
367 
369  add_session_token_env(ctx->session, &ctx->multi, &ctx->up);
370  assert_string_equal(lastsesion_statevalue, "ExpiredEmptyUser");
371 }
372 
373 static void
375 {
376  struct test_context *ctx = (struct test_context *) *state;
377 
378  now = 0x5c331e9c;
379  /* Preload the session id so the same session id is used here */
380  ctx->multi.auth_token_initial = strdup(random_token);
381  assert_non_null(ctx->multi.auth_token_initial);
382 
385 
386  /* Zero the hmac part to ensure we have a newly generated token */
388 
389  generate_auth_token(&ctx->up, &ctx->multi);
390 
391  assert_string_equal(random_token, ctx->multi.auth_token);
392 
393  strcpy(ctx->up.password, ctx->multi.auth_token);
394  assert_true(verify_auth_token(&ctx->up, &ctx->multi, ctx->session));
395 }
396 
397 
398 static void
400 {
401  struct test_context *ctx = (struct test_context *) *state;
402 
405  strcpy(ctx->up.password, now0key0);
406  assert_true(verify_auth_token(&ctx->up, &ctx->multi, ctx->session));
407 
410  assert_false(verify_auth_token(&ctx->up, &ctx->multi, ctx->session));
411 }
412 
413 int
414 main(void)
415 {
417  const struct CMUnitTest tests[] = {
418  cmocka_unit_test_setup_teardown(auth_token_basic_test, setup, teardown),
419  cmocka_unit_test_setup_teardown(auth_token_fail_invalid_key, setup, teardown),
420  cmocka_unit_test_setup_teardown(auth_token_test_known_keys, setup, teardown),
421  cmocka_unit_test_setup_teardown(auth_token_test_empty_user, setup, teardown),
422  cmocka_unit_test_setup_teardown(auth_token_test_env, setup, teardown),
423  cmocka_unit_test_setup_teardown(auth_token_test_random_keys, setup, teardown),
424  cmocka_unit_test_setup_teardown(auth_token_test_key_load, setup, teardown),
425  cmocka_unit_test_setup_teardown(auth_token_test_timeout, setup, teardown),
426  cmocka_unit_test_setup_teardown(auth_token_test_session_mismatch, setup, teardown)
427  };
428 
429 #if defined(ENABLE_CRYPTO_OPENSSL)
430  OpenSSL_add_all_algorithms();
431 #endif
432 
433  int ret = cmocka_run_group_tests_name("auth-token tests", tests, NULL, NULL);
434 
435  return ret;
436 }
SESSION_ID_PREFIX
#define SESSION_ID_PREFIX
The prefix given to auth tokens start with, this prefix is special cased to not show up in log files ...
Definition: auth_token.h:115
random_token
static const char * random_token
Definition: test_auth_token.c:81
tls_multi::auth_token
char * auth_token
If server sends a generated auth-token, this is the token to use for future user/pass authentications...
Definition: ssl_common.h:659
init_key_ctx
void init_key_ctx(struct key_ctx *ctx, const struct key_parameters *key, const struct key_type *kt, int enc, const char *prefix)
Definition: crypto.c:1015
key_state::auth_token_state_flags
unsigned int auth_token_state_flags
The state of the auth-token sent from the client.
Definition: ssl_common.h:203
tls_session::opt
struct tls_options * opt
Definition: ssl_common.h:482
verify_auth_token
unsigned int verify_auth_token(struct user_pass *up, struct tls_multi *multi, struct tls_session *session)
Verifies the auth token to be in the format that generate_auth_token create and checks if the token i...
Definition: auth_token.c:294
streq
#define streq(x, y)
Definition: options.h:726
KS_PRIMARY
#define KS_PRIMARY
Primary key state index.
Definition: ssl_common.h:456
test_context::up
struct user_pass up
Definition: test_auth_token.c:43
es
struct env_set * es
Definition: test_pkcs11.c:141
random_key
static const char * random_key
Definition: test_auth_token.c:73
test_common.h
tls_multi::session
struct tls_session session[TM_SIZE]
Array of tls_session objects representing control channel sessions with the remote peer.
Definition: ssl_common.h:690
add_session_token_env
void add_session_token_env(struct tls_session *session, struct tls_multi *multi, const struct user_pass *up)
Put the session id, and auth token status into the environment if auth-token is enabled.
Definition: auth_token.c:38
tls_options::auth_token_key
struct key_ctx auth_token_key
Definition: ssl_common.h:399
user_pass::username
char username[USER_PASS_LEN]
Definition: misc.h:72
auth_token.c
test_context
Definition: test_auth_token.c:40
auth_token_test_empty_user
static void auth_token_test_empty_user(void **state)
Definition: test_auth_token.c:308
setup
static int setup(void **state)
Definition: test_auth_token.c:85
key::hmac
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Definition: crypto.h:155
tls_options::renegotiate_seconds
interval_t renegotiate_seconds
Definition: ssl_common.h:339
tls_multi
Security parameter state for a single VPN tunnel.
Definition: ssl_common.h:596
auth_token_test_env
static void auth_token_test_env(void **state)
Definition: test_auth_token.c:340
key_state
Security parameter state of one TLS and data channel key session.
Definition: ssl_common.h:199
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:151
tls_options::auth_token_renewal
unsigned int auth_token_renewal
Definition: ssl_common.h:397
auth_token_test_key_load
static void auth_token_test_key_load(void **state)
Definition: test_auth_token.c:399
tls_options::auth_token_generate
bool auth_token_generate
Generate auth-tokens on successful user/pass auth,seet via options->auth_token_generate.
Definition: ssl_common.h:392
CLEAR
#define CLEAR(x)
Definition: basic.h:33
AUTH_TOKEN_VALID_EMPTYUSER
#define AUTH_TOKEN_VALID_EMPTYUSER
Auth-token is only valid for an empty username and not the username actually supplied from the client...
Definition: ssl_common.h:671
main
int main(void)
Definition: test_auth_token.c:414
TM_ACTIVE
#define TM_ACTIVE
Active tls_session.
Definition: ssl_common.h:535
AUTH_TOKEN_SESSION_ID_LEN
#define AUTH_TOKEN_SESSION_ID_LEN
Definition: auth_token.c:21
allx01inline
static const char * allx01inline
Definition: test_auth_token.c:67
MAX_HMAC_KEY_LENGTH
#define MAX_HMAC_KEY_LENGTH
Definition: crypto_backend.h:496
tls_options
Definition: ssl_common.h:297
auth_token_test_known_keys
static void auth_token_test_known_keys(void **state)
Definition: test_auth_token.c:244
key_type::digest
const char * digest
Message digest static parameters.
Definition: crypto.h:143
auth_token_test_session_mismatch
void auth_token_test_session_mismatch(void **state)
Definition: test_auth_token.c:276
tls_session::key
struct key_state key[KS_SIZE]
Definition: ssl_common.h:515
tls_multi::opt
struct tls_options opt
Definition: ssl_common.h:602
now0key0
static const char * now0key0
Definition: test_auth_token.c:59
AUTH_TOKEN_SESSION_ID_BASE64_LEN
#define AUTH_TOKEN_SESSION_ID_BASE64_LEN
Definition: auth_token.c:22
setenv_str
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: test_auth_token.c:267
auth_token_init_secret
void auth_token_init_secret(struct key_ctx *key_ctx, const char *key_file, bool key_inline)
Loads an HMAC secret from a file or if no file is present generates a epheremal secret for the run ti...
Definition: auth_token.c:124
auth_token_kt
static struct key_type auth_token_kt(void)
Definition: auth_token.c:32
key_type
Definition: crypto.h:140
tls_session
Security parameter state of a single session within a VPN tunnel.
Definition: ssl_common.h:479
key_state::state
int state
Definition: ssl_common.h:201
generate_auth_token
void generate_auth_token(const struct user_pass *up, struct tls_multi *multi)
Generate an auth token based on username and timestamp.
Definition: auth_token.c:164
auth_token_test_random_keys
static void auth_token_test_random_keys(void **state)
Definition: test_auth_token.c:374
auth_set_client_reason
void auth_set_client_reason(struct tls_multi *multi, const char *reason)
Sets the reason why authentication of a client failed.
Definition: test_auth_token.c:54
syshead.h
zeroinline
static const char * zeroinline
Definition: test_auth_token.c:61
openvpn_unit_test_setup
static void openvpn_unit_test_setup(void)
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition: test_common.h:36
env_set
Definition: env_set.h:42
tls_options::auth_token_lifetime
unsigned int auth_token_lifetime
Definition: ssl_common.h:396
zerohmac
static void zerohmac(char *token)
Definition: test_auth_token.c:236
free_key_ctx
void free_key_ctx(struct key_ctx *ctx)
Definition: crypto.c:1106
AUTH_TOKEN_HMAC_OK
#define AUTH_TOKEN_HMAC_OK
Auth-token sent from client has valid hmac.
Definition: ssl_common.h:667
key_parameters
internal structure similar to struct key that holds key information but is not represented on wire an...
Definition: crypto.h:162
auth_token_test_timeout
static void auth_token_test_timeout(void **state)
Definition: test_auth_token.c:171
AUTH_TOKEN_EXPIRED
#define AUTH_TOKEN_EXPIRED
Auth-token sent from client has expired.
Definition: ssl_common.h:669
teardown
static int teardown(void **state)
Definition: test_auth_token.c:117
test_context::kt
struct key_type kt
Definition: test_auth_token.c:42
auth_token_basic_test
static void auth_token_basic_test(void **state)
Definition: test_auth_token.c:131
auth_token_fail_invalid_key
static void auth_token_fail_invalid_key(void **state)
Definition: test_auth_token.c:142
now
time_t now
Definition: otime.c:34
wipe_auth_token
void wipe_auth_token(struct tls_multi *multi)
Wipes the authentication token out of the memory, frees and cleans up related buffers and flags.
Definition: auth_token.c:401
test_context::multi
struct tls_multi multi
Definition: test_auth_token.c:41
config.h
user_pass::password
char password[USER_PASS_LEN]
Definition: misc.h:73
session
Definition: keyingmaterialexporter.c:56
test_context::session
struct tls_session * session
Definition: test_auth_token.c:44
tls_multi::auth_token_initial
char * auth_token_initial
The first auth-token we sent to a client.
Definition: ssl_common.h:663
send_push_reply_auth_token
void send_push_reply_auth_token(struct tls_multi *multi)
Sends a push reply message only containin the auth-token to update the auth-token on the client.
Definition: test_auth_token.c:49
user_pass
Definition: misc.h:56
lastsesion_statevalue
static const char * lastsesion_statevalue
Definition: test_auth_token.c:265