]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Replace strtok with strtok_r master
authorArne Schwabe <arne@rfc2549.org>
Wed, 8 Jul 2026 15:31:07 +0000 (17:31 +0200)
committerGert Doering <gert@greenie.muc.de>
Wed, 15 Jul 2026 17:35:31 +0000 (19:35 +0200)
This does not change anything in our source code but makes compiling
with newer Android NDKs (version 30 pre release) -Werror safe again
as it has started throwing warning on this.

The compat version is taken from current FreeBSD (commit dc36d6f9bb1)
src/lib/libc/string/strtok.c and reformatted to our clang standard.

Change-Id: I70560efd113308b7377424127eb2c1da4266371a
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1679
Message-Id: <20260708153107.60809-1-frank@lichtenheld.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg37538.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
CMakeLists.txt
configure.ac
src/compat/Makefile.am
src/compat/compat-strtok_r.c [new file with mode: 0644]
src/compat/compat.h
src/openvpn/options_util.c
src/openvpn/ssl_mbedtls.c
src/openvpn/ssl_ncp.c
src/openvpn/ssl_verify.c
tests/unit_tests/openvpn/Makefile.am

index 23541a5dbe5ac1f62b595597333cc3d88ad2d8ba..7473f1545a7af0768c46dbdf1883d9d48d0facfa 100644 (file)
@@ -248,6 +248,7 @@ endif()
 check_symbol_exists(chsize io.h HAVE_CHSIZE)
 check_symbol_exists(getrlimit sys/resource.h HAVE_GETRLIMIT)
 check_symbol_exists(strsep string.h HAVE_STRSEP)
+check_symbol_exists(strtok_r string.h HAVE_STRTOK_R)
 
 # Some OS (e.g. FreeBSD) need some basic headers to allow
 # including network headers
@@ -423,6 +424,7 @@ set(SOURCE_FILES
     src/compat/compat-dirname.c
     src/compat/compat-gettimeofday.c
     src/compat/compat-strsep.c
+    src/compat/compat-strtok_r.c
     src/openvpn/argv.c
     src/openvpn/argv.h
     src/openvpn/base64.c
@@ -743,6 +745,8 @@ if (BUILD_TESTING)
             src/openvpn/platform.c
             src/openvpn/win32-util.c
             src/compat/compat-gettimeofday.c
+            src/compat/compat-strsep.c
+            src/compat/compat-strtok_r.c
             )
 
         add_library_deps(${test_name})
index e19d651672387af78078b182d1d56dc38caef42f..188f8fa42304a356c639640c6cce78d1042e8d2e 100644 (file)
@@ -568,7 +568,7 @@ AC_CHECK_FUNCS([ \
        setgroups flock gettimeofday \
        setsid chdir \
        chsize ftruncate execve getpeereid basename dirname \
-       epoll_create strsep \
+       epoll_create strsep strtok_r \
 ])
 
 AC_CHECK_LIB(
index 69b29906f603d3e3915eafc2dc0ea0b6698a3cb5..22867b361ab684e69ee414995cdb2321c98bfdb8 100644 (file)
@@ -20,4 +20,5 @@ libcompat_la_SOURCES = \
        compat-basename.c \
        compat-gettimeofday.c \
        compat-daemon.c \
-       compat-strsep.c
\ No newline at end of file
+       compat-strsep.c \
+       compat-strtok_r.c
\ No newline at end of file
diff --git a/src/compat/compat-strtok_r.c b/src/compat/compat-strtok_r.c
new file mode 100644 (file)
index 0000000..debcdd3
--- /dev/null
@@ -0,0 +1,101 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notices, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_STRTOK_R
+#include <string.h>
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+    char *spanp, *tok;
+    int c, sc;
+
+    if (s == NULL && (s = *last) == NULL)
+    {
+        return (NULL);
+    }
+
+/*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+    c = *s++;
+    for (spanp = (char *)delim; (sc = *spanp++) != 0;)
+    {
+        if (c == sc)
+        {
+            goto cont;
+        }
+    }
+
+    if (c == 0)
+    { /* no non-delimiter characters */
+        *last = NULL;
+        return (NULL);
+    }
+    tok = s - 1;
+
+    /*
+     * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+     * Note that delim must have one NUL; we stop if we see that, too.
+     */
+    for (;;)
+    {
+        c = *s++;
+        spanp = (char *)delim;
+        do
+        {
+            if ((sc = *spanp++) == c)
+            {
+                if (c == 0)
+                {
+                    s = NULL;
+                }
+                else
+                {
+                    s[-1] = '\0';
+                }
+                *last = s;
+                return (tok);
+            }
+        } while (sc != 0);
+    }
+    /* NOTREACHED */
+}
+#endif
\ No newline at end of file
index 6532b8612e4d37811657cb2699fd45d5306d640d..9e6f95c2f76199e0cfd1d0ba41f72cf6d7d1803e 100644 (file)
@@ -61,4 +61,9 @@ char *strsep(char **stringp, const char *delim);
 
 #endif
 
+#ifndef HAVE_STRTOK_R
+char *
+strtok_r(char *s, const char *delim, char **last);
+#endif
+
 #endif /* COMPAT_H */
