diff --git a/CMakeLists.txt b/CMakeLists.txt
index 715d02c..ceafbb4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -248,6 +248,7 @@
 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
@@ -413,6 +414,7 @@
     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
@@ -733,6 +735,8 @@
             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})
diff --git a/configure.ac b/configure.ac
index e19d651..188f8fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -568,7 +568,7 @@
 	setgroups flock gettimeofday \
 	setsid chdir \
 	chsize ftruncate execve getpeereid basename dirname \
-	epoll_create strsep \
+	epoll_create strsep strtok_r \
 ])
 
 AC_CHECK_LIB(
diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am
index 69b2990..22867b3 100644
--- a/src/compat/Makefile.am
+++ b/src/compat/Makefile.am
@@ -20,4 +20,5 @@
 	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
index 0000000..debcdd3
--- /dev/null
+++ b/src/compat/compat-strtok_r.c
@@ -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
diff --git a/src/compat/compat.h b/src/compat/compat.h
index 6532b86..9e6f95c 100644
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -61,4 +61,9 @@
 
 #endif
 
+#ifndef HAVE_STRTOK_R
+char *
+strtok_r(char *s, const char *delim, char **last);
+#endif
+
 #endif /* COMPAT_H */
diff --git a/src/openvpn/options_util.c b/src/openvpn/options_util.c
index 47fe0bc..d72ea25c 100644
--- a/src/openvpn/options_util.c
+++ b/src/openvpn/options_util.c
@@ -48,7 +48,8 @@
         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 @@
             {
                 msg(D_PUSH_ERRORS, "WARNING: unknown AUTH_FAIL,TEMP flag: %s", token);
             }
-            token = strtok(NULL, "[,");
+            token = strtok_r(NULL, "[,", &lasts);
         }
     }
 
diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
index 8a0f7d2..07caf08 100644
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
@@ -318,9 +318,10 @@
 
     /* 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 @@
         {
             i++;
         }
-        token = strtok(NULL, ":");
+        token = strtok_r(NULL, ":", &lasts);
     }
     free(tmp_ciphers_orig);
 }
diff --git a/src/openvpn/ssl_ncp.c b/src/openvpn/ssl_ncp.c
index 649665a..baf5a95 100644
--- a/src/openvpn/ssl_ncp.c
+++ b/src/openvpn/ssl_ncp.c
@@ -100,7 +100,8 @@
     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 @@
                 buf_puts(&new_list, ovpn_cipher_name);
             }
         }
-        token = strtok(NULL, ":");
+        token = strtok_r(NULL, ":", &lasts);
     }
 
 
@@ -207,15 +208,16 @@
 {
     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);
 
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index 0804d2d..1db7f55 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -868,7 +868,8 @@
         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 @@
             supported = true;
             break;
         }
-        client_method = strtok(NULL, ",");
+        client_method = strtok_r(NULL, ",", &lasts);
     }
 
     gc_free(&gc);
diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am
index 1128eb4..d861ef9 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -107,6 +107,7 @@
 	$(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 @@
 	$(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  = \
