!42 [sync] PR-41: Add support for GnuTLS as and alternative for mcrypt and gcrypt

From: @openeuler-sync-bot 
Reviewed-by: @xiangbudaomz 
Signed-off-by: @xiangbudaomz
This commit is contained in:
openeuler-ci-bot 2024-06-12 05:55:50 +00:00 committed by Gitee
commit 65877bbfc5
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 508 additions and 4 deletions

View File

@ -0,0 +1,370 @@
From 2958d1835f5bc75caad863916a259cfc700cd988 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Wed, 14 Feb 2024 17:20:32 +0100
Subject: [PATCH 1/3] configure: Add option to select HMAC library
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
configure.ac | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac
index eff027e..c36e9c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,19 +73,6 @@ AM_CONDITIONAL(IS_ASCIIDOC, test x"${ASCIIDOC}" != x"")
AM_CONDITIONAL(IS_A2X, test x"${A2X}" != x"")
AM_CONDITIONAL(BUILD_ASCIIDOC, test x"${A2X}" != x"" || test x"${ASCIIDOCTOR}" != x"")
-# libgcrypt or mhash for hmac
-libgcrypt_installed="yes"
-AC_CHECK_HEADERS(gcrypt.h, , [libgcrypt_installed="no"],)
-AC_CHECK_LIB(gcrypt, gcry_md_open, , [libgcrypt_installed="no"])
-AM_CONDITIONAL(BUILD_AUTH_C, test "x${libgcrypt_installed}" = "xyes")
-
-if test "x$libgcrypt_installed" = "xno"; then
- mhash_installed="yes"
- AC_CHECK_HEADERS(mhash.h, , [mhash_installed="no"],)
- AC_CHECK_LIB(mhash, mhash_init, , [mhash_installed="no"])
- AM_CONDITIONAL(BUILD_AUTH_C, test "x${mhash_installed}" = "xyes")
-fi
-
AC_CHECK_LIB([xml2], xmlReadDoc)
PKG_CHECK_MODULES(XML, [libxml-2.0])
PKG_CHECK_MODULES(GLIB, [glib-2.0])
@@ -247,6 +234,33 @@ AC_ARG_WITH([ocfdir],
AC_SUBST([ocfdir])
+AC_ARG_WITH([hmac_library],
+ [ --with-hmac-library=LIBRARY : Select HMAC library to use (default: autodetect one of gcrypt or mhash).])
+
+# libgcrypt or mhash for hmac
+hmac_library_installed="no"
+if test "x$with_hmac_library" == "x" && test "x$hmac_library_installed" == "xno" || \
+ test "x$with_hmac_library" == "xgcrypt"; then
+ libgcrypt_installed="yes"
+ AC_CHECK_HEADERS(gcrypt.h, , [libgcrypt_installed="no"],)
+ AC_CHECK_LIB(gcrypt, gcry_md_open, , [libgcrypt_installed="no"])
+ hmac_library_installed="${libgcrypt_installed}"
+fi
+
+if test "x$with_hmac_library" == "x" && test "x$hmac_library_installed" == "xno" || \
+ test "x$with_hmac_library" == "xmhash"; then
+ mhash_installed="yes"
+ AC_CHECK_HEADERS(mhash.h, , [mhash_installed="no"],)
+ AC_CHECK_LIB(mhash, mhash_init, , [mhash_installed="no"])
+ hmac_library_installed="${mhash_installed}"
+fi
+
+if test "x$with_hmac_library" != "x" && test "x$hmac_library_installed" == "xno";then
+ AC_MSG_ERROR([required HMAC library not detected])
+fi
+
+AM_CONDITIONAL(BUILD_AUTH_C, test "x${hmac_library_installed}" = "xyes")
+
# figure out logging provider
logging_provider=""
if test "x$logging_provider" = "x" && test "x$with_glue" = "xyes"; then
--
2.25.1
From a0aa2de8814fd32ae6b1193df54db6872dc324fa Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Thu, 15 Feb 2024 17:02:23 +0100
Subject: [PATCH 2/3] Add support for GnuTLS
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
booth.spec.in | 2 +-
configure.ac | 18 +++++++++---
src/auth.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
src/auth.h | 19 ++++++++++++
src/config.c | 2 +-
src/main.c | 13 +++++++++
src/transport.c | 6 ++--
7 files changed, 129 insertions(+), 9 deletions(-)
diff --git a/booth.spec.in b/booth.spec.in
index 9f67fff..4961763 100644
--- a/booth.spec.in
+++ b/booth.spec.in
@@ -72,7 +72,7 @@ BuildRequires: firewall-macros
%else
BuildRequires: pkgconfig(glib-2.0)
%endif
-BuildRequires: libgcrypt-devel
+BuildRequires: gnutls-devel
%if 0%{?fedora} || 0%{?centos} || 0%{?rhel}
BuildRequires: pacemaker-libs-devel
%else
diff --git a/configure.ac b/configure.ac
index c36e9c3..4c4a0af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,10 +235,20 @@ AC_ARG_WITH([ocfdir],
AC_SUBST([ocfdir])
AC_ARG_WITH([hmac_library],
- [ --with-hmac-library=LIBRARY : Select HMAC library to use (default: autodetect one of gcrypt or mhash).])
+ [ --with-hmac-library=LIBRARY : Select HMAC library to use (default: autodetect one of gnutls, gcrypt or mhash).])
-# libgcrypt or mhash for hmac
+# GnuTLS, libgcrypt or mhash for hmac
hmac_library_installed="no"
+if test "x$with_hmac_library" == "x" && test "x$hmac_library_installed" == "xno" || \
+ test "x$with_hmac_library" == "xgnutls"; then
+ libgnutls_installed="yes"
+ PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 2.10.0], [
+ AC_DEFINE([HAVE_LIBGNUTLS], [1], [Have gnutls library])
+ libgnutls_installed="yes"
+ ], [libgnutls_installed="no"])
+ hmac_library_installed="${libgnutls_installed}"
+fi
+
if test "x$with_hmac_library" == "x" && test "x$hmac_library_installed" == "xno" || \
test "x$with_hmac_library" == "xgcrypt"; then
libgcrypt_installed="yes"
@@ -457,10 +467,10 @@ fi
# final build of *FLAGS
CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS $OS_CFLAGS \
- $COVERAGE_CFLAGS $EXTRA_WARNINGS $WERROR_CFLAGS $NSS_CFLAGS"
+ $COVERAGE_CFLAGS $EXTRA_WARNINGS $WERROR_CFLAGS $LIBGNUTLS_CFLAGS"
CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS $OS_CPPFLAGS $GLIB_CFLAGS $RESMON_CFLAGS $XML_CFLAGS"
LDFLAGS="$ENV_LDFLAGS $COVERAGE_LDFLAGS $OS_LDFLAGS"
-LIBS="$LIBS $XML_LIBS"
+LIBS="$LIBS $XML_LIBS $LIBGNUTLS_LIBS"
# substitute what we need:
AC_SUBST([INITDDIR])
diff --git a/src/auth.c b/src/auth.c
index a3b3d20..26a220e 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -18,6 +18,84 @@
#include "auth.h"
+#if HAVE_LIBGNUTLS
+/* calculate the HMAC of the message in data and store it in result
+ * it is up to the caller to make sure that there's enough space
+ * at result for the MAC
+ */
+int calc_hmac(const void *data, size_t datalen,
+ int hid, unsigned char *result, char *key, unsigned int keylen)
+{
+ int rc;
+
+ /*
+ * Only SHA1 is supported so we can hardcode GNUTLS_MAC_SHA1
+ */
+ if (hid != BOOTH_COMPAT_MHASH_SHA1) {
+ log_error("calc_hmac unsupported HMAC algorithm %u", hid);
+ return -1;
+ }
+
+ /*
+ * This shouldn't happen but gnutls_hmac_fast segfault if key or
+ * data are NULL so it is better to check beforehand.
+ */
+ if (data == NULL || key == NULL) {
+ log_error("calc_hmac data or key is NULL");
+ return -1;
+ }
+
+ rc = gnutls_hmac_fast(GNUTLS_MAC_SHA1, key, keylen, data, datalen, result);
+ if (rc) {
+ log_error("gnutls_hmac_fast: %s", gnutls_strerror(rc));
+ return -1;
+ }
+
+ return rc;
+}
+
+/* test HMAC
+ */
+int verify_hmac(const void *data, size_t datalen,
+ int hid, unsigned char *hmac, char *key, int keylen)
+{
+ unsigned char *our_hmac;
+ int rc;
+ unsigned int hlen;
+
+ /*
+ * Only SHA1 is supported so we can hardcode GNUTLS_MAC_SHA1
+ */
+ if (hid != BOOTH_COMPAT_MHASH_SHA1) {
+ log_error("verify_hmac unsupported HMAC algorithm %u", hid);
+ return -1;
+ }
+
+ if (data == NULL || key == NULL) {
+ log_error("verify_hmac data or key is NULL");
+ return -1;
+ }
+
+ hlen = gnutls_hmac_get_len(GNUTLS_MAC_SHA1);
+ if (!hlen)
+ return -1;
+
+ our_hmac = calloc(hlen, 1);
+ if (!our_hmac)
+ return -1;
+
+ rc = calc_hmac(data, datalen, hid, our_hmac, key, keylen);
+ if (rc)
+ goto out_free;
+ rc = memcmp(our_hmac, hmac, hlen);
+
+out_free:
+ if (our_hmac)
+ free(our_hmac);
+ return rc;
+}
+#endif
+
#if HAVE_LIBGCRYPT
/* calculate the HMAC of the message in data and store it in result
* it is up to the caller to make sure that there's enough space
diff --git a/src/auth.h b/src/auth.h
index 98f0286..be1fc9e 100644
--- a/src/auth.h
+++ b/src/auth.h
@@ -20,6 +20,25 @@
#include "log.h"
#include <sys/types.h>
+#if HAVE_LIBGNUTLS
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+/*
+ * We need to stay backwards compatible. Both gcrypt and mhash defines
+ * SHA1 algorithm as 2. but GNUTLS_MAC_SHA1 is defined as 3, so hardcode
+ * 2 here and use correct value in auth.c
+ */
+#define BOOTH_COMPAT_MHASH_SHA1 2
+#define BOOTH_HASH BOOTH_COMPAT_MHASH_SHA1
+
+int calc_hmac(const void *data, size_t datalen,
+ int hid, unsigned char *result, char *key, unsigned int keylen);
+int verify_hmac(const void *data, size_t datalen,
+ int hid, unsigned char *hmac, char *key, int keylen);
+#endif
+
#if HAVE_LIBGCRYPT
#include <gcrypt.h>
diff --git a/src/config.c b/src/config.c
index f0ca4aa..a533da3 100644
--- a/src/config.c
+++ b/src/config.c
@@ -720,7 +720,7 @@ no_value:
continue;
}
-#if HAVE_LIBGCRYPT || HAVE_LIBMHASH
+#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH
if (strcmp(key, "authfile") == 0) {
safe_copy(booth_conf->authfile,
val, BOOTH_PATH_LEN,
diff --git a/src/main.c b/src/main.c
index 12085f4..71932fa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -46,6 +46,9 @@
#include <crm/services.h>
+#if HAVE_LIBGNUTLS
+#include <gnutls/gnutls.h>
+#endif
#if HAVE_LIBGCRYPT
#include <gcrypt.h>
#endif
@@ -376,6 +379,13 @@ static int setup_config(int type)
}
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#if HAVE_LIBGNUTLS
+ if (gnutls_global_init() != 0) {
+ log_error("Cannot initialize GnuTLS");
+ rv = -EINVAL;
+ goto out;
+ };
#endif
}
@@ -1671,6 +1681,9 @@ int main(int argc, char *argv[], char *envp[])
}
out:
+#if HAVE_LIBGNUTLS
+ gnutls_global_deinit();
+#endif
#ifdef LOGGING_LIBQB
qb_log_fini();
#endif
diff --git a/src/transport.c b/src/transport.c
index 817a4dc..8267c96 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -977,7 +977,7 @@ const struct booth_transport booth_transport[TRANSPORT_ENTRIES] = {
int add_hmac(void *data, int len)
{
int rv = 0;
-#if HAVE_LIBGCRYPT || HAVE_LIBMHASH
+#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH
int payload_len;
struct hmac *hp;
@@ -997,7 +997,7 @@ int add_hmac(void *data, int len)
return rv;
}
-#if HAVE_LIBGCRYPT || HAVE_LIBMHASH
+#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH
/* TODO: we need some client identification for logging */
#define peer_string(p) (p ? site_string(p) : "client")
@@ -1051,7 +1051,7 @@ accept:
int check_auth(struct booth_site *from, void *buf, int len)
{
int rv = 0;
-#if HAVE_LIBGCRYPT || HAVE_LIBMHASH
+#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH
int payload_len;
struct hmac *hp;
--
2.25.1
From 322fea0ef083e85ac161415b1c66f46d079932c9 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Fri, 7 Jun 2024 08:02:38 +0200
Subject: [PATCH 3/3] build: Prepare version 1.2 release
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 4c4a0af..6b86bbe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@
AC_PREREQ([2.69])
AC_INIT([booth],
- [m4_esyscmd([build-aux/git-version-gen --fallback 1.1 .tarball-version .gitarchivever])],
+ [m4_esyscmd([build-aux/git-version-gen --fallback 1.2 .tarball-version .gitarchivever])],
[users@clusterlabs.org])
AC_USE_SYSTEM_EXTENSIONS
--
2.25.1

View File

@ -24,7 +24,7 @@
%bcond_with run_build_tests
%bcond_with include_unit_test
%global release 5
%global release 7
## User and group to use for nonprivileged services (should be in sync with pacemaker)
%global uname hacluster
@ -51,7 +51,11 @@ Source0: https://github.com/%{github_owner}/%{name}/releases/download/v%{
Patch0: Remove-const-warning.patch
Patch1: pacemaker-Don-t-add-explicit-error-prefix-in-log.patch
Patch2: pacemaker-Use-long-format-for-crm_ticket-v.patch
Patch3000: backport-CVE-2024-3049.patch
Patch3: pacemaker-Check-snprintf-return-values.patch
Patch0004: backport-CVE-2024-3049.patch
Patch0005: backport-Add-support-for-GnuTLS.patch
# direct build process dependencies
BuildRequires: autoconf
@ -65,7 +69,7 @@ BuildRequires: asciidoctor
BuildRequires: gcc
BuildRequires: pkgconfig
# linking dependencies
BuildRequires: libgcrypt-devel
BuildRequires: gnutls-devel
BuildRequires: libxml2-devel
## just for <pacemaker/crm/services.h> include
BuildRequires: pacemaker-libs-devel
@ -300,12 +304,18 @@ VERBOSE=1 make check
%{_usr}/lib/ocf/resource.d/booth/sharedrsc
%changelog
* Sun Jun 09 2024 xuchenchen <xuchenchen@kylinos.cn> -1.1-5
* Tue Jun 11 2024 zouzhimin <zouzhimin@kylinos.cn> -1.1-7
- Add support for GnuTLS as and alternative for mcrypt and gcrypt
* Sun Jun 09 2024 xuchenchen <xuchenchen@kylinos.cn> -1.1-6
- Type:CVES
- ID:CVE-2024-3049
- SUG:NA
- DESC:fix CVE-2024-3049
* Sun Apr 28 2024 bizhiyuan <bizhiyuan@kylinos.cn> - 1.1-5
- pacemaker Check snprintf return values
* Thu Feb 29 2024 bizhiyuan <bizhiyuan@kylinos.cn> - 1.1-4
- pacemaker: Use long format for crm_ticket -v

View File

@ -0,0 +1,124 @@
From 7e33a45d6898e06119dbe9dfd487f6c4923b48cb Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Tue, 14 Nov 2023 17:21:49 +0100
Subject: [PATCH 2/7] pacemaker: Check snprintf return values
crm_ticket command string is stored into static buffer and not checked
so it can be truncated without notice.
Solution would be to use dynamic buffer, but for now at least check
snprintf return value and return error when string was truncated.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
src/pacemaker.c | 39 ++++++++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git a/src/pacemaker.c b/src/pacemaker.c
index 8ad3c69..80aa1a3 100644
--- a/src/pacemaker.c
+++ b/src/pacemaker.c
@@ -128,7 +128,7 @@ static int pcmk_write_ticket_atomic(struct ticket_config *tk, int grant)
/* The long format (--attr-value=) for attribute value is used instead of "-v",
* so that NO_ONE (which is -1) isn't seen as another option. */
- snprintf(cmd, COMMAND_MAX,
+ rv = snprintf(cmd, COMMAND_MAX,
"crm_ticket -t '%s' "
"%s --force "
"-S owner --attr-value=%" PRIi32 " "
@@ -142,6 +142,10 @@ static int pcmk_write_ticket_atomic(struct ticket_config *tk, int grant)
(int64_t)wall_ts(&tk->term_expires),
(int64_t)tk->current_term);
+ if (rv < 0 || rv >= COMMAND_MAX) {
+ log_error("pcmk_write_ticket_atomic: cannot format crm_ticket cmdline (probably too long)");
+ return -1;
+ }
rv = system(cmd);
log_debug("command: '%s' was executed", cmd);
if (rv != 0)
@@ -230,20 +234,34 @@ static int crm_ticket_set_int(const struct ticket_config *tk, const char *attr,
static int pcmk_set_attr(struct ticket_config *tk, const char *attr, const char *val)
{
char cmd[COMMAND_MAX];
+ int rv;
- snprintf(cmd, COMMAND_MAX,
+ rv = snprintf(cmd, COMMAND_MAX,
"crm_ticket -t '%s' -S '%s' --attr-value='%s'",
tk->name, attr, val);
+
+ if (rv < 0 || rv >= COMMAND_MAX) {
+ log_error("pcmk_set_attr: cannot format crm_ticket cmdline (probably too long)");
+ return -1;
+ }
+
return _run_crm_ticket(cmd);
}
static int pcmk_del_attr(struct ticket_config *tk, const char *attr)
{
char cmd[COMMAND_MAX];
+ int rv;
- snprintf(cmd, COMMAND_MAX,
+ rv = snprintf(cmd, COMMAND_MAX,
"crm_ticket -t '%s' -D '%s'",
tk->name, attr);
+
+ if (rv < 0 || rv >= COMMAND_MAX) {
+ log_error("pcmk_del_attr: cannot format crm_ticket cmdline (probably too long)");
+ return -1;
+ }
+
return _run_crm_ticket(cmd);
}
@@ -352,13 +370,18 @@ static int pcmk_get_attr(struct ticket_config *tk, const char *attr, const char
char cmd[COMMAND_MAX];
char line[BOOTH_ATTRVAL_LEN+1];
int rv = 0, pipe_rv;
+ int res;
FILE *p;
*vp = NULL;
- snprintf(cmd, COMMAND_MAX,
+ res = snprintf(cmd, COMMAND_MAX,
"crm_ticket -t '%s' -G '%s' --quiet",
tk->name, attr);
+ if (res < 0 || res >= COMMAND_MAX) {
+ log_error("pcmk_get_attr: cannot format crm_ticket cmdline (probably too long)");
+ return -1;
+ }
p = popen(cmd, "r");
if (p == NULL) {
@@ -483,16 +506,22 @@ static int pcmk_load_ticket(struct ticket_config *tk)
{
char cmd[COMMAND_MAX];
int rv = 0, pipe_rv;
+ int res;
FILE *p;
/* This here gets run during startup; testing that here means that
* normal operation won't be interrupted with that test. */
test_atomicity();
- snprintf(cmd, COMMAND_MAX,
+ res = snprintf(cmd, COMMAND_MAX,
"crm_ticket -t '%s' -q",
tk->name);
+ if (res < 0 || res >= COMMAND_MAX) {
+ log_error("pcmk_load_ticket: cannot format crm_ticket cmdline (probably too long)");
+ return -1;
+ }
+
p = popen(cmd, "r");
if (p == NULL) {
pipe_rv = errno;
--
2.33.0