diff --git a/Makefile.am b/Makefile.am
index 2f3022bb..98390b9e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,89 +1,91 @@
# Makefile.am - Installer for GnuPG 4 Windows Makefile.
# Copyright (C) 2005, 2008, 2012 g10 Code GmbH
#
# This file is part of GPG4Win.
#
# GPG4Win is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# GPG4Win is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip
DISTCHECK_CONFIGURE_FLAGS = --host=i686-w64-mingw32
SUBDIRS = po packages doc src
# find patches -type f | sort | sed 's/$/ \\/' | sed 's/^/ /'
EXTRA_DIST = autogen.sh README.GIT ONEWS \
doc/license-page doc/GPLv3 \
build-aux/git-log-footer build-aux/git-log-fix \
patches/boost/boost-1-fixes.patch \
patches/extra-cmake-modules/0001-Use-BIN_INSTALL_DIR-data-for-DATAROOTDIR-on-Windows.patch \
patches/glib-2.41.5/01-socket.patch \
patches/glib-2.41.5/02-formatsec.patch \
patches/kconfigwidgets/0001-Make-QDbus-optional.patch \
patches/kiconthemes/0001-Make-DBus-optional.patch \
patches/kleopatra/0005-Hack-generated-conf-files-for-Crosscompiling.patch \
patches/kleopatra/fix-qt5.6-build.patch \
patches/kleopatra/0001-Allow-build-with-older-KWindowsystem-versions.patch \
patches/kleopatra/allow-older-kde-frameworks.patch \
patches/kxmlgui/0001-make-qdbus-optional.patch \
patches/kxmlgui/0003-Make-KTextWidgets-optional.patch \
patches/kxmlgui/0004-Cruedly-disable-KSendbugmail.patch \
patches/libgpg-error-1.29/0001-doc-Fix-yat2m-build-for-cross-compilation.patch \
patches/qtbase/config-standardpaths.patch \
patches/qtbase/qtbase-mingw-fixes.patch \
patches/qtbase/relative-paths.patch \
patches/qttools/disable-most-tools.patch \
patches/qtwinextras/support-xp.patch \
patches/w32pth-2.0.5/workaround-broken-libtool.patch \
- patches/breeze-icons/0001-Make-binary-icons-cross-compilable.patch
+ patches/breeze-icons/0001-Make-binary-icons-cross-compilable.patch \
+ patches/libkleo/revert-some-string-changes.patch \
+ patches/gpgol/0001-Fix-check-for-plain-text-attachments.patch
copy-news:
cp NEWS doc/website/NEWS.last
copy-release: gpg4win-$(VERSION).tar.bz2 installers/gpg4win-$(VERSION).exe \
installers/gpg4win-light-$(VERSION).exe \
installers/gpg4win-vanilla-$(VERSION).exe
@echo Copying $(VERSION) to $(RELEASEHOST) >&2
@set -e;\
if ssh "$$(echo $(RELEASEHOST)|cut -d: -f -1)" \
test -f "$$(echo $(RELEASEHOST)/gpg4win-$(VERSION).exe|cut -d: -f2-)";\
then echo "This release has already been copied to the server" >&2 ;\
else scp gpg4win-$(VERSION).tar.bz2 \
installers/gpg4win-$(VERSION).exe \
installers/gpg4win-light-$(VERSION).exe \
installers/gpg4win-vanilla-$(VERSION).exe \
installers/gpg4win-src-$(VERSION).exe $(RELEASEHOST)/ ;\
for f in en de ; do \
scp src/README.$$f.txt \
$(RELEASEHOST)/README-$(VERSION).$$f.txt; \
done;\
fi
dist-hook: gen-ChangeLog
gen_start_date = 2012-03-26T00:00:00
.PHONY: gen-ChangeLog
gen-ChangeLog:
set -e; \
if test -d $(top_srcdir)/.git; then \
(cd $(top_srcdir) && \
$(GITLOG_TO_CHANGELOG) --append-dot --tear-off \
--amend=build-aux/git-log-fix \
--since=$(gen_start_date) ) > $(distdir)/cl-t; \
cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
rm -f $(distdir)/ChangeLog; \
mv $(distdir)/cl-t $(distdir)/ChangeLog; \
fi
diff --git a/patches/gpgol/0001-Fix-check-for-plain-text-attachments.patch b/patches/gpgol/0001-Fix-check-for-plain-text-attachments.patch
new file mode 100644
index 00000000..392dcc7d
--- /dev/null
+++ b/patches/gpgol/0001-Fix-check-for-plain-text-attachments.patch
@@ -0,0 +1,202 @@
+#! /bin/sh
+patch -p1 -l -f $* < $0
+exit $?
+
+From bbd6f516545deead2de72adc79ddf2c5706a7836 Mon Sep 17 00:00:00 2001
+From: Andre Heinecke
+Date: Mon, 16 Dec 2019 16:31:05 +0100
+Subject: [PATCH] Fix check for plain text attachments
+
+* src/mail.cpp (Mail::checkAttachments_o): Use
+count_visible_attachments.
+(Mail::close): Fix safeguard check.
+* src/oomhelp.cpp (count_visible_attachments): New.
+* src/oomhelp.h: Add prototype.
+
+--
+The change in 0d2db8b81ab24e2ab02d7ba6832cabd07b72f852
+introduced a big problem in the check for Mail::close
+which then allowed writes to pass that should have
+been prevented. This resulted in plaintext being written.
+---
+ src/mail.cpp | 72 +++++--------------------------------------------
+ src/oomhelp.cpp | 38 ++++++++++++++++++++++++++
+ src/oomhelp.h | 3 +++
+ 3 files changed, 48 insertions(+), 65 deletions(-)
+
+diff --git a/src/mail.cpp b/src/mail.cpp
+index e1d8b06..b2006dd 100644
+--- a/src/mail.cpp
++++ b/src/mail.cpp
+@@ -405,39 +405,13 @@ Mail::checkAttachments_o (bool silent)
+ SRCNAME, __func__);
+ TRETURN 1;
+ }
+- int count = get_oom_int (attachments, "Count");
++ int count = count_visible_attachments (attachments);
+ if (!count)
+ {
+ gpgol_release (attachments);
+ TRETURN 0;
+ }
+
+- /* Saveguard not to warn about our own attachment */
+- if (count == 1)
+- {
+- LPDISPATCH oom_attach = get_oom_object (attachments, "Item(1)");
+- if (oom_attach)
+- {
+- char *dispName = get_oom_string (oom_attach, "DisplayName");
+- gpgol_release (oom_attach);
+-
+- if (dispName && !strcmp (dispName, MIMEATTACHFILENAME))
+- {
+- xfree (dispName);
+- gpgol_release (attachments);
+- log_debug ("%s:%s: Found only our hidden mime structure.",
+- SRCNAME, __func__);
+- TRETURN 0;
+- }
+- else if (dispName)
+- {
+- log_debug ("%s:%s: Found %s as attachment.",
+- SRCNAME, __func__, anonstr (dispName));
+- xfree (dispName);
+- }
+- }
+- }
+-
+ std::string message;
+
+ if (isEncrypted () && isSigned ())
+@@ -2288,6 +2262,7 @@ Mail::closeInspector_o (Mail *mail)
+ TRETURN 0;
+ }
+
++
+ int
+ Mail::close (bool restoreSMIMEClass)
+ {
+@@ -2451,57 +2426,24 @@ Mail::close (bool restoreSMIMEClass)
+ * */
+ char *body = get_oom_string (m_mailitem, "Body");
+ LPDISPATCH attachments = get_oom_object (m_mailitem, "Attachments");
+- int att_count = 0;
+- if (attachments)
+- {
+- att_count = get_oom_int (attachments, "Count");
+- }
+
+- bool foundOne = false;
+ if (body && strlen (body))
+ {
+ log_debug ("%s:%s: Close successful. But body found. "
+ "Mail still open.",
+ SRCNAME, __func__);
+ }
+- else if (att_count)
++ else if (count_visible_attachments (attachments))
+ {
+- for (int i = 1; i <= att_count && !foundOne; i++)
+- {
+- std::string item_str;
+- item_str = std::string("Item(") + std::to_string (i) + ")";
+- LPDISPATCH oom_attach = get_oom_object (attachments, item_str.c_str ());
+- if (!oom_attach)
+- {
+- log_error ("%s:%s: Failed to get attachment.",
+- SRCNAME, __func__);
+- continue;
+- }
+- VARIANT var;
+- VariantInit (&var);
+- if (get_pa_variant (oom_attach, PR_ATTACHMENT_HIDDEN_DASL, &var) ||
+- (var.vt == VT_BOOL && var.boolVal == VARIANT_FALSE))
+- {
+- foundOne = true;
+- }
+- else
+- {
+- gpgol_release (oom_attach);
+- }
+- VariantClear (&var);
+- }
+- if (foundOne)
+- {
+ log_debug ("%s:%s: Close successful. But attachments found. "
+ "Mail still open.",
+ SRCNAME, __func__);
+- }
+ }
+- if (!foundOne)
++ else
+ {
+- setPassWrite (true);
+- log_debug ("%s:%s: Close successful. Next write may pass.",
+- SRCNAME, __func__);
++ setPassWrite (true);
++ log_debug ("%s:%s: Close successful. Next write may pass.",
++ SRCNAME, __func__);
+ }
+ gpgol_release (attachments);
+ xfree (body);
+diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
+index 415c256..d47d26d 100644
+--- a/src/oomhelp.cpp
++++ b/src/oomhelp.cpp
+@@ -3095,3 +3095,41 @@ format_dispparams (DISPPARAMS *p)
+ }
+ return stream.str ();
+ }
++
++int
++count_visible_attachments (LPDISPATCH attachments)
++{
++ int ret = 0;
++
++ if (!attachments)
++ {
++ return 0;
++ }
++
++ int att_count = get_oom_int (attachments, "Count");
++ for (int i = 1; i <= att_count; i++)
++ {
++ std::string item_str;
++ item_str = std::string("Item(") + std::to_string (i) + ")";
++ LPDISPATCH oom_attach = get_oom_object (attachments, item_str.c_str ());
++ if (!oom_attach)
++ {
++ log_error ("%s:%s: Failed to get attachment.",
++ SRCNAME, __func__);
++ continue;
++ }
++ VARIANT var;
++ VariantInit (&var);
++ if (get_pa_variant (oom_attach, PR_ATTACHMENT_HIDDEN_DASL, &var) ||
++ (var.vt == VT_BOOL && var.boolVal == VARIANT_FALSE))
++ {
++ ret++;
++ }
++ else
++ {
++ gpgol_release (oom_attach);
++ }
++ VariantClear (&var);
++ }
++ return ret;
++}
+diff --git a/src/oomhelp.h b/src/oomhelp.h
+index 9af0fe6..77264f1 100644
+--- a/src/oomhelp.h
++++ b/src/oomhelp.h
+@@ -440,4 +440,7 @@ bool is_draft_mail (LPDISPATCH mailitem);
+ /* Returns info about a dispparms variable for debugging. */
+ void format_variant (std::istringstream &stream, VARIANT *var);
+ std::string format_dispparams (DISPPARAMS *p);
++
++/* Returns the count of attachments that are not hidden. */
++int count_visible_attachments (LPDISPATCH attachments);
+ #endif /*OOMHELP_H*/
+--
+2.20.1
diff --git a/patches/libkleo/revert-some-string-changes.patch b/patches/libkleo/revert-some-string-changes.patch
new file mode 100755
index 00000000..b6bf3e92
--- /dev/null
+++ b/patches/libkleo/revert-some-string-changes.patch
@@ -0,0 +1,87 @@
+#! /bin/sh
+patch -p1 -l -f -R $* < $0
+exit $?
+
+diff --git a/src/ui/auditlogviewer.cpp b/src/ui/auditlogviewer.cpp
+index b32322a..db03c37 100644
+--- a/src/ui/auditlogviewer.cpp
++++ b/src/ui/auditlogviewer.cpp
+@@ -46,7 +46,7 @@ AuditLogViewer::AuditLogViewer(const QString &log, QWidget *parent)
+ m_textEdit(new QTextEdit(this))
+ #endif
+ {
+- setWindowTitle(i18n("View GnuPG Audit Log"));
++ setWindowTitle(i18nc("@title:window", "View GnuPG Audit Log"));
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+
+ QPushButton *copyClipBtn = new QPushButton;
+diff --git a/src/ui/cryptoconfigdialog.cpp b/src/ui/cryptoconfigdialog.cpp
+index 5ac4774..cfce3d5 100644
+--- a/src/ui/cryptoconfigdialog.cpp
++++ b/src/ui/cryptoconfigdialog.cpp
+@@ -42,7 +42,7 @@
+ Kleo::CryptoConfigDialog::CryptoConfigDialog(QGpgME::CryptoConfig *config, QWidget *parent)
+ : QDialog(parent)
+ {
+- setWindowTitle(i18n("Configure GnuPG Backend"));
++ setWindowTitle(i18nc("@title:window", "Configure GnuPG Backend"));
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults | QDialogButtonBox::Apply, this);
+ QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
+diff --git a/src/ui/cryptoconfigmodule.cpp b/src/ui/cryptoconfigmodule.cpp
+index 4d891c3..77a1b1e 100644
+--- a/src/ui/cryptoconfigmodule.cpp
++++ b/src/ui/cryptoconfigmodule.cpp
+@@ -831,7 +831,7 @@ void Kleo::CryptoConfigEntryLDAPURL::slotOpenDialog()
+ // I'm a bad boy and I do it all on the stack. Enough classes already :)
+ // This is just a simple dialog around the directory-services-widget
+ QDialog dialog(mPushButton->parentWidget());
+- dialog.setWindowTitle(i18n("Configure LDAP Servers"));
++ dialog.setWindowTitle(i18nc("@title:window", "Configure LDAP Servers"));
+
+ DirectoryServicesWidget *dirserv = new DirectoryServicesWidget(&dialog);
+
+@@ -958,7 +958,7 @@ void Kleo::CryptoConfigEntryKeyserver::slotOpenDialog()
+ // I'm a bad boy and I do it all on the stack. Enough classes already :)
+ // This is just a simple dialog around the directory-services-widget
+ QDialog dialog(mPushButton->parentWidget());
+- dialog.setWindowTitle(i18n("Configure Keyservers"));
++ dialog.setWindowTitle(i18nc("@title:window", "Configure Keyservers"));
+
+ DirectoryServicesWidget *dirserv = new DirectoryServicesWidget(&dialog);
+
+diff --git a/src/ui/keyapprovaldialog.cpp b/src/ui/keyapprovaldialog.cpp
+index 968daba..9849866 100644
+--- a/src/ui/keyapprovaldialog.cpp
++++ b/src/ui/keyapprovaldialog.cpp
+@@ -108,7 +108,7 @@ Kleo::KeyApprovalDialog::KeyApprovalDialog(const std::vector- &recipients,
+ : QDialog(parent),
+ d(new Private())
+ {
+- setWindowTitle(i18n("Encryption Key Approval"));
++ setWindowTitle(i18nc("@title:window", "Encryption Key Approval"));
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+diff --git a/src/ui/newkeyapprovaldialog.cpp b/src/ui/newkeyapprovaldialog.cpp
+index 43ee1e8..22a56f7 100644
+--- a/src/ui/newkeyapprovaldialog.cpp
++++ b/src/ui/newkeyapprovaldialog.cpp
+@@ -264,7 +264,7 @@ public:
+ mScrollArea->setFrameStyle(QFrame::NoFrame);
+ mScrollLayout->setContentsMargins(0, 0, 0, 0);
+
+- q->setWindowTitle(i18n("Security approval"));
++ q->setWindowTitle(i18nc("@title:window", "Security approval"));
+
+ auto fmtLayout = new QHBoxLayout;
+ mFormatBtns = new QButtonGroup;
+@@ -326,7 +326,7 @@ public:
+ auto progress = new Kleo::ProgressDialog(job, i18n("Generating key for '%1'...", addr) + QStringLiteral("\n\n") +
+ i18n("This can take several minutes."), q);
+ progress->setWindowFlags(progress->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+- progress->setWindowTitle(i18n("Key generation"));
++ progress->setWindowTitle(i18nc("@title:window", "Key generation"));
+ progress->setModal(true);
+ progress->setAutoClose(true);
+ progress->setMinimumDuration(0);