OpenVPN
misc.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/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) 2002-2023 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
10  * Copyright (C) 2016-2023 David Sommerseth <davids@openvpn.net>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2
14  * as published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #include "buffer.h"
33 #include "misc.h"
34 #include "base64.h"
35 #include "tun.h"
36 #include "error.h"
37 #include "otime.h"
38 #include "plugin.h"
39 #include "options.h"
40 #include "manage.h"
41 #include "crypto.h"
42 #include "route.h"
43 #include "console.h"
44 #include "win32.h"
45 
46 #include "memdbg.h"
47 
48 #ifdef ENABLE_IPROUTE
49 const char *iproute_path = IPROUTE_PATH; /* GLOBAL */
50 #endif
51 
52 /*
53  * Set standard file descriptors to /dev/null
54  */
55 void
56 set_std_files_to_null(bool stdin_only)
57 {
58 #if defined(HAVE_DUP) && defined(HAVE_DUP2)
59  int fd;
60  if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
61  {
62  dup2(fd, 0);
63  if (!stdin_only)
64  {
65  dup2(fd, 1);
66  dup2(fd, 2);
67  }
68  if (fd > 2)
69  {
70  close(fd);
71  }
72  }
73 #endif
74 }
75 
76 /*
77  * Prepend a random string to hostname to prevent DNS caching.
78  * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
79  * Of course, this requires explicit support in the DNS server (wildcard).
80  */
81 const char *
82 hostname_randomize(const char *hostname, struct gc_arena *gc)
83 {
84 #define n_rnd_bytes 6
85 
86  uint8_t rnd_bytes[n_rnd_bytes];
87  const char *rnd_str;
88  struct buffer hname = alloc_buf_gc(strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);
89 
90  prng_bytes(rnd_bytes, sizeof(rnd_bytes));
91  rnd_str = format_hex_ex(rnd_bytes, sizeof(rnd_bytes), 40, 0, NULL, gc);
92  buf_printf(&hname, "%s.%s", rnd_str, hostname);
93  return BSTR(&hname);
94 #undef n_rnd_bytes
95 }
96 
97 #ifdef ENABLE_MANAGEMENT
98 /* Get username/password from the management interface */
99 static bool
100 auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags,
101  const char *auth_challenge)
102 {
103  const char *sc = NULL;
104 
106  {
107  management_auth_failure(management, prefix, "previous auth credentials failed");
108  }
109 
111  {
112  sc = auth_challenge;
113  }
114  if (!management_query_user_pass(management, up, prefix, flags, sc))
115  {
116  if ((flags & GET_USER_PASS_NOFATAL) != 0)
117  {
118  return false;
119  }
120  else
121  {
122  msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
123  }
124  }
125  return true;
126 }
127 
140 static struct auth_challenge_info *
142 {
144 
145  struct auth_challenge_info *ac;
146  const int len = strlen(auth_challenge);
147  char *work = (char *) gc_malloc(len+1, false, gc);
148  char *cp;
149 
150  struct buffer b;
151  buf_set_read(&b, (const uint8_t *)auth_challenge, len);
152 
153  ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
154 
155  /* parse prefix */
156  if (!buf_parse(&b, ':', work, len))
157  {
158  return NULL;
159  }
160  if (strcmp(work, "CRV1"))
161  {
162  return NULL;
163  }
164 
165  /* parse flags */
166  if (!buf_parse(&b, ':', work, len))
167  {
168  return NULL;
169  }
170  for (cp = work; *cp != '\0'; ++cp)
171  {
172  const char c = *cp;
173  if (c == 'E')
174  {
175  ac->flags |= CR_ECHO;
176  }
177  else if (c == 'R')
178  {
179  ac->flags |= CR_RESPONSE;
180  }
181  }
182 
183  /* parse state ID */
184  if (!buf_parse(&b, ':', work, len))
185  {
186  return NULL;
187  }
188  ac->state_id = string_alloc(work, gc);
189 
190  /* parse user name */
191  if (!buf_parse(&b, ':', work, len))
192  {
193  return NULL;
194  }
195  ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
196  openvpn_base64_decode(work, (void *)ac->user, -1);
197 
198  /* parse challenge text */
199  ac->challenge_text = string_alloc(BSTR(&b), gc);
200 
201  return ac;
202 }
203 
204 #endif /* ifdef ENABLE_MANAGEMENT */
205 
206 /*
207  * Get and store a username/password
208  */
209 
210 bool
212  const char *auth_file,
213  const char *prefix,
214  const unsigned int flags,
215  const char *auth_challenge)
216 {
217  struct gc_arena gc = gc_new();
218 
219  if (!up->defined)
220  {
221  bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
222  bool username_from_stdin = false;
223  bool password_from_stdin = false;
224  bool response_from_stdin = true;
225 
227  {
228  msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
229  }
230 
231 #ifdef ENABLE_MANAGEMENT
232  /*
233  * Get username/password from management interface?
234  */
235  if (management
236  && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
238  {
239  response_from_stdin = false;
240  if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
241  {
242  return false;
243  }
244  }
245  else
246 #endif /* ifdef ENABLE_MANAGEMENT */
247  /*
248  * Get NEED_OK confirmation from the console
249  */
250  if (flags & GET_USER_PASS_NEED_OK)
251  {
252  struct buffer user_prompt = alloc_buf_gc(128, &gc);
253 
254  buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
255  if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
256  up->password, USER_PASS_LEN, false))
257  {
258  msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
259  }
260 
261  if (!strlen(up->password))
262  {
263  strcpy(up->password, "ok");
264  }
265  }
266  else if (flags & GET_USER_PASS_INLINE_CREDS)
267  {
268  struct buffer buf;
269  buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
270  if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
271  {
272  buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
273  }
274  buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
275 
276  if (strlen(up->password) == 0)
277  {
278  password_from_stdin = 1;
279  }
280  }
281  /*
282  * Read from auth file unless this is a dynamic challenge request.
283  */
284  else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
285  {
286  /*
287  * Try to get username/password from a file.
288  */
289  FILE *fp;
290  char password_buf[USER_PASS_LEN] = { '\0' };
291 
292  fp = platform_fopen(auth_file, "r");
293  if (!fp)
294  {
295  msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
296  }
297 
298  if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
299  {
300  /* Read username first */
301  if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
302  {
303  msg(M_FATAL, "Error reading username from %s authfile: %s",
304  prefix,
305  auth_file);
306  }
307  }
308  chomp(up->username);
309 
310  if (fgets(password_buf, USER_PASS_LEN, fp) != NULL)
311  {
312  chomp(password_buf);
313  }
314 
315  if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
316  {
317  msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
318  }
319 
320  if (password_buf[0])
321  {
322  strncpy(up->password, password_buf, USER_PASS_LEN);
323  }
324  /* The auth-file does not have the password: get both username
325  * and password from the management interface if possible.
326  * Otherwise set to read password from console.
327  */
328 #if defined(ENABLE_MANAGEMENT)
329  else if (management
330  && (flags & GET_USER_PASS_MANAGEMENT)
332  {
333  msg(D_LOW, "No password found in %s authfile '%s'. Querying the management interface", prefix, auth_file);
334  if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
335  {
336  fclose(fp);
337  return false;
338  }
339  }
340 #endif
341  else
342  {
343  password_from_stdin = 1;
344  }
345 
346  fclose(fp);
347 
348  if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
349  {
350  msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
351  }
352  }
353  else
354  {
355  username_from_stdin = true;
356  password_from_stdin = true;
357  }
358 
359  /*
360  * Get username/password from standard input?
361  */
362  if (username_from_stdin || password_from_stdin || response_from_stdin)
363  {
364 #ifdef ENABLE_MANAGEMENT
365  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin)
366  {
368  if (ac)
369  {
370  char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
371  struct buffer packed_resp, challenge;
372 
373  challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc);
374  buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
375  buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
376 
377  if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
378  response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
379  {
380  msg(M_FATAL, "ERROR: could not read challenge response from stdin");
381  }
383  buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
384  }
385  else
386  {
387  msg(M_FATAL, "ERROR: received malformed challenge request from server");
388  }
389  }
390  else
391 #endif /* ifdef ENABLE_MANAGEMENT */
392  {
393  struct buffer user_prompt = alloc_buf_gc(128, &gc);
394  struct buffer pass_prompt = alloc_buf_gc(128, &gc);
395 
397  buf_printf(&user_prompt, "Enter %s Username:", prefix);
398  buf_printf(&pass_prompt, "Enter %s Password:", prefix);
399 
400  if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
401  {
402  query_user_add(BSTR(&user_prompt), BLEN(&user_prompt),
403  up->username, USER_PASS_LEN, true);
404  }
405 
406  if (password_from_stdin)
407  {
408  query_user_add(BSTR(&pass_prompt), BLEN(&pass_prompt),
409  up->password, USER_PASS_LEN, false);
410  }
411 
412  if (!query_user_exec() )
413  {
414  msg(M_FATAL, "ERROR: Failed retrieving username or password");
415  }
416 
417  if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
418  {
419  if (strlen(up->username) == 0)
420  {
421  msg(M_FATAL, "ERROR: %s username is empty", prefix);
422  }
423  }
424 
425 #ifdef ENABLE_MANAGEMENT
426  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin)
427  {
428  char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
429  struct buffer packed_resp, challenge;
430  char *pw64 = NULL, *resp64 = NULL;
431 
432  challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
433  buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
434 
435  if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
436  response, USER_PASS_LEN,
438  {
439  msg(M_FATAL, "ERROR: could not retrieve static challenge response");
440  }
441  if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
442  || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
443  {
444  msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
445  }
446  buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
447  buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
448  string_clear(pw64);
449  free(pw64);
450  string_clear(resp64);
451  free(resp64);
452  }
453 #endif /* ifdef ENABLE_MANAGEMENT */
454  }
455  }
456 
459 
460  up->defined = true;
461  }
462 
463 #if 0
464  msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
465 #endif
466 
467  gc_free(&gc);
468 
469  return true;
470 }
471 
472 void
473 purge_user_pass(struct user_pass *up, const bool force)
474 {
475  const bool nocache = up->nocache;
476  static bool warn_shown = false;
477  if (nocache || force)
478  {
479  secure_memzero(up, sizeof(*up));
480  up->nocache = nocache;
481  }
482  /*
483  * don't show warning if the pass has been replaced by a token: this is an
484  * artificial "auth-nocache"
485  */
486  else if (!warn_shown)
487  {
488  msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
489  warn_shown = true;
490  }
491 }
492 
493 void
494 set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token)
495 {
496 
497  if (strlen(token))
498  {
499  strncpynt(tk->password, token, USER_PASS_LEN);
500  tk->token_defined = true;
501 
502  /*
503  * --auth-token has no username, so it needs the username
504  * either already set or copied from up, or later set by
505  * --auth-token-user
506  * If already set, tk is fully defined.
507  */
508  if (strlen(tk->username))
509  {
510  tk->defined = true;
511  }
512  }
513 }
514 
515 void
516 set_auth_token_user(struct user_pass *tk, const char *username)
517 {
518  if (strlen(username))
519  {
520  /* Clear the username before decoding to ensure no old material is left
521  * and also allow decoding to not use all space to ensure the last byte is
522  * always 0 */
523  CLEAR(tk->username);
524  int len = openvpn_base64_decode(username, tk->username, USER_PASS_LEN - 1);
525  tk->defined = len > 0;
526  if (!tk->defined)
527  {
528  msg(D_PUSH, "Error decoding auth-token-username");
529  }
530  }
531 }
532 
533 
534 /*
535  * Process string received by untrusted peer before
536  * printing to console or log file.
537  *
538  * Assumes that string has been null terminated.
539  */
540 const char *
541 safe_print(const char *str, struct gc_arena *gc)
542 {
543  return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
544 }
545 
546 const char **
547 make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
548 {
549  char **ret = NULL;
550  int base = 0;
551  const int max_parms = MAX_PARMS + 2;
552  int n = 0;
553 
554  /* alloc return array */
555  ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
556 
557  /* process first parameter, if provided */
558  if (first)
559  {
560  ret[base++] = string_alloc(first, gc);
561  }
562 
563  if (parms)
564  {
565  n = parse_line(parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
566  ASSERT(n >= 0 && n + base + 1 <= max_parms);
567  }
568  ret[base + n] = NULL;
569 
570  return (const char **)ret;
571 }
572 
573 static const char **
574 make_inline_array(const char *str, struct gc_arena *gc)
575 {
576  char line[OPTION_LINE_SIZE];
577  struct buffer buf;
578  int len = 0;
579  char **ret = NULL;
580  int i = 0;
581 
582  buf_set_read(&buf, (const uint8_t *) str, strlen(str));
583  while (buf_parse(&buf, '\n', line, sizeof(line)))
584  {
585  ++len;
586  }
587 
588  /* alloc return array */
589  ALLOC_ARRAY_CLEAR_GC(ret, char *, len + 1, gc);
590 
591  buf_set_read(&buf, (const uint8_t *) str, strlen(str));
592  while (buf_parse(&buf, '\n', line, sizeof(line)))
593  {
594  chomp(line);
595  ASSERT(i < len);
596  ret[i] = string_alloc(skip_leading_whitespace(line), gc);
597  ++i;
598  }
599  ASSERT(i <= len);
600  ret[i] = NULL;
601  return (const char **)ret;
602 }
603 
604 static const char **
605 make_arg_copy(char **p, struct gc_arena *gc)
606 {
607  char **ret = NULL;
608  const int len = string_array_len((const char **)p);
609  const int max_parms = len + 1;
610  int i;
611 
612  /* alloc return array */
613  ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
614 
615  for (i = 0; i < len; ++i)
616  {
617  ret[i] = p[i];
618  }
619 
620  return (const char **)ret;
621 }
622 
623 const char **
624 make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
625 {
626  const int argc = string_array_len((const char **)p);
627  if (is_inline)
628  {
629  return make_inline_array(p[0], gc);
630  }
631  else if (argc == 0)
632  {
633  return make_arg_array(NULL, NULL, gc);
634  }
635  else if (argc == 1)
636  {
637  return make_arg_array(p[0], NULL, gc);
638  }
639  else if (argc == 2)
640  {
641  return make_arg_array(p[0], p[1], gc);
642  }
643  else
644  {
645  return make_arg_copy(p, gc);
646  }
647 }
648 
649 /*
650  * Remove security-sensitive strings from control message
651  * so that they will not be output to log file.
652  */
653 const char *
654 sanitize_control_message(const char *src, struct gc_arena *gc)
655 {
656  char *ret = gc_malloc(strlen(src)+1, false, gc);
657  char *dest = ret;
658  bool redact = false;
659  int skip = 0;
660 
661  for (;; )
662  {
663  const char c = *src;
664  if (c == '\0')
665  {
666  break;
667  }
668  if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
669  {
670  skip = 7;
671  redact = true;
672  }
673  else if (c == 'e' && !strncmp(src, "echo ", 5))
674  {
675  skip = 4;
676  redact = true;
677  }
678  else if (!check_debug_level(D_SHOW_KEYS)
679  && (c == 'a' && !strncmp(src, "auth-token ", 11)))
680  {
681  /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
682  * the auth-token value coming in the src string
683  */
684  skip = 10;
685  redact = true;
686  }
687 
688  if (c == ',') /* end of redacted item? */
689  {
690  skip = 0;
691  redact = false;
692  }
693 
694  if (redact)
695  {
696  if (skip > 0)
697  {
698  --skip;
699  *dest++ = c;
700  }
701  }
702  else
703  {
704  *dest++ = c;
705  }
706 
707  ++src;
708  }
709  *dest = '\0';
710  return ret;
711 }
712 
713 /* helper to parse peer_info received from multi client, validate
714  * (this is untrusted data) and put into environment
715  */
716 bool
718 {
719  uint8_t c;
720  int state = 0;
721  while (*line)
722  {
723  c = *line;
724  switch (state)
725  {
726  case 0:
727  case 1:
728  if (c == '=' && state == 1)
729  {
730  state = 2;
731  }
732  else if (isalnum(c) || c == '_')
733  {
734  state = 1;
735  }
736  else
737  {
738  return false;
739  }
740 
741  case 2:
742  /* after the '=', replace non-printable or shell meta with '_' */
743  if (!isprint(c) || isspace(c)
744  || c == '$' || c == '(' || c == '`')
745  {
746  *line = '_';
747  }
748  }
749  line++;
750  }
751  return (state == 2);
752 }
753 
754 void
755 output_peer_info_env(struct env_set *es, const char *peer_info)
756 {
757  char line[256];
758  struct buffer buf;
759  buf_set_read(&buf, (const uint8_t *) peer_info, strlen(peer_info));
760  while (buf_parse(&buf, '\n', line, sizeof(line)))
761  {
762  chomp(line);
763  if (validate_peer_info_line(line)
764  && (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0) )
765  {
766  msg(M_INFO, "peer info: %s", line);
767  env_set_add(es, line);
768  }
769  else
770  {
771  msg(M_WARN, "validation failed on peer_info line received from client");
772  }
773  }
774 }
775 
776 struct buffer
777 prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
778 {
779  size_t len = strlen(dir) + strlen(PATH_SEPARATOR_STR) + strlen(path) + 1;
780  struct buffer combined_path = alloc_buf_gc(len, gc);
781  buf_printf(&combined_path, "%s%s%s", dir, PATH_SEPARATOR_STR, path);
782  ASSERT(combined_path.len > 0);
783 
784  return combined_path;
785 }
output_peer_info_env
void output_peer_info_env(struct env_set *es, const char *peer_info)
Definition: misc.c:755
openvpn_base64_decode
int openvpn_base64_decode(const char *str, void *data, int size)
Definition: base64.c:158
set_auth_token_user
void set_auth_token_user(struct user_pass *tk, const char *username)
Sets the auth-token username by base64 decoding the passed username.
Definition: misc.c:516
M_INFO
#define M_INFO
Definition: errlevel.h:55
GET_USER_PASS_PREVIOUS_CREDS_FAILED
#define GET_USER_PASS_PREVIOUS_CREDS_FAILED
Definition: misc.h:113
error.h
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1031
string_array_len
int string_array_len(const char **array)
Definition: buffer.c:747
make_arg_copy
static const char ** make_arg_copy(char **p, struct gc_arena *gc)
Definition: misc.c:605
get_user_pass_cr
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge)
Retrieves the user credentials from various sources depending on the flags.
Definition: misc.c:211
buffer::len
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
prepend_dir
struct buffer prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
Prepend a directory to a path.
Definition: misc.c:777
GET_USER_PASS_STATIC_CHALLENGE_ECHO
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO
Definition: misc.h:117
M_FATAL
#define M_FATAL
Definition: error.h:95
win32.h
streq
#define streq(x, y)
Definition: options.h:708
management_auth_failure
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition: manage.c:3080
manage.h
es
struct env_set * es
Definition: test_pkcs11.c:133
BSTR
#define BSTR(buf)
Definition: buffer.h:129
user_pass::username
char username[USER_PASS_LEN]
Definition: misc.h:71
management_query_user_pass
bool management_query_user_pass(struct management *man, struct user_pass *up, const char *type, const unsigned int flags, const char *static_challenge)
Definition: manage.c:3482
multi_instance::gc
struct gc_arena gc
Definition: multi.h:105
parse_auth_challenge
static struct auth_challenge_info * parse_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
Parses an authentication challenge string and returns an auth_challenge_info structure.
Definition: misc.c:141
make_extended_arg_array
const char ** make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
Definition: misc.c:624
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
CC_CRLF
#define CC_CRLF
carriage return or newline
Definition: buffer.h:938
user_pass::defined
bool defined
Definition: misc.h:58
openvpn_base64_encode
int openvpn_base64_encode(const void *data, int size, char **str)
Definition: base64.c:52
safe_print
const char * safe_print(const char *str, struct gc_arena *gc)
Definition: misc.c:541
parse_line
int parse_line(const char *line, char *p[], const int n, const char *file, const int line_num, int msglevel, struct gc_arena *gc)
Definition: options.c:4961
MAX_PARMS
#define MAX_PARMS
Definition: options.h:52
prng_bytes
void prng_bytes(uint8_t *output, int len)
Definition: crypto.c:1604
format_hex_ex
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition: buffer.c:527
D_LOW
#define D_LOW
Definition: errlevel.h:97
plugin.h
CR_RESPONSE
#define CR_RESPONSE
Definition: misc.h:81
options.h
IPROUTE_PATH
#define IPROUTE_PATH
Definition: config.h:468
console.h
GET_USER_PASS_MANAGEMENT
#define GET_USER_PASS_MANAGEMENT
Definition: misc.h:107
env_set_add
void env_set_add(struct env_set *es, const char *str)
Definition: env_set.c:193
CLEAR
#define CLEAR(x)
Definition: basic.h:33
query_user_SINGLE
static bool query_user_SINGLE(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
A plain "make Gert happy" wrapper.
Definition: console.h:110
string_alloc
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:693
secure_memzero
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition: buffer.h:414
ASSERT
#define ASSERT(x)
Definition: error.h:201
string_clear
void string_clear(char *str)
Definition: buffer.c:735
query_user_add
void query_user_add(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
Adds an item to ask the user for.
Definition: console.c:57
auth_challenge_info
Definition: misc.h:79
query_user_exec
static bool query_user_exec(void)
Wrapper function enabling query_user_exec() if no alternative methods have been enabled.
Definition: console.h:95
tun.h
BLEN
#define BLEN(buf)
Definition: buffer.h:127
make_arg_array
const char ** make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
Definition: misc.c:547
purge_user_pass
void purge_user_pass(struct user_pass *up, const bool force)
Definition: misc.c:473
OPTION_LINE_SIZE
#define OPTION_LINE_SIZE
Definition: options.h:58
auth_challenge_info::challenge_text
const char * challenge_text
Definition: misc.h:86
auth_challenge
static char * auth_challenge
Definition: ssl.c:276
CC_PRINT
#define CC_PRINT
printable (>= 32, != 127)
Definition: buffer.h:909
GET_USER_PASS_DYNAMIC_CHALLENGE
#define GET_USER_PASS_DYNAMIC_CHALLENGE
Definition: misc.h:115
string_mod
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition: buffer.c:1085
ALLOC_ARRAY_CLEAR_GC
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Definition: buffer.h:1088
misc.h
route.h
make_inline_array
static const char ** make_inline_array(const char *str, struct gc_arena *gc)
Definition: misc.c:574
M_WARN
#define M_WARN
Definition: error.h:97
ALLOC_OBJ_CLEAR_GC
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition: buffer.h:1103
n_rnd_bytes
#define n_rnd_bytes
crypto.h
GET_USER_PASS_NOFATAL
#define GET_USER_PASS_NOFATAL
Definition: misc.h:111
M_ERR
#define M_ERR
Definition: error.h:111
base64.h
user_pass::nocache
bool nocache
Definition: misc.h:62
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
query_user_clear
void query_user_clear(void)
Wipes all data put into all of the query_user structs.
Definition: console.c:45
management_query_user_pass_enabled
static bool management_query_user_pass_enabled(const struct management *man)
Definition: manage.h:442
auth_challenge_info::state_id
const char * state_id
Definition: misc.h:85
buffer.h
syshead.h
platform_fopen
FILE * platform_fopen(const char *path, const char *mode)
Definition: platform.c:514
CR_ECHO
#define CR_ECHO
Definition: misc.h:80
D_PUSH
#define D_PUSH
Definition: errlevel.h:83
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
buf_set_write
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition: buffer.h:331
strncpynt
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:361
env_set
Definition: env_set.h:42
auth_challenge_info::user
const char * user
Definition: misc.h:84
set_auth_token
void set_auth_token(struct user_pass *up, struct user_pass *tk, const char *token)
Sets the auth-token to token.
Definition: misc.c:494
check_debug_level
static bool check_debug_level(unsigned int level)
Definition: error.h:226
chomp
void chomp(char *str)
Definition: buffer.c:658
set_std_files_to_null
void set_std_files_to_null(bool stdin_only)
Definition: misc.c:56
gc_malloc
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:380
otime.h
user_pass::token_defined
bool token_defined
Definition: misc.h:61
management
Definition: manage.h:335
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1039
GET_USER_PASS_PASSWORD_ONLY
#define GET_USER_PASS_PASSWORD_ONLY
Definition: misc.h:109
USER_PASS_LEN
#define USER_PASS_LEN
Definition: misc.h:68
GET_USER_PASS_NEED_OK
#define GET_USER_PASS_NEED_OK
Definition: misc.h:110
config.h
validate_peer_info_line
bool validate_peer_info_line(char *line)
Definition: misc.c:717
D_SHOW_KEYS
#define D_SHOW_KEYS
Definition: errlevel.h:121
sanitize_control_message
const char * sanitize_control_message(const char *src, struct gc_arena *gc)
Definition: misc.c:654
user_pass::password
char password[USER_PASS_LEN]
Definition: misc.h:72
GET_USER_PASS_INLINE_CREDS
#define GET_USER_PASS_INLINE_CREDS
Definition: misc.h:119
auth_challenge_info::flags
unsigned int flags
Definition: misc.h:82
user_pass
Definition: misc.h:56
PATH_SEPARATOR_STR
#define PATH_SEPARATOR_STR
Definition: syshead.h:417
memdbg.h
auth_user_pass_mgmt
static bool auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags, const char *auth_challenge)
Definition: misc.c:100
skip_leading_whitespace
const char * skip_leading_whitespace(const char *str)
Definition: buffer.c:623
GET_USER_PASS_STATIC_CHALLENGE
#define GET_USER_PASS_STATIC_CHALLENGE
Definition: misc.h:116
string_mod_const
const char * string_mod_const(const char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace, struct gc_arena *gc)
Returns a copy of a string with certain classes of characters of it replaced with a specified charact...
Definition: buffer.c:1117
msg
#define msg(flags,...)
Definition: error.h:150
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
BOOL_CAST
#define BOOL_CAST(x)
Definition: basic.h:27
buf_set_read
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition: buffer.h:348
hostname_randomize
const char * hostname_randomize(const char *hostname, struct gc_arena *gc)
Definition: misc.c:82
buf_parse
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition: buffer.c:869