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);