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-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
9  * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
10  * Copyright (C) 2016-2017 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 /* contains an SSEC_x value defined in misc.h */
55 int script_security = SSEC_BUILT_IN; /* GLOBAL */
56 
57 /*
58  * Set standard file descriptors to /dev/null
59  */
60 void
61 set_std_files_to_null(bool stdin_only)
62 {
63 #if defined(HAVE_DUP) && defined(HAVE_DUP2)
64  int fd;
65  if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
66  {
67  dup2(fd, 0);
68  if (!stdin_only)
69  {
70  dup2(fd, 1);
71  dup2(fd, 2);
72  }
73  if (fd > 2)
74  {
75  close(fd);
76  }
77  }
78 #endif
79 }
80 
81 /*
82  * dup inetd/xinetd socket descriptor and save
83  */
84 
86 
87 void
89 {
91 #if defined(HAVE_DUP) && defined(HAVE_DUP2)
92  /* use handle passed by inetd/xinetd */
94  {
95  msg(M_ERR, "INETD_SOCKET_DESCRIPTOR dup(%d) failed", INETD_SOCKET_DESCRIPTOR);
96  }
98 #endif
99 }
100 
101 /*
102  * Print an error message based on the status code returned by system().
103  */
104 const char *
105 system_error_message(int stat, struct gc_arena *gc)
106 {
107  struct buffer out = alloc_buf_gc(256, gc);
108 #ifdef _WIN32
109  if (stat == -1)
110  {
111  buf_printf(&out, "external program did not execute -- ");
112  }
113  buf_printf(&out, "returned error code %d", stat);
114 #else /* ifdef _WIN32 */
115  if (stat == -1)
116  {
117  buf_printf(&out, "external program fork failed");
118  }
119  else if (!WIFEXITED(stat))
120  {
121  buf_printf(&out, "external program did not exit normally");
122  }
123  else
124  {
125  const int cmd_ret = WEXITSTATUS(stat);
126  if (!cmd_ret)
127  {
128  buf_printf(&out, "external program exited normally");
129  }
130  else if (cmd_ret == 127)
131  {
132  buf_printf(&out, "could not execute external program");
133  }
134  else
135  {
136  buf_printf(&out, "external program exited with error status: %d", cmd_ret);
137  }
138  }
139 #endif /* ifdef _WIN32 */
140  return (const char *)out.data;
141 }
142 
143 /*
144  * Wrapper around openvpn_execve
145  */
146 bool
147 openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
148 {
149  struct gc_arena gc = gc_new();
150  const int stat = openvpn_execve(a, es, flags);
151  int ret = false;
152 
153  if (platform_system_ok(stat))
154  {
155  ret = true;
156  }
157  else
158  {
159  if (error_message)
160  {
161  msg(((flags & S_FATAL) ? M_FATAL : M_WARN), "%s: %s",
162  error_message,
163  system_error_message(stat, &gc));
164  }
165  }
166  gc_free(&gc);
167  return ret;
168 }
169 
170 bool
171 openvpn_execve_allowed(const unsigned int flags)
172 {
173  if (flags & S_SCRIPT)
174  {
175  return script_security >= SSEC_SCRIPTS;
176  }
177  else
178  {
179  return script_security >= SSEC_BUILT_IN;
180  }
181 }
182 
183 
184 #ifndef _WIN32
185 /*
186  * Run execve() inside a fork(). Designed to replicate the semantics of system() but
187  * in a safer way that doesn't require the invocation of a shell or the risks
188  * assocated with formatting and parsing a command line.
189  */
190 int
191 openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
192 {
193  struct gc_arena gc = gc_new();
194  int ret = -1;
195  static bool warn_shown = false;
196 
197  if (a && a->argv[0])
198  {
199 #if defined(ENABLE_FEATURE_EXECVE)
200  if (openvpn_execve_allowed(flags))
201  {
202  const char *cmd = a->argv[0];
203  char *const *argv = a->argv;
204  char *const *envp = (char *const *)make_env_array(es, true, &gc);
205  pid_t pid;
206 
207  pid = fork();
208  if (pid == (pid_t)0) /* child side */
209  {
210  execve(cmd, argv, envp);
211  exit(127);
212  }
213  else if (pid < (pid_t)0) /* fork failed */
214  {
215  msg(M_ERR, "openvpn_execve: unable to fork");
216  }
217  else /* parent side */
218  {
219  if (waitpid(pid, &ret, 0) != pid)
220  {
221  ret = -1;
222  }
223  }
224  }
225  else if (!warn_shown && (script_security < SSEC_SCRIPTS))
226  {
228  warn_shown = true;
229  }
230 #else /* if defined(ENABLE_FEATURE_EXECVE) */
231  msg(M_WARN, "openvpn_execve: execve function not available");
232 #endif /* if defined(ENABLE_FEATURE_EXECVE) */
233  }
234  else
235  {
236  msg(M_FATAL, "openvpn_execve: called with empty argv");
237  }
238 
239  gc_free(&gc);
240  return ret;
241 }
242 #endif /* ifndef _WIN32 */
243 
244 /*
245  * Run execve() inside a fork(), duping stdout. Designed to replicate the semantics of popen() but
246  * in a safer way that doesn't require the invocation of a shell or the risks
247  * assocated with formatting and parsing a command line.
248  */
249 int
250 openvpn_popen(const struct argv *a, const struct env_set *es)
251 {
252  struct gc_arena gc = gc_new();
253  int ret = -1;
254  static bool warn_shown = false;
255 
256  if (a && a->argv[0])
257  {
258 #if defined(ENABLE_FEATURE_EXECVE)
260  {
261  const char *cmd = a->argv[0];
262  char *const *argv = a->argv;
263  char *const *envp = (char *const *)make_env_array(es, true, &gc);
264  pid_t pid;
265  int pipe_stdout[2];
266 
267  if (pipe(pipe_stdout) == 0)
268  {
269  pid = fork();
270  if (pid == (pid_t)0) /* child side */
271  {
272  close(pipe_stdout[0]); /* Close read end */
273  dup2(pipe_stdout[1],1);
274  execve(cmd, argv, envp);
275  exit(127);
276  }
277  else if (pid > (pid_t)0) /* parent side */
278  {
279  int status = 0;
280 
281  close(pipe_stdout[1]); /* Close write end */
282  waitpid(pid, &status, 0);
283  ret = pipe_stdout[0];
284  }
285  else /* fork failed */
286  {
287  close(pipe_stdout[0]);
288  close(pipe_stdout[1]);
289  msg(M_ERR, "openvpn_popen: unable to fork %s", cmd);
290  }
291  }
292  else
293  {
294  msg(M_WARN, "openvpn_popen: unable to create stdout pipe for %s", cmd);
295  ret = -1;
296  }
297  }
298  else if (!warn_shown && (script_security < SSEC_SCRIPTS))
299  {
301  warn_shown = true;
302  }
303 #else /* if defined(ENABLE_FEATURE_EXECVE) */
304  msg(M_WARN, "openvpn_popen: execve function not available");
305 #endif /* if defined(ENABLE_FEATURE_EXECVE) */
306  }
307  else
308  {
309  msg(M_FATAL, "openvpn_popen: called with empty argv");
310  }
311 
312  gc_free(&gc);
313  return ret;
314 }
315 
316 
317 
318 /*
319  * Set environmental variable (int or string).
320  *
321  * On Posix, we use putenv for portability,
322  * and put up with its painful semantics
323  * that require all the support code below.
324  */
325 
326 /* General-purpose environmental variable set functions */
327 
328 static char *
329 construct_name_value(const char *name, const char *value, struct gc_arena *gc)
330 {
331  struct buffer out;
332 
333  ASSERT(name);
334  if (!value)
335  {
336  value = "";
337  }
338  out = alloc_buf_gc(strlen(name) + strlen(value) + 2, gc);
339  buf_printf(&out, "%s=%s", name, value);
340  return BSTR(&out);
341 }
342 
343 static bool
344 env_string_equal(const char *s1, const char *s2)
345 {
346  int c1, c2;
347  ASSERT(s1);
348  ASSERT(s2);
349 
350  while (true)
351  {
352  c1 = *s1++;
353  c2 = *s2++;
354  if (c1 == '=')
355  {
356  c1 = 0;
357  }
358  if (c2 == '=')
359  {
360  c2 = 0;
361  }
362  if (!c1 && !c2)
363  {
364  return true;
365  }
366  if (c1 != c2)
367  {
368  break;
369  }
370  }
371  return false;
372 }
373 
374 static bool
375 remove_env_item(const char *str, const bool do_free, struct env_item **list)
376 {
377  struct env_item *current, *prev;
378 
379  ASSERT(str);
380  ASSERT(list);
381 
382  for (current = *list, prev = NULL; current != NULL; current = current->next)
383  {
384  if (env_string_equal(current->string, str))
385  {
386  if (prev)
387  {
388  prev->next = current->next;
389  }
390  else
391  {
392  *list = current->next;
393  }
394  if (do_free)
395  {
396  secure_memzero(current->string, strlen(current->string));
397  free(current->string);
398  free(current);
399  }
400  return true;
401  }
402  prev = current;
403  }
404  return false;
405 }
406 
407 static void
408 add_env_item(char *str, const bool do_alloc, struct env_item **list, struct gc_arena *gc)
409 {
410  struct env_item *item;
411 
412  ASSERT(str);
413  ASSERT(list);
414 
415  ALLOC_OBJ_GC(item, struct env_item, gc);
416  item->string = do_alloc ? string_alloc(str, gc) : str;
417  item->next = *list;
418  *list = item;
419 }
420 
421 /* struct env_set functions */
422 
423 static bool
424 env_set_del_nolock(struct env_set *es, const char *str)
425 {
426  return remove_env_item(str, es->gc == NULL, &es->list);
427 }
428 
429 static void
430 env_set_add_nolock(struct env_set *es, const char *str)
431 {
432  remove_env_item(str, es->gc == NULL, &es->list);
433  add_env_item((char *)str, true, &es->list, es->gc);
434 }
435 
436 struct env_set *
438 {
439  struct env_set *es;
440  ALLOC_OBJ_CLEAR_GC(es, struct env_set, gc);
441  es->list = NULL;
442  es->gc = gc;
443  return es;
444 }
445 
446 void
448 {
449  if (es && es->gc == NULL)
450  {
451  struct env_item *e = es->list;
452  while (e)
453  {
454  struct env_item *next = e->next;
455  free(e->string);
456  free(e);
457  e = next;
458  }
459  free(es);
460  }
461 }
462 
463 bool
464 env_set_del(struct env_set *es, const char *str)
465 {
466  bool ret;
467  ASSERT(es);
468  ASSERT(str);
469  ret = env_set_del_nolock(es, str);
470  return ret;
471 }
472 
473 void
474 env_set_add(struct env_set *es, const char *str)
475 {
476  ASSERT(es);
477  ASSERT(str);
478  env_set_add_nolock(es, str);
479 }
480 
481 const char *
482 env_set_get(const struct env_set *es, const char *name)
483 {
484  const struct env_item *item = es->list;
485  while (item && !env_string_equal(item->string, name))
486  {
487  item = item->next;
488  }
489  return item ? item->string : NULL;
490 }
491 
492 void
493 env_set_print(int msglevel, const struct env_set *es)
494 {
495  if (check_debug_level(msglevel))
496  {
497  const struct env_item *e;
498  int i;
499 
500  if (es)
501  {
502  e = es->list;
503  i = 0;
504 
505  while (e)
506  {
507  if (env_safe_to_print(e->string))
508  {
509  msg(msglevel, "ENV [%d] '%s'", i, e->string);
510  }
511  ++i;
512  e = e->next;
513  }
514  }
515  }
516 }
517 
518 void
519 env_set_inherit(struct env_set *es, const struct env_set *src)
520 {
521  const struct env_item *e;
522 
523  ASSERT(es);
524 
525  if (src)
526  {
527  e = src->list;
528  while (e)
529  {
530  env_set_add_nolock(es, e->string);
531  e = e->next;
532  }
533  }
534 }
535 
536 
537 /* add/modify/delete environmental strings */
538 
539 void
540 setenv_counter(struct env_set *es, const char *name, counter_type value)
541 {
542  char buf[64];
543  openvpn_snprintf(buf, sizeof(buf), counter_format, value);
544  setenv_str(es, name, buf);
545 }
546 
547 void
548 setenv_int(struct env_set *es, const char *name, int value)
549 {
550  char buf[64];
551  openvpn_snprintf(buf, sizeof(buf), "%d", value);
552  setenv_str(es, name, buf);
553 }
554 
555 void
556 setenv_unsigned(struct env_set *es, const char *name, unsigned int value)
557 {
558  char buf[64];
559  openvpn_snprintf(buf, sizeof(buf), "%u", value);
560  setenv_str(es, name, buf);
561 }
562 
563 void
564 setenv_str(struct env_set *es, const char *name, const char *value)
565 {
566  setenv_str_ex(es, name, value, CC_NAME, 0, 0, CC_PRINT, 0, 0);
567 }
568 
569 void
570 setenv_str_safe(struct env_set *es, const char *name, const char *value)
571 {
572  uint8_t b[64];
573  struct buffer buf;
574  buf_set_write(&buf, b, sizeof(b));
575  if (buf_printf(&buf, "OPENVPN_%s", name))
576  {
577  setenv_str(es, BSTR(&buf), value);
578  }
579  else
580  {
581  msg(M_WARN, "setenv_str_safe: name overflow");
582  }
583 }
584 
585 void
586 setenv_str_incr(struct env_set *es, const char *name, const char *value)
587 {
588  unsigned int counter = 1;
589  const size_t tmpname_len = strlen(name) + 5; /* 3 digits counter max */
590  char *tmpname = gc_malloc(tmpname_len, true, NULL);
591  strcpy(tmpname, name);
592  while (NULL != env_set_get(es, tmpname) && counter < 1000)
593  {
594  ASSERT(openvpn_snprintf(tmpname, tmpname_len, "%s_%u", name, counter));
595  counter++;
596  }
597  if (counter < 1000)
598  {
599  setenv_str(es, tmpname, value);
600  }
601  else
602  {
603  msg(D_TLS_DEBUG_MED, "Too many same-name env variables, ignoring: %s", name);
604  }
605  free(tmpname);
606 }
607 
608 void
609 setenv_del(struct env_set *es, const char *name)
610 {
611  ASSERT(name);
612  setenv_str(es, name, NULL);
613 }
614 
615 void
617  const char *name,
618  const char *value,
619  const unsigned int name_include,
620  const unsigned int name_exclude,
621  const char name_replace,
622  const unsigned int value_include,
623  const unsigned int value_exclude,
624  const char value_replace)
625 {
626  struct gc_arena gc = gc_new();
627  const char *name_tmp;
628  const char *val_tmp = NULL;
629 
630  ASSERT(name && strlen(name) > 1);
631 
632  name_tmp = string_mod_const(name, name_include, name_exclude, name_replace, &gc);
633 
634  if (value)
635  {
636  val_tmp = string_mod_const(value, value_include, value_exclude, value_replace, &gc);
637  }
638 
639  ASSERT(es);
640 
641  if (val_tmp)
642  {
643  const char *str = construct_name_value(name_tmp, val_tmp, &gc);
644  env_set_add(es, str);
645 #if DEBUG_VERBOSE_SETENV
646  msg(M_INFO, "SETENV_ES '%s'", str);
647 #endif
648  }
649  else
650  {
651  env_set_del(es, name_tmp);
652  }
653 
654  gc_free(&gc);
655 }
656 
657 /*
658  * Setenv functions that append an integer index to the name
659  */
660 static const char *
661 setenv_format_indexed_name(const char *name, const int i, struct gc_arena *gc)
662 {
663  struct buffer out = alloc_buf_gc(strlen(name) + 16, gc);
664  if (i >= 0)
665  {
666  buf_printf(&out, "%s_%d", name, i);
667  }
668  else
669  {
670  buf_printf(&out, "%s", name);
671  }
672  return BSTR(&out);
673 }
674 
675 void
676 setenv_int_i(struct env_set *es, const char *name, const int value, const int i)
677 {
678  struct gc_arena gc = gc_new();
679  const char *name_str = setenv_format_indexed_name(name, i, &gc);
680  setenv_int(es, name_str, value);
681  gc_free(&gc);
682 }
683 
684 void
685 setenv_str_i(struct env_set *es, const char *name, const char *value, const int i)
686 {
687  struct gc_arena gc = gc_new();
688  const char *name_str = setenv_format_indexed_name(name, i, &gc);
689  setenv_str(es, name_str, value);
690  gc_free(&gc);
691 }
692 
693 /* return true if filename can be opened for read */
694 bool
695 test_file(const char *filename)
696 {
697  bool ret = false;
698  if (filename)
699  {
700  FILE *fp = platform_fopen(filename, "r");
701  if (fp)
702  {
703  fclose(fp);
704  ret = true;
705  }
706  else
707  {
708  if (openvpn_errno() == EACCES)
709  {
710  msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
711  }
712  }
713  }
714 
715  dmsg(D_TEST_FILE, "TEST FILE '%s' [%d]",
716  filename ? filename : "UNDEF",
717  ret);
718 
719  return ret;
720 }
721 
722 /* create a temporary filename in directory */
723 const char *
724 create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
725 {
726  static unsigned int counter;
727  struct buffer fname = alloc_buf_gc(256, gc);
728  int fd;
729  const char *retfname = NULL;
730  unsigned int attempts = 0;
731 
732  do
733  {
734  ++attempts;
735  ++counter;
736 
737  buf_printf(&fname, PACKAGE "_%s_%08lx%08lx.tmp", prefix,
738  (unsigned long) get_random(), (unsigned long) get_random());
739 
740  retfname = gen_path(directory, BSTR(&fname), gc);
741  if (!retfname)
742  {
743  msg(M_FATAL, "Failed to create temporary filename and path");
744  return NULL;
745  }
746 
747  /* Atomically create the file. Errors out if the file already
748  * exists. */
749  fd = platform_open(retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
750  if (fd != -1)
751  {
752  close(fd);
753  return retfname;
754  }
755  else if (fd == -1 && errno != EEXIST)
756  {
757  /* Something else went wrong, no need to retry. */
758  msg(M_FATAL | M_ERRNO, "Could not create temporary file '%s'",
759  retfname);
760  return NULL;
761  }
762  }
763  while (attempts < 6);
764 
765  msg(M_FATAL, "Failed to create temporary file after %i attempts", attempts);
766  return NULL;
767 }
768 
769 #ifdef ENABLE_CRYPTO
770 
771 /*
772  * Prepend a random string to hostname to prevent DNS caching.
773  * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
774  * Of course, this requires explicit support in the DNS server (wildcard).
775  */
776 const char *
777 hostname_randomize(const char *hostname, struct gc_arena *gc)
778 {
779 #define n_rnd_bytes 6
780 
781  uint8_t rnd_bytes[n_rnd_bytes];
782  const char *rnd_str;
783  struct buffer hname = alloc_buf_gc(strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);
784 
785  prng_bytes(rnd_bytes, sizeof(rnd_bytes));
786  rnd_str = format_hex_ex(rnd_bytes, sizeof(rnd_bytes), 40, 0, NULL, gc);
787  buf_printf(&hname, "%s.%s", rnd_str, hostname);
788  return BSTR(&hname);
789 #undef n_rnd_bytes
790 }
791 
792 #else /* ifdef ENABLE_CRYPTO */
793 
794 const char *
795 hostname_randomize(const char *hostname, struct gc_arena *gc)
796 {
797  msg(M_WARN, "WARNING: hostname randomization disabled when crypto support is not compiled");
798  return hostname;
799 }
800 
801 #endif /* ifdef ENABLE_CRYPTO */
802 
803 /*
804  * Put a directory and filename together.
805  */
806 const char *
807 gen_path(const char *directory, const char *filename, struct gc_arena *gc)
808 {
809 #ifdef _WIN32
810  const int CC_PATH_RESERVED = CC_LESS_THAN|CC_GREATER_THAN|CC_COLON
812 #else
813  const int CC_PATH_RESERVED = CC_SLASH;
814 #endif
815  const char *safe_filename = string_mod_const(filename, CC_PRINT, CC_PATH_RESERVED, '_', gc);
816 
817  if (safe_filename
818  && strcmp(safe_filename, ".")
819  && strcmp(safe_filename, "..")
820 #ifdef _WIN32
821  && win_safe_filename(safe_filename)
822 #endif
823  )
824  {
825  const size_t outsize = strlen(safe_filename) + (directory ? strlen(directory) : 0) + 16;
826  struct buffer out = alloc_buf_gc(outsize, gc);
827  char dirsep[2];
828 
829  dirsep[0] = OS_SPECIFIC_DIRSEP;
830  dirsep[1] = '\0';
831 
832  if (directory)
833  {
834  buf_printf(&out, "%s%s", directory, dirsep);
835  }
836  buf_printf(&out, "%s", safe_filename);
837 
838  return BSTR(&out);
839  }
840  else
841  {
842  return NULL;
843  }
844 }
845 
846 bool
847 absolute_pathname(const char *pathname)
848 {
849  if (pathname)
850  {
851  const int c = pathname[0];
852 #ifdef _WIN32
853  return c == '\\' || (isalpha(c) && pathname[1] == ':' && pathname[2] == '\\');
854 #else
855  return c == '/';
856 #endif
857  }
858  else
859  {
860  return false;
861  }
862 }
863 
864 /*
865  * Get and store a username/password
866  */
867 
868 bool
870  const char *auth_file,
871  const char *prefix,
872  const unsigned int flags,
873  const char *auth_challenge)
874 {
875  struct gc_arena gc = gc_new();
876 
877  if (!up->defined)
878  {
879  bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
880  bool username_from_stdin = false;
881  bool password_from_stdin = false;
882  bool response_from_stdin = true;
883 
885  {
886  msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
887  }
888 
889 #ifdef ENABLE_MANAGEMENT
890  /*
891  * Get username/password from management interface?
892  */
893  if (management
894  && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
896  {
897  const char *sc = NULL;
898  response_from_stdin = false;
899 
900  if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
901  {
902  management_auth_failure(management, prefix, "previous auth credentials failed");
903  }
904 
905 #ifdef ENABLE_CLIENT_CR
906  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
907  {
908  sc = auth_challenge;
909  }
910 #endif
911  if (!management_query_user_pass(management, up, prefix, flags, sc))
912  {
913  if ((flags & GET_USER_PASS_NOFATAL) != 0)
914  {
915  return false;
916  }
917  else
918  {
919  msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
920  }
921  }
922  }
923  else
924 #endif /* ifdef ENABLE_MANAGEMENT */
925  /*
926  * Get NEED_OK confirmation from the console
927  */
928  if (flags & GET_USER_PASS_NEED_OK)
929  {
930  struct buffer user_prompt = alloc_buf_gc(128, &gc);
931 
932  buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
933  if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
934  up->password, USER_PASS_LEN, false))
935  {
936  msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
937  }
938 
939  if (!strlen(up->password))
940  {
941  strcpy(up->password, "ok");
942  }
943  }
944  else if (flags & GET_USER_PASS_INLINE_CREDS)
945  {
946  struct buffer buf;
947  buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
948  if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
949  {
950  buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
951  }
952  buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
953  }
954  /*
955  * Read from auth file unless this is a dynamic challenge request.
956  */
957  else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
958  {
959  /*
960  * Try to get username/password from a file.
961  */
962  FILE *fp;
963  char password_buf[USER_PASS_LEN] = { '\0' };
964 
965  fp = platform_fopen(auth_file, "r");
966  if (!fp)
967  {
968  msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
969  }
970 
971  if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
972  {
973  /* Read username first */
974  if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
975  {
976  msg(M_FATAL, "Error reading username from %s authfile: %s",
977  prefix,
978  auth_file);
979  }
980  }
981  chomp(up->username);
982 
983  if (fgets(password_buf, USER_PASS_LEN, fp) != NULL)
984  {
985  chomp(password_buf);
986  }
987 
988  if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
989  {
990  msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
991  }
992 
993  if (password_buf[0])
994  {
995  strncpy(up->password, password_buf, USER_PASS_LEN);
996  }
997  else
998  {
999  password_from_stdin = 1;
1000  }
1001 
1002  fclose(fp);
1003 
1004  if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
1005  {
1006  msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
1007  }
1008  }
1009  else
1010  {
1011  username_from_stdin = true;
1012  password_from_stdin = true;
1013  }
1014 
1015  /*
1016  * Get username/password from standard input?
1017  */
1018  if (username_from_stdin || password_from_stdin || response_from_stdin)
1019  {
1020 #ifdef ENABLE_CLIENT_CR
1021  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin)
1022  {
1023  struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc);
1024  if (ac)
1025  {
1026  char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
1027  struct buffer packed_resp, challenge;
1028 
1029  challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc);
1030  buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
1031  buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
1032 
1033  if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
1034  response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
1035  {
1036  msg(M_FATAL, "ERROR: could not read challenge response from stdin");
1037  }
1038  strncpynt(up->username, ac->user, USER_PASS_LEN);
1039  buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
1040  }
1041  else
1042  {
1043  msg(M_FATAL, "ERROR: received malformed challenge request from server");
1044  }
1045  }
1046  else
1047 #endif /* ifdef ENABLE_CLIENT_CR */
1048  {
1049  struct buffer user_prompt = alloc_buf_gc(128, &gc);
1050  struct buffer pass_prompt = alloc_buf_gc(128, &gc);
1051 
1052  query_user_clear();
1053  buf_printf(&user_prompt, "Enter %s Username:", prefix);
1054  buf_printf(&pass_prompt, "Enter %s Password:", prefix);
1055 
1056  if (username_from_stdin && !(flags & GET_USER_PASS_PASSWORD_ONLY))
1057  {
1058  query_user_add(BSTR(&user_prompt), BLEN(&user_prompt),
1059  up->username, USER_PASS_LEN, true);
1060  }
1061 
1062  if (password_from_stdin)
1063  {
1064  query_user_add(BSTR(&pass_prompt), BLEN(&pass_prompt),
1065  up->password, USER_PASS_LEN, false);
1066  }
1067 
1068  if (!query_user_exec() )
1069  {
1070  msg(M_FATAL, "ERROR: Failed retrieving username or password");
1071  }
1072 
1073  if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
1074  {
1075  if (strlen(up->username) == 0)
1076  {
1077  msg(M_FATAL, "ERROR: %s username is empty", prefix);
1078  }
1079  }
1080 
1081 #ifdef ENABLE_CLIENT_CR
1082  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin)
1083  {
1084  char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
1085  struct buffer packed_resp, challenge;
1086  char *pw64 = NULL, *resp64 = NULL;
1087 
1088  challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
1089  buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
1090 
1091  if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
1092  response, USER_PASS_LEN,
1094  {
1095  msg(M_FATAL, "ERROR: could not retrieve static challenge response");
1096  }
1097  if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
1098  || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
1099  {
1100  msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
1101  }
1102  buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
1103  buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
1104  string_clear(pw64);
1105  free(pw64);
1106  string_clear(resp64);
1107  free(resp64);
1108  }
1109 #endif /* ifdef ENABLE_CLIENT_CR */
1110  }
1111  }
1112 
1113  string_mod(up->username, CC_PRINT, CC_CRLF, 0);
1114  string_mod(up->password, CC_PRINT, CC_CRLF, 0);
1115 
1116  up->defined = true;
1117  }
1118 
1119 #if 0
1120  msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
1121 #endif
1122 
1123  gc_free(&gc);
1124 
1125  return true;
1126 }
1127 
1128 #ifdef ENABLE_CLIENT_CR
1129 
1130 /*
1131  * See management/management-notes.txt for more info on the
1132  * the dynamic challenge/response protocol implemented here.
1133  */
1134 struct auth_challenge_info *
1136 {
1137  if (auth_challenge)
1138  {
1139  struct auth_challenge_info *ac;
1140  const int len = strlen(auth_challenge);
1141  char *work = (char *) gc_malloc(len+1, false, gc);
1142  char *cp;
1143 
1144  struct buffer b;
1145  buf_set_read(&b, (const uint8_t *)auth_challenge, len);
1146 
1147  ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
1148 
1149  /* parse prefix */
1150  if (!buf_parse(&b, ':', work, len))
1151  {
1152  return NULL;
1153  }
1154  if (strcmp(work, "CRV1"))
1155  {
1156  return NULL;
1157  }
1158 
1159  /* parse flags */
1160  if (!buf_parse(&b, ':', work, len))
1161  {
1162  return NULL;
1163  }
1164  for (cp = work; *cp != '\0'; ++cp)
1165  {
1166  const char c = *cp;
1167  if (c == 'E')
1168  {
1169  ac->flags |= CR_ECHO;
1170  }
1171  else if (c == 'R')
1172  {
1173  ac->flags |= CR_RESPONSE;
1174  }
1175  }
1176 
1177  /* parse state ID */
1178  if (!buf_parse(&b, ':', work, len))
1179  {
1180  return NULL;
1181  }
1182  ac->state_id = string_alloc(work, gc);
1183 
1184  /* parse user name */
1185  if (!buf_parse(&b, ':', work, len))
1186  {
1187  return NULL;
1188  }
1189  ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
1190  openvpn_base64_decode(work, (void *)ac->user, -1);
1191 
1192  /* parse challenge text */
1193  ac->challenge_text = string_alloc(BSTR(&b), gc);
1194 
1195  return ac;
1196  }
1197  else
1198  {
1199  return NULL;
1200  }
1201 }
1202 
1203 #endif /* ifdef ENABLE_CLIENT_CR */
1204 
1205 #if AUTO_USERID
1206 
1207 void
1208 get_user_pass_auto_userid(struct user_pass *up, const char *tag)
1209 {
1210  struct gc_arena gc = gc_new();
1211  struct buffer buf;
1212  uint8_t macaddr[6];
1213  static uint8_t digest [MD5_DIGEST_LENGTH];
1214  static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST";
1215 
1216  const md_kt_t *md5_kt = md_kt_get("MD5");
1217  md_ctx_t *ctx;
1218 
1219  CLEAR(*up);
1221  buf_printf(&buf, "%s", TARGET_PREFIX);
1222  if (get_default_gateway_mac_addr(macaddr))
1223  {
1224  dmsg(D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex(macaddr, sizeof(macaddr), 0, 1, ":", &gc));
1225  ctx = md_ctx_new();
1226  md_ctx_init(ctx, md5_kt);
1227  md_ctx_update(ctx, hashprefix, sizeof(hashprefix) - 1);
1228  md_ctx_update(ctx, macaddr, sizeof(macaddr));
1229  md_ctx_final(ctx, digest);
1230  md_ctx_cleanup(ctx);
1231  md_ctx_free(ctx);
1232  buf_printf(&buf, "%s", format_hex_ex(digest, sizeof(digest), 0, 256, " ", &gc));
1233  }
1234  else
1235  {
1236  buf_printf(&buf, "UNKNOWN");
1237  }
1238  if (tag && strcmp(tag, "stdin"))
1239  {
1240  buf_printf(&buf, "-%s", tag);
1241  }
1242  up->defined = true;
1243  gc_free(&gc);
1244 
1245  dmsg(D_AUTO_USERID, "GUPAU: AUTO_USERID: '%s'", up->username);
1246 }
1247 
1248 #endif /* if AUTO_USERID */
1249 
1250 void
1251 purge_user_pass(struct user_pass *up, const bool force)
1252 {
1253  const bool nocache = up->nocache;
1254  static bool warn_shown = false;
1255  if (nocache || force)
1256  {
1257  secure_memzero(up, sizeof(*up));
1258  up->nocache = nocache;
1259  }
1260  /*
1261  * don't show warning if the pass has been replaced by a token: this is an
1262  * artificial "auth-nocache"
1263  */
1264  else if (!warn_shown && (!up->tokenized))
1265  {
1266  msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
1267  warn_shown = true;
1268  }
1269 }
1270 
1271 void
1272 set_auth_token(struct user_pass *up, const char *token)
1273 {
1274  if (token && strlen(token) && up && up->defined && !up->nocache)
1275  {
1276  CLEAR(up->password);
1277  strncpynt(up->password, token, USER_PASS_LEN);
1278  up->tokenized = true;
1279  }
1280 }
1281 
1282 /*
1283  * Process string received by untrusted peer before
1284  * printing to console or log file.
1285  *
1286  * Assumes that string has been null terminated.
1287  */
1288 const char *
1289 safe_print(const char *str, struct gc_arena *gc)
1290 {
1291  return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
1292 }
1293 
1294 static bool
1295 is_password_env_var(const char *str)
1296 {
1297  return (strncmp(str, "password", 8) == 0);
1298 }
1299 
1300 bool
1301 env_allowed(const char *str)
1302 {
1303  return (script_security >= SSEC_PW_ENV || !is_password_env_var(str));
1304 }
1305 
1306 bool
1307 env_safe_to_print(const char *str)
1308 {
1309 #ifndef UNSAFE_DEBUG
1310  if (is_password_env_var(str))
1311  {
1312  return false;
1313  }
1314 #endif
1315  return true;
1316 }
1317 
1318 /* Make arrays of strings */
1319 
1320 const char **
1321 make_env_array(const struct env_set *es,
1322  const bool check_allowed,
1323  struct gc_arena *gc)
1324 {
1325  char **ret = NULL;
1326  struct env_item *e = NULL;
1327  int i = 0, n = 0;
1328 
1329  /* figure length of es */
1330  if (es)
1331  {
1332  for (e = es->list; e != NULL; e = e->next)
1333  {
1334  ++n;
1335  }
1336  }
1337 
1338  /* alloc return array */
1339  ALLOC_ARRAY_CLEAR_GC(ret, char *, n+1, gc);
1340 
1341  /* fill return array */
1342  if (es)
1343  {
1344  i = 0;
1345  for (e = es->list; e != NULL; e = e->next)
1346  {
1347  if (!check_allowed || env_allowed(e->string))
1348  {
1349  ASSERT(i < n);
1350  ret[i++] = e->string;
1351  }
1352  }
1353  }
1354 
1355  ret[i] = NULL;
1356  return (const char **)ret;
1357 }
1358 
1359 const char **
1360 make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
1361 {
1362  char **ret = NULL;
1363  int base = 0;
1364  const int max_parms = MAX_PARMS + 2;
1365  int n = 0;
1366 
1367  /* alloc return array */
1368  ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
1369 
1370  /* process first parameter, if provided */
1371  if (first)
1372  {
1373  ret[base++] = string_alloc(first, gc);
1374  }
1375 
1376  if (parms)
1377  {
1378  n = parse_line(parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
1379  ASSERT(n >= 0 && n + base + 1 <= max_parms);
1380  }
1381  ret[base + n] = NULL;
1382 
1383  return (const char **)ret;
1384 }
1385 
1386 static const char **
1387 make_inline_array(const char *str, struct gc_arena *gc)
1388 {
1389  char line[OPTION_LINE_SIZE];
1390  struct buffer buf;
1391  int len = 0;
1392  char **ret = NULL;
1393  int i = 0;
1394 
1395  buf_set_read(&buf, (const uint8_t *) str, strlen(str));
1396  while (buf_parse(&buf, '\n', line, sizeof(line)))
1397  {
1398  ++len;
1399  }
1400 
1401  /* alloc return array */
1402  ALLOC_ARRAY_CLEAR_GC(ret, char *, len + 1, gc);
1403 
1404  buf_set_read(&buf, (const uint8_t *) str, strlen(str));
1405  while (buf_parse(&buf, '\n', line, sizeof(line)))
1406  {
1407  chomp(line);
1408  ASSERT(i < len);
1409  ret[i] = string_alloc(skip_leading_whitespace(line), gc);
1410  ++i;
1411  }
1412  ASSERT(i <= len);
1413  ret[i] = NULL;
1414  return (const char **)ret;
1415 }
1416 
1417 static const char **
1418 make_arg_copy(char **p, struct gc_arena *gc)
1419 {
1420  char **ret = NULL;
1421  const int len = string_array_len((const char **)p);
1422  const int max_parms = len + 1;
1423  int i;
1424 
1425  /* alloc return array */
1426  ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
1427 
1428  for (i = 0; i < len; ++i)
1429  {
1430  ret[i] = p[i];
1431  }
1432 
1433  return (const char **)ret;
1434 }
1435 
1436 const char **
1437 make_extended_arg_array(char **p, struct gc_arena *gc)
1438 {
1439  const int argc = string_array_len((const char **)p);
1440  if (!strcmp(p[0], INLINE_FILE_TAG) && argc == 2)
1441  {
1442  return make_inline_array(p[1], gc);
1443  }
1444  else if (argc == 0)
1445  {
1446  return make_arg_array(NULL, NULL, gc);
1447  }
1448  else if (argc == 1)
1449  {
1450  return make_arg_array(p[0], NULL, gc);
1451  }
1452  else if (argc == 2)
1453  {
1454  return make_arg_array(p[0], p[1], gc);
1455  }
1456  else
1457  {
1458  return make_arg_copy(p, gc);
1459  }
1460 }
1461 
1462 /*
1463  * Remove security-sensitive strings from control message
1464  * so that they will not be output to log file.
1465  */
1466 const char *
1467 sanitize_control_message(const char *src, struct gc_arena *gc)
1468 {
1469  char *ret = gc_malloc(strlen(src)+1, false, gc);
1470  char *dest = ret;
1471  bool redact = false;
1472  int skip = 0;
1473 
1474  for (;; )
1475  {
1476  const char c = *src;
1477  if (c == '\0')
1478  {
1479  break;
1480  }
1481  if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
1482  {
1483  skip = 7;
1484  redact = true;
1485  }
1486  else if (c == 'e' && !strncmp(src, "echo ", 5))
1487  {
1488  skip = 4;
1489  redact = true;
1490  }
1491  else if (!check_debug_level(D_SHOW_KEYS)
1492  && (c == 'a' && !strncmp(src, "auth-token ", 11)))
1493  {
1494  /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
1495  * the auth-token value coming in the src string
1496  */
1497  skip = 10;
1498  redact = true;
1499  }
1500 
1501  if (c == ',') /* end of redacted item? */
1502  {
1503  skip = 0;
1504  redact = false;
1505  }
1506 
1507  if (redact)
1508  {
1509  if (skip > 0)
1510  {
1511  --skip;
1512  *dest++ = c;
1513  }
1514  }
1515  else
1516  {
1517  *dest++ = c;
1518  }
1519 
1520  ++src;
1521  }
1522  *dest = '\0';
1523  return ret;
1524 }
1525 
1535 bool
1536 compat_flag(unsigned int flag)
1537 {
1538  static unsigned int compat_flags = 0;
1539 
1540  if (flag & COMPAT_FLAG_SET)
1541  {
1542  compat_flags |= (flag >> 1);
1543  }
1544 
1545  return (compat_flags & (flag >> 1));
1546 
1547 }
1548 
1549 #if P2MP_SERVER
1550 
1551 /* helper to parse peer_info received from multi client, validate
1552  * (this is untrusted data) and put into environment
1553  */
1554 bool
1556 {
1557  uint8_t c;
1558  int state = 0;
1559  while (*line)
1560  {
1561  c = *line;
1562  switch (state)
1563  {
1564  case 0:
1565  case 1:
1566  if (c == '=' && state == 1)
1567  {
1568  state = 2;
1569  }
1570  else if (isalnum(c) || c == '_')
1571  {
1572  state = 1;
1573  }
1574  else
1575  {
1576  return false;
1577  }
1578 
1579  case 2:
1580  /* after the '=', replace non-printable or shell meta with '_' */
1581  if (!isprint(c) || isspace(c)
1582  || c == '$' || c == '(' || c == '`')
1583  {
1584  *line = '_';
1585  }
1586  }
1587  line++;
1588  }
1589  return (state == 2);
1590 }
1591 
1592 void
1593 output_peer_info_env(struct env_set *es, const char *peer_info)
1594 {
1595  char line[256];
1596  struct buffer buf;
1597  buf_set_read(&buf, (const uint8_t *) peer_info, strlen(peer_info));
1598  while (buf_parse(&buf, '\n', line, sizeof(line)))
1599  {
1600  chomp(line);
1601  if (validate_peer_info_line(line)
1602  && (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0) )
1603  {
1604  msg(M_INFO, "peer info: %s", line);
1605  env_set_add(es, line);
1606  }
1607  else
1608  {
1609  msg(M_WARN, "validation failed on peer_info line received from client");
1610  }
1611  }
1612 }
1613 
1614 #endif /* P2MP_SERVER */
int openvpn_execve(const struct argv *a, const struct env_set *es, const unsigned int flags)
Definition: win32.c:1089
#define COMPAT_FLAG_SET
Definition: misc.h:298
void set_std_files_to_null(bool stdin_only)
Definition: misc.c:61
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:343
md_ctx_t * md_ctx_new(void)
#define D_TEST_FILE
Definition: errlevel.h:133
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:626
#define USER_PASS_LEN
Definition: misc.h:183
bool validate_peer_info_line(char *line)
Definition: misc.c:1555
#define GET_USER_PASS_STATIC_CHALLENGE
Definition: misc.h:232
#define streq(x, y)
Definition: options.h:613
void string_clear(char *str)
Definition: buffer.c:669
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition: buffer.h:396
int openvpn_base64_encode(const void *data, int size, char **str)
Definition: base64.c:54
#define OS_SPECIFIC_DIRSEP
Definition: syshead.h:477
bool openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
Definition: misc.c:147
#define M_INFO
Definition: errlevel.h:55
struct gc_arena * gc
Definition: misc.h:50
void setenv_int_i(struct env_set *es, const char *name, const int value, const int i)
Definition: misc.c:676
void env_set_print(int msglevel, const struct env_set *es)
Definition: misc.c:493
#define CC_LESS_THAN
Definition: buffer.h:903
bool absolute_pathname(const char *pathname)
Definition: misc.c:847
void save_inetd_socket_descriptor(void)
Definition: misc.c:88
static void gc_free(struct gc_arena *a)
Definition: buffer.h:990
static bool check_debug_level(unsigned int level)
Definition: error.h:245
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition: manage.c:2987
#define CC_PRINT
Definition: buffer.h:882
#define GET_USER_PASS_INLINE_CREDS
Definition: misc.h:235
int script_security
Definition: misc.c:55
#define ASSERT(x)
Definition: error.h:221
static void add_env_item(char *str, const bool do_alloc, struct env_item **list, struct gc_arena *gc)
Definition: misc.c:408
static bool env_set_del_nolock(struct env_set *es, const char *str)
Definition: misc.c:424
const char * env_set_get(const struct env_set *es, const char *name)
Definition: misc.c:482
void md_ctx_free(md_ctx_t *ctx)
void set_auth_token(struct user_pass *up, const char *token)
Definition: misc.c:1272
const char ** make_env_array(const struct env_set *es, const bool check_allowed, struct gc_arena *gc)
Definition: misc.c:1321
void setenv_str_incr(struct env_set *es, const char *name, const char *value)
Store the supplied name value pair in the env_set.
Definition: misc.c:586
#define M_FATAL
Definition: error.h:94
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:223
#define GET_USER_PASS_NOFATAL
Definition: misc.h:227
#define INETD_SOCKET_DESCRIPTOR
Definition: misc.h:35
void env_set_add(struct env_set *es, const char *str)
Definition: misc.c:474
#define CLEAR(x)
Definition: basic.h:33
bool defined
Definition: misc.h:174
const char * hostname_randomize(const char *hostname, struct gc_arena *gc)
Definition: misc.c:777
const char * gen_path(const char *directory, const char *filename, struct gc_arena *gc)
Definition: misc.c:807
const char * system_error_message(int stat, struct gc_arena *gc)
Definition: misc.c:105
#define MAX_PARMS
Definition: options.h:53
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:4219
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: misc.c:564
#define CC_BACKSLASH
Definition: buffer.h:891
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
#define S_SCRIPT
Definition: misc.h:55
void setenv_str_ex(struct env_set *es, const char *name, const char *value, const unsigned int name_include, const unsigned int name_exclude, const char name_replace, const unsigned int value_include, const unsigned int value_exclude, const char value_replace)
Definition: misc.c:616
const char * skip_leading_whitespace(const char *str)
Definition: buffer.c:556
static void env_set_add_nolock(struct env_set *es, const char *str)
Definition: misc.c:430
#define openvpn_errno()
Definition: error.h:74
#define S_IWUSR
Definition: config-msvc.h:108
char username[USER_PASS_LEN]
Definition: misc.h:185
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:3380
#define MD5_DIGEST_LENGTH
#define ALLOC_OBJ_GC(dptr, type, gc)
Definition: buffer.h:1049
Definition: misc.h:44
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:229
const char * safe_print(const char *str, struct gc_arena *gc)
Definition: misc.c:1289
bool platform_system_ok(int stat)
Definition: platform.c:232
FILE * platform_fopen(const char *path, const char *mode)
Definition: platform.c:300
static char * auth_challenge
Definition: ssl.c:405
bool test_file(const char *filename)
Definition: misc.c:695
bool nocache
Definition: misc.h:175
void md_ctx_final(md_ctx_t *ctx, uint8_t *dst)
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO
Definition: misc.h:233
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:277
void setenv_unsigned(struct env_set *es, const char *name, unsigned int value)
Definition: misc.c:556
struct env_item * list
Definition: misc.h:51
#define CC_ASTERISK
Definition: buffer.h:907
int platform_open(const char *path, int flags, int mode)
Definition: platform.c:313
void md_ctx_update(md_ctx_t *ctx, const uint8_t *src, int src_len)
#define counter_format
Definition: common.h:39
static struct gc_arena gc_new(void)
Definition: buffer.h:982
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:85
char ** argv
Definition: argv.h:38
void chomp(char *str)
Definition: buffer.c:591
bool tokenized
Definition: misc.h:176
#define OPTION_LINE_SIZE
Definition: options.h:59
void prng_bytes(uint8_t *output, int len)
Definition: crypto.c:1756
static char * construct_name_value(const char *name, const char *value, struct gc_arena *gc)
Definition: misc.c:329
#define INLINE_FILE_TAG
Definition: common.h:95
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:346
#define M_ERR
Definition: error.h:110
#define GET_USER_PASS_PASSWORD_ONLY
Definition: misc.h:225
#define GET_USER_PASS_NEED_OK
Definition: misc.h:226
mbedtls_md_info_t md_kt_t
Generic message digest key type context.
struct gc_arena gc
Definition: multi.h:78
#define S_FATAL
Definition: misc.h:56
#define CC_NAME
Definition: buffer.h:910
int openvpn_popen(const struct argv *a, const struct env_set *es)
Definition: misc.c:250
static SERVICE_STATUS status
Definition: automatic.c:47
struct env_set * env_set_create(struct gc_arena *gc)
Definition: misc.c:437
void setenv_counter(struct env_set *es, const char *name, counter_type value)
Definition: misc.c:540
static bool env_string_equal(const char *s1, const char *s2)
Definition: misc.c:344
#define S_IRUSR
Definition: config-msvc.h:107
const char * sanitize_control_message(const char *src, struct gc_arena *gc)
Definition: misc.c:1467
static bool remove_env_item(const char *str, const bool do_free, struct env_item **list)
Definition: misc.c:375
const md_kt_t * md_kt_get(const char *digest)
Return message digest parameters, based on the given digest name.
unsigned int counter_type
Definition: common.h:38
struct env_item * next
Definition: misc.h:46
char * string
Definition: misc.h:45
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:460
bool env_allowed(const char *str)
Definition: misc.c:1301
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68
#define dmsg
Definition: error.h:174
#define SOCKET_UNDEFINED
Definition: syshead.h:486
void md_ctx_cleanup(md_ctx_t *ctx)
void query_user_clear(void)
Wipes all data put into all of the query_user structs.
Definition: console.c:47
#define n_rnd_bytes
const char * create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
Definition: misc.c:724
#define CC_QUESTION_MARK
Definition: buffer.h:906
#define BLEN(buf)
Definition: buffer.h:127
void env_set_inherit(struct env_set *es, const struct env_set *src)
Definition: misc.c:519
const char ** make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
Definition: misc.c:1360
#define SSEC_BUILT_IN
Definition: misc.h:291
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:1051
struct auth_challenge_info * get_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
Definition: misc.c:1135
static const char ** make_arg_copy(char **p, struct gc_arena *gc)
Definition: misc.c:1418
#define GET_USER_PASS_DYNAMIC_CHALLENGE
Definition: misc.h:231
unsigned __int8 uint8_t
Definition: config-msvc.h:123
#define SSEC_PW_ENV
Definition: misc.h:293
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:869
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Definition: buffer.c:1019
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Definition: buffer.h:1039
void purge_user_pass(struct user_pass *up, const bool force)
Definition: misc.c:1251
#define D_AUTO_USERID
Definition: errlevel.h:142
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition: buffer.h:1054
bool openvpn_execve_allowed(const unsigned int flags)
Definition: misc.c:171
int string_array_len(const char **array)
Definition: buffer.c:681
#define CC_GREATER_THAN
Definition: buffer.h:904
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition: buffer.c:803
const char ** make_extended_arg_array(char **p, struct gc_arena *gc)
Definition: misc.c:1437
#define CC_SLASH
Definition: buffer.h:897
static bool management_query_user_pass_enabled(const struct management *man)
Definition: manage.h:455
void output_peer_info_env(struct env_set *es, const char *peer_info)
Definition: misc.c:1593
static bool is_password_env_var(const char *str)
Definition: misc.c:1295
#define CC_PIPE
Definition: buffer.h:905
#define msg
Definition: error.h:173
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
#define SCRIPT_SECURITY_WARNING
Definition: common.h:100
#define D_SHOW_KEYS
Definition: errlevel.h:117
#define D_TLS_DEBUG_MED
Definition: errlevel.h:152
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
bool env_safe_to_print(const char *str)
Definition: misc.c:1307
Definition: misc.h:49
void setenv_int(struct env_set *es, const char *name, int value)
Definition: misc.c:548
static const char ** make_inline_array(const char *str, struct gc_arena *gc)
Definition: misc.c:1387
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
void setenv_str_safe(struct env_set *es, const char *name, const char *value)
Definition: misc.c:570
void md_ctx_init(md_ctx_t *ctx, const md_kt_t *kt)
#define BSTR(buf)
Definition: buffer.h:129
static const char * setenv_format_indexed_name(const char *name, const int i, struct gc_arena *gc)
Definition: misc.c:661
long int get_random(void)
Definition: crypto.c:1788
#define M_ERRNO
Definition: error.h:99
char password[USER_PASS_LEN]
Definition: misc.h:186
bool env_set_del(struct env_set *es, const char *str)
Definition: misc.c:464
Definition: argv.h:35
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition: buffer.h:313
void setenv_str_i(struct env_set *es, const char *name, const char *value, const int i)
Definition: misc.c:685
#define CC_COLON
Definition: buffer.h:896
void env_set_destroy(struct env_set *es)
Definition: misc.c:447
#define CC_CRLF
Definition: buffer.h:911
char * dest
Definition: compat-lz4.h:431
#define BOOL_CAST(x)
Definition: basic.h:27
static void buf_set_read(struct buffer *buf, const uint8_t *data, int size)
Definition: buffer.h:330
void setenv_del(struct env_set *es, const char *name)
Definition: misc.c:609
bool compat_flag(unsigned int flag)
Will set or query for a global compat flag.
Definition: misc.c:1536
mbedtls_md_context_t md_ctx_t
Generic message digest context.
int openvpn_base64_decode(const char *str, void *data, int size)
Definition: base64.c:160
#define M_WARN
Definition: error.h:96
#define CC_DOUBLE_QUOTE
Definition: buffer.h:899
bool win_safe_filename(const char *fn)
Definition: win32.c:936
#define GET_USER_PASS_MANAGEMENT
Definition: misc.h:223
#define SSEC_SCRIPTS
Definition: misc.h:292