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-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 2
12 *  as published by the Free Software Foundation.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program (see the file COPYING included with this
21 *  distribution); if not, write to the Free Software Foundation, Inc.,
22 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#elif defined(_MSC_VER)
28#include "config-msvc.h"
29#endif
30
31#include "syshead.h"
32
33#include "buffer.h"
34#include "misc.h"
35#include "base64.h"
36#include "tun.h"
37#include "error.h"
38#include "otime.h"
39#include "plugin.h"
40#include "options.h"
41#include "manage.h"
42#include "crypto.h"
43#include "route.h"
44#include "console.h"
45#include "win32.h"
46
47#include "memdbg.h"
48
49#ifdef ENABLE_IPROUTE
50const char *iproute_path = IPROUTE_PATH; /* GLOBAL */
51#endif
52
53/* contains an SSEC_x value defined in misc.h */
54int script_security = SSEC_BUILT_IN; /* GLOBAL */
55
56/*
57 * Pass tunnel endpoint and MTU parms to a user-supplied script.
58 * Used to execute the up/down script/plugins.
59 */
60void
61run_up_down (const char *command,
62	     const struct plugin_list *plugins,
63	     int plugin_type,
64	     const char *arg,
65	     const char *dev_type,
66	     int tun_mtu,
67	     int link_mtu,
68	     const char *ifconfig_local,
69	     const char* ifconfig_remote,
70	     const char *context,
71	     const char *signal_text,
72	     const char *script_type,
73	     struct env_set *es)
74{
75  struct gc_arena gc = gc_new ();
76
77  if (signal_text)
78    setenv_str (es, "signal", signal_text);
79  setenv_str (es, "script_context", context);
80  setenv_int (es, "tun_mtu", tun_mtu);
81  setenv_int (es, "link_mtu", link_mtu);
82  setenv_str (es, "dev", arg);
83  if (dev_type)
84    setenv_str (es, "dev_type", dev_type);
85
86  if (!ifconfig_local)
87    ifconfig_local = "";
88  if (!ifconfig_remote)
89    ifconfig_remote = "";
90  if (!context)
91    context = "";
92
93  if (plugin_defined (plugins, plugin_type))
94    {
95      struct argv argv = argv_new ();
96      ASSERT (arg);
97      argv_printf (&argv,
98		   "%s %d %d %s %s %s",
99		   arg,
100		   tun_mtu, link_mtu,
101		   ifconfig_local, ifconfig_remote,
102		   context);
103
104      if (plugin_call (plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
105	msg (M_FATAL, "ERROR: up/down plugin call failed");
106
107      argv_reset (&argv);
108    }
109
110  if (command)
111    {
112      struct argv argv = argv_new ();
113      ASSERT (arg);
114      setenv_str (es, "script_type", script_type);
115      argv_printf (&argv,
116		  "%sc %s %d %d %s %s %s",
117		  command,
118		  arg,
119		  tun_mtu, link_mtu,
120		  ifconfig_local, ifconfig_remote,
121		  context);
122      argv_msg (M_INFO, &argv);
123      openvpn_run_script (&argv, es, S_FATAL, "--up/--down");
124      argv_reset (&argv);
125    }
126
127  gc_free (&gc);
128}
129
130/* Get the file we will later write our process ID to */
131void
132get_pid_file (const char* filename, struct pid_state *state)
133{
134  CLEAR (*state);
135  if (filename)
136    {
137      state->fp = platform_fopen (filename, "w");
138      if (!state->fp)
139	msg (M_ERR, "Open error on pid file %s", filename);
140      state->filename = filename;
141    }
142}
143
144/* Write our PID to a file */
145void
146write_pid (const struct pid_state *state)
147{
148  if (state->filename && state->fp)
149    {
150      unsigned int pid = platform_getpid ();
151      fprintf(state->fp, "%u\n", pid);
152      if (fclose (state->fp))
153	msg (M_ERR, "Close error on pid file %s", state->filename);
154    }
155}
156
157/*
158 * Set standard file descriptors to /dev/null
159 */
160void
161set_std_files_to_null (bool stdin_only)
162{
163#if defined(HAVE_DUP) && defined(HAVE_DUP2)
164  int fd;
165  if ((fd = open ("/dev/null", O_RDWR, 0)) != -1)
166    {
167      dup2 (fd, 0);
168      if (!stdin_only)
169	{
170	  dup2 (fd, 1);
171	  dup2 (fd, 2);
172	}
173      if (fd > 2)
174	close (fd);
175    }
176#endif
177}
178
179/*
180 *  dup inetd/xinetd socket descriptor and save
181 */
182
183int inetd_socket_descriptor = SOCKET_UNDEFINED; /* GLOBAL */
184
185void
186save_inetd_socket_descriptor (void)
187{
188  inetd_socket_descriptor = INETD_SOCKET_DESCRIPTOR;
189#if defined(HAVE_DUP) && defined(HAVE_DUP2)
190  /* use handle passed by inetd/xinetd */
191  if ((inetd_socket_descriptor = dup (INETD_SOCKET_DESCRIPTOR)) < 0)
192    msg (M_ERR, "INETD_SOCKET_DESCRIPTOR dup(%d) failed", INETD_SOCKET_DESCRIPTOR);
193  set_std_files_to_null (true);
194#endif
195}
196
197/*
198 * Warn if a given file is group/others accessible.
199 */
200void
201warn_if_group_others_accessible (const char* filename)
202{
203#ifndef WIN32
204#ifdef HAVE_STAT
205  if (strcmp (filename, INLINE_FILE_TAG))
206    {
207      struct stat st;
208      if (stat (filename, &st))
209	{
210	  msg (M_WARN | M_ERRNO, "WARNING: cannot stat file '%s'", filename);
211	}
212      else
213	{
214	  if (st.st_mode & (S_IRWXG|S_IRWXO))
215	    msg (M_WARN, "WARNING: file '%s' is group or others accessible", filename);
216	}
217    }
218#endif
219#endif
220}
221
222/*
223 * Print an error message based on the status code returned by system().
224 */
225const char *
226system_error_message (int stat, struct gc_arena *gc)
227{
228  struct buffer out = alloc_buf_gc (256, gc);
229#ifdef WIN32
230  if (stat == -1)
231    buf_printf (&out, "external program did not execute -- ");
232  buf_printf (&out, "returned error code %d", stat);
233#else
234  if (stat == -1)
235    buf_printf (&out, "external program fork failed");
236  else if (!WIFEXITED (stat))
237    buf_printf (&out, "external program did not exit normally");
238  else
239    {
240      const int cmd_ret = WEXITSTATUS (stat);
241      if (!cmd_ret)
242	buf_printf (&out, "external program exited normally");
243      else if (cmd_ret == 127)
244	buf_printf (&out, "could not execute external program");
245      else
246	buf_printf (&out, "external program exited with error status: %d", cmd_ret);
247    }
248#endif
249  return (const char *)out.data;
250}
251
252/*
253 * Wrapper around openvpn_execve
254 */
255bool
256openvpn_execve_check (const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
257{
258  struct gc_arena gc = gc_new ();
259  const int stat = openvpn_execve (a, es, flags);
260  int ret = false;
261
262  if (platform_system_ok (stat))
263    ret = true;
264  else
265    {
266      if (error_message)
267	msg (((flags & S_FATAL) ? M_FATAL : M_WARN), "%s: %s",
268	     error_message,
269	     system_error_message (stat, &gc));
270    }
271  gc_free (&gc);
272  return ret;
273}
274
275bool
276openvpn_execve_allowed (const unsigned int flags)
277{
278  if (flags & S_SCRIPT)
279    return script_security >= SSEC_SCRIPTS;
280  else
281    return script_security >= SSEC_BUILT_IN;
282}
283
284
285#ifndef WIN32
286/*
287 * Run execve() inside a fork().  Designed to replicate the semantics of system() but
288 * in a safer way that doesn't require the invocation of a shell or the risks
289 * assocated with formatting and parsing a command line.
290 */
291int
292openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags)
293{
294  struct gc_arena gc = gc_new ();
295  int ret = -1;
296  static bool warn_shown = false;
297
298  if (a && a->argv[0])
299    {
300#if defined(ENABLE_FEATURE_EXECVE)
301      if (openvpn_execve_allowed (flags))
302	{
303          const char *cmd = a->argv[0];
304          char *const *argv = a->argv;
305          char *const *envp = (char *const *)make_env_array (es, true, &gc);
306          pid_t pid;
307
308          pid = fork ();
309          if (pid == (pid_t)0) /* child side */
310            {
311              execve (cmd, argv, envp);
312              exit (127);
313            }
314          else if (pid < (pid_t)0) /* fork failed */
315            msg (M_ERR, "openvpn_execve: unable to fork");
316          else /* parent side */
317            {
318              if (waitpid (pid, &ret, 0) != pid)
319                ret = -1;
320            }
321        }
322      else if (!warn_shown && (script_security < SSEC_SCRIPTS))
323	{
324	  msg (M_WARN, SCRIPT_SECURITY_WARNING);
325          warn_shown = true;
326	}
327#else
328      msg (M_WARN, "openvpn_execve: execve function not available");
329#endif
330    }
331  else
332    {
333      msg (M_FATAL, "openvpn_execve: called with empty argv");
334    }
335
336  gc_free (&gc);
337  return ret;
338}
339#endif
340
341/*
342 * Run execve() inside a fork(), duping stdout.  Designed to replicate the semantics of popen() but
343 * in a safer way that doesn't require the invocation of a shell or the risks
344 * assocated with formatting and parsing a command line.
345 */
346int
347openvpn_popen (const struct argv *a,  const struct env_set *es)
348{
349  struct gc_arena gc = gc_new ();
350  int ret = -1;
351  static bool warn_shown = false;
352
353  if (a && a->argv[0])
354    {
355#if defined(ENABLE_FEATURE_EXECVE)
356      if (script_security >= SSEC_BUILT_IN)
357	{
358	      const char *cmd = a->argv[0];
359	      char *const *argv = a->argv;
360	      char *const *envp = (char *const *)make_env_array (es, true, &gc);
361	      pid_t pid;
362	      int pipe_stdout[2];
363
364              if (pipe (pipe_stdout) == 0) {
365		      pid = fork ();
366		      if (pid == (pid_t)0) /* child side */
367			{
368			  close (pipe_stdout[0]);
369			  dup2 (pipe_stdout[1],1);
370			  execve (cmd, argv, envp);
371			  exit (127);
372			}
373		      else if (pid < (pid_t)0) /* fork failed */
374			{
375			  msg (M_ERR, "openvpn_popen: unable to fork");
376			}
377		      else /* parent side */
378			{
379                            ret=pipe_stdout[0];
380			    close (pipe_stdout[1]);
381			}
382	      }
383	      else {
384		      msg (M_WARN, "openvpn_popen: unable to create stdout pipe");
385		      ret = -1;
386	      }
387	}
388      else if (!warn_shown && (script_security < SSEC_SCRIPTS))
389	{
390	  msg (M_WARN, SCRIPT_SECURITY_WARNING);
391          warn_shown = true;
392	}
393#else
394      msg (M_WARN, "openvpn_popen: execve function not available");
395#endif
396    }
397  else
398    {
399      msg (M_FATAL, "openvpn_popen: called with empty argv");
400    }
401
402  gc_free (&gc);
403  return ret;
404}
405
406
407
408/*
409 * Initialize random number seed.  random() is only used
410 * when "weak" random numbers are acceptable.
411 * OpenSSL routines are always used when cryptographically
412 * strong random numbers are required.
413 */
414
415void
416init_random_seed(void)
417{
418  struct timeval tv;
419
420  if (!gettimeofday (&tv, NULL))
421    {
422      const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec;
423      srandom (seed);
424    }
425}
426
427/* thread-safe strerror */
428
429const char *
430strerror_ts (int errnum, struct gc_arena *gc)
431{
432#ifdef HAVE_STRERROR
433  struct buffer out = alloc_buf_gc (256, gc);
434
435  buf_printf (&out, "%s", openvpn_strerror (errnum, gc));
436  return BSTR (&out);
437#else
438  return "[error string unavailable]";
439#endif
440}
441
442/*
443 * Set environmental variable (int or string).
444 *
445 * On Posix, we use putenv for portability,
446 * and put up with its painful semantics
447 * that require all the support code below.
448 */
449
450/* General-purpose environmental variable set functions */
451
452static char *
453construct_name_value (const char *name, const char *value, struct gc_arena *gc)
454{
455  struct buffer out;
456
457  ASSERT (name);
458  if (!value)
459    value = "";
460  out = alloc_buf_gc (strlen (name) + strlen (value) + 2, gc);
461  buf_printf (&out, "%s=%s", name, value);
462  return BSTR (&out);
463}
464
465bool
466deconstruct_name_value (const char *str, const char **name, const char **value, struct gc_arena *gc)
467{
468  char *cp;
469
470  ASSERT (str);
471  ASSERT (name && value);
472
473  *name = cp = string_alloc (str, gc);
474  *value = NULL;
475
476  while ((*cp))
477    {
478      if (*cp == '=' && !*value)
479	{
480	  *cp = 0;
481	  *value = cp + 1;
482	}
483      ++cp;
484    }
485  return *name && *value;
486}
487
488static bool
489env_string_equal (const char *s1, const char *s2)
490{
491  int c1, c2;
492  ASSERT (s1);
493  ASSERT (s2);
494
495  while (true)
496    {
497      c1 = *s1++;
498      c2 = *s2++;
499      if (c1 == '=')
500	c1 = 0;
501      if (c2 == '=')
502	c2 = 0;
503      if (!c1 && !c2)
504	return true;
505      if (c1 != c2)
506	break;
507    }
508  return false;
509}
510
511static bool
512remove_env_item (const char *str, const bool do_free, struct env_item **list)
513{
514  struct env_item *current, *prev;
515
516  ASSERT (str);
517  ASSERT (list);
518
519  for (current = *list, prev = NULL; current != NULL; current = current->next)
520    {
521      if (env_string_equal (current->string, str))
522	{
523	  if (prev)
524	    prev->next = current->next;
525	  else
526	    *list = current->next;
527	  if (do_free)
528	    {
529	      memset (current->string, 0, strlen (current->string));
530	      free (current->string);
531	      free (current);
532	    }
533	  return true;
534	}
535      prev = current;
536    }
537  return false;
538}
539
540static void
541add_env_item (char *str, const bool do_alloc, struct env_item **list, struct gc_arena *gc)
542{
543  struct env_item *item;
544
545  ASSERT (str);
546  ASSERT (list);
547
548  ALLOC_OBJ_GC (item, struct env_item, gc);
549  item->string = do_alloc ? string_alloc (str, gc): str;
550  item->next = *list;
551  *list = item;
552}
553
554/* struct env_set functions */
555
556static bool
557env_set_del_nolock (struct env_set *es, const char *str)
558{
559  return remove_env_item (str, es->gc == NULL, &es->list);
560}
561
562static void
563env_set_add_nolock (struct env_set *es, const char *str)
564{
565  remove_env_item (str, es->gc == NULL, &es->list);
566  add_env_item ((char *)str, true, &es->list, es->gc);
567}
568
569struct env_set *
570env_set_create (struct gc_arena *gc)
571{
572  struct env_set *es;
573  ALLOC_OBJ_CLEAR_GC (es, struct env_set, gc);
574  es->list = NULL;
575  es->gc = gc;
576  return es;
577}
578
579void
580env_set_destroy (struct env_set *es)
581{
582  if (es && es->gc == NULL)
583    {
584      struct env_item *e = es->list;
585      while (e)
586	{
587	  struct env_item *next = e->next;
588	  free (e->string);
589	  free (e);
590	  e = next;
591	}
592      free (es);
593    }
594}
595
596bool
597env_set_del (struct env_set *es, const char *str)
598{
599  bool ret;
600  ASSERT (es);
601  ASSERT (str);
602  ret = env_set_del_nolock (es, str);
603  return ret;
604}
605
606void
607env_set_add (struct env_set *es, const char *str)
608{
609  ASSERT (es);
610  ASSERT (str);
611  env_set_add_nolock (es, str);
612}
613
614void
615env_set_print (int msglevel, const struct env_set *es)
616{
617  if (check_debug_level (msglevel))
618    {
619      const struct env_item *e;
620      int i;
621
622      if (es)
623	{
624	  e = es->list;
625	  i = 0;
626
627	  while (e)
628	    {
629	      if (env_safe_to_print (e->string))
630		msg (msglevel, "ENV [%d] '%s'", i, e->string);
631	      ++i;
632	      e = e->next;
633	    }
634	}
635    }
636}
637
638void
639env_set_inherit (struct env_set *es, const struct env_set *src)
640{
641  const struct env_item *e;
642
643  ASSERT (es);
644
645  if (src)
646    {
647      e = src->list;
648      while (e)
649	{
650	  env_set_add_nolock (es, e->string);
651	  e = e->next;
652	}
653    }
654}
655
656void
657env_set_add_to_environment (const struct env_set *es)
658{
659  if (es)
660    {
661      struct gc_arena gc = gc_new ();
662      const struct env_item *e;
663
664      e = es->list;
665
666      while (e)
667	{
668	  const char *name;
669	  const char *value;
670
671	  if (deconstruct_name_value (e->string, &name, &value, &gc))
672	    setenv_str (NULL, name, value);
673
674	  e = e->next;
675	}
676      gc_free (&gc);
677    }
678}
679
680void
681env_set_remove_from_environment (const struct env_set *es)
682{
683  if (es)
684    {
685      struct gc_arena gc = gc_new ();
686      const struct env_item *e;
687
688      e = es->list;
689
690      while (e)
691	{
692	  const char *name;
693	  const char *value;
694
695	  if (deconstruct_name_value (e->string, &name, &value, &gc))
696	    setenv_del (NULL, name);
697
698	  e = e->next;
699	}
700      gc_free (&gc);
701    }
702}
703
704#ifdef HAVE_PUTENV
705
706/* companion functions to putenv */
707
708static struct env_item *global_env = NULL; /* GLOBAL */
709
710#endif
711
712/* add/modify/delete environmental strings */
713
714void
715setenv_counter (struct env_set *es, const char *name, counter_type value)
716{
717  char buf[64];
718  openvpn_snprintf (buf, sizeof(buf), counter_format, value);
719  setenv_str (es, name, buf);
720}
721
722void
723setenv_int (struct env_set *es, const char *name, int value)
724{
725  char buf[64];
726  openvpn_snprintf (buf, sizeof(buf), "%d", value);
727  setenv_str (es, name, buf);
728}
729
730void
731setenv_unsigned (struct env_set *es, const char *name, unsigned int value)
732{
733  char buf[64];
734  openvpn_snprintf (buf, sizeof(buf), "%u", value);
735  setenv_str (es, name, buf);
736}
737
738void
739setenv_str (struct env_set *es, const char *name, const char *value)
740{
741  setenv_str_ex (es, name, value, CC_NAME, 0, 0, CC_PRINT, 0, 0);
742}
743
744void
745setenv_str_safe (struct env_set *es, const char *name, const char *value)
746{
747  uint8_t b[64];
748  struct buffer buf;
749  buf_set_write (&buf, b, sizeof (b));
750  if (buf_printf (&buf, "OPENVPN_%s", name))
751    setenv_str (es, BSTR(&buf), value);
752  else
753    msg (M_WARN, "setenv_str_safe: name overflow");
754}
755
756void
757setenv_del (struct env_set *es, const char *name)
758{
759  ASSERT (name);
760  setenv_str (es, name, NULL);
761}
762
763void
764setenv_str_ex (struct env_set *es,
765	       const char *name,
766	       const char *value,
767	       const unsigned int name_include,
768	       const unsigned int name_exclude,
769	       const char name_replace,
770	       const unsigned int value_include,
771	       const unsigned int value_exclude,
772	       const char value_replace)
773{
774  struct gc_arena gc = gc_new ();
775  const char *name_tmp;
776  const char *val_tmp = NULL;
777
778  ASSERT (name && strlen (name) > 1);
779
780  name_tmp = string_mod_const (name, name_include, name_exclude, name_replace, &gc);
781
782  if (value)
783    val_tmp = string_mod_const (value, value_include, value_exclude, value_replace, &gc);
784
785  ASSERT (es);
786
787  if (val_tmp)
788    {
789      const char *str = construct_name_value (name_tmp, val_tmp, &gc);
790      env_set_add (es, str);
791#if DEBUG_VERBOSE_SETENV
792      msg (M_INFO, "SETENV_ES '%s'", str);
793#endif
794    }
795  else
796    env_set_del (es, name_tmp);
797
798  gc_free (&gc);
799}
800
801/*
802 * Setenv functions that append an integer index to the name
803 */
804static const char *
805setenv_format_indexed_name (const char *name, const int i, struct gc_arena *gc)
806{
807  struct buffer out = alloc_buf_gc (strlen (name) + 16, gc);
808  if (i >= 0)
809    buf_printf (&out, "%s_%d", name, i);
810  else
811    buf_printf (&out, "%s", name);
812  return BSTR (&out);
813}
814
815void
816setenv_int_i (struct env_set *es, const char *name, const int value, const int i)
817{
818  struct gc_arena gc = gc_new ();
819  const char *name_str = setenv_format_indexed_name (name, i, &gc);
820  setenv_int (es, name_str, value);
821  gc_free (&gc);
822}
823
824void
825setenv_str_i (struct env_set *es, const char *name, const char *value, const int i)
826{
827  struct gc_arena gc = gc_new ();
828  const char *name_str = setenv_format_indexed_name (name, i, &gc);
829  setenv_str (es, name_str, value);
830  gc_free (&gc);
831}
832
833/*
834 * taken from busybox networking/ifupdown.c
835 */
836unsigned int
837count_bits(unsigned int a)
838{
839  unsigned int result;
840  result = (a & 0x55) + ((a >> 1) & 0x55);
841  result = (result & 0x33) + ((result >> 2) & 0x33);
842  return((result & 0x0F) + ((result >> 4) & 0x0F));
843}
844
845int
846count_netmask_bits(const char *dotted_quad)
847{
848  unsigned int result, a, b, c, d;
849  /* Found a netmask...  Check if it is dotted quad */
850  if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
851    return -1;
852  result = count_bits(a);
853  result += count_bits(b);
854  result += count_bits(c);
855  result += count_bits(d);
856  return ((int)result);
857}
858
859/* return true if filename can be opened for read */
860bool
861test_file (const char *filename)
862{
863  bool ret = false;
864  if (filename)
865    {
866      FILE *fp = platform_fopen (filename, "r");
867      if (fp)
868	{
869	  fclose (fp);
870	  ret = true;
871	}
872    }
873
874  dmsg (D_TEST_FILE, "TEST FILE '%s' [%d]",
875       filename ? filename : "UNDEF",
876       ret);
877
878  return ret;
879}
880
881#ifdef ENABLE_CRYPTO
882
883/* create a temporary filename in directory */
884const char *
885create_temp_file (const char *directory, const char *prefix, struct gc_arena *gc)
886{
887  static unsigned int counter;
888  struct buffer fname = alloc_buf_gc (256, gc);
889  int fd;
890  const char *retfname = NULL;
891  unsigned int attempts = 0;
892
893  do
894    {
895      uint8_t rndbytes[16];
896      const char *rndstr;
897
898      ++attempts;
899      ++counter;
900
901      prng_bytes (rndbytes, sizeof rndbytes);
902      rndstr = format_hex_ex (rndbytes, sizeof rndbytes, 40, 0, NULL, gc);
903      buf_printf (&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr);
904
905      retfname = gen_path (directory, BSTR (&fname), gc);
906      if (!retfname)
907        {
908          msg (M_FATAL, "Failed to create temporary filename and path");
909          return NULL;
910        }
911
912      /* Atomically create the file.  Errors out if the file already
913         exists.  */
914      fd = platform_open (retfname, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
915      if (fd != -1)
916        {
917          close (fd);
918          return retfname;
919        }
920      else if (fd == -1 && errno != EEXIST)
921        {
922          /* Something else went wrong, no need to retry.  */
923          struct gc_arena gcerr = gc_new ();
924          msg (M_FATAL, "Could not create temporary file '%s': %s",
925               retfname, strerror_ts (errno, &gcerr));
926          gc_free (&gcerr);
927          return NULL;
928        }
929    }
930  while (attempts < 6);
931
932  msg (M_FATAL, "Failed to create temporary file after %i attempts", attempts);
933  return NULL;
934}
935
936/*
937 * Add a random string to first DNS label of hostname to prevent DNS caching.
938 * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
939 * Of course, this requires explicit support in the DNS server.
940 */
941const char *
942hostname_randomize(const char *hostname, struct gc_arena *gc)
943{
944# define n_rnd_bytes 6
945
946  char *hst = string_alloc(hostname, gc);
947  char *dot = strchr(hst, '.');
948
949  if (dot)
950    {
951      uint8_t rnd_bytes[n_rnd_bytes];
952      const char *rnd_str;
953      struct buffer hname = alloc_buf_gc (strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);
954
955      *dot++ = '\0';
956      prng_bytes (rnd_bytes, sizeof (rnd_bytes));
957      rnd_str = format_hex_ex (rnd_bytes, sizeof (rnd_bytes), 40, 0, NULL, gc);
958      buf_printf(&hname, "%s-0x%s.%s", hst, rnd_str, dot);
959      return BSTR(&hname);
960    }
961  else
962    return hostname;
963# undef n_rnd_bytes
964}
965
966#else
967
968const char *
969hostname_randomize(const char *hostname, struct gc_arena *gc)
970{
971  msg (M_WARN, "WARNING: hostname randomization disabled when crypto support is not compiled");
972  return hostname;
973}
974
975#endif
976
977/*
978 * Put a directory and filename together.
979 */
980const char *
981gen_path (const char *directory, const char *filename, struct gc_arena *gc)
982{
983#if WIN32
984  const int CC_PATH_RESERVED = CC_LESS_THAN|CC_GREATER_THAN|CC_COLON|
985    CC_DOUBLE_QUOTE|CC_SLASH|CC_BACKSLASH|CC_PIPE|CC_QUESTION_MARK|CC_ASTERISK;
986#else
987  const int CC_PATH_RESERVED = CC_SLASH;
988#endif
989  const char *safe_filename = string_mod_const (filename, CC_PRINT, CC_PATH_RESERVED, '_', gc);
990
991  if (safe_filename
992      && strcmp (safe_filename, ".")
993      && strcmp (safe_filename, "..")
994#ifdef WIN32
995      && win_safe_filename (safe_filename)
996#endif
997      )
998    {
999      const size_t outsize = strlen(safe_filename) + (directory ? strlen (directory) : 0) + 16;
1000      struct buffer out = alloc_buf_gc (outsize, gc);
1001      char dirsep[2];
1002
1003      dirsep[0] = OS_SPECIFIC_DIRSEP;
1004      dirsep[1] = '\0';
1005
1006      if (directory)
1007	buf_printf (&out, "%s%s", directory, dirsep);
1008      buf_printf (&out, "%s", safe_filename);
1009
1010      return BSTR (&out);
1011    }
1012  else
1013    return NULL;
1014}
1015
1016bool
1017absolute_pathname (const char *pathname)
1018{
1019  if (pathname)
1020    {
1021      const int c = pathname[0];
1022#ifdef WIN32
1023      return c == '\\' || (isalpha(c) && pathname[1] == ':' && pathname[2] == '\\');
1024#else
1025      return c == '/';
1026#endif
1027    }
1028  else
1029    return false;
1030}
1031
1032/*
1033 * Get and store a username/password
1034 */
1035
1036bool
1037get_user_pass_cr (struct user_pass *up,
1038		  const char *auth_file,
1039		  const char *prefix,
1040		  const unsigned int flags,
1041		  const char *auth_challenge)
1042{
1043  struct gc_arena gc = gc_new ();
1044
1045  if (!up->defined)
1046    {
1047      const bool from_stdin = (!auth_file || !strcmp (auth_file, "stdin"));
1048
1049      if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
1050	msg (M_WARN, "Note: previous '%s' credentials failed", prefix);
1051
1052#ifdef ENABLE_MANAGEMENT
1053      /*
1054       * Get username/password from management interface?
1055       */
1056      if (management
1057	  && ((auth_file && streq (auth_file, "management")) || (from_stdin && (flags & GET_USER_PASS_MANAGEMENT)))
1058	  && management_query_user_pass_enabled (management))
1059	{
1060	  const char *sc = NULL;
1061
1062	  if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
1063	    management_auth_failure (management, prefix, "previous auth credentials failed");
1064
1065#ifdef ENABLE_CLIENT_CR
1066	  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
1067	    sc = auth_challenge;
1068#endif
1069	  if (!management_query_user_pass (management, up, prefix, flags, sc))
1070	    {
1071	      if ((flags & GET_USER_PASS_NOFATAL) != 0)
1072		return false;
1073	      else
1074		msg (M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
1075	    }
1076	}
1077      else
1078#endif
1079      /*
1080       * Get NEED_OK confirmation from the console
1081       */
1082      if (flags & GET_USER_PASS_NEED_OK)
1083	{
1084	  struct buffer user_prompt = alloc_buf_gc (128, &gc);
1085
1086	  buf_printf (&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
1087
1088	  if (!get_console_input (BSTR (&user_prompt), true, up->password, USER_PASS_LEN))
1089	    msg (M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
1090
1091	  if (!strlen (up->password))
1092	    strcpy (up->password, "ok");
1093	}
1094
1095      /*
1096       * Get username/password from standard input?
1097       */
1098      else if (from_stdin)
1099	{
1100#ifdef ENABLE_CLIENT_CR
1101	  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
1102	    {
1103	      struct auth_challenge_info *ac = get_auth_challenge (auth_challenge, &gc);
1104	      if (ac)
1105		{
1106		  char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
1107		  struct buffer packed_resp;
1108
1109		  buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN);
1110		  msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text);
1111		  if (!get_console_input ("Response:", BOOL_CAST(ac->flags&CR_ECHO), response, USER_PASS_LEN))
1112		    msg (M_FATAL, "ERROR: could not read challenge response from stdin");
1113		  strncpynt (up->username, ac->user, USER_PASS_LEN);
1114		  buf_printf (&packed_resp, "CRV1::%s::%s", ac->state_id, response);
1115		}
1116	      else
1117		{
1118		  msg (M_FATAL, "ERROR: received malformed challenge request from server");
1119		}
1120	    }
1121	  else
1122#endif
1123	    {
1124	      struct buffer user_prompt = alloc_buf_gc (128, &gc);
1125	      struct buffer pass_prompt = alloc_buf_gc (128, &gc);
1126
1127	      buf_printf (&user_prompt, "Enter %s Username:", prefix);
1128	      buf_printf (&pass_prompt, "Enter %s Password:", prefix);
1129
1130	      if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
1131		{
1132		  if (!get_console_input (BSTR (&user_prompt), true, up->username, USER_PASS_LEN))
1133		    msg (M_FATAL, "ERROR: could not read %s username from stdin", prefix);
1134		  if (strlen (up->username) == 0)
1135		    msg (M_FATAL, "ERROR: %s username is empty", prefix);
1136		}
1137
1138	      if (!get_console_input (BSTR (&pass_prompt), false, up->password, USER_PASS_LEN))
1139		msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix);
1140
1141#ifdef ENABLE_CLIENT_CR
1142	      if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
1143		{
1144		  char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
1145		  struct buffer packed_resp;
1146		  char *pw64=NULL, *resp64=NULL;
1147
1148		  msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge);
1149		  if (!get_console_input ("Response:", BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), response, USER_PASS_LEN))
1150		    msg (M_FATAL, "ERROR: could not read static challenge response from stdin");
1151		  if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
1152		      || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
1153		    msg (M_FATAL, "ERROR: could not base64-encode password/static_response");
1154		  buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN);
1155		  buf_printf (&packed_resp, "SCRV1:%s:%s", pw64, resp64);
1156		  string_clear(pw64);
1157		  free(pw64);
1158		  string_clear(resp64);
1159		  free(resp64);
1160		}
1161#endif
1162	    }
1163	}
1164      else
1165	{
1166	  /*
1167	   * Get username/password from a file.
1168	   */
1169	  FILE *fp;
1170
1171#ifndef ENABLE_PASSWORD_SAVE
1172	  /*
1173	   * Unless ENABLE_PASSWORD_SAVE is defined, don't allow sensitive passwords
1174	   * to be read from a file.
1175	   */
1176	  if (flags & GET_USER_PASS_SENSITIVE)
1177	    msg (M_FATAL, "Sorry, '%s' password cannot be read from a file", prefix);
1178#endif
1179
1180	  warn_if_group_others_accessible (auth_file);
1181
1182	  fp = platform_fopen (auth_file, "r");
1183	  if (!fp)
1184	    msg (M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
1185
1186	  if (flags & GET_USER_PASS_PASSWORD_ONLY)
1187	    {
1188	      if (fgets (up->password, USER_PASS_LEN, fp) == NULL)
1189		msg (M_FATAL, "Error reading password from %s authfile: %s",
1190		     prefix,
1191		     auth_file);
1192	    }
1193	  else
1194	    {
1195	      if (fgets (up->username, USER_PASS_LEN, fp) == NULL
1196		  || fgets (up->password, USER_PASS_LEN, fp) == NULL)
1197		msg (M_FATAL, "Error reading username and password (must be on two consecutive lines) from %s authfile: %s",
1198		     prefix,
1199		     auth_file);
1200	    }
1201
1202	  fclose (fp);
1203
1204	  chomp (up->username);
1205	  chomp (up->password);
1206
1207	  if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen (up->username) == 0)
1208	    msg (M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
1209	}
1210
1211      string_mod (up->username, CC_PRINT, CC_CRLF, 0);
1212      string_mod (up->password, CC_PRINT, CC_CRLF, 0);
1213
1214      up->defined = true;
1215    }
1216
1217#if 0
1218  msg (M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
1219#endif
1220
1221  gc_free (&gc);
1222
1223  return true;
1224}
1225
1226#ifdef ENABLE_CLIENT_CR
1227
1228/*
1229 * See management/management-notes.txt for more info on the
1230 * the dynamic challenge/response protocol implemented here.
1231 */
1232struct auth_challenge_info *
1233get_auth_challenge (const char *auth_challenge, struct gc_arena *gc)
1234{
1235  if (auth_challenge)
1236    {
1237      struct auth_challenge_info *ac;
1238      const int len = strlen (auth_challenge);
1239      char *work = (char *) gc_malloc (len+1, false, gc);
1240      char *cp;
1241
1242      struct buffer b;
1243      buf_set_read (&b, (const uint8_t *)auth_challenge, len);
1244
1245      ALLOC_OBJ_CLEAR_GC (ac, struct auth_challenge_info, gc);
1246
1247      /* parse prefix */
1248      if (!buf_parse(&b, ':', work, len))
1249	return NULL;
1250      if (strcmp(work, "CRV1"))
1251	return NULL;
1252
1253      /* parse flags */
1254      if (!buf_parse(&b, ':', work, len))
1255	return NULL;
1256      for (cp = work; *cp != '\0'; ++cp)
1257	{
1258	  const char c = *cp;
1259	  if (c == 'E')
1260	    ac->flags |= CR_ECHO;
1261	  else if (c == 'R')
1262	    ac->flags |= CR_RESPONSE;
1263	}
1264
1265      /* parse state ID */
1266      if (!buf_parse(&b, ':', work, len))
1267	return NULL;
1268      ac->state_id = string_alloc(work, gc);
1269
1270      /* parse user name */
1271      if (!buf_parse(&b, ':', work, len))
1272	return NULL;
1273      ac->user = (char *) gc_malloc (strlen(work)+1, true, gc);
1274      openvpn_base64_decode(work, (void*)ac->user, -1);
1275
1276      /* parse challenge text */
1277      ac->challenge_text = string_alloc(BSTR(&b), gc);
1278
1279      return ac;
1280    }
1281  else
1282    return NULL;
1283}
1284
1285#endif
1286
1287#if AUTO_USERID
1288
1289void
1290get_user_pass_auto_userid (struct user_pass *up, const char *tag)
1291{
1292  struct gc_arena gc = gc_new ();
1293  struct buffer buf;
1294  uint8_t macaddr[6];
1295  static uint8_t digest [MD5_DIGEST_LENGTH];
1296  static const uint8_t hashprefix[] = "AUTO_USERID_DIGEST";
1297
1298  const md_kt_t *md5_kt = md_kt_get("MD5");
1299  md_ctx_t ctx;
1300
1301  CLEAR (*up);
1302  buf_set_write (&buf, (uint8_t*)up->username, USER_PASS_LEN);
1303  buf_printf (&buf, "%s", TARGET_PREFIX);
1304  if (get_default_gateway_mac_addr (macaddr))
1305    {
1306      dmsg (D_AUTO_USERID, "GUPAU: macaddr=%s", format_hex_ex (macaddr, sizeof (macaddr), 0, 1, ":", &gc));
1307      md_ctx_init(&ctx, md5_kt);
1308      md_ctx_update(&ctx, hashprefix, sizeof (hashprefix) - 1);
1309      md_ctx_update(&ctx, macaddr, sizeof (macaddr));
1310      md_ctx_final(&ctx, digest);
1311      md_ctx_cleanup(&ctx)
1312      buf_printf(&buf, "%s", format_hex_ex (digest, sizeof (digest), 0, 256, " ", &gc));
1313    }
1314  else
1315    {
1316      buf_printf (&buf, "UNKNOWN");
1317    }
1318  if (tag && strcmp (tag, "stdin"))
1319    buf_printf (&buf, "-%s", tag);
1320  up->defined = true;
1321  gc_free (&gc);
1322
1323  dmsg (D_AUTO_USERID, "GUPAU: AUTO_USERID: '%s'", up->username);
1324}
1325
1326#endif
1327
1328void
1329purge_user_pass (struct user_pass *up, const bool force)
1330{
1331  const bool nocache = up->nocache;
1332  static bool warn_shown = false;
1333  if (nocache || force)
1334    {
1335      CLEAR (*up);
1336      up->nocache = nocache;
1337    }
1338  else if (!warn_shown)
1339    {
1340      msg (M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
1341      warn_shown = true;
1342    }
1343}
1344
1345void
1346set_auth_token (struct user_pass *up, const char *token)
1347{
1348  if (token && strlen(token) && up && up->defined && !up->nocache)
1349    {
1350      CLEAR (up->password);
1351      strncpynt (up->password, token, USER_PASS_LEN);
1352    }
1353}
1354
1355/*
1356 * Process string received by untrusted peer before
1357 * printing to console or log file.
1358 *
1359 * Assumes that string has been null terminated.
1360 */
1361const char *
1362safe_print (const char *str, struct gc_arena *gc)
1363{
1364  return string_mod_const (str, CC_PRINT, CC_CRLF, '.', gc);
1365}
1366
1367static bool
1368is_password_env_var (const char *str)
1369{
1370  return (strncmp (str, "password", 8) == 0);
1371}
1372
1373bool
1374env_allowed (const char *str)
1375{
1376  return (script_security >= SSEC_PW_ENV || !is_password_env_var (str));
1377}
1378
1379bool
1380env_safe_to_print (const char *str)
1381{
1382#ifndef UNSAFE_DEBUG
1383  if (is_password_env_var (str))
1384    return false;
1385#endif
1386  return true;
1387}
1388
1389/* Make arrays of strings */
1390
1391const char **
1392make_env_array (const struct env_set *es,
1393		const bool check_allowed,
1394		struct gc_arena *gc)
1395{
1396  char **ret = NULL;
1397  struct env_item *e = NULL;
1398  int i = 0, n = 0;
1399
1400  /* figure length of es */
1401  if (es)
1402    {
1403      for (e = es->list; e != NULL; e = e->next)
1404	++n;
1405    }
1406
1407  /* alloc return array */
1408  ALLOC_ARRAY_CLEAR_GC (ret, char *, n+1, gc);
1409
1410  /* fill return array */
1411  if (es)
1412    {
1413      i = 0;
1414      for (e = es->list; e != NULL; e = e->next)
1415	{
1416	  if (!check_allowed || env_allowed (e->string))
1417	    {
1418	      ASSERT (i < n);
1419	      ret[i++] = e->string;
1420	    }
1421	}
1422    }
1423
1424  ret[i] = NULL;
1425  return (const char **)ret;
1426}
1427
1428const char **
1429make_arg_array (const char *first, const char *parms, struct gc_arena *gc)
1430{
1431  char **ret = NULL;
1432  int base = 0;
1433  const int max_parms = MAX_PARMS + 2;
1434  int n = 0;
1435
1436  /* alloc return array */
1437  ALLOC_ARRAY_CLEAR_GC (ret, char *, max_parms, gc);
1438
1439  /* process first parameter, if provided */
1440  if (first)
1441    {
1442      ret[base++] = string_alloc (first, gc);
1443    }
1444
1445  if (parms)
1446    {
1447      n = parse_line (parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
1448      ASSERT (n >= 0 && n + base + 1 <= max_parms);
1449    }
1450  ret[base + n] = NULL;
1451
1452  return (const char **)ret;
1453}
1454
1455static const char **
1456make_inline_array (const char *str, struct gc_arena *gc)
1457{
1458  char line[OPTION_LINE_SIZE];
1459  struct buffer buf;
1460  int len = 0;
1461  char **ret = NULL;
1462  int i = 0;
1463
1464  buf_set_read (&buf, (const uint8_t *) str, strlen (str));
1465  while (buf_parse (&buf, '\n', line, sizeof (line)))
1466    ++len;
1467
1468  /* alloc return array */
1469  ALLOC_ARRAY_CLEAR_GC (ret, char *, len + 1, gc);
1470
1471  buf_set_read (&buf, (const uint8_t *) str, strlen(str));
1472  while (buf_parse (&buf, '\n', line, sizeof (line)))
1473    {
1474      chomp (line);
1475      ASSERT (i < len);
1476      ret[i] = string_alloc (skip_leading_whitespace (line), gc);
1477      ++i;
1478    }
1479  ASSERT (i <= len);
1480  ret[i] = NULL;
1481  return (const char **)ret;
1482}
1483
1484static const char **
1485make_arg_copy (char **p, struct gc_arena *gc)
1486{
1487  char **ret = NULL;
1488  const int len = string_array_len ((const char **)p);
1489  const int max_parms = len + 1;
1490  int i;
1491
1492  /* alloc return array */
1493  ALLOC_ARRAY_CLEAR_GC (ret, char *, max_parms, gc);
1494
1495  for (i = 0; i < len; ++i)
1496    ret[i] = p[i];
1497
1498  return (const char **)ret;
1499}
1500
1501const char **
1502make_extended_arg_array (char **p, struct gc_arena *gc)
1503{
1504  const int argc = string_array_len ((const char **)p);
1505  if (!strcmp (p[0], INLINE_FILE_TAG) && argc == 2)
1506    return make_inline_array (p[1], gc);
1507  else
1508  if (argc == 0)
1509    return make_arg_array (NULL, NULL, gc);
1510  else if (argc == 1)
1511    return make_arg_array (p[0], NULL, gc);
1512  else if (argc == 2)
1513    return make_arg_array (p[0], p[1], gc);
1514  else
1515    return make_arg_copy (p, gc);
1516}
1517
1518void
1519openvpn_sleep (const int n)
1520{
1521#ifdef ENABLE_MANAGEMENT
1522  if (management)
1523    {
1524      management_event_loop_n_seconds (management, n);
1525      return;
1526    }
1527#endif
1528  sleep (n);
1529}
1530
1531/*
1532 * Return the next largest power of 2
1533 * or u if u is a power of 2.
1534 */
1535size_t
1536adjust_power_of_2 (size_t u)
1537{
1538  size_t ret = 1;
1539
1540  while (ret < u)
1541    {
1542      ret <<= 1;
1543      ASSERT (ret > 0);
1544    }
1545
1546  return ret;
1547}
1548
1549/*
1550 * A printf-like function (that only recognizes a subset of standard printf
1551 * format operators) that prints arguments to an argv list instead
1552 * of a standard string.  This is used to build up argv arrays for passing
1553 * to execve.
1554 */
1555
1556void
1557argv_init (struct argv *a)
1558{
1559  a->capacity = 0;
1560  a->argc = 0;
1561  a->argv = NULL;
1562  a->system_str = NULL;
1563}
1564
1565struct argv
1566argv_new (void)
1567{
1568  struct argv ret;
1569  argv_init (&ret);
1570  return ret;
1571}
1572
1573void
1574argv_reset (struct argv *a)
1575{
1576  size_t i;
1577  for (i = 0; i < a->argc; ++i)
1578    free (a->argv[i]);
1579  free (a->argv);
1580  free (a->system_str);
1581  argv_init (a);
1582}
1583
1584static void
1585argv_extend (struct argv *a, const size_t newcap)
1586{
1587  if (newcap > a->capacity)
1588    {
1589      char **newargv;
1590      size_t i;
1591      ALLOC_ARRAY_CLEAR (newargv, char *, newcap);
1592      for (i = 0; i < a->argc; ++i)
1593	newargv[i] = a->argv[i];
1594      free (a->argv);
1595      a->argv = newargv;
1596      a->capacity = newcap;
1597    }
1598}
1599
1600static void
1601argv_grow (struct argv *a, const size_t add)
1602{
1603  const size_t newargc = a->argc + add + 1;
1604  ASSERT (newargc > a->argc);
1605  argv_extend (a, adjust_power_of_2 (newargc));
1606}
1607
1608static void
1609argv_append (struct argv *a, char *str) /* str must have been malloced or be NULL */
1610{
1611  argv_grow (a, 1);
1612  a->argv[a->argc++] = str;
1613}
1614
1615static void
1616argv_system_str_append (struct argv *a, const char *str, const bool enquote)
1617{
1618  if (str)
1619    {
1620      char *newstr;
1621
1622      /* compute length of new system_str */
1623      size_t l = strlen (str) + 1; /* space for new string plus trailing '\0' */
1624      if (a->system_str)
1625	l += strlen (a->system_str) + 1; /* space for existing string + space (" ") separator */
1626      if (enquote)
1627	l += 2; /* space for two quotes */
1628
1629      /* build new system_str */
1630      newstr = (char *) malloc (l);
1631      newstr[0] = '\0';
1632      check_malloc_return (newstr);
1633      if (a->system_str)
1634	{
1635	  strcpy (newstr, a->system_str);
1636	  strcat (newstr, " ");
1637	}
1638      if (enquote)
1639	strcat (newstr, "\"");
1640      strcat (newstr, str);
1641      if (enquote)
1642	strcat (newstr, "\"");
1643      free (a->system_str);
1644      a->system_str = newstr;
1645    }
1646}
1647
1648static char *
1649argv_extract_cmd_name (const char *path)
1650{
1651  if (path)
1652    {
1653      char *path_cp = strdup(path); /* POSIX basename() implementaions may modify its arguments */
1654      const char *bn = basename (path_cp);
1655      if (bn)
1656	{
1657	  char *ret = string_alloc (bn, NULL);
1658	  char *dot = strrchr (ret, '.');
1659	  if (dot)
1660	    *dot = '\0';
1661	  free(path_cp);
1662	  if (ret[0] != '\0')
1663	    return ret;
1664	}
1665    }
1666  return NULL;
1667}
1668
1669const char *
1670argv_system_str (const struct argv *a)
1671{
1672  return a->system_str;
1673}
1674
1675struct argv
1676argv_clone (const struct argv *a, const size_t headroom)
1677{
1678  struct argv r;
1679  size_t i;
1680
1681  argv_init (&r);
1682  for (i = 0; i < headroom; ++i)
1683    argv_append (&r, NULL);
1684  if (a)
1685    {
1686      for (i = 0; i < a->argc; ++i)
1687	argv_append (&r, string_alloc (a->argv[i], NULL));
1688      r.system_str = string_alloc (a->system_str, NULL);
1689    }
1690  return r;
1691}
1692
1693struct argv
1694argv_insert_head (const struct argv *a, const char *head)
1695{
1696  struct argv r;
1697  char *s;
1698
1699  r = argv_clone (a, 1);
1700  r.argv[0] = string_alloc (head, NULL);
1701  s = r.system_str;
1702  r.system_str = string_alloc (head, NULL);
1703  if (s)
1704    {
1705      argv_system_str_append (&r, s, false);
1706      free (s);
1707    }
1708  return r;
1709}
1710
1711char *
1712argv_term (const char **f)
1713{
1714  const char *p = *f;
1715  const char *term = NULL;
1716  size_t termlen = 0;
1717
1718  if (*p == '\0')
1719    return NULL;
1720
1721  while (true)
1722    {
1723      const int c = *p;
1724      if (c == '\0')
1725	break;
1726      if (term)
1727	{
1728	  if (!isspace (c))
1729	    ++termlen;
1730	  else
1731	    break;
1732	}
1733      else
1734	{
1735	  if (!isspace (c))
1736	    {
1737	      term = p;
1738	      termlen = 1;
1739	    }
1740	}
1741      ++p;
1742    }
1743  *f = p;
1744
1745  if (term)
1746    {
1747      char *ret;
1748      ASSERT (termlen > 0);
1749      ret = malloc (termlen + 1);
1750      check_malloc_return (ret);
1751      memcpy (ret, term, termlen);
1752      ret[termlen] = '\0';
1753      return ret;
1754    }
1755  else
1756    return NULL;
1757}
1758
1759const char *
1760argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags)
1761{
1762  if (a->argv)
1763    return print_argv ((const char **)a->argv, gc, flags);
1764  else
1765    return "";
1766}
1767
1768void
1769argv_msg (const int msglev, const struct argv *a)
1770{
1771  struct gc_arena gc = gc_new ();
1772  msg (msglev, "%s", argv_str (a, &gc, 0));
1773  gc_free (&gc);
1774}
1775
1776void
1777argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix)
1778{
1779  struct gc_arena gc = gc_new ();
1780  msg (msglev, "%s: %s", prefix, argv_str (a, &gc, 0));
1781  gc_free (&gc);
1782}
1783
1784void
1785argv_printf (struct argv *a, const char *format, ...)
1786{
1787  va_list arglist;
1788  va_start (arglist, format);
1789  argv_printf_arglist (a, format, 0, arglist);
1790  va_end (arglist);
1791 }
1792
1793void
1794argv_printf_cat (struct argv *a, const char *format, ...)
1795{
1796  va_list arglist;
1797  va_start (arglist, format);
1798  argv_printf_arglist (a, format, APA_CAT, arglist);
1799  va_end (arglist);
1800}
1801
1802void
1803argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist)
1804{
1805  struct gc_arena gc = gc_new ();
1806  char *term;
1807  const char *f = format;
1808
1809  if (!(flags & APA_CAT))
1810    argv_reset (a);
1811  argv_extend (a, 1); /* ensure trailing NULL */
1812
1813  while ((term = argv_term (&f)) != NULL)
1814    {
1815      if (term[0] == '%')
1816	{
1817	  if (!strcmp (term, "%s"))
1818	    {
1819	      char *s = va_arg (arglist, char *);
1820	      if (!s)
1821		s = "";
1822	      argv_append (a, string_alloc (s, NULL));
1823	      argv_system_str_append (a, s, true);
1824	    }
1825	  else if (!strcmp (term, "%sc"))
1826	    {
1827	      char *s = va_arg (arglist, char *);
1828	      if (s)
1829		{
1830		  int nparms;
1831		  char *parms[MAX_PARMS+1];
1832		  int i;
1833
1834		  nparms = parse_line (s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc);
1835		  if (nparms)
1836		    {
1837		      for (i = 0; i < nparms; ++i)
1838			argv_append (a, string_alloc (parms[i], NULL));
1839		    }
1840		  else
1841		    argv_append (a, string_alloc (s, NULL));
1842
1843		  argv_system_str_append (a, s, false);
1844		}
1845	      else
1846		{
1847		  argv_append (a, string_alloc ("", NULL));
1848		  argv_system_str_append (a, "echo", false);
1849		}
1850	    }
1851	  else if (!strcmp (term, "%d"))
1852	    {
1853	      char numstr[64];
1854	      openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
1855	      argv_append (a, string_alloc (numstr, NULL));
1856	      argv_system_str_append (a, numstr, false);
1857	    }
1858	  else if (!strcmp (term, "%u"))
1859	    {
1860	      char numstr[64];
1861	      openvpn_snprintf (numstr, sizeof (numstr), "%u", va_arg (arglist, unsigned int));
1862	      argv_append (a, string_alloc (numstr, NULL));
1863	      argv_system_str_append (a, numstr, false);
1864	    }
1865	  else if (!strcmp (term, "%s/%d"))
1866	    {
1867	      char numstr[64];
1868	      char *s = va_arg (arglist, char *);
1869
1870	      if (!s)
1871		s = "";
1872
1873	      openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
1874
1875	      {
1876		const size_t len = strlen(s) + strlen(numstr) + 2;
1877		char *combined = (char *) malloc (len);
1878		check_malloc_return (combined);
1879
1880		strcpy (combined, s);
1881		strcat (combined, "/");
1882		strcat (combined, numstr);
1883		argv_append (a, combined);
1884		argv_system_str_append (a, combined, false);
1885	      }
1886	    }
1887	  else if (!strcmp (term, "%s%sc"))
1888	    {
1889	      char *s1 = va_arg (arglist, char *);
1890	      char *s2 = va_arg (arglist, char *);
1891	      char *combined;
1892	      char *cmd_name;
1893
1894	      if (!s1) s1 = "";
1895	      if (!s2) s2 = "";
1896	      combined = (char *) malloc (strlen(s1) + strlen(s2) + 1);
1897	      check_malloc_return (combined);
1898	      strcpy (combined, s1);
1899	      strcat (combined, s2);
1900	      argv_append (a, combined);
1901
1902	      cmd_name = argv_extract_cmd_name (combined);
1903	      if (cmd_name)
1904		{
1905		  argv_system_str_append (a, cmd_name, false);
1906		  free (cmd_name);
1907		}
1908	    }
1909	  else
1910	    ASSERT (0);
1911	  free (term);
1912	}
1913      else
1914	{
1915	  argv_append (a, term);
1916	  argv_system_str_append (a, term, false);
1917	}
1918    }
1919  gc_free (&gc);
1920}
1921
1922#ifdef ARGV_TEST
1923void
1924argv_test (void)
1925{
1926  struct gc_arena gc = gc_new ();
1927  const char *s;
1928
1929  struct argv a;
1930
1931  argv_init (&a);
1932  argv_printf (&a, "%sc foo bar %s", "c:\\\\src\\\\test\\\\jyargs.exe", "foo bar");
1933  argv_msg_prefix (M_INFO, &a, "ARGV");
1934  msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
1935  /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
1936
1937  argv_printf (&a, "%sc %s %s", "c:\\\\src\\\\test files\\\\batargs.bat", "foo", "bar");
1938  argv_msg_prefix (M_INFO, &a, "ARGV");
1939  msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
1940  /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
1941
1942  argv_printf (&a, "%s%sc foo bar %s %s/%d %d %u", "/foo", "/bar.exe", "one two", "1.2.3.4", 24, -69, 96);
1943  argv_msg_prefix (M_INFO, &a, "ARGV");
1944  msg (M_INFO, "ARGV-S: %s", argv_system_str(&a));
1945  /*openvpn_execve_check (&a, NULL, 0, "command failed");*/
1946
1947  argv_printf (&a, "this is a %s test of int %d unsigned %u", "FOO", -69, 42);
1948  s = argv_str (&a, &gc, PA_BRACKET);
1949  printf ("PF: %s\n", s);
1950  printf ("PF-S: %s\n", argv_system_str(&a));
1951
1952  {
1953    struct argv b = argv_insert_head (&a, "MARK");
1954    s = argv_str (&b, &gc, PA_BRACKET);
1955    printf ("PF: %s\n", s);
1956    printf ("PF-S: %s\n", argv_system_str(&b));
1957    argv_reset (&b);
1958  }
1959
1960  argv_printf (&a, "%sc foo bar %d", "\"multi term\" command      following \\\"spaces", 99);
1961  s = argv_str (&a, &gc, PA_BRACKET);
1962  printf ("PF: %s\n", s);
1963  printf ("PF-S: %s\n", argv_system_str(&a));
1964  argv_reset (&a);
1965
1966  s = argv_str (&a, &gc, PA_BRACKET);
1967  printf ("PF: %s\n", s);
1968  printf ("PF-S: %s\n", argv_system_str(&a));
1969  argv_reset (&a);
1970
1971  argv_printf (&a, "foo bar %d", 99);
1972  argv_printf_cat (&a, "bar %d foo %sc", 42, "nonesuch");
1973  argv_printf_cat (&a, "cool %s %d u %s/%d end", "frood", 4, "hello", 7);
1974  s = argv_str (&a, &gc, PA_BRACKET);
1975  printf ("PF: %s\n", s);
1976  printf ("PF-S: %s\n", argv_system_str(&a));
1977  argv_reset (&a);
1978
1979#if 0
1980  {
1981    char line[512];
1982    while (fgets (line, sizeof(line), stdin) != NULL)
1983      {
1984	char *term;
1985	const char *f = line;
1986	int i = 0;
1987
1988	while ((term = argv_term (&f)) != NULL)
1989	  {
1990	    printf ("[%d] '%s'\n", i, term);
1991	    ++i;
1992	    free (term);
1993	  }
1994      }
1995  }
1996#endif
1997
1998  argv_reset (&a);
1999  gc_free (&gc);
2000}
2001#endif
2002
2003/*
2004 * Remove security-sensitive strings from control message
2005 * so that they will not be output to log file.
2006 */
2007const char *
2008sanitize_control_message(const char *src, struct gc_arena *gc)
2009{
2010  char *ret = gc_malloc (strlen(src)+1, false, gc);
2011  char *dest = ret;
2012  bool redact = false;
2013  int skip = 0;
2014
2015  for (;;)
2016    {
2017      const char c = *src;
2018      if (c == '\0')
2019	  break;
2020      if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
2021	{
2022	  skip = 7;
2023	  redact = true;
2024	}
2025      else if (c == 'e' && !strncmp(src, "echo ", 5))
2026	{
2027	  skip = 4;
2028	  redact = true;
2029	}
2030
2031      if (c == ',') /* end of redacted item? */
2032	{
2033	  skip = 0;
2034	  redact = false;
2035	}
2036
2037      if (redact)
2038	{
2039	  if (skip > 0)
2040	    {
2041	      --skip;
2042	      *dest++ = c;
2043	    }
2044	}
2045      else
2046	*dest++ = c;
2047
2048      ++src;
2049    }
2050  *dest = '\0';
2051  return ret;
2052}
2053
2054/**
2055 * Will set or query for a global compat flag.  To modify the compat flags
2056 * the COMPAT_FLAG_SET must be bitwise ORed together with the flag to set.
2057 * If no "operator" flag is given it defaults to COMPAT_FLAG_QUERY,
2058 * which returns the flag state.
2059 *
2060 * @param  flag  Flag to be set/queried for bitwise ORed with the operator flag
2061 * @return Returns 0 if the flag is not set, otherwise the 'flag' value is returned
2062 */
2063bool
2064compat_flag (unsigned int flag)
2065{
2066  static unsigned int compat_flags = 0;
2067
2068  if (flag & COMPAT_FLAG_SET)
2069    compat_flags |= (flag >> 1);
2070
2071  return (compat_flags & (flag >> 1));
2072
2073}
2074