Compare commits
No commits in common. "e407e7a139729728cde7df92f6b8c02d6db1686f" and "587e6822e93e979458c455791dce71fc3b063e35" have entirely different histories.
e407e7a139
...
587e6822e9
@ -1,98 +0,0 @@
|
|||||||
From af3e382649d96ae77cc5e42be8270f355e5cfec5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: David Sommerseth <davids@openvpn.net>
|
|
||||||
Date: Sun, 13 Mar 2022 20:31:53 +0100
|
|
||||||
Subject: [PATCH] plug-ins: Disallow multiple deferred authentication plug-ins
|
|
||||||
|
|
||||||
The plug-in API in OpenVPN 2.x is not designed for running multiple
|
|
||||||
deferred authentication processes in parallel. The authentication
|
|
||||||
results of such configurations are not to be trusted. For now we bail
|
|
||||||
out when this is discovered with an error in the log.
|
|
||||||
|
|
||||||
CVE: 2022-0547
|
|
||||||
Signed-off-by: David Sommerseth <davids@openvpn.net>
|
|
||||||
|
|
||||||
Acked-by: Antonio Quartulli <antonio@openvpn.net>
|
|
||||||
Message-Id: <20220313193154.9350-3-openvpn@sf.lists.topphemmelig.net>
|
|
||||||
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg23931.html
|
|
||||||
Signed-off-by: Gert Doering <gert@greenie.muc.de>
|
|
||||||
(cherry picked from commit 282ddbac54f8d4923844f69983b38dd2b813a00a)
|
|
||||||
---
|
|
||||||
doc/man-sections/plugin-options.rst | 9 ++++++++
|
|
||||||
src/openvpn/plugin.c | 33 ++++++++++++++++++++++++++---
|
|
||||||
2 files changed, 39 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/doc/man-sections/plugin-options.rst b/doc/man-sections/plugin-options.rst
|
|
||||||
index 51c574fe6..9266429ea 100644
|
|
||||||
--- a/doc/man-sections/plugin-options.rst
|
|
||||||
+++ b/doc/man-sections/plugin-options.rst
|
|
||||||
@@ -55,3 +55,12 @@ plug-ins must be prebuilt and adhere to the OpenVPN Plug-In API.
|
|
||||||
(such as tls-verify, auth-user-pass-verify, or client-connect), then
|
|
||||||
every module and script must return success (:code:`0`) in order for the
|
|
||||||
connection to be authenticated.
|
|
||||||
+
|
|
||||||
+ **WARNING**:
|
|
||||||
+ Plug-ins may do deferred execution, meaning the plug-in will
|
|
||||||
+ return the control back to the main OpenVPN process and provide
|
|
||||||
+ the plug-in result later on via a different thread or process.
|
|
||||||
+ OpenVPN does **NOT** support multiple authentication plug-ins
|
|
||||||
+ **where more than one plugin** tries to do deferred authentication.
|
|
||||||
+ If this behaviour is detected, OpenVPN will shut down upon first
|
|
||||||
+ authentication.
|
|
||||||
diff --git a/src/openvpn/plugin.c b/src/openvpn/plugin.c
|
|
||||||
index e8f8830d0..ed5d7c067 100644
|
|
||||||
--- a/src/openvpn/plugin.c
|
|
||||||
+++ b/src/openvpn/plugin.c
|
|
||||||
@@ -806,7 +806,7 @@ plugin_call_ssl(const struct plugin_list *pl,
|
|
||||||
const int n = plugin_n(pl);
|
|
||||||
bool success = false;
|
|
||||||
bool error = false;
|
|
||||||
- bool deferred = false;
|
|
||||||
+ bool deferred_auth_done = false;
|
|
||||||
|
|
||||||
setenv_del(es, "script_type");
|
|
||||||
envp = make_env_array(es, false, &gc);
|
|
||||||
@@ -829,7 +829,34 @@ plugin_call_ssl(const struct plugin_list *pl,
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPENVPN_PLUGIN_FUNC_DEFERRED:
|
|
||||||
- deferred = true;
|
|
||||||
+ if ((type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
|
|
||||||
+ && deferred_auth_done)
|
|
||||||
+ {
|
|
||||||
+ /*
|
|
||||||
+ * Do not allow deferred auth if a deferred auth has
|
|
||||||
+ * already been started. This should allow a single
|
|
||||||
+ * deferred auth call to happen, with one or more
|
|
||||||
+ * auth calls with an instant authentication result.
|
|
||||||
+ *
|
|
||||||
+ * The plug-in API is not designed for multiple
|
|
||||||
+ * deferred authentications to happen, as the
|
|
||||||
+ * auth_control_file file will be shared across all
|
|
||||||
+ * the plug-ins.
|
|
||||||
+ *
|
|
||||||
+ * Since this is considered a critical configuration
|
|
||||||
+ * error, we bail out and exit the OpenVPN process.
|
|
||||||
+ */
|
|
||||||
+ error = true;
|
|
||||||
+ msg(M_FATAL,
|
|
||||||
+ "Exiting due to multiple authentication plug-ins "
|
|
||||||
+ "performing deferred authentication. Only one "
|
|
||||||
+ "authentication plug-in doing deferred auth is "
|
|
||||||
+ "allowed. Ignoring the result and stopping now, "
|
|
||||||
+ "the current authentication result is not to be "
|
|
||||||
+ "trusted.");
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ deferred_auth_done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
@@ -853,7 +880,7 @@ plugin_call_ssl(const struct plugin_list *pl,
|
|
||||||
{
|
|
||||||
return OPENVPN_PLUGIN_FUNC_ERROR;
|
|
||||||
}
|
|
||||||
- else if (deferred)
|
|
||||||
+ else if (deferred_auth_done)
|
|
||||||
{
|
|
||||||
return OPENVPN_PLUGIN_FUNC_DEFERRED;
|
|
||||||
}
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
From 65fb67cd6c320a426567b2922c4282fb8738ba3f Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= <reynir@reynir.dk>
|
|
||||||
Date: Thu, 16 May 2024 13:58:08 +0200
|
|
||||||
Subject: [PATCH] Only schedule_exit() once
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
If an exit has already been scheduled we should not schedule it again.
|
|
||||||
Otherwise, the exit signal is never emitted if the peer reschedules the
|
|
||||||
exit before the timeout occurs.
|
|
||||||
|
|
||||||
schedule_exit() now only takes the context as argument. The signal is
|
|
||||||
hard coded to SIGTERM, and the interval is read directly from the
|
|
||||||
context options.
|
|
||||||
|
|
||||||
Furthermore, schedule_exit() now returns a bool signifying whether an
|
|
||||||
exit was scheduled; false if exit is already scheduled. The call sites
|
|
||||||
are updated accordingly. A notable difference is that management is only
|
|
||||||
notified *once* when an exit is scheduled - we no longer notify
|
|
||||||
management on redundant exit.
|
|
||||||
|
|
||||||
This patch was assigned a CVE number after already reviewed and ACKed,
|
|
||||||
because it was discovered that a misbehaving client can use the (now
|
|
||||||
fixed) server behaviour to avoid being disconnected by means of a
|
|
||||||
managment interface "client-kill" command - the security issue here is
|
|
||||||
"client can circumvent security policy set by management interface".
|
|
||||||
|
|
||||||
This only affects previously authenticated clients, and only management
|
|
||||||
client-kill, so normal renegotion / AUTH_FAIL ("your session ends") is not
|
|
||||||
affected.
|
|
||||||
|
|
||||||
CVE: 2024-28882
|
|
||||||
|
|
||||||
Change-Id: I9457f005f4ba970502e6b667d9dc4299a588d661
|
|
||||||
Signed-off-by: Reynir Björnsson <reynir@reynir.dk>
|
|
||||||
Acked-by: Arne Schwabe <arne-openvpn@rfc2549.org>
|
|
||||||
Message-Id: <20240516120434.23499-1-gert@greenie.muc.de>
|
|
||||||
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28679.html
|
|
||||||
Signed-off-by: Gert Doering <gert@greenie.muc.de>
|
|
||||||
(cherry picked from commit 55bb3260c12bae33b6a8eac73cbb6972f8517411)
|
|
||||||
---
|
|
||||||
src/openvpn/forward.c | 15 +++++++++++----
|
|
||||||
src/openvpn/forward.h | 2 +-
|
|
||||||
src/openvpn/push.c | 4 +---
|
|
||||||
3 files changed, 13 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
|
|
||||||
index 042ba9e..26eca49 100644
|
|
||||||
--- a/src/openvpn/forward.c
|
|
||||||
+++ b/src/openvpn/forward.c
|
|
||||||
@@ -428,17 +428,24 @@ check_server_poll_timeout(struct context *c)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Schedule a signal n_seconds from now.
|
|
||||||
+ * Schedule a SIGTERM signal c->options.scheduled_exit_interval seconds from now.
|
|
||||||
*/
|
|
||||||
-void
|
|
||||||
-schedule_exit(struct context *c, const int n_seconds, const int signal)
|
|
||||||
+bool
|
|
||||||
+schedule_exit(struct context *c)
|
|
||||||
{
|
|
||||||
+ const int n_seconds = c->options.scheduled_exit_interval;
|
|
||||||
+ /* don't reschedule if already scheduled. */
|
|
||||||
+ if (event_timeout_defined(&c->c2.scheduled_exit))
|
|
||||||
+ {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
tls_set_single_session(c->c2.tls_multi);
|
|
||||||
update_time();
|
|
||||||
reset_coarse_timers(c);
|
|
||||||
event_timeout_init(&c->c2.scheduled_exit, n_seconds, now);
|
|
||||||
- c->c2.scheduled_exit_signal = signal;
|
|
||||||
+ c->c2.scheduled_exit_signal = SIGTERM;
|
|
||||||
msg(D_SCHED_EXIT, "Delayed exit in %d seconds", n_seconds);
|
|
||||||
+ return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h
|
|
||||||
index 5585366..9dd9e47 100644
|
|
||||||
--- a/src/openvpn/forward.h
|
|
||||||
+++ b/src/openvpn/forward.h
|
|
||||||
@@ -328,7 +328,7 @@ send_control_channel_string_dowork(struct tls_multi *multi,
|
|
||||||
void process_ip_header(struct context *c, unsigned int flags, struct buffer *buf);
|
|
||||||
|
|
||||||
#if P2MP
|
|
||||||
-void schedule_exit(struct context *c, const int n_seconds, const int signal);
|
|
||||||
+bool schedule_exit(struct context *c);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
diff --git a/src/openvpn/push.c b/src/openvpn/push.c
|
|
||||||
index bc94c32..b8e7c93 100644
|
|
||||||
--- a/src/openvpn/push.c
|
|
||||||
+++ b/src/openvpn/push.c
|
|
||||||
@@ -266,8 +266,6 @@ send_auth_failed(struct context *c, const char *client_reason)
|
|
||||||
static const char auth_failed[] = "AUTH_FAILED";
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
- schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
|
|
||||||
-
|
|
||||||
len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
|
|
||||||
if (len > PUSH_BUNDLE_SIZE)
|
|
||||||
{
|
|
||||||
@@ -317,7 +315,7 @@ send_auth_pending_messages(struct context *c, const char *extra)
|
|
||||||
void
|
|
||||||
send_restart(struct context *c, const char *kill_msg)
|
|
||||||
{
|
|
||||||
- schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM);
|
|
||||||
+ schedule_exit(c);
|
|
||||||
send_control_channel_string(c, kill_msg ? kill_msg : "RESTART", D_PUSH);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,341 +0,0 @@
|
|||||||
Backport of:
|
|
||||||
|
|
||||||
From 90e7a858e5594d9a019ad2b4ac6154124986291a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Arne Schwabe <arne@rfc2549.org>
|
|
||||||
Date: Mon, 27 May 2024 15:02:41 +0200
|
|
||||||
Subject: [PATCH] Properly handle null bytes and invalid characters in control
|
|
||||||
messages
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This makes OpenVPN more picky in accepting control message in two aspects:
|
|
||||||
- Characters are checked in the whole buffer and not until the first
|
|
||||||
NUL byte
|
|
||||||
- if the message contains invalid characters, we no longer continue
|
|
||||||
evaluating a fixed up version of the message but rather stop
|
|
||||||
processing it completely.
|
|
||||||
|
|
||||||
Previously it was possible to get invalid characters to end up in log
|
|
||||||
files or on a terminal.
|
|
||||||
|
|
||||||
This also prepares the logic a bit in the direction of having a proper
|
|
||||||
framing of control messages separated by null bytes instead of relying
|
|
||||||
on the TLS framing for that. All OpenVPN implementations write the 0
|
|
||||||
bytes between control commands.
|
|
||||||
|
|
||||||
This patch also include several improvement suggestion from Reynir
|
|
||||||
(thanks!).
|
|
||||||
|
|
||||||
CVE: 2024-5594
|
|
||||||
|
|
||||||
Reported-By: Reynir Björnsson <reynir@reynir.dk>
|
|
||||||
Change-Id: I0d926f910637dabc89bf5fa919dc6beef1eb46d9
|
|
||||||
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
|
|
||||||
Acked-by: Antonio Quartulli <a@unstable.cc>
|
|
||||||
|
|
||||||
Message-Id: <20240619103004.56460-1-gert@greenie.muc.de>
|
|
||||||
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28791.html
|
|
||||||
Signed-off-by: Gert Doering <gert@greenie.muc.de>
|
|
||||||
(cherry picked from commit 414f428fa29694090ec4c46b10a8aba419c85659)
|
|
||||||
---
|
|
||||||
src/openvpn/buffer.c | 17 ++++
|
|
||||||
src/openvpn/buffer.h | 11 +++
|
|
||||||
src/openvpn/forward.c | 121 ++++++++++++++++---------
|
|
||||||
tests/unit_tests/openvpn/test_buffer.c | 109 ++++++++++++++++++++++
|
|
||||||
4 files changed, 215 insertions(+), 43 deletions(-)
|
|
||||||
|
|
||||||
--- a/src/openvpn/buffer.c
|
|
||||||
+++ b/src/openvpn/buffer.c
|
|
||||||
@@ -1085,6 +1085,23 @@ string_mod(char *str, const unsigned int
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+bool
|
|
||||||
+string_check_buf(struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive)
|
|
||||||
+{
|
|
||||||
+ ASSERT(buf);
|
|
||||||
+
|
|
||||||
+ for (int i = 0; i < BLEN(buf); i++)
|
|
||||||
+ {
|
|
||||||
+ char c = BSTR(buf)[i];
|
|
||||||
+
|
|
||||||
+ if (!char_inc_exc(c, inclusive, exclusive))
|
|
||||||
+ {
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
const char *
|
|
||||||
string_mod_const(const char *str,
|
|
||||||
const unsigned int inclusive,
|
|
||||||
--- a/src/openvpn/buffer.h
|
|
||||||
+++ b/src/openvpn/buffer.h
|
|
||||||
@@ -933,6 +933,17 @@ bool string_class(const char *str, const
|
|
||||||
|
|
||||||
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * Check a buffer if it only consists of allowed characters.
|
|
||||||
+ *
|
|
||||||
+ * @param buf The buffer to be checked.
|
|
||||||
+ * @param inclusive The character classes that are allowed.
|
|
||||||
+ * @param exclusive Character classes that are not allowed even if they are also in inclusive.
|
|
||||||
+ * @return True if the string consists only of allowed characters, false otherwise.
|
|
||||||
+ */
|
|
||||||
+bool
|
|
||||||
+string_check_buf(struct buffer *buf, const unsigned int inclusive, const unsigned int exclusive);
|
|
||||||
+
|
|
||||||
const char *string_mod_const(const char *str,
|
|
||||||
const unsigned int inclusive,
|
|
||||||
const unsigned int exclusive,
|
|
||||||
--- a/src/openvpn/forward.c
|
|
||||||
+++ b/src/openvpn/forward.c
|
|
||||||
@@ -184,6 +184,43 @@ check_tls_errors_nco(struct context *c)
|
|
||||||
|
|
||||||
#if P2MP
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+parse_incoming_control_channel_command(struct context *c, struct buffer *buf)
|
|
||||||
+{
|
|
||||||
+ if (buf_string_match_head_str(buf, "AUTH_FAILED"))
|
|
||||||
+ {
|
|
||||||
+ receive_auth_failed(c, buf);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "PUSH_"))
|
|
||||||
+ {
|
|
||||||
+ incoming_push_message(c, buf);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "RESTART"))
|
|
||||||
+ {
|
|
||||||
+ server_pushed_signal(c, buf, true, 7);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "HALT"))
|
|
||||||
+ {
|
|
||||||
+ server_pushed_signal(c, buf, false, 4);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "INFO_PRE"))
|
|
||||||
+ {
|
|
||||||
+ server_pushed_info(c, buf, 8);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "INFO"))
|
|
||||||
+ {
|
|
||||||
+ server_pushed_info(c, buf, 4);
|
|
||||||
+ }
|
|
||||||
+ else if (buf_string_match_head_str(buf, "CR_RESPONSE"))
|
|
||||||
+ {
|
|
||||||
+ receive_cr_response(c, buf);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ msg(D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR(buf));
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Handle incoming configuration
|
|
||||||
* messages on the control channel.
|
|
||||||
@@ -199,43 +236,40 @@ check_incoming_control_channel(struct co
|
|
||||||
struct buffer buf = alloc_buf_gc(len, &gc);
|
|
||||||
if (tls_rec_payload(c->c2.tls_multi, &buf))
|
|
||||||
{
|
|
||||||
- /* force null termination of message */
|
|
||||||
- buf_null_terminate(&buf);
|
|
||||||
+ while (BLEN(&buf) > 1)
|
|
||||||
+ {
|
|
||||||
+ /* commands on the control channel are seperated by 0x00 bytes.
|
|
||||||
+ * cmdlen does not include the 0 byte of the string */
|
|
||||||
+ int cmdlen = (int)strnlen(BSTR(&buf), BLEN(&buf));
|
|
||||||
|
|
||||||
- /* enforce character class restrictions */
|
|
||||||
- string_mod(BSTR(&buf), CC_PRINT, CC_CRLF, 0);
|
|
||||||
+ if (cmdlen < BLEN(&buf))
|
|
||||||
+ {
|
|
||||||
+ /* include the NUL byte and ensure NUL termination */
|
|
||||||
+ int cmdlen = (int)strlen(BSTR(&buf)) + 1;
|
|
||||||
|
|
||||||
- if (buf_string_match_head_str(&buf, "AUTH_FAILED"))
|
|
||||||
- {
|
|
||||||
- receive_auth_failed(c, &buf);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "PUSH_"))
|
|
||||||
- {
|
|
||||||
- incoming_push_message(c, &buf);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "RESTART"))
|
|
||||||
- {
|
|
||||||
- server_pushed_signal(c, &buf, true, 7);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "HALT"))
|
|
||||||
- {
|
|
||||||
- server_pushed_signal(c, &buf, false, 4);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "INFO_PRE"))
|
|
||||||
- {
|
|
||||||
- server_pushed_info(c, &buf, 8);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "INFO"))
|
|
||||||
- {
|
|
||||||
- server_pushed_info(c, &buf, 4);
|
|
||||||
- }
|
|
||||||
- else if (buf_string_match_head_str(&buf, "CR_RESPONSE"))
|
|
||||||
- {
|
|
||||||
- receive_cr_response(c, &buf);
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- {
|
|
||||||
- msg(D_PUSH_ERRORS, "WARNING: Received unknown control message: %s", BSTR(&buf));
|
|
||||||
+ /* Construct a buffer that only holds the current command and
|
|
||||||
+ * its closing NUL byte */
|
|
||||||
+ struct buffer cmdbuf = alloc_buf_gc(cmdlen, &gc);
|
|
||||||
+ buf_write(&cmdbuf, BPTR(&buf), cmdlen);
|
|
||||||
+
|
|
||||||
+ /* check we have only printable characters or null byte in the
|
|
||||||
+ * command string and no newlines */
|
|
||||||
+ if (!string_check_buf(&buf, CC_PRINT | CC_NULL, CC_CRLF))
|
|
||||||
+ {
|
|
||||||
+ msg(D_PUSH_ERRORS, "WARNING: Received control with invalid characters: %s",
|
|
||||||
+ format_hex(BPTR(&buf), BLEN(&buf), 256, &gc));
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ parse_incoming_control_channel_command(c, &cmdbuf);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ msg(D_PUSH_ERRORS, "WARNING: Ignoring control channel "
|
|
||||||
+ "message command without NUL termination");
|
|
||||||
+ }
|
|
||||||
+ buf_advance(&buf, cmdlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
--- a/tests/unit_tests/openvpn/test_buffer.c
|
|
||||||
+++ b/tests/unit_tests/openvpn/test_buffer.c
|
|
||||||
@@ -242,6 +242,113 @@ test_buffer_free_gc_two(void **state)
|
|
||||||
gc_free(&gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+test_character_class(void **state)
|
|
||||||
+{
|
|
||||||
+ char buf[256];
|
|
||||||
+ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+ assert_false(string_mod(buf, CC_PRINT, 0, '@'));
|
|
||||||
+ assert_string_equal(buf, "There is @ a nice 1234 year old tr@ ee!");
|
|
||||||
+
|
|
||||||
+ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+ assert_true(string_mod(buf, CC_ANY, 0, '@'));
|
|
||||||
+ assert_string_equal(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+
|
|
||||||
+ /* 0 as replace removes characters */
|
|
||||||
+ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+ assert_false(string_mod(buf, CC_PRINT, 0, '\0'));
|
|
||||||
+ assert_string_equal(buf, "There is a nice 1234 year old tr ee!");
|
|
||||||
+
|
|
||||||
+ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+ assert_false(string_mod(buf, CC_PRINT, CC_DIGIT, '@'));
|
|
||||||
+ assert_string_equal(buf, "There is @ a nice @@@@ year old tr@ ee!");
|
|
||||||
+
|
|
||||||
+ strcpy(buf, "There is \x01 a nice 1234 year old tr\x7f ee!");
|
|
||||||
+ assert_false(string_mod(buf, CC_ALPHA, CC_DIGIT, '.'));
|
|
||||||
+ assert_string_equal(buf, "There.is...a.nice......year.old.tr..ee.");
|
|
||||||
+
|
|
||||||
+ strcpy(buf, "There is \x01 a 'nice' \"1234\"\n year old \ntr\x7f ee!");
|
|
||||||
+ assert_false(string_mod(buf, CC_ALPHA|CC_DIGIT|CC_NEWLINE|CC_SINGLE_QUOTE, CC_DOUBLE_QUOTE|CC_BLANK, '.'));
|
|
||||||
+ assert_string_equal(buf, "There.is...a.'nice'..1234.\n.year.old.\ntr..ee.");
|
|
||||||
+
|
|
||||||
+ strcpy(buf, "There is a \\'nice\\' \"1234\" [*] year old \ntree!");
|
|
||||||
+ assert_false(string_mod(buf, CC_PRINT, CC_BACKSLASH|CC_ASTERISK, '.'));
|
|
||||||
+ assert_string_equal(buf, "There is a .'nice.' \"1234\" [.] year old .tree!");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+test_character_string_mod_buf(void **state)
|
|
||||||
+{
|
|
||||||
+ struct gc_arena gc = gc_new();
|
|
||||||
+
|
|
||||||
+ struct buffer buf = alloc_buf_gc(1024, &gc);
|
|
||||||
+
|
|
||||||
+ const char test1[] = "There is a nice 1234\x00 year old tree!";
|
|
||||||
+ buf_write(&buf, test1, sizeof(test1));
|
|
||||||
+
|
|
||||||
+ /* allow the null bytes and string but not the ! */
|
|
||||||
+ assert_false(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, 0));
|
|
||||||
+
|
|
||||||
+ /* remove final ! and null byte to pass */
|
|
||||||
+ buf_inc_len(&buf, -2);
|
|
||||||
+ assert_true(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, 0));
|
|
||||||
+
|
|
||||||
+ /* Check excluding digits works */
|
|
||||||
+ assert_false(string_check_buf(&buf, CC_ALNUM | CC_SPACE | CC_NULL, CC_DIGIT));
|
|
||||||
+ gc_free(&gc);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+test_snprintf(void **state)
|
|
||||||
+{
|
|
||||||
+ /* we used to have a custom openvpn_snprintf function because some
|
|
||||||
+ * OS (the comment did not specify which) did not always put the
|
|
||||||
+ * null byte there. So we unit test this to be sure.
|
|
||||||
+ *
|
|
||||||
+ * This probably refers to the MSVC behaviour, see also
|
|
||||||
+ * https://stackoverflow.com/questions/7706936/is-snprintf-always-null-terminating
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+ /* Instead of trying to trick the compiler here, disable the warnings
|
|
||||||
+ * for this unit test. We know that the results will be truncated
|
|
||||||
+ * and we want to test that */
|
|
||||||
+#if defined(__GNUC__)
|
|
||||||
+/* some clang version do not understand -Wformat-truncation, so ignore the
|
|
||||||
+ * warning to avoid warnings/errors (-Werror) about unknown pragma/option */
|
|
||||||
+#if defined(__clang__)
|
|
||||||
+#pragma clang diagnostic push
|
|
||||||
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
|
||||||
+#endif
|
|
||||||
+#pragma GCC diagnostic push
|
|
||||||
+#pragma GCC diagnostic ignored "-Wformat-truncation"
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ char buf[10] = { 'a' };
|
|
||||||
+ int ret = 0;
|
|
||||||
+
|
|
||||||
+ ret = snprintf(buf, sizeof(buf), "0123456789abcde");
|
|
||||||
+ assert_int_equal(ret, 15);
|
|
||||||
+ assert_int_equal(buf[9], '\0');
|
|
||||||
+
|
|
||||||
+ memset(buf, 'b', sizeof(buf));
|
|
||||||
+ ret = snprintf(buf, sizeof(buf), "- %d - %d -", 77, 88);
|
|
||||||
+ assert_int_equal(ret, 11);
|
|
||||||
+ assert_int_equal(buf[9], '\0');
|
|
||||||
+
|
|
||||||
+ memset(buf, 'c', sizeof(buf));
|
|
||||||
+ ret = snprintf(buf, sizeof(buf), "- %8.2f", 77.8899);
|
|
||||||
+ assert_int_equal(ret, 10);
|
|
||||||
+ assert_int_equal(buf[9], '\0');
|
|
||||||
+
|
|
||||||
+#if defined(__GNUC__)
|
|
||||||
+#pragma GCC diagnostic pop
|
|
||||||
+#if defined(__clang__)
|
|
||||||
+#pragma clang diagnostic pop
|
|
||||||
+#endif
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
@@ -273,6 +380,9 @@ main(void)
|
|
||||||
test_buffer_list_teardown),
|
|
||||||
cmocka_unit_test(test_buffer_free_gc_one),
|
|
||||||
cmocka_unit_test(test_buffer_free_gc_two),
|
|
||||||
+ cmocka_unit_test(test_character_class),
|
|
||||||
+ cmocka_unit_test(test_character_string_mod_buf),
|
|
||||||
+ cmocka_unit_test(test_snprintf)
|
|
||||||
};
|
|
||||||
|
|
||||||
return cmocka_run_group_tests_name("buffer", tests, NULL, NULL);
|
|
||||||
File diff suppressed because it is too large
Load Diff
23
openvpn.spec
23
openvpn.spec
@ -1,15 +1,10 @@
|
|||||||
Name: openvpn
|
Name: openvpn
|
||||||
Version: 2.5.5
|
Version: 2.5.5
|
||||||
Release: 5
|
Release: 1
|
||||||
Summary: A full-featured open source SSL VPN solution
|
Summary: A full-featured open source SSL VPN solution
|
||||||
License: GPL-2.0-or-later and OpenSSL and SSLeay
|
License: GPL-2.0-or-later and OpenSSL and SSLeay
|
||||||
URL: https://community.openvpn.net/openvpn
|
URL: https://community.openvpn.net/openvpn
|
||||||
Source0: https://swupdate.openvpn.org/community/releases/openvpn-%{version}.tar.gz
|
Source0: https://swupdate.openvpn.org/community/releases/openvpn-%{version}.tar.gz
|
||||||
# https://github.com/OpenVPN/openvpn/commit/af3e382
|
|
||||||
Patch0: CVE-2022-0547.patch
|
|
||||||
Patch1: CVE-2024-28882.patch
|
|
||||||
Patch2: CVE-2024-5594.patch
|
|
||||||
Patch3: backport-update-sample-keys.patch
|
|
||||||
BuildRequires: openssl-devel lz4-devel systemd-devel lzo-devel gcc
|
BuildRequires: openssl-devel lz4-devel systemd-devel lzo-devel gcc
|
||||||
BuildRequires: iproute pam-devel pkcs11-helper-devel >= 1.11
|
BuildRequires: iproute pam-devel pkcs11-helper-devel >= 1.11
|
||||||
|
|
||||||
@ -39,7 +34,7 @@ User guide and other related documents for %{name}.
|
|||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -n %{name}-%{version} -p1 -S git
|
%autosetup -n %{name}-%{version} -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure --enable-x509-alt-username --enable-iproute2 --with-crypto-library=openssl --enable-pkcs11 --enable-selinux --enable-systemd SYSTEMD_UNIT_DIR=%{_unitdir} TMPFILES_DIR=%{_tmpfilesdir} IPROUTE=/sbin/ip
|
%configure --enable-x509-alt-username --enable-iproute2 --with-crypto-library=openssl --enable-pkcs11 --enable-selinux --enable-systemd SYSTEMD_UNIT_DIR=%{_unitdir} TMPFILES_DIR=%{_tmpfilesdir} IPROUTE=/sbin/ip
|
||||||
@ -126,18 +121,6 @@ fi
|
|||||||
%{_mandir}/man5/openvpn-examples.5.gz
|
%{_mandir}/man5/openvpn-examples.5.gz
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Wed Nov 06 2024 liningjie <liningjie@xfusion.com> - 2.5.5-5
|
|
||||||
- update sample-keys
|
|
||||||
|
|
||||||
* Sat Jul 20 2024 Funda Wang <fundawang@yeah.net> - 2.5.5-4
|
|
||||||
- Fix CVE-2024-5594
|
|
||||||
|
|
||||||
* Tue Jul 09 2024 zhangxianting <zhangxianting@uniontech.com> - 2.5.5-3
|
|
||||||
- Fix CVE-2024-28882
|
|
||||||
|
|
||||||
* Wed Mar 30 2022 wangkai <wangkai385@huawei.com> - 2.5.5-2
|
|
||||||
- Fix CVE-2022-0547
|
|
||||||
|
|
||||||
* Wed Dec 29 2021 zhangjiapeng <zhangjiapeng9@huawei.com> - 2.5.5-1
|
* Wed Dec 29 2021 zhangjiapeng <zhangjiapeng9@huawei.com> - 2.5.5-1
|
||||||
- Update to 2.5.5
|
- Update to 2.5.5
|
||||||
|
|
||||||
@ -150,7 +133,7 @@ fi
|
|||||||
* Thu Feb 04 2021 wangyue <wangyue92@huawei.com> 2.4.8-4
|
* Thu Feb 04 2021 wangyue <wangyue92@huawei.com> 2.4.8-4
|
||||||
- fix CVE-2020-11810
|
- fix CVE-2020-11810
|
||||||
|
|
||||||
* Mon Mar 16 2020 daiqianwen <daiqianwen@huawei.com> 2.4.8-3
|
* Tue Mar 16 2020 daiqianwen <daiqianwen@huawei.com> 2.4.8-3
|
||||||
- modify systemd post preun postun
|
- modify systemd post preun postun
|
||||||
|
|
||||||
* Mon Nov 11 2019 guanyalong <guanyalong@huawei.com> 2.4.8-2
|
* Mon Nov 11 2019 guanyalong <guanyalong@huawei.com> 2.4.8-2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user