From b8fb090c167ff500a8d702f612a42914d4f0bb03 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 6 Sep 2008 09:42:17 +0000 Subject: 2.1_rc8 and earlier did implicit shell expansion on script arguments since all scripts were called by system(). The security hardening changes made to 2.1_rc9 no longer use system(), but rather use the safer execve or CreateProcess system calls. The security hardening also introduced a backward incompatibility with 2.1_rc8 and earlier in that script parameters were no longer shell-expanded, so for example: client-connect "docc CLIENT-CONNECT" would fail to work because execve would try to execute a script called "docc CLIENT-CONNECT" instead of "docc" with "CLIENT-CONNECT" as the first argument. This patch fixes the issue, bringing the script argument semantics back to pre 2.1_rc9 behavior in order to preserve backward compatibility while still using execve or CreateProcess to execute the script/executable. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3311 e7ae566f-a301-0410-adde-c780ea21d3b5 --- buffer.c | 252 --------------------------------------------------------------- 1 file changed, 252 deletions(-) (limited to 'buffer.c') diff --git a/buffer.c b/buffer.c index dfaaaa1..c1ffb83 100644 --- a/buffer.c +++ b/buffer.c @@ -234,258 +234,6 @@ int openvpn_snprintf(char *str, size_t size, const char *format, ...) return ret; } -/* - * A printf-like function (that only recognizes a subset of standard printf - * format operators) that prints arguments to an argv list instead - * of a standard string. This is used to build up argv arrays for passing - * to execve. - */ - -void -argv_init (struct argv *a) -{ - a->argc = 0; - a->argv = NULL; -} - -struct argv -argv_new (void) -{ - struct argv ret; - argv_init (&ret); - return ret; -} - -void -argv_reset (struct argv *a) -{ - size_t i; - for (i = 0; i < a->argc; ++i) - free (a->argv[i]); - free (a->argv); - a->argc = 0; - a->argv = NULL; -} - -size_t -argv_argc (const char *format) -{ - char *term; - const char *f = format; - size_t argc = 0; - - while ((term = argv_term (&f)) != NULL) - { - ++argc; - free (term); - } - return argc; -} - -struct argv -argv_insert_head (const struct argv *a, const char *head) -{ - struct argv r; - size_t i; - - r.argc = (a ? a->argc : 0) + 1; - ALLOC_ARRAY_CLEAR (r.argv, char *, r.argc + 1); - r.argv[0] = string_alloc (head, NULL); - if (a) - { - for (i = 0; i < a->argc; ++i) - r.argv[i+1] = string_alloc (a->argv[i], NULL); - } - return r; -} - -char * -argv_term (const char **f) -{ - const char *p = *f; - const char *term = NULL; - size_t termlen = 0; - - if (*p == '\0') - return NULL; - - while (true) - { - const int c = *p; - if (c == '\0') - break; - if (term) - { - if (!isspace (c)) - ++termlen; - else - break; - } - else - { - if (!isspace (c)) - { - term = p; - termlen = 1; - } - } - ++p; - } - *f = p; - - if (term) - { - char *ret; - ASSERT (termlen > 0); - ret = malloc (termlen + 1); - check_malloc_return (ret); - memcpy (ret, term, termlen); - ret[termlen] = '\0'; - return ret; - } - else - return NULL; -} - -const char * -argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags) -{ - if (a->argv) - return print_argv ((const char **)a->argv, gc, flags); - else - return ""; -} - -void -argv_msg (const int msglev, const struct argv *a) -{ - struct gc_arena gc = gc_new (); - msg (msglev, "%s", argv_str (a, &gc, 0)); - gc_free (&gc); -} - -void -argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix) -{ - struct gc_arena gc = gc_new (); - msg (msglev, "%s: %s", prefix, argv_str (a, &gc, 0)); - gc_free (&gc); -} - -void -argv_printf (struct argv *a, const char *format, ...) -{ - va_list arglist; - va_start (arglist, format); - argv_printf_arglist (a, format, 0, arglist); - va_end (arglist); - } - -void -argv_printf_cat (struct argv *a, const char *format, ...) -{ - va_list arglist; - va_start (arglist, format); - argv_printf_arglist (a, format, APA_CAT, arglist); - va_end (arglist); -} - -void -argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist) -{ - char *term; - const char *f = format; - size_t argc = 0; - - if (flags & APA_CAT) - { - char **old_argv = a->argv; - size_t i; - argc = a->argc; - a->argc += argv_argc (format); - ALLOC_ARRAY_CLEAR (a->argv, char *, a->argc + 1); - for (i = 0; i < argc; ++i) - a->argv[i] = old_argv[i]; - free (old_argv); - } - else - { - argv_reset (a); - a->argc = argv_argc (format); - ALLOC_ARRAY_CLEAR (a->argv, char *, a->argc + 1); - } - - while ((term = argv_term (&f)) != NULL) - { - ASSERT (argc < a->argc); - if (term[0] == '%') - { - if (!strcmp (term, "%s")) - { - char *s = va_arg (arglist, char *); - if (!s) - s = ""; - a->argv[argc++] = string_alloc (s, NULL); - } - else if (!strcmp (term, "%d")) - { - char numstr[64]; - openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int)); - a->argv[argc++] = string_alloc (numstr, NULL); - } - else if (!strcmp (term, "%u")) - { - char numstr[64]; - openvpn_snprintf (numstr, sizeof (numstr), "%u", va_arg (arglist, unsigned int)); - a->argv[argc++] = string_alloc (numstr, NULL); - } - else if (!strcmp (term, "%s/%d")) - { - char numstr[64]; - char *s = va_arg (arglist, char *); - - if (!s) - s = ""; - - openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int)); - - { - const size_t len = strlen(s) + strlen(numstr) + 2; - char *combined = (char *) malloc (len); - check_malloc_return (combined); - - strcpy (combined, s); - strcat (combined, "/"); - strcat (combined, numstr); - a->argv[argc++] = combined; - } - } - else if (!strcmp (term, "%s%s")) - { - char *s1 = va_arg (arglist, char *); - char *s2 = va_arg (arglist, char *); - char *combined; - - if (!s1) s1 = ""; - if (!s2) s2 = ""; - combined = (char *) malloc (strlen(s1) + strlen(s2) + 1); - check_malloc_return (combined); - strcpy (combined, s1); - strcat (combined, s2); - a->argv[argc++] = combined; - } - else - ASSERT (0); - free (term); - } - else - { - a->argv[argc++] = term; - } - } - ASSERT (argc == a->argc); -} - /* * write a string to the end of a buffer that was * truncated by buf_printf -- cgit v1.2.3