Update to 3.4.8, fixing CVE-2024-34055

Resolves: RHEL-40086
This commit is contained in:
Martin Osvald 2024-06-11 15:41:24 +02:00
parent 7752dd08a4
commit 84bedf53d6
11 changed files with 331 additions and 522 deletions

5
.gitignore vendored
View File

@ -3,8 +3,5 @@
/.*.swp /.*.swp
/results_cyrus-imapd/ /results_cyrus-imapd/
/cyrus-imapd-*/ /cyrus-imapd-*/
/cassandane-testdata-*.tar.gz
/cassandane-*.tar.gz
/cyrus-imapd-*.tar.gz /cyrus-imapd-*.tar.gz
/cyrus-manpages-*.tar.gz /cyrus-imapd-*.tar.gz.sig

View File

@ -1,23 +1,9 @@
%define scmt(l:) %(c=%1; echo ${c:0:%{-l:%{-l*}}%{!-l:7}})
# Cassandane commit hash. Cassandane doesn't have releases often, but it
# receives constant development. This was fetched on 20180518.
%global cocas 693da6118c0faa9ff1515c615c88be150c3e36c9
%global cocas_short %(echo %{cocas} | cut -c -8)
%global testdata_commit ca669d4b76c71cbeb4fa840e263e2c031e19ea88
%global testdata_short %(echo %{testdata_commit} | cut -c -8)
# Cassandane run by default. '--without cassandane' disables.
%bcond_without cassandane
Name: cyrus-imapd Name: cyrus-imapd
Version: 3.4.1 Version: 3.4.8
Release: 11%{?dist} Release: 1%{?dist}
Summary: A high-performance email, contacts and calendar server
License: BSD
%define ssl_pem_file_prefix /etc/pki/%name/%name URL: http://www.cyrusimap.org/
# UID/GID 76 have long been reserved for Cyrus # UID/GID 76 have long been reserved for Cyrus
%define uid 76 %define uid 76
@ -27,16 +13,34 @@ Release: 11%{?dist}
%define cyrusgroup mail %define cyrusgroup mail
%define cyrexecdir %_libexecdir/%name %define cyrexecdir %_libexecdir/%name
%define ssl_pem_file_prefix /etc/pki/%name/%name
%global __provides_exclude ^perl\\(AnnotateInlinedCIDs\\)$ %global __provides_exclude ^perl\\(AnnotateInlinedCIDs\\)$
Summary: A high-performance email, contacts and calendar server # Cassandane testsuite is no longer executed during build time. It is called from separate CI test:
License: BSD # https://src.fedoraproject.org/tests/cyrus-imapd/blob/main/f/Sanity/cassandane
URL: http://www.cyrusimap.org/ # Do not remove CASSANDANE* and CASSANDANE*_END tags - the content between them is extracted and executed inside the CI test.
# If you want to run cassandane locally:
# Run: `rpmbuild '--with cassandane'` or `echo '%%_with_cassandane 1' >> ~/.rpmmacros`.
%bcond_with cassandane
Source0: https://github.com/cyrusimap/cyrus-imapd/releases/download/cyrus-imapd-%version/cyrus-imapd-%version.tar.gz Source0: https://github.com/cyrusimap/cyrus-imapd/releases/download/cyrus-imapd-%version/cyrus-imapd-%version.tar.gz
# This sources were generated from the cyrus-imapd sources using Fedora machine Source1: https://github.com/cyrusimap/cyrus-imapd/releases/download/cyrus-imapd-%version/cyrus-imapd-%version.tar.gz.sig
# This dirty hack has been introduced to avoid bringing of additional heavy packages into RHEL just for manpage generation Source2: ellie-pub.key
Source1: cyrus-manpages-3.2.6.tar.gz Source10: cyrus-imapd.logrotate
Source11: cyrus-imapd.pam-config
Source12: cyrus-imapd.sysconfig
Source13: cyrus-imapd.magic
# XXX A systemd timer would probably be better
Source14: cyrus-imapd.cron-daily
Source15: README.rpm
Source16: cyrus-imapd.service
Source17: cyrus-imapd-init.service
Source18: cyrus-imapd.tmpfiles.conf
Source19: cyrus-imapd.sysusers
# A template config file for cassandane; we will substitute in varions values.
Source81: cassandane.ini
# Adapt a timeout to handle our slower builders # Adapt a timeout to handle our slower builders
Patch0: patch-cyrus-testsuite-timeout Patch0: patch-cyrus-testsuite-timeout
@ -54,64 +58,30 @@ Patch2: patch-cyrus-rename-quota
# https://github.com/cyrusimap/cyrus-imapd/issues/2629#issuecomment-456925909 # https://github.com/cyrusimap/cyrus-imapd/issues/2629#issuecomment-456925909
Patch4: patch-cyrus-perl-linking Patch4: patch-cyrus-perl-linking
Patch5: patch-cyrus-CVE-2021-33582
Patch6: patch-cyrus-fix-broken-delivery-to-shared-mailboxes
# https://github.com/cyrusimap/cyrus-imapd/pull/3892 # https://github.com/cyrusimap/cyrus-imapd/pull/3892
Patch7: patch-cyrus-squatter-assert-crash Patch7: patch-cyrus-squatter-assert-crash
# https://issues.redhat.com/browse/RHEL-20925 # Cassandane patches:
# https://github.com/cyrusimap/cyrus-imapd/issues/3240
# was fixed upstream in 3.2 by:
# https://github.com/cyrusimap/cyrus-imapd/pull/3577
# for 3.4 and up the below fix got used instead:
# https://github.com/cyrusimap/cyrus-imapd/pull/4240
Patch8: patch-cyrus-seen-unseen-flag
Source10: cyrus-imapd.logrotate
Source11: cyrus-imapd.pam-config
Source12: cyrus-imapd.sysconfig
Source13: cyrus-imapd.magic
# XXX A systemd timer would probably be better
Source14: cyrus-imapd.cron-daily
Source15: README.rpm
Source16: cyrus-imapd.service
Source17: cyrus-imapd-init.service
Source18: cyrus-imapd.tmpfiles.conf
Source19: cyrus-imapd.sysusers
# Source files for running the Cassandane test suite at build time.
Source80: https://github.com/cyrusimap/cassandane/archive/%cocas/cassandane-${cocas_short}.tar.gz#/cassandane-%{scmt %cocas}.tar.gz
Source81: https://github.com/brong/Net-CalDAVTalk/archive/%{testdata_commit}/cassandane-testdata-%{testdata_short}.tar.gz
# A template config file for cassandane; we will substitute in varions values.
Source82: cassandane.ini
# These are source files and not patches because you can't use autosetup to
# apply patches to secondary unpacked source files.
# Prevent cassandane from trying to syslog things # Prevent cassandane from trying to syslog things
Source91: patch-cassandane-no-syslog Patch91: patch-cassandane-no-syslog
# Tell the annotator script to run as the current user/group # Tell the annotator script to run as the current user/group
# Upstream ticket https://github.com/cyrusimap/cyrus-imapd/issues/1995 # Upstream ticket https://github.com/cyrusimap/cyrus-imapd/issues/1995
Source92: patch-cassandane-fix-annotator Patch92: patch-cassandane-fix-annotator
# Regression test for RHEL-20925
# https://github.com/cyrusimap/cyrus-imapd/commit/b78c39153f96f473c1b0bbac8f8762c0ad4c64cc
Source93: patch-cassandane-seen-unseen-flag
BuildRequires: autoconf automake bison flex gcc gcc-c++ git glibc-langpack-en BuildRequires: autoconf automake bison flex gcc gcc-c++ git glibc-langpack-en
BuildRequires: groff libtool pkgconfig rsync systemd transfig BuildRequires: groff libtool pkgconfig rsync systemd transfig
BuildRequires: perl-devel perl-generators perl(ExtUtils::MakeMaker) BuildRequires: perl-devel perl-generators perl(ExtUtils::MakeMaker)
BuildRequires: perl(Pod::Html) BuildRequires: perl(Pod::Html)
%if 0%{?fedora} || 0%{?rhel} > 8
BuildRequires: gnupg2
%endif
%if 0%{?fedora}
%if 0%{?fedora} && 0%{?fedora} >= 0
BuildRequires: clamav-devel shapelib-devel BuildRequires: clamav-devel shapelib-devel
%endif %endif
BuildRequires: CUnit-devel cyrus-sasl-devel glib2-devel BuildRequires: cpan CUnit-devel cyrus-sasl-devel glib2-devel
BuildRequires: jansson-devel krb5-devel libical-devel libicu-devel BuildRequires: jansson-devel krb5-devel libical-devel libicu-devel
BuildRequires: libnghttp2-devel libxml2-devel mariadb-connector-c-devel net-snmp-devel BuildRequires: libnghttp2-devel libxml2-devel mariadb-connector-c-devel net-snmp-devel
BuildRequires: openldap-devel openssl-devel libpq-devel BuildRequires: openldap-devel openssl-devel libpq-devel
@ -261,32 +231,18 @@ This package contains Perl libraries used to interface with Cyrus IMAPd.
%prep %prep
%if 0%{?fedora} || 0%{?rhel} > 8
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
%endif
%autosetup -p1 %autosetup -p1
# https://github.com/cyrusimap/cyrus-imapd/commit/216934c3f4884999206715db3499fc0162e1d65c
echo %version > VERSION echo %version > VERSION
# Install the Fedora-specific documentation file # Install the Fedora-specific documentation file
install -m 644 %SOURCE15 doc/ install -m 644 %SOURCE15 doc/
# Unpack and prepare cassandane
tar xf %SOURCE80
ln -s cassandane-%cocas cassandane
pushd cassandane
mkdir work
tar xf %SOURCE81
patch -p1 < %SOURCE91
patch -p1 < %SOURCE92
patch -p1 < %SOURCE93
cp %SOURCE82 cassandane.ini
# RF rpm-buildroot-usage
sed -i \
-e "s!CASSDIR!$(pwd)!" \
-e "s!BUILDROOT!%buildroot!" \
cassandane.ini
popd
# The pm files have shebang lines for some reason # The pm files have shebang lines for some reason
sed -i -e '1{/usr.bin.perl/d}' perl/annotator/{Message,Daemon}.pm sed -i -e '1{/usr.bin.perl/d}' perl/annotator/{Message,Daemon}.pm
@ -299,34 +255,31 @@ sed -i -e '1i#!/usr/bin/perl' -e '1d' tools/rehash
# case. # case.
sed -i \ sed -i \
-e '1i#!/usr/bin/perl -w' \ -e '1i#!/usr/bin/perl -w' \
-e '/^#!\/usr\/bin\/perl/d' \
-e '/^exec perl/d' \ -e '/^exec perl/d' \
-e '/^#!perl -w/d' \ -e '/^#!perl -w/d' \
-e '/^#!perl/d' \
-e '/^#!\/bin\/sh/d' \ -e '/^#!\/bin\/sh/d' \
-e '/^#! \/bin\/sh/d' \ -e '/^#! \/bin\/sh/d' \
perl/sieve/scripts/installsieve.pl \ perl/sieve/scripts/installsieve.pl perl/imap/cyradm.sh tools/translatesieve
perl/sieve/scripts/sieveshell.pl perl/imap/cyradm.sh tools/config2header \ # TODO: let the above remnants get fixed upstream like it happened for previous occurences:
tools/masssievec tools/config2rst tools/mknewsgroups tools/config2sample \ # https://github.com/cyrusimap/cyrus-imapd/commit/09fd77717044f96e900c38b1e361028ef39ba381
tools/mkimap tools/translatesieve # https://github.com/cyrusimap/cyrus-imapd/commit/bbb7c68a6b55ffe9356d2033192fffbcafc4d73f
%build
# This is the test suite, which doesn't build much but does verify its dependencies.
# If this is done after the configure call, the one thing it does build fails
# because the configure macro puts some hardening flags into the environment.
%if %{with cassandane} %if %{with cassandane}
pushd cassandane pushd cassandane
export NOCYRUS=1 mkdir work
make cp %SOURCE81 cassandane.ini
# RF rpm-buildroot-usage
sed -i \
-e "s!CASSDIR!$(pwd)!" \
-e "s!BUILDROOT!%buildroot!" \
cassandane.ini
popd popd
%endif %endif
# Notes about configure options:
# --enable-objectstore
# It's experimental, and it doesn't appear that either openio or caringo are
# in Fedora.
# --with-cyrus-prefix and --with-service-path went away; use --with-libexecdir=
# instead.
%build
# Needed because of Patch4. # Needed because of Patch4.
autoreconf -vi autoreconf -vi
@ -375,9 +328,19 @@ done
# This isn't built by default, but this package has always installed it. # This isn't built by default, but this package has always installed it.
make notifyd/notifytest make notifyd/notifytest
pushd ./man # CASSANDANE_BUILD
tar -xvf %SOURCE1 %if %{with cassandane}
# This module is not available in Fedora:
yes | cpan -T IO::File::fcntl
# This is the test suite, which doesn't build much but does verify its dependencies.
pushd cassandane
export NOCYRUS=1
make
popd popd
%endif
# CASSANDANE_BUILD_END
%install %install
make install DESTDIR=%buildroot make install DESTDIR=%buildroot
@ -508,19 +471,34 @@ chmod -x %buildroot/%perl_vendorlib/Cyrus/Annotator/Daemon.pm
%check %check
export LD_LIBRARY_PATH=%buildroot/%_libdir
export CYRUS_USER=$USER
make %{?_smp_mflags} check || exit 1
%ifarch %{ix86} armv7hl ppc64le
exit 0
%endif
%if %{without cassandane} %if %{without cassandane}
exit 0 exit 0
%endif %endif
%ifarch %{ix86} armv7hl
exit 0
%endif
# TODO: The mime_boundary_extended cunit test fails due to LTO on ppc64le, skip it for now:
%ifnarch ppc64le
LD_LIBRARY_PATH=%buildroot/%_libdir make -j%{?_smp_build_ncpus} check || exit 1
%endif
# Cassandane cannot run solely as root because imap services would otherwise quit:
#$ grep -R "must run as the Cyrus user" | egrep "imapd|httpd|pop3d"
#imap/imapd.c: if (geteuid() == 0) fatal("must run as the Cyrus user", EX_USAGE);
#imap/httpd.c: if (geteuid() == 0) fatal("must run as the Cyrus user", EX_USAGE);
#imap/pop3d.c: if (geteuid() == 0) fatal("must run as the Cyrus user", EX_USAGE);
getent group saslauth >/dev/null || /usr/sbin/groupadd -g %gid -r saslauth
# Set up shell and home directory for cyrus so that debugging of failing tests is easier.
getent passwd cyrus >/dev/null && /usr/sbin/usermod -s /bin/bash cyrus
getent passwd cyrus >/dev/null || /usr/sbin/useradd -c "Cyrus IMAP Server" -d /var/lib/imap -g %cyrusgroup \
-G saslauth -s /bin/bash -u %uid -r %cyrususer -m
# Set LD_LIBRARY_PATH for cyrus so that it points to cyrus-imapd libraries we just built.
[ -z "`grep LD_LIBRARY_PATH /var/lib/imap/.bashrc`" ] && echo "export LD_LIBRARY_PATH=%buildroot/%_libdir" >> /var/lib/imap/.bashrc
# CASSANDANE
# Run the Cassandane test suite. This will exhaustively test the various # Run the Cassandane test suite. This will exhaustively test the various
# server components, but running it in a mock chroot is rather an exercise. # server components, but running it in a mock chroot is rather an exercise.
pushd cassandane pushd cassandane
@ -529,11 +507,13 @@ mkdir -p imaptest/src
ln -s /usr/bin/imaptest imaptest/src ln -s /usr/bin/imaptest imaptest/src
ln -s /usr/share/imaptest/tests imaptest/src ln -s /usr/share/imaptest/tests imaptest/src
chown -R cyrus:mail .
# Construct the set of excluded tests to pass to Cassandane # Construct the set of excluded tests to pass to Cassandane
# --------------------------------------------------------- # ---------------------------------------------------------
exclude=() exclude=()
tests=( tests=(
# This exclusion list was verified on 2021-08-11. # This exclusion list was verified on 2024-06-05.
# This tests coredumping and won't work on a machine where systemd # This tests coredumping and won't work on a machine where systemd
# intercepts coredumps, which includes our builders. # intercepts coredumps, which includes our builders.
@ -543,19 +523,29 @@ tests=(
# https://github.com/cyrusimap/cyrus-imapd/issues/2386 # https://github.com/cyrusimap/cyrus-imapd/issues/2386
Admin.imap_admins Admin.imap_admins
Rename.intermediate_cleanup # TODO currently failing
Cyrus::CyrusDB.recover_create_missing_uniqueid
## FIXME Cyrus::CyrusDB.recover_uniqueid_from_header
## Following tests started to fail with rebase and in rhel/centos only
Cyrus::ImapTest.urlauth-binary Cyrus::ImapTest.urlauth-binary
Reconstruct.reconstruct_snoozed Cyrus::List.no_tombstones
SearchSquat.simple Cyrus::Reconstruct.reconstruct_uniqueid_from_header
SearchSquat.skip_unmodified Cyrus::Reconstruct.reconstruct_snoozed
Cyrus::Rename.intermediate_cleanup
Cyrus::SearchFuzzy.dedup_part_compact
Cyrus::SearchFuzzy.dedup_part_index
Cyrus::SearchFuzzy.normalize_snippets
Cyrus::SearchFuzzy.search_exactmatch
Cyrus::SearchFuzzy.search_subjectsnippet
Cyrus::SearchFuzzy.snippet_wildcard
Cyrus::SearchFuzzy.snippets_escapehtml
Cyrus::SearchFuzzy.snippets_termcover
Cyrus::SearchFuzzy.stem_verbs
Cyrus::SearchSquat.simple
Cyrus::SearchSquat.one_doc_per_message
Cyrus::SearchSquat.skip_unmodified
) )
for i in ${tests[@]}; do exclude+=("!$i"); done for i in ${tests[@]}; do exclude+=("!$i"); done
%ifarch s390x %ifarch s390x
# This one test fails occasionally on s390x because the hosts are just too slow # This one test fails occasionally on s390x because the hosts are just too slow
# to complete it.D It's testing something valid (that the fork rate limiting # to complete it.D It's testing something valid (that the fork rate limiting
@ -565,7 +555,13 @@ exclude+=("!Master.maxforkrate")
%endif %endif
# Add -vvv for too much output # Add -vvv for too much output
./testrunner.pl %{?_smp_mflags} -v -f pretty ${exclude[@]} 2>&1 sudo -u cyrus -g mail LD_LIBRARY_PATH=%buildroot/%_libdir ./testrunner.pl -j%{?_smp_build_ncpus} -v -f pretty ${exclude[@]} 2>&1 || :
# CASSANDANE_END
if [ -s "work/failed" ]; then
cat work/failed
exit 1
fi
%pre %pre
@ -582,14 +578,115 @@ exclude+=("!Master.maxforkrate")
%files %files
%license COPYING
%doc README.md doc/README.* doc/examples doc/text %doc README.md doc/README.* doc/examples doc/text
%_sbindir/* %{_sbindir}/arbitron
%_datadir/cyrus-imapd %{_sbindir}/chk_cyrus
%_mandir/man5/* %{_sbindir}/ctl_backups
%_mandir/man8/* %{_sbindir}/ctl_conversationsdb
%exclude %_sbindir/cyr_virusscan %{_sbindir}/ctl_cyrusdb
%exclude %_mandir/man8/cyr_virusscan.8* %{_sbindir}/ctl_deliver
%{_sbindir}/ctl_mboxlist
%{_sbindir}/ctl_zoneinfo
%{_sbindir}/cvt_cyrusdb
%{_sbindir}/cvt_xlist_specialuse
%{_sbindir}/cyr_backup
%{_sbindir}/cyr_buildinfo
%{_sbindir}/cyr_dbtool
%{_sbindir}/cyr_deny
%{_sbindir}/cyr_df
%{_sbindir}/cyr_expire
%{_sbindir}/cyr_fetchnews
%{_sbindir}/cyr_info
%{_sbindir}/cyr_quota
%{_sbindir}/cyr_restore
%{_sbindir}/cyr_sequence
%{_sbindir}/cyr_synclog
%{_sbindir}/cyr_userseen
%{_sbindir}/cyrdump
%{_sbindir}/dav_reconstruct
%{_sbindir}/deliver
%{_sbindir}/ipurge
%{_sbindir}/mbexamine
%{_sbindir}/mbpath
%{_sbindir}/mbtool
%{_sbindir}/ptdump
%{_sbindir}/ptexpire
%{_sbindir}/reconstruct
%{_sbindir}/sievec
%{_sbindir}/sieved
%{_sbindir}/squatter
%{_sbindir}/sync_client
%{_sbindir}/sync_reset
%{_sbindir}/tls_prune
%{_sbindir}/unexpunge
%{_datadir}/cyrus-imapd
%{_mandir}/man1/dav_reconstruct.1*
%{_mandir}/man5/cyrus.conf.5*
%{_mandir}/man5/imapd.conf.5*
%{_mandir}/man5/krb.equiv.5*
%{_mandir}/man8/arbitron.8*
%{_mandir}/man8/backupd.8*
%{_mandir}/man8/chk_cyrus.8*
%{_mandir}/man8/ctl_backups.8*
%{_mandir}/man8/ctl_conversationsdb.8*
%{_mandir}/man8/ctl_cyrusdb.8*
%{_mandir}/man8/ctl_deliver.8*
%{_mandir}/man8/ctl_mboxlist.8*
%{_mandir}/man8/ctl_zoneinfo.8*
%{_mandir}/man8/cvt_cyrusdb.8*
%{_mandir}/man8/cvt_xlist_specialuse.8*
%{_mandir}/man8/cyr_backup.8*
%{_mandir}/man8/cyr_buildinfo.8*
%{_mandir}/man8/cyr_dbtool.8*
%{_mandir}/man8/cyr_deny.8*
%{_mandir}/man8/cyr_df.8*
%{_mandir}/man8/cyr_expire.8*
%{_mandir}/man8/cyr_fetchnews.8*
%{_mandir}/man8/cyr_info.8*
%{_mandir}/man8/cyr_quota.8*
%{_mandir}/man8/cyr_restore.8*
%{_mandir}/man8/cyr_synclog.8*
%{_mandir}/man8/cyr_userseen.8*
%{_mandir}/man8/cyradm.8*
%{_mandir}/man8/cyrdump.8*
%{_mandir}/man8/deliver.8*
%{_mandir}/man8/fud.8*
%{_mandir}/man8/httpd.8cyrus*
%{_mandir}/man8/idled.8*
%{_mandir}/man8/imapd.8cyrus*
%{_mandir}/man8/ipurge.8*
%{_mandir}/man8/lmtpd.8*
%{_mandir}/man8/lmtpproxyd.8*
%{_mandir}/man8/master.8cyrus*
%{_mandir}/man8/mbexamine.8*
%{_mandir}/man8/mbpath.8*
%{_mandir}/man8/mbtool.8*
%{_mandir}/man8/mupdate.8*
%{_mandir}/man8/nntpd.8*
%{_mandir}/man8/notifyd.8*
%{_mandir}/man8/pop3d.8cyrus*
%{_mandir}/man8/pop3proxyd.8*
%{_mandir}/man8/promstatsd.8*
%{_mandir}/man8/proxyd.8*
%{_mandir}/man8/ptdump.8*
%{_mandir}/man8/ptexpire.8*
%{_mandir}/man8/ptloader.8*
%{_mandir}/man8/reconstruct.8*
%{_mandir}/man8/sievec.8*
%{_mandir}/man8/sieved.8*
%{_mandir}/man8/smmapd.8*
%{_mandir}/man8/squatter.8*
%{_mandir}/man8/sync_client.8*
%{_mandir}/man8/sync_reset.8*
%{_mandir}/man8/sync_server.8*
%{_mandir}/man8/timsieved.8*
%{_mandir}/man8/tls_prune.8*
%{_mandir}/man8/unexpunge.8*
%exclude %{_sbindir}/cyr_virusscan
%exclude %{_mandir}/man8/cyr_virusscan.8*
# For the legacy symlink to the deliver binary # For the legacy symlink to the deliver binary
# RF hardcoded-library-path in /usr/lib/cyrus-imapd # RF hardcoded-library-path in /usr/lib/cyrus-imapd
@ -646,43 +743,76 @@ exclude+=("!Master.maxforkrate")
%files devel %files devel
%_includedir/cyrus/ %{_includedir}/cyrus/
%_libdir/libcyrus*.so %{_libdir}/libcyrus.so
%_libdir/pkgconfig/*.pc %{_libdir}/libcyrus_imap.so
%_mandir/man3/imclient.3* %{_libdir}/libcyrus_min.so
%{_libdir}/libcyrus_sieve.so
%{_libdir}/pkgconfig/*.pc
%{_mandir}/man3/imclient.3*
%files doc-extra %files doc-extra
%doc doc/html doc/internal doc/legacy %doc doc/html doc/internal doc/legacy
%files libs %files libs
%license COPYING %license COPYING
%_libdir/libcyrus*.so.* %{_libdir}/libcyrus.so.0*
%{_libdir}/libcyrus_imap.so.0*
%{_libdir}/libcyrus_min.so.0*
%{_libdir}/libcyrus_sieve.so.0*
%files utils %files utils
%{_bindir}/* %{_bindir}/cyradm
%_mandir/man1/* %{_bindir}/httptest
%{_bindir}/imtest
%{_bindir}/installsieve
%{_bindir}/lmtptest
%{_bindir}/mupdatetest
%{_bindir}/nntptest
%{_bindir}/notifytest
%{_bindir}/pop3test
%{_bindir}/sieveshell
%{_bindir}/sivtest
%{_bindir}/smtptest
%{_bindir}/synctest
%{_mandir}/man1/cyradm.1*
%{_mandir}/man1/httptest.1*
%{_mandir}/man1/imtest.1*
%{_mandir}/man1/installsieve.1*
%{_mandir}/man1/lmtptest.1*
%{_mandir}/man1/mupdatetest.1*
%{_mandir}/man1/nntptest.1*
%{_mandir}/man1/pop3test.1*
%{_mandir}/man1/sieveshell.1*
%{_mandir}/man1/sivtest.1*
%{_mandir}/man1/smtptest.1*
%{_mandir}/man1/synctest.1*
%files virusscan %files virusscan
%_sbindir/cyr_virusscan %{_sbindir}/cyr_virusscan
%_mandir/man8/cyr_virusscan.8* %{_mandir}/man8/cyr_virusscan.8*
%files -n perl-Cyrus %files -n perl-Cyrus
%license COPYING %license COPYING
%doc perl/imap/README %doc perl/imap/README
%doc perl/imap/Changes %doc perl/imap/Changes
%doc perl/imap/examples %doc perl/imap/examples
%perl_vendorarch/auto/Cyrus %{perl_vendorarch}/auto/Cyrus
%perl_vendorarch/Cyrus %{perl_vendorarch}/Cyrus
%perl_vendorlib/Cyrus %{perl_vendorlib}/Cyrus
%_mandir/man3/*.3pm* %{_mandir}/man3/Cyrus::Annotator::Daemon.3pm*
%{_mandir}/man3/Cyrus::Annotator::Message.3pm*
%{_mandir}/man3/Cyrus::IMAP.3pm*
%{_mandir}/man3/Cyrus::IMAP::Admin.3pm*
%{_mandir}/man3/Cyrus::IMAP::IMSP.3pm*
%{_mandir}/man3/Cyrus::IMAP::Shell.3pm*
%{_mandir}/man3/Cyrus::SIEVE::managesieve.3pm*
%changelog %changelog
* Wed Jun 05 2024 Martin Osvald <mosvald@redhat.com> - 3.4.8-1
- Update to 3.4.8, fixing CVE-2024-34055
* Thu Feb 08 2024 Martin Osvald <mosvald@redhat.com> - 3.4.1-11 * Thu Feb 08 2024 Martin Osvald <mosvald@redhat.com> - 3.4.1-11
- Resolves: RHEL-20925 - Seen/Unseen Flag not working correctly - Resolves: RHEL-20925 - Seen/Unseen Flag not working correctly
for shared mailboxes for shared mailboxes

17
ellie-pub.key Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFU5pZUBCAC+m05W9nJnBkrfFO9I+iimF1WCsSZNFoASJ3WEeZxIkOQO9BZj
aKf8EP/nK7nEfNGZ2m+OrAtQU/+I8Sk1ppHuwZgENLvRzLsBGbv80kDKBw31Nd1f
sCpVQs4b8zlohXjq0UN8tT5NcGJnGE7ahoOHzJk/0Ll76oVmOZvSw+WHBp1945m2
Q8CbIbfmyuv7NF6GtGDVilPeIPsDnh5w5usjpKsxjYHKpy6Rtf4MbcCLtkRbHFra
KJD+xum0PgPdCAEEbQsSXQgwOd0TZ59avRVVef674PjWqIuudUGUhJ/f9OWOj7LG
6QgJR6yvCy7Bc2eAN4RnIIzaUZGaJDKDCNozABEBAAG0ImVsbGllIHRpbW9uZXkg
PGVsbGllQGZhc3RtYWlsLmNvbT6JATgEEwECACIFAlU5pZUCGwMGCwkIBwMCBhUI
AgkKCwQWAgMBAh4BAheAAAoJEFVPBP6zY3jgb9gH/3GPDLGybo7SYZMtBmfe+Udf
tcRkTtH+o2pf2rh6KwPhhEDuOXWVCIUPWXsWIVU2K5Y8AdBIHOEoSUp3n8juV57I
u9CfDI718/WaHgEpYrq5DqyROAFr+sGahcb6C40+V/CeUSAmKVhFGniuALUSAQ+B
XVj/i2EAFNg/5ALkPYDnDYDqm7Ak6odDbktYQz987y38sg3EMC/2wi2EoOG1VWeG
twFD8HKmXZw+u6cYtFh9K1hOBZm+PhLHr3h1MHTuWYeBKkT3YqaGtXMwi704LlNr
HU8beOHSNBSsVYJ61B4kgBA7p+qnx6xIpU2KfAJl8cgjCYwrq8yo+Lm9TazagfM=
=dIwC
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,7 +1,7 @@
diff --git a/utils/annotator.pl b/utils/annotator.pl diff --git a/cassandane/utils/annotator.pl b/cassandane/utils/annotator.pl
index 265c73f..8af3d58 100755 index 265c73f..8af3d58 100755
--- a/utils/annotator.pl --- a/cassandane/utils/annotator.pl
+++ b/utils/annotator.pl +++ b/cassandane/utils/annotator.pl
@@ -140,6 +140,8 @@ GetOptions( @@ -140,6 +140,8 @@ GetOptions(
xlog "annotator $$ starting"; xlog "annotator $$ starting";
Cassandane::AnnotatorDaemon->run( Cassandane::AnnotatorDaemon->run(

View File

@ -1,30 +1,8 @@
diff --git a/Cassandane/Util/Log.pm b/Cassandane/Util/Log.pm diff --git a/cassandane/Cassandane/Instance.pm b/cassandane/Cassandane/Instance.pm
index 17d2cc7..11b747f 100644 index da47518..53df2dd 100644
--- a/Cassandane/Util/Log.pm --- a/cassandane/Cassandane/Instance.pm
+++ b/Cassandane/Util/Log.pm +++ b/cassandane/Cassandane/Instance.pm
@@ -51,9 +51,6 @@ our @EXPORT = qw( @@ -2179,12 +2179,8 @@ sub setup_syslog_replacement
my $verbose = 0;
-openlog('cassandane', '', LOG_LOCAL6)
- or die "Cannot openlog";
-
sub xlog
{
my $id;
@@ -70,7 +67,6 @@ sub xlog
$msg .= "($id) " if $id;
$msg .= join(' ', @_);
print STDERR "$msg\n";
- syslog(LOG_ERR, "$msg");
}
sub set_verbose
diff --git a/Cassandane/Instance.pm b/Cassandane/Instance.pm
index bdfa44f..e852599 100644
--- a/Cassandane/Instance.pm
+++ b/Cassandane/Instance.pm
@@ -2030,12 +2030,8 @@ sub setup_syslog_replacement
{ {
my ($self) = @_; my ($self) = @_;
@ -39,3 +17,25 @@ index bdfa44f..e852599 100644
$self->{syslog_fname} = "$self->{basedir}/conf/log/syslog"; $self->{syslog_fname} = "$self->{basedir}/conf/log/syslog";
$self->{have_syslog_replacement} = 1; $self->{have_syslog_replacement} = 1;
diff --git a/cassandane/Cassandane/Util/Log.pm b/cassandane/Cassandane/Util/Log.pm
index 2720801..73ae390 100644
--- a/cassandane/Cassandane/Util/Log.pm
+++ b/cassandane/Cassandane/Util/Log.pm
@@ -52,9 +52,6 @@ our @EXPORT = qw(
my $verbose = 0;
-openlog('cassandane', '', LOG_LOCAL6)
- or die "Cannot openlog";
-
sub xlog
{
my $id;
@@ -89,7 +86,6 @@ sub xlog
else {
print STDERR "$msg\n";
}
- syslog(LOG_ERR, "$msg");
}
sub set_verbose

View File

@ -1,78 +0,0 @@
diff --git a/Cassandane/Cyrus/Flags.pm b/Cassandane/Cyrus/Flags.pm
index a61d256..eedaf40 100644
--- a/Cassandane/Cyrus/Flags.pm
+++ b/Cassandane/Cyrus/Flags.pm
@@ -239,6 +239,73 @@ sub test_seen_otheruser
$self->check_messages(\%msg);
}
+# https://github.com/cyrusimap/cyrus-imapd/issues/3240
+sub test_seen_sharedmb_nosharedseen
+ :UnixHierarchySep :AltNamespace
+{
+ my ($self) = @_;
+
+ my $folder = 'shared';
+
+ # shared mailbox with sharedseen=false
+ my $admintalk = $self->{adminstore}->get_client();
+ $admintalk->create($folder);
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+ $admintalk->setacl('shared', 'cassandane' => 'lrswipkxtecdan');
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+ $admintalk->setmetadata($folder,
+ '/shared/vendor/cmu/cyrus-imapd/sharedseen' => 'false'
+ );
+ $self->assert_str_equals('ok', $admintalk->get_last_completion_response());
+
+
+ # add some messages
+ my $talk = $self->{store}->get_client();
+ $self->{store}->set_folder("Shared Folders/$folder");
+ $self->{store}->_select();
+ $self->assert_num_equals(1, $talk->uid());
+ $self->{store}->set_fetch_attributes(qw(uid flags));
+
+ xlog $self, "Add two messages";
+ my %msg;
+ $msg{A} = $self->make_message('Message A');
+ $msg{A}->set_attributes(id => 1,
+ uid => 1,
+ flags => []);
+ $msg{B} = $self->make_message('Message B');
+ $msg{B}->set_attributes(id => 2,
+ uid => 2,
+ flags => []);
+ $self->check_messages(\%msg);
+
+ # fiddle with seen flag, making sure we get both the expected results
+ # and the expected untagged fetch response
+ xlog $self, "Set \\Seen on message A";
+ my $res = $talk->store('1', '+flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [ '\\Seen' ] }}, $res);
+ $msg{A}->set_attribute(flags => ['\\Seen']);
+ $self->check_messages(\%msg);
+
+ xlog $self, "Clear \\Seen on message A";
+ $res = $talk->store('1', '-flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [] }}, $res);
+ $msg{A}->set_attribute(flags => []);
+ $self->check_messages(\%msg);
+
+ xlog $self, "Set \\Seen on message A again";
+ $res = $talk->store('1', '+flags', '(\\Seen)');
+ $self->assert_deep_equals({ '1' => { 'flags' => [ '\\Seen' ] }}, $res);
+ $msg{A}->set_attribute(flags => ['\\Seen']);
+ $self->check_messages(\%msg);
+
+ # seen flag should survive a reconnect
+ xlog $self, "Reconnect, \\Seen should still be on message A";
+ $self->{store}->disconnect();
+ $self->{store}->connect();
+ $self->{store}->_select();
+ $self->check_messages(\%msg);
+}
+
#
# Test that
# - the \Flagged flag can be set

View File

@ -1,170 +0,0 @@
diff --git a/imap/http_dav.c b/imap/http_dav.c
index d5f7c114a2..abc6da42ca 100644
--- a/imap/http_dav.c
+++ b/imap/http_dav.c
@@ -6108,7 +6108,7 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
xmlDocPtr indoc = NULL, outdoc = NULL;
xmlNodePtr root, cur = NULL, props = NULL;
xmlNsPtr ns[NUM_NAMESPACE];
- struct hash_table ns_table = { 0, NULL, NULL };
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
struct propfind_ctx fctx;
memset(&fctx, 0, sizeof(struct propfind_ctx));
@@ -8083,7 +8083,7 @@ int meth_report(struct transaction_t *txn, void *params)
xmlNodePtr inroot = NULL, outroot = NULL, cur, prop = NULL, props = NULL;
const struct report_type_t *report = NULL;
xmlNsPtr ns[NUM_NAMESPACE];
- struct hash_table ns_table = { 0, NULL, NULL };
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
struct propfind_ctx fctx;
memset(&fctx, 0, sizeof(struct propfind_ctx));
diff --git a/imap/jmap_mail.c b/imap/jmap_mail.c
index 7f2d9cb563..84845d273b 100644
--- a/imap/jmap_mail.c
+++ b/imap/jmap_mail.c
@@ -4334,7 +4334,7 @@ static void _email_querychanges_collapsed(jmap_req_t *req,
memset(&touched_ids, 0, sizeof(hash_table));
construct_hash_table(&touched_ids, mdcount + 1, 0);
- hashu64_table touched_cids = HASH_TABLE_INITIALIZER;
+ hashu64_table touched_cids = HASHU64_TABLE_INITIALIZER;
memset(&touched_cids, 0, sizeof(hashu64_table));
construct_hashu64_table(&touched_cids, mdcount + 1, 0);
diff --git a/lib/hash.c b/lib/hash.c
index 639b6997e6..593f1bf968 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -43,10 +43,11 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us
assert(table);
assert(size);
- table->size = size;
+ table->size = size;
+ table->seed = rand(); /* might be zero, that's okay */
/* Allocate the table -- different for using memory pools and not */
- if(use_mpool) {
+ if (use_mpool) {
/* Allocate an initial memory pool for 32 byte keys + the hash table
* + the buckets themselves */
table->pool =
@@ -72,7 +73,7 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us
EXPORTED void *hash_insert(const char *key, void *data, hash_table *table)
{
- unsigned val = strhash(key) % table->size;
+ unsigned val = strhash_seeded(table->seed, key) % table->size;
bucket *ptr, *newptr;
bucket **prev;
@@ -159,7 +160,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
if (!table->size)
return NULL;
- val = strhash(key) % table->size;
+ val = strhash_seeded(table->seed, key) % table->size;
if (!(table->table)[val])
return NULL;
@@ -183,7 +184,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
* since it will leak memory until you get rid of the entire hash table */
EXPORTED void *hash_del(const char *key, hash_table *table)
{
- unsigned val = strhash(key) % table->size;
+ unsigned val = strhash_seeded(table->seed, key) % table->size;
bucket *ptr, *last = NULL;
if (!(table->table)[val])
diff --git a/lib/hash.h b/lib/hash.h
index e49037d614..e476de77da 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -3,10 +3,11 @@
#define HASH__H
#include <stddef.h> /* For size_t */
+#include <stdint.h>
#include "mpool.h"
#include "strarray.h"
-#define HASH_TABLE_INITIALIZER {0, NULL, NULL}
+#define HASH_TABLE_INITIALIZER {0, 0, NULL, NULL}
/*
** A hash table consists of an array of these buckets. Each bucket
@@ -32,6 +33,7 @@ typedef struct bucket {
typedef struct hash_table {
size_t size;
+ uint32_t seed;
bucket **table;
struct mpool *pool;
} hash_table;
diff --git a/lib/strhash.c b/lib/strhash.c
index d7c1741d2a..1b3251db73 100644
--- a/lib/strhash.c
+++ b/lib/strhash.c
@@ -42,17 +42,32 @@
#include "config.h"
-EXPORTED unsigned strhash(const char *string)
+#include "lib/strhash.h"
+
+/* The well-known djb2 algorithm (e.g. http://www.cse.yorku.ca/~oz/hash.html),
+ * with the addition of an optional seed to limit predictability.
+ *
+ * XXX return type 'unsigned' for back-compat to previous version, but
+ * XXX ought to be 'uint32_t'
+ */
+EXPORTED unsigned strhash_seeded_djb2(uint32_t seed, const char *string)
{
- unsigned ret_val = 0;
- int i;
+ const unsigned char *ustr = (const unsigned char *) string;
+ unsigned hash = 5381;
+ int c;
- while (*string)
- {
- i = (int) *string;
- ret_val ^= i;
- ret_val <<= 1;
- string ++;
- }
- return ret_val;
+ if (seed) {
+ /* treat the bytes of the seed as a prefix to the string */
+ unsigned i;
+ for (i = 0; i < sizeof seed; i++) {
+ c = seed & 0xff;
+ hash = ((hash << 5) + hash) ^ c;
+ seed >>= 8;
+ }
+ }
+
+ while ((c = *ustr++))
+ hash = ((hash << 5) + hash) ^ c;
+
+ return hash;
}
diff --git a/lib/strhash.h b/lib/strhash.h
index 34533fdffa..27339bb288 100644
--- a/lib/strhash.h
+++ b/lib/strhash.h
@@ -41,7 +41,11 @@
*/
#ifndef _STRHASH_H_
+#include <stdint.h>
-unsigned strhash(const char *string);
+unsigned strhash_seeded_djb2(uint32_t seed, const char *string);
+
+#define strhash(in) strhash_seeded_djb2((0), (in))
+#define strhash_seeded(sd, in) strhash_seeded_djb2((sd), (in))
#endif /* _STRHASH_H_ */

View File

@ -1,25 +0,0 @@
commit a8ccdaf109b85cedfd609678d95f7b7d5fdb91f5
Author: ellie timoney <ellie@fastmail.com>
Date: Mon Jun 7 12:00:27 2021 +1000
lmtpd: shared mailboxes don't have conversations to lock
Fixes #3488
diff --git a/imap/lmtpd.c b/imap/lmtpd.c
index 498bb8765..dc9ca21bc 100644
--- a/imap/lmtpd.c
+++ b/imap/lmtpd.c
@@ -843,8 +843,10 @@ int deliver(message_data_t *msgdata, char *authuser,
// lock conversations for the duration of delivery, so nothing else can read
// the state of any mailbox while the delivery is half done
struct conversations_state *state = NULL;
- r = conversations_open_user(mbname_userid(mbname), 0/*shared*/, &state);
- if (r) goto setstatus;
+ if (mbname_userid(mbname)) {
+ r = conversations_open_user(mbname_userid(mbname), 0/*shared*/, &state);
+ if (r) goto setstatus;
+ }
/* local mailbox */
mydata.cur_rcpt = n;

View File

@ -1,60 +0,0 @@
From 6dc8b483b5045a94e72e631a8faee388713c3c05 Mon Sep 17 00:00:00 2001
From: Bron Gondwana <brong@fastmail.fm>
Date: Wed, 21 Sep 2022 16:08:07 +1000
Subject: [PATCH] index: track changes for modseq bump when setting seen on
shared folders
---
imap/index.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/imap/index.c b/imap/index.c
index af06e94e6..5c96216ad 100644
--- a/imap/index.c
+++ b/imap/index.c
@@ -4778,6 +4778,7 @@ static int index_storeflag(struct index_state *state,
int dirty = 0;
modseq_t oldmodseq;
struct index_map *im = &state->map[msgno-1];
+ int seen_dirty = 0;
int r;
memset(modified_flags, 0, sizeof(struct index_modified_flags));
@@ -4803,6 +4804,7 @@ static int index_storeflag(struct index_state *state,
im->isseen = new;
state->seen_dirty = 1;
dirty++;
+ seen_dirty = 1;
}
}
@@ -4925,6 +4927,7 @@ static int index_storeflag(struct index_state *state,
else
system_flags &= ~FLAG_SEEN;
}
+
/* add back the internal tracking flags */
system_flags |= keep;
@@ -4942,6 +4945,18 @@ static int index_storeflag(struct index_state *state,
r = msgrecord_set_userflags(msgrec, user_flags);
if (r) return r;
+ // patch back in seen state for non-internal-seen
+ if (seen_dirty && !state->internalseen) {
+ if (im->isseen) {
+ modified_flags->added_system_flags |= FLAG_SEEN;
+ modified_flags->added_flags++;
+ }
+ else {
+ modified_flags->removed_system_flags |= FLAG_SEEN;
+ modified_flags->removed_flags++;
+ }
+ }
+
/* if it's silent and unchanged, update the seen value, but
* not if qresync is enabled - RFC 4551 says that the MODSEQ
* must always been told, and we prefer just to tell flags
--
2.43.0

View File

@ -7,7 +7,7 @@ index 46dc358..ca37f22 100644
/* Each test gets a maximum of 20 seconds. */ /* Each test gets a maximum of 20 seconds. */
-#define TEST_TIMEOUT_MS (20*1000) -#define TEST_TIMEOUT_MS (20*1000)
+#define TEST_TIMEOUT_MS (30*1000) +#define TEST_TIMEOUT_MS (300*1000)
static jmp_buf jbuf; static jmp_buf jbuf;
static const char *code; static const char *code;

View File

@ -1,4 +1,2 @@
SHA512 (cassandane-693da61.tar.gz) = 63f381bdd1404a90a029610b08e2a0ad621203eabae441f457821cecfd769f5c30acaeb997ab83adfb8c77ce630b9655baeca1079ca5fbec84bf01c0ae6e8863 SHA512 (cyrus-imapd-3.4.8.tar.gz) = 173686c02dfbfe13cb9e7634f7b9bee3a222227ad90f43b49575dcf0caadf08f8e2f893ee8c6961a227b0545c31cc3857a8246eef7af714b28ec7cae5d516a21
SHA512 (cassandane-testdata-ca669d4b.tar.gz) = c153ab0a57d04d9deeabc5ef724eaecc05030c23b170abaa44eaea2e7df409efcdeb24871f7896759e85d64193fb9f289a470b0af9a593a740ffcc45c80033ff SHA512 (cyrus-imapd-3.4.8.tar.gz.sig) = f618e74bdbdd6983fce457fdc70043c950eefaa276f80528b7e0cd2cfb7aca2d686792635fb3f289d039759d288b222834ec2a3a07df270357706c8a1240c0e9
SHA512 (cyrus-imapd-3.4.1.tar.gz) = 9fd13e93755aca98215c1bd9c21fa3ef3a3db8b1ff48f71dd6070e614e9c68cb591b1cb411fa1319d46ab1d49ddc971f188a41cc0c9a2e2c9df0cc08299f8bfa
SHA512 (cyrus-manpages-3.2.6.tar.gz) = b1ce700707e8c2848125ecb2a4203ac93bde42582055dcb0d30124dd8601a9564e87069264b14cff95ff5c5cf5810682c8c523c907f3167c8923580c8be3e805