index 47fe0bc253060714bd0306cf4836db8c0215f386..d72ea25c798f8ccdbf2f37344750ff8ae536617e 100644 (file)
@@ -48,7 +48,8 @@ parse_auth_failed_temp(struct options *o, const char *reason)
         message = strstr(reason, "]") + 1;
         /* null terminate the substring to only looks for flags between [ and ] */
         *endofflags = '\x00';
-        const char *token = strtok(m, "[,");
+        char *lasts = NULL;
+        const char *token = strtok_r(m, "[,", &lasts);
         while (token)
         {
             if (!strncmp(token, "backoff ", strlen("backoff ")))
@@ -81,7 +82,7 @@ parse_auth_failed_temp(struct options *o, const char *reason)
             {
                 msg(D_PUSH_ERRORS, "WARNING: unknown AUTH_FAIL,TEMP flag: %s", token);
             }
-            token = strtok(NULL, "[,");
+            token = strtok_r(NULL, "[,", &lasts);
         }
     }
 
index 8a0f7d247c44d21eebee6917652b3e8ff8d062c6..07caf082cc4bbb04dfb8d18d592dc92f850d7321 100644 (file)
@@ -318,9 +318,10 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
 
     /* Parse allowed ciphers, getting IDs */
     int i = 0;
+    char *lasts = NULL;
     tmp_ciphers_orig = tmp_ciphers = string_alloc(ciphers, NULL);
 
-    token = strtok(tmp_ciphers, ":");
+    token = strtok_r(tmp_ciphers, ":", &lasts);
     while (token)
     {
         ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id(tls_translate_cipher_name(token));
@@ -328,7 +329,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
         {
             i++;
         }
-        token = strtok(NULL, ":");
+        token = strtok_r(NULL, ":", &lasts);
     }
     free(tmp_ciphers_orig);
 }
index 649665abc066628e3bcd31b48fdfd4b65b71fc1a..baf5a951078e1eb8885254b34c658b0a8e038fc2 100644 (file)
@@ -100,7 +100,8 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
     struct buffer new_list = alloc_buf(MAX_NCP_CIPHERS_LENGTH);
 
     char *const tmp_ciphers = string_alloc(list, NULL);
-    const char *token = strtok(tmp_ciphers, ":");
+    char *lasts = NULL;
+    const char *token = strtok_r(tmp_ciphers, ":", &lasts);
     while (token)
     {
         /*
@@ -174,7 +175,7 @@ mutate_ncp_cipher_list(const char *list, struct gc_arena *gc)
                 buf_puts(&new_list, ovpn_cipher_name);
             }
         }
-        token = strtok(NULL, ":");
+        token = strtok_r(NULL, ":", &lasts);
     }
 
 
@@ -207,15 +208,16 @@ tls_item_in_cipher_list(const char *item, const char *list)
 {
     char *tmp_ciphers = string_alloc(list, NULL);
     char *tmp_ciphers_orig = tmp_ciphers;
+    char *lasts = NULL;
 
-    const char *token = strtok(tmp_ciphers, ":");
+    const char *token = strtok_r(tmp_ciphers, ":", &lasts);
     while (token)
     {
         if (0 == strcmp(token, item))
         {
             break;
         }
-        token = strtok(NULL, ":");
+        token = strtok_r(NULL, ":", &lasts);
     }
     free(tmp_ciphers_orig);
 
index 9197adfba1967a81737cdc73c049f7277813ca11..162f68fba963f12b8457dd28cdd39dd90fcc22af 100644 (file)
@@ -868,7 +868,8 @@ check_auth_pending_method(const char *peer_info, const char *method)
         return false;
     }
 
-    const char *client_method = strtok(iv_sso, ",");
+    char *lasts = NULL;
+    const char *client_method = strtok_r(iv_sso, ",", &lasts);
     bool supported = false;
 
     while (client_method)
@@ -878,7 +879,7 @@ check_auth_pending_method(const char *peer_info, const char *method)
             supported = true;
             break;
         }
-        client_method = strtok(NULL, ",");
+        client_method = strtok_r(NULL, ",", &lasts);
     }
 
     gc_free(&gc);
index 1128eb49e2ed90ecdd047b84f515eeb3f89a082f..d861ef9a3a4608875afb79acabf5387d246d6e1c 100644 (file)
@@ -107,6 +107,7 @@ ssl_testdriver_SOURCES = test_ssl.c \
        $(top_srcdir)/src/openvpn/base64.c \
        $(top_srcdir)/src/openvpn/buffer.c \
        $(top_srcdir)/src/compat/compat-strsep.c \
+       $(top_srcdir)/src/compat/compat-strtok_r.c \
        $(top_srcdir)/src/openvpn/crypto.c \
        $(top_srcdir)/src/openvpn/cryptoapi.c \
        $(top_srcdir)/src/openvpn/crypto_epoch.c \
@@ -345,6 +346,7 @@ ncp_testdriver_SOURCES = test_ncp.c \
        $(top_srcdir)/src/openvpn/platform.c \
        $(top_srcdir)/src/openvpn/win32-util.c \
        $(top_srcdir)/src/compat/compat-strsep.c \
+       $(top_srcdir)/src/compat/compat-strtok_r.c \
        $(top_srcdir)/src/openvpn/ssl_util.c
 
 mbuf_testdriver_CFLAGS  = \