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