control: tags -1 patch pending Dear maintainer,
I've prepared an NMU for rspamd (versioned as 4.0.1-1.1) and uploaded it. Regards. Sebastian
diffstat for rspamd-4.0.1 rspamd-4.0.1 changelog | 8 patches/rspamd-Fix-mime_string-const-iterator.patch | 177 ++++++++++ patches/rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch | 73 ++++ patches/series | 2 4 files changed, 260 insertions(+) diff -Nru rspamd-4.0.1/debian/changelog rspamd-4.0.1/debian/changelog --- rspamd-4.0.1/debian/changelog 2026-04-08 11:37:03.000000000 +0200 +++ rspamd-4.0.1/debian/changelog 2026-09-06 14:48:47.000000000 +0200 @@ -1,3 +1,11 @@ +rspamd (4.0.1-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Get it compiled against OpenSSL 4 (Closes: 1138355). + * Get it compiled against newer doctest (Closes: 1143390). + + -- Sebastian Andrzej Siewior <[email protected]> Sun, 06 Sep 2026 14:48:47 +0200 + rspamd (4.0.1-1) unstable; urgency=medium * New upstream version 4.0.1 diff -Nru rspamd-4.0.1/debian/patches/rspamd-Fix-mime_string-const-iterator.patch rspamd-4.0.1/debian/patches/rspamd-Fix-mime_string-const-iterator.patch --- rspamd-4.0.1/debian/patches/rspamd-Fix-mime_string-const-iterator.patch 1970-01-01 01:00:00.000000000 +0100 +++ rspamd-4.0.1/debian/patches/rspamd-Fix-mime_string-const-iterator.patch 2026-09-06 14:43:03.000000000 +0200 @@ -0,0 +1,177 @@ +From b67a1e92b0ecde54e1db80390388f41c35551635 Mon Sep 17 00:00:00 2001 +From: Alexandra Parker <[email protected]> +Date: Sun, 31 May 2026 13:52:35 -0700 +Subject: [PATCH] [Fix] mime_string const iterator + +mime_string's iterator is just a value iterator anyway. it's +intrinsically const. drop reference to const_iterator, let iterator_base +take a const pointer, and mark begin() and end() as const. + +doctest 2.5.0 receives a const reference and can't use a mutable iterator, +which leads to compile error. +--- + src/libmime/mime_string.hxx | 49 ++++++++++++++----------------------- + 1 file changed, 19 insertions(+), 30 deletions(-) + +diff --git a/src/libmime/mime_string.hxx b/src/libmime/mime_string.hxx +index d6c11d018bde..8bde5fd4df63 100644 +--- a/src/libmime/mime_string.hxx ++++ b/src/libmime/mime_string.hxx +@@ -94,7 +94,7 @@ struct iterator_base { + return idx != it.idx; + } + +- iterator_base(difference_type index, Container *instance) noexcept ++ iterator_base(difference_type index, const Container *instance) noexcept + : idx(index), cont_instance(instance) + { + } +@@ -103,11 +103,6 @@ struct iterator_base { + + iterator_base &operator=(const iterator_base &) noexcept = default; + +- Container *get_instance() const noexcept +- { +- return cont_instance; +- } +- + codepoint_type get_value() const noexcept + { + auto i = idx; +@@ -118,7 +113,7 @@ struct iterator_base { + + protected: + difference_type idx; +- Container *cont_instance = nullptr; ++ const Container *cont_instance = nullptr; + + protected: + void advance(difference_type n) noexcept +@@ -164,7 +159,7 @@ struct iterator_base<Container, true> { + return idx != it.idx; + } + +- iterator_base(difference_type index, Container *instance) noexcept ++ iterator_base(difference_type index, const Container *instance) noexcept + : idx(index), cont_instance(instance) + { + } +@@ -172,10 +167,6 @@ struct iterator_base<Container, true> { + iterator_base() noexcept = default; + iterator_base(const iterator_base &) noexcept = default; + iterator_base &operator=(const iterator_base &) noexcept = default; +- Container *get_instance() const noexcept +- { +- return cont_instance; +- } + + value_type get_value() const noexcept + { +@@ -184,7 +175,7 @@ struct iterator_base<Container, true> { + + protected: + difference_type idx; +- Container *cont_instance = nullptr; ++ const Container *cont_instance = nullptr; + + protected: + //! Advance the iterator n times (negative values allowed!) +@@ -203,23 +194,21 @@ struct iterator_base<Container, true> { + } + }; + +-template<typename Container, bool Raw> +-struct iterator; +-template<typename Container, bool Raw> +-struct const_iterator; + + template<typename Container, bool Raw = false> + struct iterator : iterator_base<Container, Raw> { +- iterator(typename iterator_base<Container, Raw>::difference_type index, Container *instance) noexcept +- : iterator_base<Container, Raw>(index, instance) ++ using base = iterator_base<Container, Raw>; ++ using typename base::difference_type; ++ using typename base::reference_type; ++ ++ iterator(difference_type index, const Container *instance) noexcept ++ : base(index, instance) + { + } + iterator() noexcept = default; + iterator(const iterator &) noexcept = default; + + iterator &operator=(const iterator &) noexcept = default; +- /* Disallow creating from const_iterator */ +- iterator(const const_iterator<Container, Raw> &) = delete; + + /* Prefix */ + iterator &operator++() noexcept +@@ -251,33 +240,33 @@ struct iterator : iterator_base<Container, Raw> { + return tmp; + } + +- iterator operator+(typename iterator_base<Container, Raw>::difference_type n) const noexcept ++ iterator operator+(difference_type n) const noexcept + { + iterator it{*this}; + it.advance(n); + return it; + } + +- iterator &operator+=(typename iterator_base<Container, Raw>::difference_type n) noexcept ++ iterator &operator+=(difference_type n) noexcept + { + this->advance(n); + return *this; + } + +- iterator operator-(typename iterator_base<Container, Raw>::difference_type n) const noexcept ++ iterator operator-(difference_type n) const noexcept + { + iterator it{*this}; + it.advance(-n); + return it; + } + +- iterator &operator-=(typename iterator_base<Container, Raw>::difference_type n) noexcept ++ iterator &operator-=(difference_type n) noexcept + { + this->advance(-n); + return *this; + } + +- typename iterator::reference_type operator*() const noexcept ++ reference_type operator*() const noexcept + { + return this->get_value(); + } +@@ -523,22 +512,22 @@ class basic_mime_string : private Allocator { + } + + /* Iterators */ +- inline auto begin() noexcept -> iterator ++ inline auto begin() const noexcept -> iterator + { + return {0, this}; + } + +- inline auto raw_begin() noexcept -> raw_iterator ++ inline auto raw_begin() const noexcept -> raw_iterator + { + return {0, this}; + } + +- inline auto end() noexcept -> iterator ++ inline auto end() const noexcept -> iterator + { + return {(difference_type) size(), this}; + } + +- inline auto raw_end() noexcept -> raw_iterator ++ inline auto raw_end() const noexcept -> raw_iterator + { + return {(difference_type) size(), this}; + } +-- +2.55.0 + diff -Nru rspamd-4.0.1/debian/patches/rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch rspamd-4.0.1/debian/patches/rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch --- rspamd-4.0.1/debian/patches/rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch 1970-01-01 01:00:00.000000000 +0100 +++ rspamd-4.0.1/debian/patches/rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch 2026-09-06 14:18:50.000000000 +0200 @@ -0,0 +1,73 @@ +From d2c42975fae971cffa32038dbb6b2cdcca704b1d Mon Sep 17 00:00:00 2001 +From: Vsevolod Stakhov <[email protected]> +Date: Thu, 11 Jun 2026 18:20:02 +0100 +Subject: [PATCH] [Fix] mime: fix build with OpenSSL 4.0 opaque ASN1_STRING + +OpenSSL 4.0 made ASN1_STRING (and thus ASN1_OCTET_STRING) opaque, so +direct access to its length/data fields no longer compiles. Use +ASN1_STRING_length()/ASN1_STRING_get0_data() which are available since +OpenSSL 1.1.0 and LibreSSL 2.7. + +Also move the legacy OpenSSL init calls (ERR_load_crypto_strings, +SSL_load_error_strings, OpenSSL_add_all_*) under the pre-1.1.0 guard: +they are redundant on modern OpenSSL and break no-deprecated builds. + +Fixes: #6087 +--- + src/libmime/mime_parser.c | 16 +++++++++------- + src/libserver/ssl_util.c | 2 ++ + 2 files changed, 11 insertions(+), 7 deletions(-) + +--- a/src/libmime/mime_parser.c ++++ b/src/libmime/mime_parser.c +@@ -887,24 +887,26 @@ rspamd_mime_parse_normal_part(struct rsp + + ct_nid = OBJ_obj2nid(p7_signed_content->type); + ++ /* ASN1_STRING is opaque since OpenSSL 4.0, use accessors */ + if (ct_nid == NID_pkcs7_data && p7_signed_content->d.data) { ++ int p7_data_len = ASN1_STRING_length(p7_signed_content->d.data); ++ const unsigned char *p7_data = ASN1_STRING_get0_data(p7_signed_content->d.data); + int ret; + + msg_debug_mime("found an additional part inside of " + "smime structure of type %T/%T; length=%d", +- &ct->type, &ct->subtype, p7_signed_content->d.data->length); ++ &ct->type, &ct->subtype, p7_data_len); + /* + * Since ASN.1 structures are freed, we need to copy + * the content + */ + char *cpy = rspamd_mempool_alloc(task->task_pool, +- p7_signed_content->d.data->length); +- memcpy(cpy, p7_signed_content->d.data->data, +- p7_signed_content->d.data->length); ++ p7_data_len); ++ memcpy(cpy, p7_data, p7_data_len); + ret = rspamd_mime_process_multipart_node(task, +- st, NULL, +- cpy, cpy + p7_signed_content->d.data->length, +- TRUE, err); ++ st, NULL, ++ cpy, cpy + p7_data_len, ++ TRUE, err); + + PKCS7_free(p7); + BIO_free(bio); +--- a/src/libserver/ssl_util.c ++++ b/src/libserver/ssl_util.c +@@ -1224,12 +1224,14 @@ void rspamd_openssl_maybe_init(struct rs + static gboolean openssl_initialized = FALSE; + + if (!openssl_initialized) { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + ERR_load_crypto_strings(); + SSL_load_error_strings(); + + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_ciphers(); ++#endif + + #if OPENSSL_VERSION_NUMBER >= 0x1000104fL && OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) + ENGINE_load_builtin_engines(); diff -Nru rspamd-4.0.1/debian/patches/series rspamd-4.0.1/debian/patches/series --- rspamd-4.0.1/debian/patches/series 2026-04-08 11:37:03.000000000 +0200 +++ rspamd-4.0.1/debian/patches/series 2026-09-06 14:48:47.000000000 +0200 @@ -1,3 +1,5 @@ 0002-use-jquery-from-debian-package.patch 0003-use-system-effective_tld_names.patch 0005-remove-rspamd_stats-and-mapstats.patch +rspamd-openssl4-Fix-mime-fix-build-with-OpenSSL-4.0-opaque-ASN1_STRI.patch +rspamd-Fix-mime_string-const-iterator.patch

