Page MenuHome GnuPG

No OneTemporary

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e421007c..f0f160985 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,279 +1,280 @@
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
set(RELEASE_SERVICE_VERSION_MAJOR "23")
set(RELEASE_SERVICE_VERSION_MINOR "07")
set(RELEASE_SERVICE_VERSION_MICRO "70")
# The RELEASE_SERVICE_VERSION is used by Gpg4win to add the Gpg4win version
if (NOT RELEASE_SERVICE_VERSION)
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
endif()
if(RELEASE_SERVICE_VERSION_MICRO LESS 10)
set(KDE_APPLICATIONS_COMPACT_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}${RELEASE_SERVICE_VERSION_MINOR}0${RELEASE_SERVICE_VERSION_MICRO}")
else()
set(KDE_APPLICATIONS_COMPACT_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}${RELEASE_SERVICE_VERSION_MINOR}${RELEASE_SERVICE_VERSION_MICRO}")
endif()
set(KLEOPATRA_VERSION_MAJOR "3")
set(KLEOPATRA_VERSION_MINOR "1")
set(KLEOPATRA_VERSION_MICRO "26")
set(kleopatra_version "${KLEOPATRA_VERSION_MAJOR}.${KLEOPATRA_VERSION_MINOR}.${KLEOPATRA_VERSION_MICRO}.${KDE_APPLICATIONS_COMPACT_VERSION}")
# The following is for Windows
set(kleopatra_version_win "${KLEOPATRA_VERSION_MAJOR}.${KLEOPATRA_VERSION_MINOR}.${KLEOPATRA_VERSION_MICRO}")
set(kleopatra_fileversion_win "${KLEOPATRA_VERSION_MAJOR},${KLEOPATRA_VERSION_MINOR},${KLEOPATRA_VERSION_MICRO},0")
if (NOT KLEOPATRA_DISTRIBUTION_TEXT)
# This is only used on Windows for the file attributes of Kleopatra
set(KLEOPATRA_DISTRIBUTION_TEXT "KDE")
endif()
project(kleopatra VERSION ${kleopatra_version})
option(DISABLE_KWATCHGNUPG "Don't build the kwatchgnupg tool [default=OFF]" OFF)
# Standalone build. Find / include everything necessary.
set(KF_MIN_VERSION "5.104.0")
set(KIDENTITYMANAGEMENT_VERSION "5.23.40")
set(KMAILTRANSPORT_VERSION "5.23.40")
set(KMIME_VERSION "5.23.40")
set(LIBKLEO_VERSION "5.23.40")
set(QT_REQUIRED_VERSION "5.15.2")
if (QT_MAJOR_VERSION STREQUAL "6")
set(QT_REQUIRED_VERSION "6.4.0")
endif()
set(GPGME_REQUIRED_VERSION "1.16.0")
set(LIBASSUAN_REQUIRED_VERSION "2.4.2")
set(GPG_ERROR_REQUIRED_VERSION "1.36")
if (WIN32)
set(KF5_WANT_VERSION "5.70.0")
set(KMIME_WANT_VERSION "5.12.0")
else ()
set(KF5_WANT_VERSION ${KF_MIN_VERSION})
set(KMIME_WANT_VERSION ${KMIME_VERSION})
endif ()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF5_WANT_VERSION} CONFIG REQUIRED)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
include(ECMInstallIcons)
include(ECMSetupVersion)
include(ECMAddTests)
include(GenerateExportHeader)
include(ECMGenerateHeaders)
include(FeatureSummary)
include(CheckFunctionExists)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMAddAppIcon)
include(ECMQtDeclareLoggingCategory)
include(ECMDeprecationSettings)
include(KDEClangFormat)
if (QT_MAJOR_VERSION STREQUAL "6")
set(QT_REQUIRED_VERSION "6.4.0")
set(KF_MIN_VERSION "5.240.0")
set(KF_MAJOR_VERSION "6")
else()
set(KF_MIN_VERSION "5.104.0")
set(KF_MAJOR_VERSION "5")
endif()
# Find KF5 packages
find_package(KF${KF_MAJOR_VERSION} ${KF5_WANT_VERSION}
REQUIRED COMPONENTS
Codecs
Config
ConfigWidgets
CoreAddons
Crash
I18n
IconThemes
ItemModels
+ KIO
WidgetsAddons
WindowSystem
XmlGui
OPTIONAL_COMPONENTS
DocTools
)
set_package_properties(KF${KF_MAJOR_VERSION}DocTools PROPERTIES
DESCRIPTION "Documentation tools"
PURPOSE "Required to generate Kleopatra documentation."
TYPE OPTIONAL)
# Optional packages
if (WIN32)
# Only a replacement available for Windows so this
# is required on other platforms.
find_package(KF${KF_MAJOR_VERSION}DBusAddons ${KF5_WANT_VERSION} CONFIG)
set_package_properties(KF${KF_MAJOR_VERSION}DBusAddons PROPERTIES DESCRIPTION "Support library to work with DBus"
PURPOSE "DBus session integration"
URL "https://inqlude.org/libraries/kdbusaddons.html"
TYPE OPTIONAL)
else()
find_package(KF${KF_MAJOR_VERSION}DBusAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
set(_kleopatra_dbusaddons_libs KF${KF_MAJOR_VERSION}::DBusAddons)
endif()
set(HAVE_QDBUS ${Qt${QT_MAJOR_VERSION}DBus_FOUND})
find_package(Gpgmepp ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
if (Gpgmepp_VERSION VERSION_GREATER_EQUAL "1.19.0")
set(GPGMEPP_SUPPORTS_SET_CURVE 1)
endif()
if (QT_MAJOR_VERSION STREQUAL "6")
find_package(QGpgmeQt6 ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
else()
find_package(QGpgme ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
endif()
if (QGpgme_VERSION VERSION_GREATER_EQUAL "1.17.0")
set(QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY 1)
set(QGPGME_CRYPTOCONFIGENTRY_HAS_DEFAULT_VALUE 1)
set(QGPGME_SUPPORTS_WKDLOOKUP 1)
set(QGPGME_SUPPORTS_IMPORT_WITH_FILTER 1)
set(QGPGME_SUPPORTS_IMPORT_WITH_KEY_ORIGIN 1)
set(QGPGME_SUPPORTS_SECRET_KEY_EXPORT 1)
set(QGPGME_SUPPORTS_SECRET_SUBKEY_EXPORT 1)
set(QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID 1)
endif()
if (QGpgme_VERSION VERSION_GREATER_EQUAL "1.18.0")
set(QGPGME_SUPPORTS_KEY_REVOCATION 1)
set(QGPGME_SUPPORTS_KEY_REFRESH 1)
set(QGPGME_SUPPORTS_SET_FILENAME 1)
set(QGPGME_SUPPORTS_SET_PRIMARY_UID 1)
endif()
if (QGpgme_VERSION VERSION_GREATER_EQUAL "1.19.0")
set(QGPGME_SUPPORTS_DEFERRED_IMPORT_JOB 1)
set(QGPGME_SUPPORTS_ARCHIVE_JOBS 1)
set(QGPGME_JOB_HAS_NEW_PROGRESS_SIGNALS 1)
endif()
if (QT_MAJOR_VERSION STREQUAL "6")
find_package(Qt6Core5Compat)
endif()
# Kdepimlibs packages
find_package(KPim${KF_MAJOR_VERSION}Libkleo ${LIBKLEO_VERSION} CONFIG REQUIRED)
find_package(KPim${KF_MAJOR_VERSION}Mime ${KMIME_WANT_VERSION} CONFIG REQUIRED)
find_package(KPim${KF_MAJOR_VERSION}IdentityManagement ${KIDENTITYMANAGEMENT_VERSION} CONFIG)
find_package(KPim${KF_MAJOR_VERSION}MailTransport ${KMAILTRANSPORT_VERSION} CONFIG)
find_package(KPim${KF_MAJOR_VERSION}MailTransportAkonadi ${KMAILTRANSPORT_VERSION} CONFIG)
find_package(Qt${QT_MAJOR_VERSION} ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test Network PrintSupport)
find_package(LibAssuan ${LIBASSUAN_REQUIRED_VERSION} REQUIRED)
set_package_properties(LibAssuan PROPERTIES
TYPE REQUIRED
PURPOSE "Needed for Kleopatra to act as the GnuPG UI Server"
)
find_package(LibGpgError ${GPG_ERROR_REQUIRED_VERSION} REQUIRED)
set_package_properties(LibGpgError PROPERTIES
TYPE REQUIRED
)
set(kleopatra_release FALSE)
if(NOT kleopatra_release)
find_package(Git)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE rc
ERROR_QUIET)
if(rc EQUAL 0)
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --oneline --format=%h ${CMAKE_CURRENT_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE Kleopatra_WC_REVISION)
string(REGEX REPLACE "\n" "" Kleopatra_WC_REVISION "${Kleopatra_WC_REVISION}")
execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --oneline --format=%cI ${CMAKE_CURRENT_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE Kleopatra_WC_LAST_CHANGED_DATE)
string(REGEX REPLACE "^([0-9]+)-([0-9]+)-([0-9]+)T([0-9]+):([0-9]+):([0-9]+).*$" "\\1\\2\\3T\\4\\5\\6"
Kleopatra_WC_LAST_CHANGED_DATE "${Kleopatra_WC_LAST_CHANGED_DATE}")
set(kleopatra_version "${kleopatra_version}+git${Kleopatra_WC_LAST_CHANGED_DATE}~${Kleopatra_WC_REVISION}")
endif()
endif()
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version-kleopatra.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version-kleopatra.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-kleopatra.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kleopatra.h)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
if (WIN32)
# On Windows, we need to use stuff deprecated since Qt 5.11, e.g. from QDesktopWidget
ecm_set_disabled_deprecation_versions(QT 5.10.0 KF 5.103.0)
else ()
ecm_set_disabled_deprecation_versions(QT 6.4 KF 5.103.0)
endif ()
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-braces -Wno-parentheses -Wno-ignored-qualifiers")
endif()
if(MINGW)
# we do not care about different signedness of passed pointer arguments
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wno-pointer-sign>)
endif()
add_definitions(-DQT_NO_EMIT)
remove_definitions(-DQT_NO_FOREACH)
# Disable the use of QStringBuilder for operator+ to prevent crashes when
# returning the result of concatenating string temporaries in lambdas. We do
# this for example in some std::transform expressions.
# This is a known issue: https://bugreports.qt.io/browse/QTBUG-47066
# Alternatively, one would always have to remember to force the lambdas to
# return a QString instead of QStringBuilder, but that's just too easy to
# forget and, unfortunately, the compiler doesn't issue a warning if one forgets
# this. So, it's just too dangerous.
# One can still use QStringBuilder explicitly with the operator% if necessary.
remove_definitions(-DQT_USE_FAST_OPERATOR_PLUS)
remove_definitions(-DQT_USE_QSTRINGBUILDER)
kde_enable_exceptions()
option(USE_UNITY_CMAKE_SUPPORT "Use UNITY cmake support (speedup compile time)" OFF)
set(COMPILE_WITH_UNITY_CMAKE_SUPPORT OFF)
if (USE_UNITY_CMAKE_SUPPORT)
set(COMPILE_WITH_UNITY_CMAKE_SUPPORT ON)
endif()
add_subdirectory(pics)
add_subdirectory(src)
if(BUILD_TESTING)
add_subdirectory(tests)
add_subdirectory(autotests)
endif()
ecm_qt_install_logging_categories(
EXPORT KLEOPATRA
FILE kleopatra.categories
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)
ki18n_install(po)
if(KF${KF_MAJOR_VERSION}DocTools_FOUND)
kdoctools_install(po)
add_subdirectory(doc)
endif()
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
# add clang-format target for all our real source files
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h *.c)
kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c79220314..4e4c0dd6e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,615 +1,617 @@
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(icons)
add_subdirectory(mimetypes)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
if (NOT DISABLE_KWATCHGNUPG)
add_subdirectory(kwatchgnupg)
endif()
add_subdirectory(libkleopatraclient)
add_subdirectory(conf)
add_subdirectory(kconf_update)
if(WIN32)
set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp)
set(_kleopatra_extra_SRCS
selftest/registrycheck.cpp selftest/registrycheck.h
utils/gnupg-registry.c
utils/userinfo_win.cpp
utils/windowsprocessdevice.cpp utils/windowsprocessdevice.h
versioninfo.rc
)
else()
set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp)
set(_kleopatra_extra_SRCS)
endif()
set(_kleopatra_uiserver_SRCS
${_kleopatra_extra_uiserver_SRCS}
selftest/uiservercheck.cpp selftest/uiservercheck.h
uiserver/assuanserverconnection.cpp uiserver/assuanserverconnection.h
uiserver/createchecksumscommand.cpp uiserver/createchecksumscommand.h
uiserver/decryptverifycommandemailbase.cpp uiserver/decryptverifycommandemailbase.h
uiserver/decryptverifycommandfilesbase.cpp uiserver/decryptverifycommandfilesbase.h
uiserver/echocommand.cpp uiserver/echocommand.h
uiserver/encryptcommand.cpp uiserver/encryptcommand.h
uiserver/importfilescommand.cpp uiserver/importfilescommand.h
uiserver/prepencryptcommand.cpp uiserver/prepencryptcommand.h
uiserver/prepsigncommand.cpp uiserver/prepsigncommand.h
uiserver/selectcertificatecommand.cpp
uiserver/sessiondata.cpp uiserver/sessiondata.h
uiserver/signcommand.cpp uiserver/signcommand.h
uiserver/signencryptfilescommand.cpp
uiserver/uiserver.cpp
uiserver/verifychecksumscommand.cpp uiserver/verifychecksumscommand.h
)
set(_kleopatra_uiserver_extra_libs LibAssuan::LibAssuan LibGpgError::LibGpgError)
if(HAVE_GPG_ERR_SOURCE_KLEO)
add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
else()
add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
endif()
if(KF${KF_MAJOR_VERSION}IdentityManagement_FOUND AND KF${KF_MAJOR_VERSION}MailTransport_FOUND AND KF${KF_MAJOR_VERSION}MailTransportAkonadi_FOUND)
set(_kleopatra_mail_libs
KPim${KF_MAJOR_VERSION}::IdentityManagement # Export OpenPGP keys using WKS
KPim${KF_MAJOR_VERSION}::MailTransport
KPim${KF_MAJOR_VERSION}::MailTransportAkonadi
)
add_definitions(-DMAILAKONADI_ENABLED)
endif()
ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui)
set(_kleopatra_SRCS
${_kleopatra_extra_SRCS}
accessibility/accessiblelink.cpp
accessibility/accessiblelink_p.h
accessibility/accessiblerichtextlabel.cpp
accessibility/accessiblerichtextlabel_p.h
accessibility/accessiblevaluelabel.cpp
accessibility/accessiblevaluelabel_p.h
accessibility/accessiblewidgetfactory.cpp
accessibility/accessiblewidgetfactory.h
commands/adduseridcommand.cpp
commands/adduseridcommand.h
commands/authenticatepivcardapplicationcommand.cpp
commands/authenticatepivcardapplicationcommand.h
commands/cardcommand.cpp
commands/cardcommand.h
commands/certificatetopivcardcommand.cpp
commands/certificatetopivcardcommand.h
commands/certifycertificatecommand.cpp
commands/certifycertificatecommand.h
commands/changeexpirycommand.cpp
commands/changeexpirycommand.h
commands/changeownertrustcommand.cpp
commands/changeownertrustcommand.h
commands/changepassphrasecommand.cpp
commands/changepassphrasecommand.h
commands/changepincommand.cpp
commands/changepincommand.h
commands/changeroottrustcommand.cpp
commands/changeroottrustcommand.h
commands/checksumcreatefilescommand.cpp
commands/checksumcreatefilescommand.h
commands/checksumverifyfilescommand.cpp
commands/checksumverifyfilescommand.h
commands/clearcrlcachecommand.cpp
commands/clearcrlcachecommand.h
commands/command.cpp
commands/command.h
commands/createcsrforcardkeycommand.cpp
commands/createcsrforcardkeycommand.h
commands/createopenpgpkeyfromcardkeyscommand.cpp
commands/createopenpgpkeyfromcardkeyscommand.h
commands/decryptverifyclipboardcommand.cpp
commands/decryptverifyclipboardcommand.h
commands/decryptverifyfilescommand.cpp
commands/decryptverifyfilescommand.h
commands/deletecertificatescommand.cpp
commands/deletecertificatescommand.h
commands/detailscommand.cpp
commands/detailscommand.h
commands/dumpcertificatecommand.cpp
commands/dumpcertificatecommand.h
commands/dumpcrlcachecommand.cpp
commands/dumpcrlcachecommand.h
commands/encryptclipboardcommand.cpp
commands/encryptclipboardcommand.h
commands/exportcertificatecommand.cpp
commands/exportcertificatecommand.h
commands/exportgroupscommand.cpp
commands/exportgroupscommand.h
commands/exportopenpgpcertstoservercommand.cpp
commands/exportopenpgpcertstoservercommand.h
commands/exportopenpgpcerttoprovidercommand.cpp
commands/exportopenpgpcerttoprovidercommand.h
commands/exportpaperkeycommand.cpp
commands/exportpaperkeycommand.h
commands/exportsecretkeycommand.cpp
commands/exportsecretkeycommand.h
commands/exportsecretkeycommand_old.cpp
commands/exportsecretkeycommand_old.h
commands/exportsecretsubkeycommand.cpp
commands/exportsecretsubkeycommand.h
commands/genrevokecommand.cpp
commands/genrevokecommand.h
commands/gnupgprocesscommand.cpp
commands/gnupgprocesscommand.h
commands/importcertificatefromclipboardcommand.cpp
commands/importcertificatefromclipboardcommand.h
commands/importcertificatefromdatacommand.cpp
commands/importcertificatefromdatacommand.h
commands/importcertificatefromfilecommand.cpp
commands/importcertificatefromfilecommand.h
commands/importcertificatefromkeyservercommand.cpp
commands/importcertificatefromkeyservercommand.h
commands/importcertificatefrompivcardcommand.cpp
commands/importcertificatefrompivcardcommand.h
commands/importcertificatescommand.cpp
commands/importcertificatescommand.h
commands/importcrlcommand.cpp
commands/importcrlcommand.h
commands/importpaperkeycommand.cpp
commands/importpaperkeycommand.h
commands/keytocardcommand.cpp
commands/keytocardcommand.h
commands/learncardkeyscommand.cpp
commands/learncardkeyscommand.h
commands/lookupcertificatescommand.cpp
commands/lookupcertificatescommand.h
commands/newcertificatesigningrequestcommand.cpp
commands/newcertificatesigningrequestcommand.h
commands/newopenpgpcertificatecommand.cpp
commands/newopenpgpcertificatecommand.h
commands/openpgpgeneratecardkeycommand.cpp
commands/openpgpgeneratecardkeycommand.h
commands/pivgeneratecardkeycommand.cpp
commands/pivgeneratecardkeycommand.h
commands/refreshcertificatecommand.cpp
commands/refreshcertificatecommand.h
commands/refreshopenpgpcertscommand.cpp
commands/refreshopenpgpcertscommand.h
commands/refreshx509certscommand.cpp
commands/refreshx509certscommand.h
commands/reloadkeyscommand.cpp
commands/reloadkeyscommand.h
commands/revokecertificationcommand.cpp
commands/revokecertificationcommand.h
commands/revokekeycommand.cpp
commands/revokekeycommand.h
commands/revokeuseridcommand.cpp
commands/revokeuseridcommand.h
commands/selftestcommand.cpp
commands/selftestcommand.h
commands/setinitialpincommand.cpp
commands/setinitialpincommand.h
commands/setpivcardapplicationadministrationkeycommand.cpp
commands/setpivcardapplicationadministrationkeycommand.h
commands/setprimaryuseridcommand.cpp
commands/setprimaryuseridcommand.h
commands/signclipboardcommand.cpp
commands/signclipboardcommand.h
commands/signencryptfilescommand.cpp
commands/signencryptfilescommand.h
commands/signencryptfoldercommand.cpp
commands/signencryptfoldercommand.h
conf/configuredialog.cpp
conf/configuredialog.h
conf/groupsconfigdialog.cpp
conf/groupsconfigdialog.h
conf/groupsconfigpage.cpp
conf/groupsconfigpage.h
conf/groupsconfigwidget.cpp
conf/groupsconfigwidget.h
crypto/autodecryptverifyfilescontroller.cpp
crypto/autodecryptverifyfilescontroller.h
crypto/certificateresolver.cpp
crypto/certificateresolver.h
crypto/checksumsutils_p.cpp
crypto/checksumsutils_p.h
crypto/controller.cpp
crypto/controller.h
crypto/createchecksumscontroller.cpp
crypto/createchecksumscontroller.h
crypto/decryptverifyemailcontroller.cpp
crypto/decryptverifyemailcontroller.h
crypto/decryptverifyfilescontroller.cpp
crypto/decryptverifyfilescontroller.h
crypto/decryptverifytask.cpp
crypto/decryptverifytask.h
crypto/encryptemailcontroller.cpp
crypto/encryptemailcontroller.h
crypto/encryptemailtask.cpp
crypto/encryptemailtask.h
crypto/gui/certificatelineedit.cpp
crypto/gui/certificatelineedit.h
crypto/gui/certificateselectionline.cpp
crypto/gui/certificateselectionline.h
crypto/gui/decryptverifyfilesdialog.cpp
crypto/gui/decryptverifyfilesdialog.h
crypto/gui/decryptverifyfileswizard.cpp
crypto/gui/decryptverifyfileswizard.h
crypto/gui/decryptverifyoperationwidget.cpp
crypto/gui/decryptverifyoperationwidget.h
crypto/gui/encryptemailwizard.cpp
crypto/gui/encryptemailwizard.h
crypto/gui/newresultpage.cpp
crypto/gui/newresultpage.h
crypto/gui/objectspage.cpp
crypto/gui/objectspage.h
crypto/gui/resolverecipientspage.cpp
crypto/gui/resolverecipientspage.h
crypto/gui/resultitemwidget.cpp
crypto/gui/resultitemwidget.h
crypto/gui/resultlistwidget.cpp
crypto/gui/resultlistwidget.h
crypto/gui/resultpage.cpp
crypto/gui/resultpage.h
crypto/gui/signemailwizard.cpp
crypto/gui/signemailwizard.h
crypto/gui/signencryptemailconflictdialog.cpp
crypto/gui/signencryptemailconflictdialog.h
crypto/gui/signencryptfileswizard.cpp
crypto/gui/signencryptfileswizard.h
crypto/gui/signencryptwidget.cpp
crypto/gui/signencryptwidget.h
crypto/gui/signencryptwizard.cpp
crypto/gui/signencryptwizard.h
crypto/gui/signerresolvepage.cpp
crypto/gui/signerresolvepage.h
crypto/gui/signingcertificateselectiondialog.cpp
crypto/gui/signingcertificateselectiondialog.h
crypto/gui/signingcertificateselectionwidget.cpp
crypto/gui/signingcertificateselectionwidget.h
crypto/gui/unknownrecipientwidget.cpp
crypto/gui/unknownrecipientwidget.h
crypto/gui/verifychecksumsdialog.cpp
crypto/gui/verifychecksumsdialog.h
crypto/gui/wizard.cpp
crypto/gui/wizard.h
crypto/gui/wizardpage.cpp
crypto/gui/wizardpage.h
crypto/newsignencryptemailcontroller.cpp
crypto/newsignencryptemailcontroller.h
crypto/recipient.cpp
crypto/recipient.h
crypto/sender.cpp
crypto/sender.h
crypto/signemailcontroller.cpp
crypto/signemailcontroller.h
crypto/signemailtask.cpp
crypto/signemailtask.h
crypto/signencryptfilescontroller.cpp
crypto/signencryptfilescontroller.h
crypto/signencrypttask.cpp
crypto/signencrypttask.h
crypto/task.cpp
crypto/task.h
crypto/taskcollection.cpp
crypto/taskcollection.h
crypto/verifychecksumscontroller.cpp
crypto/verifychecksumscontroller.h
dialogs/adduseriddialog.cpp
dialogs/adduseriddialog.h
dialogs/certificatedetailsdialog.cpp
dialogs/certificatedetailsdialog.h
dialogs/certificatedetailsinputwidget.cpp
dialogs/certificatedetailsinputwidget.h
dialogs/certificatedetailswidget.cpp
dialogs/certificatedetailswidget.h
dialogs/certificateselectiondialog.cpp
dialogs/certificateselectiondialog.h
dialogs/certifycertificatedialog.cpp
dialogs/certifycertificatedialog.h
dialogs/certifywidget.cpp
dialogs/certifywidget.h
dialogs/createcsrforcardkeydialog.cpp
dialogs/createcsrforcardkeydialog.h
dialogs/deletecertificatesdialog.cpp
dialogs/deletecertificatesdialog.h
dialogs/editgroupdialog.cpp
dialogs/editgroupdialog.h
dialogs/expirydialog.cpp
dialogs/expirydialog.h
dialogs/exportdialog.cpp
dialogs/exportdialog.h
dialogs/gencardkeydialog.cpp
dialogs/gencardkeydialog.h
dialogs/groupdetailsdialog.cpp
dialogs/groupdetailsdialog.h
dialogs/lookupcertificatesdialog.cpp
dialogs/lookupcertificatesdialog.h
dialogs/nameandemailwidget.cpp
dialogs/nameandemailwidget.h
dialogs/newopenpgpcertificatedetailsdialog.cpp
dialogs/newopenpgpcertificatedetailsdialog.h
dialogs/pivcardapplicationadministrationkeyinputdialog.cpp
dialogs/pivcardapplicationadministrationkeyinputdialog.h
dialogs/revokekeydialog.cpp
dialogs/revokekeydialog.h
dialogs/selftestdialog.cpp
dialogs/selftestdialog.h
dialogs/setinitialpindialog.cpp
dialogs/setinitialpindialog.h
dialogs/subkeyswidget.cpp
dialogs/subkeyswidget.h
dialogs/trustchainwidget.cpp
dialogs/trustchainwidget.h
dialogs/updatenotification.cpp
dialogs/updatenotification.h
dialogs/weboftrustdialog.cpp
dialogs/weboftrustdialog.h
dialogs/weboftrustwidget.cpp
dialogs/weboftrustwidget.h
interfaces/anchorprovider.h
interfaces/focusfirstchild.h
newcertificatewizard/advancedsettingsdialog.cpp
newcertificatewizard/advancedsettingsdialog_p.h
newcertificatewizard/enterdetailspage.cpp
newcertificatewizard/enterdetailspage_p.h
newcertificatewizard/keyalgo.cpp
newcertificatewizard/keyalgo_p.h
newcertificatewizard/keycreationpage.cpp
newcertificatewizard/keycreationpage_p.h
newcertificatewizard/listwidget.cpp
newcertificatewizard/listwidget.h
newcertificatewizard/newcertificatewizard.cpp
newcertificatewizard/newcertificatewizard.h
newcertificatewizard/resultpage.cpp
newcertificatewizard/resultpage_p.h
newcertificatewizard/wizardpage.cpp
newcertificatewizard/wizardpage_p.h
selftest/compliancecheck.cpp
selftest/compliancecheck.h
selftest/enginecheck.cpp
selftest/enginecheck.h
selftest/gpgagentcheck.cpp
selftest/gpgagentcheck.h
selftest/gpgconfcheck.cpp
selftest/gpgconfcheck.h
selftest/libkleopatrarccheck.cpp
selftest/libkleopatrarccheck.h
selftest/selftest.cpp
selftest/selftest.h
smartcard/algorithminfo.h
smartcard/card.cpp
smartcard/card.h
smartcard/deviceinfowatcher.cpp
smartcard/deviceinfowatcher.h
smartcard/keypairinfo.cpp
smartcard/keypairinfo.h
smartcard/netkeycard.cpp
smartcard/netkeycard.h
smartcard/openpgpcard.cpp
smartcard/openpgpcard.h
smartcard/p15card.cpp
smartcard/p15card.h
smartcard/pivcard.cpp
smartcard/pivcard.h
smartcard/readerstatus.cpp
smartcard/readerstatus.h
smartcard/utils.cpp
smartcard/utils.h
utils/accessibility.cpp
utils/accessibility.h
utils/action_data.cpp
utils/action_data.h
utils/applicationstate.cpp
utils/applicationstate.h
utils/archivedefinition.cpp
utils/archivedefinition.h
utils/clipboardmenu.cpp
utils/clipboardmenu.h
utils/debug-helpers.cpp
utils/debug-helpers.h
utils/dragqueen.cpp
utils/dragqueen.h
utils/email.cpp
utils/email.h
utils/emptypassphraseprovider.cpp
utils/emptypassphraseprovider.h
utils/filedialog.cpp
utils/filedialog.h
utils/gui-helper.cpp
utils/gui-helper.h
utils/headerview.cpp
utils/headerview.h
utils/input.cpp
utils/input.h
utils/iodevicelogger.cpp
utils/iodevicelogger.h
utils/kdpipeiodevice.cpp
utils/kdpipeiodevice.h
utils/keyparameters.cpp
utils/keyparameters.h
utils/keys.cpp
utils/keys.h
utils/kuniqueservice.cpp
utils/kuniqueservice.h
utils/log.cpp
utils/log.h
utils/memory-helpers.h
utils/multivalidator.cpp
utils/multivalidator.h
utils/output.cpp
utils/output.h
utils/overwritedialog.cpp
utils/overwritedialog.h
utils/path-helper.cpp
utils/path-helper.h
utils/scrollarea.cpp
utils/scrollarea.h
utils/systemtrayicon.cpp
utils/systemtrayicon.h
utils/tags.cpp
utils/tags.h
utils/types.cpp
utils/types.h
utils/userinfo.cpp
utils/userinfo.h
utils/validation.cpp
utils/validation.h
utils/writecertassuantransaction.cpp
utils/writecertassuantransaction.h
utils/wsastarter.cpp
utils/wsastarter.h
view/anchorcache.cpp
view/anchorcache_p.h
view/errorlabel.cpp
view/errorlabel.h
view/formtextinput.cpp
view/formtextinput.h
view/htmllabel.cpp
view/htmllabel.h
view/infofield.cpp
view/infofield.h
view/keycacheoverlay.cpp
view/keycacheoverlay.h
view/keylistcontroller.cpp
view/keylistcontroller.h
view/keytreeview.cpp
view/keytreeview.h
view/netkeywidget.cpp
view/netkeywidget.h
view/nullpinwidget.cpp
view/nullpinwidget.h
view/openpgpkeycardwidget.cpp
view/openpgpkeycardwidget.h
view/p15cardwidget.cpp
view/p15cardwidget.h
view/padwidget.cpp
view/padwidget.h
view/pgpcardwidget.cpp
view/pgpcardwidget.h
view/pivcardwidget.cpp
view/pivcardwidget.h
view/searchbar.cpp
view/searchbar.h
view/smartcardwidget.cpp
view/smartcardwidget.h
view/tabwidget.cpp
view/tabwidget.h
view/urllabel.cpp
view/urllabel.h
view/waitwidget.cpp
view/waitwidget.h
view/welcomewidget.cpp
view/welcomewidget.h
aboutdata.cpp
aboutdata.h
kleopatra.qrc
kleopatraapplication.cpp
kleopatraapplication.h
main.cpp
mainwindow.cpp
mainwindow.h
systrayicon.cpp
systrayicon.h
)
if(WIN32)
configure_file (versioninfo.rc.in versioninfo.rc)
set(_kleopatra_SRCS ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc ${_kleopatra_SRCS})
endif()
set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp conf/kleopageconfigdialog.h ${_kleopatra_SRCS})
ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra
DESCRIPTION "kleopatra (kleopatra)"
OLD_CATEGORY_NAMES log_kleopatra
EXPORT KLEOPATRA
)
if(KLEO_MODEL_TEST)
add_definitions(-DKLEO_MODEL_TEST)
set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp)
endif()
ki18n_wrap_ui(_kleopatra_SRCS
dialogs/setinitialpindialog.ui
dialogs/trustchainwidget.ui
newcertificatewizard/listwidget.ui
)
kconfig_add_kcfg_files(_kleopatra_SRCS
kcfg/emailoperationspreferences.kcfgc
kcfg/fileoperationspreferences.kcfgc
kcfg/settings.kcfgc
kcfg/smimevalidationpreferences.kcfgc
kcfg/tagspreferences.kcfgc
kcfg/tooltippreferences.kcfgc
)
file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png")
ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS})
add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS})
# For the ConfigureDialog & KCMs
target_link_libraries(kleopatra_bin kcm_kleopatra_static)
#if (COMPILE_WITH_UNITY_CMAKE_SUPPORT)
# set_target_properties(kleopatra_bin PROPERTIES UNITY_BUILD ON)
#endif()
set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
if (WIN32)
set(_kleopatra_platform_libs "secur32")
endif ()
target_link_libraries(kleopatra_bin
Gpgmepp
KPim${KF_MAJOR_VERSION}::Libkleo
KPim${KF_MAJOR_VERSION}::Mime
KF${KF_MAJOR_VERSION}::Codecs
KF${KF_MAJOR_VERSION}::CoreAddons
KF${KF_MAJOR_VERSION}::Crash
KF${KF_MAJOR_VERSION}::I18n
KF${KF_MAJOR_VERSION}::IconThemes
KF${KF_MAJOR_VERSION}::ItemModels
+ KF${KF_MAJOR_VERSION}::KIOCore
+ KF${KF_MAJOR_VERSION}::KIOWidgets
KF${KF_MAJOR_VERSION}::WindowSystem
KF${KF_MAJOR_VERSION}::XmlGui
Qt::Network
Qt::PrintSupport # Printing secret keys
kleopatraclientcore
${_kleopatra_extra_libs}
${_kleopatra_mail_libs}
${_kleopatra_uiserver_extra_libs}
${_kleopatra_dbusaddons_libs}
${_kleopatra_platform_libs}
)
if (QT_MAJOR_VERSION STREQUAL "6")
target_link_libraries(kleopatra_bin Qt6::Core5Compat)
target_link_libraries(kleopatra_bin QGpgmeQt6)
else()
target_link_libraries(kleopatra_bin QGpgme)
endif()
install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(
PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop
DESTINATION ${KDE_INSTALL_APPDIR}
)
install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
install(
PROGRAMS data/kleopatra_signencryptfiles.desktop
data/kleopatra_signencryptfolders.desktop
data/kleopatra_decryptverifyfiles.desktop
data/kleopatra_decryptverifyfolders.desktop
DESTINATION ${KDE_INSTALL_DATADIR}/kio/servicemenus
)
diff --git a/src/crypto/autodecryptverifyfilescontroller.cpp b/src/crypto/autodecryptverifyfilescontroller.cpp
index 069b37736..5f0c3da3b 100644
--- a/src/crypto/autodecryptverifyfilescontroller.cpp
+++ b/src/crypto/autodecryptverifyfilescontroller.cpp
@@ -1,593 +1,600 @@
/* -*- mode: c++; c-basic-offset:4 -*-
autodecryptverifyfilescontroller.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "autodecryptverifyfilescontroller.h"
#include "fileoperationspreferences.h"
#include <crypto/gui/decryptverifyoperationwidget.h>
#include <crypto/gui/decryptverifyfilesdialog.h>
#include <crypto/decryptverifytask.h>
#include <crypto/taskcollection.h>
#include "commands/decryptverifyfilescommand.h"
#include <Libkleo/GnuPG>
#include <utils/path-helper.h>
#include <utils/input.h>
#include <utils/output.h>
#include <utils/kleo_assert.h>
#include <utils/archivedefinition.h>
#include <Libkleo/Classify>
+#include <KIO/CopyJob>
#include <KLocalizedString>
#include <KMessageBox>
#include "kleopatra_debug.h"
#if QGPGME_SUPPORTS_ARCHIVE_JOBS
#include <QGpgME/DecryptVerifyArchiveJob>
#endif
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTimer>
#include <QFileDialog>
#include <QTemporaryDir>
#include <gpgme++/decryptionresult.h>
using namespace GpgME;
using namespace Kleo;
using namespace Kleo::Crypto;
using namespace Kleo::Crypto::Gui;
class AutoDecryptVerifyFilesController::Private
{
AutoDecryptVerifyFilesController *const q;
public:
explicit Private(AutoDecryptVerifyFilesController *qq);
void slotDialogCanceled();
void schedule();
QString getEmbeddedFileName(const QString &fileName) const;
void exec();
std::vector<std::shared_ptr<Task> > buildTasks(const QStringList &, QStringList &);
struct CryptoFile {
QString baseName;
QString fileName;
GpgME::Protocol protocol = GpgME::UnknownProtocol;
int classification = 0;
std::shared_ptr<Output> output;
};
QVector<CryptoFile> classifyAndSortFiles(const QStringList &files);
void reportError(int err, const QString &details)
{
q->setLastError(err, details);
q->emitDoneOrError();
}
void cancelAllTasks();
QStringList m_passedFiles, m_filesAfterPreparation;
std::vector<std::shared_ptr<const DecryptVerifyResult> > m_results;
std::vector<std::shared_ptr<Task> > m_runnableTasks, m_completedTasks;
std::shared_ptr<Task> m_runningTask;
bool m_errorDetected = false;
DecryptVerifyOperation m_operation = DecryptVerify;
QPointer<DecryptVerifyFilesDialog> m_dialog;
std::unique_ptr<QTemporaryDir> m_workDir;
};
AutoDecryptVerifyFilesController::Private::Private(AutoDecryptVerifyFilesController *qq) : q(qq)
{
qRegisterMetaType<VerificationResult>();
}
void AutoDecryptVerifyFilesController::Private::slotDialogCanceled()
{
qCDebug(KLEOPATRA_LOG);
}
void AutoDecryptVerifyFilesController::Private::schedule()
{
if (!m_runningTask && !m_runnableTasks.empty()) {
const std::shared_ptr<Task> t = m_runnableTasks.back();
m_runnableTasks.pop_back();
t->start();
m_runningTask = t;
}
if (!m_runningTask) {
kleo_assert(m_runnableTasks.empty());
for (const std::shared_ptr<const DecryptVerifyResult> &i : std::as_const(m_results)) {
Q_EMIT q->verificationResult(i->verificationResult());
}
}
}
QString AutoDecryptVerifyFilesController::Private::getEmbeddedFileName(const QString &fileName) const
{
auto it = std::find_if(m_results.cbegin(), m_results.cend(), [fileName](const auto &r) {
return r->fileName() == fileName;
});
if (it != m_results.cend()) {
const auto embeddedFilePath = QString::fromUtf8((*it)->decryptionResult().fileName());
if (embeddedFilePath.contains(QLatin1Char{'\\'})) {
// ignore embedded file names containing '\'
return {};
}
// strip the path from the embedded file name
return QFileInfo{embeddedFilePath}.fileName();
} else {
return {};
}
}
void AutoDecryptVerifyFilesController::Private::exec()
{
Q_ASSERT(!m_dialog);
QStringList undetected;
std::vector<std::shared_ptr<Task> > tasks = buildTasks(m_passedFiles, undetected);
if (!undetected.isEmpty()) {
// Since GpgME 1.7.0 Classification is supposed to be reliable
// so we really can't do anything with this data.
reportError(makeGnuPGError(GPG_ERR_GENERAL),
xi18n("Failed to find encrypted or signed data in one or more files.<nl/>"
"You can manually select what to do with the files now.<nl/>"
"If they contain signed or encrypted data please report a bug (see Help->Report Bug)."));
auto cmd = new Commands::DecryptVerifyFilesCommand(undetected, nullptr, true);
cmd->start();
}
if (tasks.empty()) {
q->emitDoneOrError();
return;
}
Q_ASSERT(m_runnableTasks.empty());
m_runnableTasks.swap(tasks);
std::shared_ptr<TaskCollection> coll(new TaskCollection);
for (const std::shared_ptr<Task> &i : std::as_const(m_runnableTasks)) {
q->connectTask(i);
}
coll->setTasks(m_runnableTasks);
DecryptVerifyFilesDialog dialog{coll};
m_dialog = &dialog;
m_dialog->setOutputLocation(heuristicBaseDirectory(m_passedFiles));
QTimer::singleShot(0, q, SLOT(schedule()));
if (m_dialog->exec() == QDialog::Accepted && m_workDir) {
// Without workdir there is nothing to move.
const QDir workdir(m_workDir->path());
const QDir outDir(m_dialog->outputLocation());
bool overWriteAll = false;
qCDebug(KLEOPATRA_LOG) << workdir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &fi: workdir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot)) {
const auto inpath = fi.absoluteFilePath();
if (fi.isDir()) {
// A directory. Assume that the input was an archive
// and avoid directory merges by trying to find a non
// existing directory.
auto candidate = fi.fileName();
if (candidate.startsWith(QLatin1Char('-'))) {
// Bug in GpgTar Extracts stdout passed archives to a dir named -
candidate = QFileInfo(m_passedFiles.first()).baseName();
}
QString suffix;
QFileInfo ofi;
int i = 0;
do {
ofi = QFileInfo(outDir.absoluteFilePath(candidate + suffix));
if (!ofi.exists()) {
break;
}
suffix = QStringLiteral("_%1").arg(++i);
} while (i < 1000);
- if (!moveDir(inpath, ofi.absoluteFilePath())) {
+ auto job = KIO::moveAs(QUrl::fromLocalFile(inpath), QUrl::fromLocalFile(ofi.absoluteFilePath()));
+ qCDebug(KLEOPATRA_LOG) << "Moving" << job->srcUrls().front().toLocalFile() << "to" << job->destUrl().toLocalFile();
+ if (!job->exec()) {
+ if (job->error() == KIO::ERR_USER_CANCELED) {
+ break;
+ }
reportError(makeGnuPGError(GPG_ERR_GENERAL),
- xi18n("Failed to move <filename>%1</filename> to <filename>%2</filename>.",
- inpath, ofi.absoluteFilePath()));
+ xi18nc("@info", "<para>Failed to move <filename>%1</filename> to <filename>%2</filename>.</para>"
+ "<para><message>%3</message></para>",
+ inpath, ofi.absoluteFilePath(), job->errorString()));
}
continue;
}
const auto embeddedFileName = getEmbeddedFileName(inpath);
QString outFileName = fi.fileName();
if (!embeddedFileName.isEmpty() && embeddedFileName != fi.fileName()) {
// we switch "Yes" and "No" because Yes is default, but saving with embedded file name could be dangerous
const auto answer = KMessageBox::questionTwoActionsCancel(
m_dialog,
xi18n("Shall the file be saved with the original file name <filename>%1</filename>?", embeddedFileName),
i18n("Use Original File Name?"),
KGuiItem(xi18n("No, Save As <filename>%1</filename>", fi.fileName())),
KGuiItem(xi18n("Yes, Save As <filename>%1</filename>", embeddedFileName)));
if (answer == KMessageBox::Cancel) {
qCDebug(KLEOPATRA_LOG) << "Saving canceled for:" << inpath;
continue;
} else if (answer == KMessageBox::ButtonCode::SecondaryAction) {
outFileName = embeddedFileName;
}
}
const auto outpath = outDir.absoluteFilePath(outFileName);
qCDebug(KLEOPATRA_LOG) << "Moving " << inpath << " to " << outpath;
const QFileInfo ofi(outpath);
if (ofi.exists()) {
int sel = KMessageBox::Cancel;
if (!overWriteAll) {
sel = KMessageBox::questionTwoActionsCancel(m_dialog,
i18n("The file <b>%1</b> already exists.\n"
"Overwrite?",
outpath),
i18n("Overwrite Existing File?"),
KStandardGuiItem::overwrite(),
KGuiItem(i18n("Overwrite All")),
KStandardGuiItem::cancel());
}
if (sel == KMessageBox::Cancel) {
qCDebug(KLEOPATRA_LOG) << "Overwriting canceled for: " << outpath;
continue;
}
if (sel == KMessageBox::ButtonCode::SecondaryAction) { // Overwrite All
overWriteAll = true;
}
if (!QFile::remove(outpath)) {
reportError(makeGnuPGError(GPG_ERR_GENERAL),
xi18n("Failed to delete <filename>%1</filename>.",
outpath));
continue;
}
}
if (!QFile::rename(inpath, outpath)) {
reportError(makeGnuPGError(GPG_ERR_GENERAL),
xi18n("Failed to move <filename>%1</filename> to <filename>%2</filename>.",
inpath, outpath));
}
}
}
q->emitDoneOrError();
}
QVector<AutoDecryptVerifyFilesController::Private::CryptoFile> AutoDecryptVerifyFilesController::Private::classifyAndSortFiles(const QStringList &files)
{
const auto isSignature = [](int classification) -> bool {
return mayBeDetachedSignature(classification)
|| mayBeOpaqueSignature(classification)
|| (classification & Class::TypeMask) == Class::ClearsignedMessage;
};
QVector<CryptoFile> out;
for (const auto &file : files) {
CryptoFile cFile;
cFile.fileName = file;
cFile.baseName = stripSuffix(file);
cFile.classification = classify(file);
cFile.protocol = findProtocol(cFile.classification);
auto it = std::find_if(out.begin(), out.end(),
[&cFile](const CryptoFile &other) {
return other.protocol == cFile.protocol
&& other.baseName == cFile.baseName;
});
if (it != out.end()) {
// If we found a file with the same basename, make sure that encrypted
// file is before the signature file, so that we first decrypt and then
// verify
if (isSignature(cFile.classification) && isCipherText(it->classification)) {
out.insert(it + 1, cFile);
} else if (isCipherText(cFile.classification) && isSignature(it->classification)) {
out.insert(it, cFile);
} else {
// both are signatures or both are encrypted files, in which
// case order does not matter
out.insert(it, cFile);
}
} else {
out.push_back(cFile);
}
}
return out;
}
static bool archiveJobsCanBeUsed([[maybe_unused]] GpgME::Protocol protocol)
{
#if QGPGME_SUPPORTS_ARCHIVE_JOBS
return (protocol == GpgME::OpenPGP) && QGpgME::DecryptVerifyArchiveJob::isSupported();
#else
return false;
#endif
}
std::vector< std::shared_ptr<Task> > AutoDecryptVerifyFilesController::Private::buildTasks(const QStringList &fileNames, QStringList &undetected)
{
// sort files so that we make sure we first decrypt and then verify
QVector<CryptoFile> cryptoFiles = classifyAndSortFiles(fileNames);
std::vector<std::shared_ptr<Task> > tasks;
for (auto it = cryptoFiles.begin(), end = cryptoFiles.end(); it != end; ++it) {
auto &cFile = (*it);
QFileInfo fi(cFile.fileName);
qCDebug(KLEOPATRA_LOG) << "classified" << cFile.fileName << "as" << printableClassification(cFile.classification);
if (!fi.isReadable()) {
reportError(makeGnuPGError(GPG_ERR_ASS_NO_INPUT),
xi18n("Cannot open <filename>%1</filename> for reading.", cFile.fileName));
continue;
}
if (mayBeAnyCertStoreType(cFile.classification)) {
// Trying to verify a certificate. Possible because extensions are often similar
// for PGP Keys.
reportError(makeGnuPGError(GPG_ERR_ASS_NO_INPUT),
xi18n("The file <filename>%1</filename> contains certificates and can't be decrypted or verified.", cFile.fileName));
qCDebug(KLEOPATRA_LOG) << "reported error";
continue;
}
// We can't reliably detect CMS detached signatures, so we will try to do
// our best to use the current file as a detached signature and fallback to
// opaque signature otherwise.
if (cFile.protocol == GpgME::CMS && mayBeDetachedSignature(cFile.classification)) {
// First, see if previous task was a decryption task for the same file
// and "pipe" it's output into our input
std::shared_ptr<Input> input;
bool prepend = false;
if (it != cryptoFiles.begin()) {
const auto prev = it - 1;
if (prev->protocol == cFile.protocol && prev->baseName == cFile.baseName) {
input = Input::createFromOutput(prev->output);
prepend = true;
}
}
if (!input) {
if (QFile::exists(cFile.baseName)) {
input = Input::createFromFile(cFile.baseName);
}
}
if (input) {
qCDebug(KLEOPATRA_LOG) << "Detached CMS verify: " << cFile.fileName;
std::shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
t->setInput(Input::createFromFile(cFile.fileName));
t->setSignedData(input);
t->setProtocol(cFile.protocol);
if (prepend) {
// Put the verify task BEFORE the decrypt task in the tasks queue,
// because the tasks are executed in reverse order!
tasks.insert(tasks.end() - 1, t);
} else {
tasks.push_back(t);
}
continue;
} else {
// No signed data, maybe not a detached signature
}
}
if (isDetachedSignature(cFile.classification)) {
// Detached signature, try to find data or ask the user.
QString signedDataFileName = cFile.baseName;
if (!QFile::exists(signedDataFileName)) {
signedDataFileName = QFileDialog::getOpenFileName(nullptr, xi18n("Select the file to verify with the signature <filename>%1</filename>", fi.fileName()),
fi.path());
}
if (signedDataFileName.isEmpty()) {
qCDebug(KLEOPATRA_LOG) << "No signed data selected. Verify aborted.";
} else {
qCDebug(KLEOPATRA_LOG) << "Detached verify: " << cFile.fileName << " Data: " << signedDataFileName;
std::shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
t->setInput(Input::createFromFile(cFile.fileName));
t->setSignedData(Input::createFromFile(signedDataFileName));
t->setProtocol(cFile.protocol);
tasks.push_back(t);
}
continue;
}
if (!mayBeAnyMessageType(cFile.classification)) {
// Not a Message? Maybe there is a signature for this file?
const auto signatures = findSignatures(cFile.fileName);
bool foundSig = false;
if (!signatures.empty()) {
for (const QString &sig : signatures) {
const auto classification = classify(sig);
qCDebug(KLEOPATRA_LOG) << "Guessing: " << sig << " is a signature for: " << cFile.fileName
<< "Classification: " << classification;
const auto proto = findProtocol(classification);
if (proto == GpgME::UnknownProtocol) {
qCDebug(KLEOPATRA_LOG) << "Could not determine protocol. Skipping guess.";
continue;
}
foundSig = true;
std::shared_ptr<VerifyDetachedTask> t(new VerifyDetachedTask);
t->setInput(Input::createFromFile(sig));
t->setSignedData(Input::createFromFile(cFile.fileName));
t->setProtocol(proto);
tasks.push_back(t);
}
}
if (!foundSig) {
undetected << cFile.fileName;
qCDebug(KLEOPATRA_LOG) << "Failed detection for: " << cFile.fileName << " adding to undetected.";
}
} else {
const FileOperationsPreferences fileOpSettings;
// Any Message type so we have input and output.
const auto input = Input::createFromFile(cFile.fileName);
std::shared_ptr<ArchiveDefinition> ad;
if (fileOpSettings.autoExtractArchives()) {
const auto archiveDefinitions = ArchiveDefinition::getArchiveDefinitions();
ad = q->pick_archive_definition(cFile.protocol, archiveDefinitions, cFile.fileName);
}
if (fileOpSettings.dontUseTmpDir()) {
if (!m_workDir) {
m_workDir = std::make_unique<QTemporaryDir>(heuristicBaseDirectory(fileNames) + QStringLiteral("/kleopatra-XXXXXX"));
}
if (!m_workDir->isValid()) {
qCDebug(KLEOPATRA_LOG) << heuristicBaseDirectory(fileNames) << "not a valid temporary directory.";
m_workDir.reset();
}
}
if (!m_workDir) {
m_workDir = std::make_unique<QTemporaryDir>();
}
qCDebug(KLEOPATRA_LOG) << "Using:" << m_workDir->path() << "as temporary directory.";
const auto wd = QDir(m_workDir->path());
std::shared_ptr<Output> output;
if (ad) {
if ((ad->id() == QLatin1String{"tar"}) && archiveJobsCanBeUsed(cFile.protocol)) {
// we don't need an output
} else {
output = ad->createOutputFromUnpackCommand(cFile.protocol, cFile.fileName, wd);
}
} else {
output = Output::createFromFile(wd.absoluteFilePath(outputFileName(fi.fileName())), false);
}
// If this might be opaque CMS signature, then try that. We already handled
// detached CMS signature above
const auto isCMSOpaqueSignature = cFile.protocol == GpgME::CMS && mayBeOpaqueSignature(cFile.classification);
if (isOpaqueSignature(cFile.classification) || isCMSOpaqueSignature) {
qCDebug(KLEOPATRA_LOG) << "creating a VerifyOpaqueTask";
std::shared_ptr<VerifyOpaqueTask> t(new VerifyOpaqueTask);
t->setInput(input);
if (output) {
t->setOutput(output);
}
t->setProtocol(cFile.protocol);
if (ad) {
t->setExtractArchive(true);
t->setOutputDirectory(m_workDir->path());
}
tasks.push_back(t);
} else {
// Any message. That is not an opaque signature needs to be
// decrypted. Verify we always do because we can't know if
// an encrypted message is also signed.
qCDebug(KLEOPATRA_LOG) << "creating a DecryptVerifyTask";
std::shared_ptr<DecryptVerifyTask> t(new DecryptVerifyTask);
t->setInput(input);
if (output) {
t->setOutput(output);
}
t->setProtocol(cFile.protocol);
if (ad) {
t->setExtractArchive(true);
t->setOutputDirectory(m_workDir->path());
}
cFile.output = output;
tasks.push_back(t);
}
}
}
return tasks;
}
void AutoDecryptVerifyFilesController::setFiles(const QStringList &files)
{
d->m_passedFiles = files;
}
AutoDecryptVerifyFilesController::AutoDecryptVerifyFilesController(QObject *parent) :
DecryptVerifyFilesController(parent), d(new Private(this))
{
}
AutoDecryptVerifyFilesController::AutoDecryptVerifyFilesController(const std::shared_ptr<const ExecutionContext> &ctx, QObject *parent) :
DecryptVerifyFilesController(ctx, parent), d(new Private(this))
{
}
AutoDecryptVerifyFilesController::~AutoDecryptVerifyFilesController()
{
qCDebug(KLEOPATRA_LOG);
}
void AutoDecryptVerifyFilesController::start()
{
d->exec();
}
void AutoDecryptVerifyFilesController::setOperation(DecryptVerifyOperation op)
{
d->m_operation = op;
}
DecryptVerifyOperation AutoDecryptVerifyFilesController::operation() const
{
return d->m_operation;
}
void AutoDecryptVerifyFilesController::Private::cancelAllTasks()
{
// we just kill all runnable tasks - this will not result in
// signal emissions.
m_runnableTasks.clear();
// a cancel() will result in a call to
if (m_runningTask) {
m_runningTask->cancel();
}
}
void AutoDecryptVerifyFilesController::cancel()
{
qCDebug(KLEOPATRA_LOG);
try {
d->m_errorDetected = true;
if (d->m_dialog) {
d->m_dialog->close();
}
d->cancelAllTasks();
} catch (const std::exception &e) {
qCDebug(KLEOPATRA_LOG) << "Caught exception: " << e.what();
}
}
void AutoDecryptVerifyFilesController::doTaskDone(const Task *task, const std::shared_ptr<const Task::Result> &result)
{
Q_ASSERT(task);
Q_UNUSED(task)
// We could just delete the tasks here, but we can't use
// Qt::QueuedConnection here (we need sender()) and other slots
// might not yet have executed. Therefore, we push completed tasks
// into a burial container
d->m_completedTasks.push_back(d->m_runningTask);
d->m_runningTask.reset();
if (const std::shared_ptr<const DecryptVerifyResult> &dvr = std::dynamic_pointer_cast<const DecryptVerifyResult>(result)) {
d->m_results.push_back(dvr);
}
QTimer::singleShot(0, this, SLOT(schedule()));
}
#include "moc_autodecryptverifyfilescontroller.cpp"

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:52 PM (19 h, 1 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e5/ac/afae08243a61668046cd02c6ad49

Event Timeline