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