diff --git a/CMakeLists.txt b/CMakeLists.txt
index f75239101..f249e3355 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,223 +1,224 @@
# SPDX-FileCopyrightText: none
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
set(RELEASE_SERVICE_VERSION_MAJOR "22")
set(RELEASE_SERVICE_VERSION_MINOR "03")
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 "20")
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")
project(kleopatra VERSION ${kleopatra_version})
option(DISABLE_KWATCHGNUPG "Don't build the kwatchgnupg tool [default=OFF]" OFF)
# Standalone build. Find / include everything necessary.
set(KF5_MIN_VERSION "5.90.0")
set(KMIME_VERSION "5.19.40")
set(LIBKLEO_VERSION "5.19.49")
set(QT_REQUIRED_VERSION "5.15.2")
set(GPGME_REQUIRED_VERSION "1.15.0")
set(BOOST_REQUIRED_VERSION "1.58")
if (WIN32)
set(KF5_WANT_VERSION "5.70.0")
set(KMIME_WANT_VERSION "5.12.0")
else ()
set(KF5_WANT_VERSION ${KF5_MIN_VERSION})
set(KMIME_WANT_VERSION ${KMIME_VERSION})
endif ()
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)
# Find KF5 packages
find_package(KF5WidgetsAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5ConfigWidgets ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5CoreAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5Codecs ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5Config ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5I18n ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5IconThemes ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5ItemModels ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5XmlGui ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5WindowSystem ${KF5_WANT_VERSION} CONFIG REQUIRED)
find_package(KF5DocTools ${KF5_WANT_VERSION} CONFIG)
find_package(KF5Crash ${KF5_WANT_VERSION} REQUIRED)
set_package_properties(KF5DocTools 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(KF5DBusAddons ${KF5_WANT_VERSION} CONFIG)
set_package_properties(KF5DBusAddons PROPERTIES DESCRIPTION "Support library to work with DBus"
PURPOSE "DBus session integration"
URL "https://inqlude.org/libraries/kdbusaddons.html"
TYPE OPTIONAL)
else()
find_package(KF5DBusAddons ${KF5_WANT_VERSION} CONFIG REQUIRED)
set(_kleopatra_dbusaddons_libs KF5::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.16.0")
set(GPGMEPP_SUPPORTS_TRUST_SIGNATURES 1)
endif()
find_package(QGpgme ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
if (QGpgme_VERSION VERSION_GREATER_EQUAL "1.16.0")
set(QGPGME_SUPPORTS_TRUST_SIGNATURES 1)
set(QGPGME_SUPPORTS_SIGNATURE_EXPIRATION 1)
endif()
if (QGpgme_VERSION VERSION_GREATER_EQUAL "1.16.1")
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()
# Kdepimlibs packages
find_package(KF5Libkleo ${LIBKLEO_VERSION} CONFIG REQUIRED)
find_package(KF5Mime ${KMIME_WANT_VERSION} CONFIG REQUIRED)
find_package(Qt${QT_MAJOR_VERSION} ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Test Network PrintSupport)
find_package(Assuan2 REQUIRED)
find_package(Boost ${BOOST_REQUIRED_VERSION} MODULE REQUIRED)
find_path(Boost_TOPOLOGICAL_SORT_DIR NAMES boost/graph/topological_sort.hpp PATHS ${Boost_INCLUDE_DIRS})
if(NOT Boost_TOPOLOGICAL_SORT_DIR)
message(FATAL_ERROR "The Boost Topological_sort header was NOT found. Should be part of Boost graph module.")
endif()
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)
include (ConfigureChecks.cmake)
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}
${Boost_INCLUDE_DIRS}
${ASSUAN2_INCLUDES}
)
add_definitions(-D_ASSUAN_ONLY_GPG_ERRORS)
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050e00)
add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x055B00)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-braces -Wno-parentheses -Wno-ignored-qualifiers")
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(KF5DocTools_FOUND)
kdoctools_install(po)
add_subdirectory(doc)
endif()
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/config-kleopatra.h.cmake b/config-kleopatra.h.cmake
index 8606784de..4e59e3bb8 100644
--- a/config-kleopatra.h.cmake
+++ b/config-kleopatra.h.cmake
@@ -1,55 +1,58 @@
/* Define to 1 if you have a recent enough libassuan */
#cmakedefine HAVE_USABLE_ASSUAN 1
/* Define to 1 if you have libassuan v2 */
#cmakedefine HAVE_ASSUAN2 1
#ifndef HAVE_ASSUAN2
/* Define to 1 if your libassuan has the assuan_fd_t type */
#cmakedefine HAVE_ASSUAN_FD_T 1
/* Define to 1 if your libassuan has the assuan_inquire_ext function */
#cmakedefine HAVE_ASSUAN_INQUIRE_EXT 1
/* Define to 1 if your assuan_inquire_ext puts the buffer arguments into the callback signature */
#cmakedefine HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT 1
/* Define to 1 if your libassuan has the assuan_sock_get_nonce function */
#cmakedefine HAVE_ASSUAN_SOCK_GET_NONCE 1
#endif
/* Define to 1 if you build libkleopatraclient */
#cmakedefine HAVE_KLEOPATRACLIENT_LIBRARY 1
/* DBus available */
#cmakedefine01 HAVE_QDBUS
/* Defined if GpgME++ supports trust signatures */
#cmakedefine GPGMEPP_SUPPORTS_TRUST_SIGNATURES 1
/* Defined if QGpgME supports trust signatures */
#cmakedefine QGPGME_SUPPORTS_TRUST_SIGNATURES 1
/* Defined if QGpgME supports setting an expiration date for signatures */
#cmakedefine QGPGME_SUPPORTS_SIGNATURE_EXPIRATION 1
/* Defined if QGpgME supports changing the expiration date of the primary key and the subkeys simultaneously */
#cmakedefine QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY 1
/* Defined if QGpgME supports retrieving the default value of a config entry */
#cmakedefine QGPGME_CRYPTOCONFIGENTRY_HAS_DEFAULT_VALUE 1
/* Defined if QGpgME supports WKD lookup */
#cmakedefine QGPGME_SUPPORTS_WKDLOOKUP 1
/* Defined if QGpgME supports specifying an import filter when importing keys */
#cmakedefine QGPGME_SUPPORTS_IMPORT_WITH_FILTER 1
/* Defined if QGpgME supports setting key origin when importing keys */
#cmakedefine QGPGME_SUPPORTS_IMPORT_WITH_KEY_ORIGIN 1
/* Defined if QGpgME supports the export of secret keys */
#cmakedefine QGPGME_SUPPORTS_SECRET_KEY_EXPORT 1
/* Defined if QGpgME supports the export of secret subkeys */
#cmakedefine QGPGME_SUPPORTS_SECRET_SUBKEY_EXPORT 1
+
+/* Defined if QGpgME supports receiving keys by their key ids */
+#cmakedefine QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID 1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e792ccb2c..476a9c366 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,389 +1,390 @@
# 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
utils/gnupg-registry.c
selftest/registrycheck.cpp
utils/windowsprocessdevice.cpp
utils/userinfo_win.cpp
)
else()
set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp)
set(_kleopatra_extra_SRCS)
endif()
set(_kleopatra_uiserver_SRCS
uiserver/sessiondata.cpp
uiserver/uiserver.cpp
${_kleopatra_extra_uiserver_SRCS}
uiserver/assuanserverconnection.cpp
uiserver/echocommand.cpp
uiserver/decryptverifycommandemailbase.cpp
uiserver/decryptverifycommandfilesbase.cpp
uiserver/signcommand.cpp
uiserver/signencryptfilescommand.cpp
uiserver/prepencryptcommand.cpp
uiserver/prepsigncommand.cpp
uiserver/encryptcommand.cpp
uiserver/selectcertificatecommand.cpp
uiserver/importfilescommand.cpp
uiserver/createchecksumscommand.cpp
uiserver/verifychecksumscommand.cpp
selftest/uiservercheck.cpp
)
if(ASSUAN2_FOUND)
include_directories(${ASSUAN2_INCLUDES})
set(_kleopatra_uiserver_extra_libs ${ASSUAN2_LIBRARIES})
else()
include_directories(${ASSUAN_INCLUDES})
if(WIN32)
set(_kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES})
else()
set(_kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES})
endif()
endif()
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()
ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui)
set(_kleopatra_SRCS
utils/gui-helper.cpp
utils/filedialog.cpp
utils/kdpipeiodevice.cpp
utils/headerview.cpp
utils/scrollarea.cpp
utils/dragqueen.cpp
utils/multivalidator.cpp
utils/systemtrayicon.cpp
utils/path-helper.cpp
utils/input.cpp
utils/output.cpp
utils/validation.cpp
utils/wsastarter.cpp
utils/iodevicelogger.cpp
utils/log.cpp
utils/action_data.cpp
utils/types.cpp
utils/archivedefinition.cpp
utils/auditlog.cpp
utils/clipboardmenu.cpp
utils/kuniqueservice.cpp
utils/tags.cpp
utils/writecertassuantransaction.cpp
utils/keyparameters.cpp
utils/userinfo.cpp
selftest/selftest.cpp
selftest/enginecheck.cpp
selftest/gpgconfcheck.cpp
selftest/gpgagentcheck.cpp
selftest/libkleopatrarccheck.cpp
selftest/compliancecheck.cpp
${_kleopatra_extra_SRCS}
view/htmllabel.cpp
view/keylistcontroller.cpp
view/keytreeview.cpp
view/searchbar.cpp
view/smartcardwidget.cpp
view/openpgpkeycardwidget.cpp
view/padwidget.cpp
view/pgpcardwidget.cpp
view/pivcardwidget.cpp
view/p15cardwidget.cpp
view/netkeywidget.cpp
view/nullpinwidget.cpp
view/tabwidget.cpp
view/keycacheoverlay.cpp
view/urllabel.cpp
view/waitwidget.cpp
view/welcomewidget.cpp
dialogs/certificateselectiondialog.cpp
dialogs/certifywidget.cpp
dialogs/expirydialog.cpp
dialogs/lookupcertificatesdialog.cpp
dialogs/ownertrustdialog.cpp
dialogs/selftestdialog.cpp
dialogs/certifycertificatedialog.cpp
dialogs/revokecertificationwidget.cpp
dialogs/revokecertificationdialog.cpp
dialogs/adduseriddialog.cpp
dialogs/addemaildialog.cpp
dialogs/deletecertificatesdialog.cpp
dialogs/setinitialpindialog.cpp
dialogs/certificatedetailsdialog.cpp
dialogs/certificatedetailswidget.cpp
dialogs/trustchainwidget.cpp
dialogs/weboftrustwidget.cpp
dialogs/weboftrustdialog.cpp
dialogs/exportdialog.cpp
dialogs/subkeyswidget.cpp
dialogs/gencardkeydialog.cpp
dialogs/updatenotification.cpp
dialogs/pivcardapplicationadministrationkeyinputdialog.cpp
dialogs/certificatedetailsinputwidget.cpp
dialogs/createcsrforcardkeydialog.cpp
dialogs/groupdetailsdialog.cpp
dialogs/editgroupdialog.cpp
crypto/controller.cpp
crypto/certificateresolver.cpp
crypto/sender.cpp
crypto/recipient.cpp
crypto/task.cpp
crypto/taskcollection.cpp
crypto/decryptverifytask.cpp
crypto/decryptverifyemailcontroller.cpp
crypto/decryptverifyfilescontroller.cpp
crypto/autodecryptverifyfilescontroller.cpp
crypto/encryptemailtask.cpp
crypto/encryptemailcontroller.cpp
crypto/newsignencryptemailcontroller.cpp
crypto/signencrypttask.cpp
crypto/signencryptfilescontroller.cpp
crypto/signemailtask.cpp
crypto/signemailcontroller.cpp
crypto/createchecksumscontroller.cpp
crypto/verifychecksumscontroller.cpp
crypto/gui/wizard.cpp
crypto/gui/wizardpage.cpp
crypto/gui/certificateselectionline.cpp
crypto/gui/certificatelineedit.cpp
crypto/gui/signingcertificateselectionwidget.cpp
crypto/gui/signingcertificateselectiondialog.cpp
crypto/gui/resultitemwidget.cpp
crypto/gui/resultlistwidget.cpp
crypto/gui/resultpage.cpp
crypto/gui/newresultpage.cpp
crypto/gui/signencryptfileswizard.cpp
crypto/gui/signencryptemailconflictdialog.cpp
crypto/gui/decryptverifyoperationwidget.cpp
crypto/gui/decryptverifyfileswizard.cpp
crypto/gui/decryptverifyfilesdialog.cpp
crypto/gui/objectspage.cpp
crypto/gui/resolverecipientspage.cpp
crypto/gui/signerresolvepage.cpp
crypto/gui/encryptemailwizard.cpp
crypto/gui/signemailwizard.cpp
crypto/gui/signencryptwidget.cpp
crypto/gui/signencryptwizard.cpp
crypto/gui/unknownrecipientwidget.cpp
crypto/gui/verifychecksumsdialog.cpp
commands/command.cpp
commands/gnupgprocesscommand.cpp
commands/detailscommand.cpp
commands/exportcertificatecommand.cpp
commands/exportgroupscommand.cpp
commands/importcertificatescommand.cpp
commands/importcertificatefromfilecommand.cpp
commands/importcertificatefromclipboardcommand.cpp
commands/importcertificatefromdatacommand.cpp
+ commands/importcertificatefromkeyservercommand.cpp
commands/lookupcertificatescommand.cpp
commands/reloadkeyscommand.cpp
commands/refreshx509certscommand.cpp
commands/refreshopenpgpcertscommand.cpp
commands/deletecertificatescommand.cpp
commands/decryptverifyfilescommand.cpp
commands/signencryptfilescommand.cpp
commands/signencryptfoldercommand.cpp
commands/encryptclipboardcommand.cpp
commands/signclipboardcommand.cpp
commands/decryptverifyclipboardcommand.cpp
commands/clearcrlcachecommand.cpp
commands/dumpcrlcachecommand.cpp
commands/dumpcertificatecommand.cpp
commands/importcrlcommand.cpp
commands/changeexpirycommand.cpp
commands/changeownertrustcommand.cpp
commands/changeroottrustcommand.cpp
commands/changepassphrasecommand.cpp
commands/certifycertificatecommand.cpp
commands/revokecertificationcommand.cpp
commands/selftestcommand.cpp
commands/exportsecretkeycommand.cpp
commands/exportsecretkeycommand_old.cpp
commands/exportsecretsubkeycommand.cpp
commands/exportopenpgpcertstoservercommand.cpp
commands/adduseridcommand.cpp
commands/newcertificatecommand.cpp
commands/setinitialpincommand.cpp
commands/learncardkeyscommand.cpp
commands/checksumcreatefilescommand.cpp
commands/checksumverifyfilescommand.cpp
commands/exportpaperkeycommand.cpp
commands/importpaperkeycommand.cpp
commands/genrevokecommand.cpp
commands/keytocardcommand.cpp
commands/cardcommand.cpp
commands/pivgeneratecardkeycommand.cpp
commands/changepincommand.cpp
commands/authenticatepivcardapplicationcommand.cpp
commands/setpivcardapplicationadministrationkeycommand.cpp
commands/certificatetopivcardcommand.cpp
commands/importcertificatefrompivcardcommand.cpp
commands/createopenpgpkeyfromcardkeyscommand.cpp
commands/createcsrforcardkeycommand.cpp
commands/listreaderscommand.cpp
${_kleopatra_uiserver_files}
conf/configuredialog.cpp
conf/groupsconfigdialog.cpp
conf/groupsconfigpage.cpp
conf/groupsconfigwidget.cpp
newcertificatewizard/listwidget.cpp
newcertificatewizard/newcertificatewizard.cpp
smartcard/readerstatus.cpp
smartcard/card.cpp
smartcard/openpgpcard.cpp
smartcard/netkeycard.cpp
smartcard/pivcard.cpp
smartcard/p15card.cpp
smartcard/keypairinfo.cpp
smartcard/utils.cpp
smartcard/deviceinfowatcher.cpp
accessibility/accessiblerichtextlabel.cpp
accessibility/accessiblewidgetfactory.cpp
aboutdata.cpp
systrayicon.cpp
kleopatraapplication.cpp
mainwindow.cpp
main.cpp
kleopatra.qrc
)
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 ${_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/ownertrustdialog.ui
dialogs/selectchecklevelwidget.ui
dialogs/selftestdialog.ui
dialogs/adduseriddialog.ui
dialogs/setinitialpindialog.ui
dialogs/trustchainwidget.ui
dialogs/subkeyswidget.ui
newcertificatewizard/listwidget.ui
newcertificatewizard/chooseprotocolpage.ui
newcertificatewizard/enterdetailspage.ui
newcertificatewizard/keycreationpage.ui
newcertificatewizard/resultpage.ui
newcertificatewizard/advancedsettingsdialog.ui
)
kconfig_add_kcfg_files(_kleopatra_SRCS
kcfg/tooltippreferences.kcfgc
kcfg/emailoperationspreferences.kcfgc
kcfg/fileoperationspreferences.kcfgc
kcfg/smimevalidationpreferences.kcfgc
kcfg/tagspreferences.kcfgc
kcfg/settings.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
QGpgme
${_kleopatra_extra_libs}
KF5::Libkleo
KF5::Mime
KF5::I18n
KF5::XmlGui
KF5::IconThemes
KF5::WindowSystem
KF5::CoreAddons
KF5::ItemModels
KF5::Crash
Qt${QT_MAJOR_VERSION}::Network
Qt${QT_MAJOR_VERSION}::PrintSupport # Printing secret keys
${_kleopatra_uiserver_extra_libs}
${_kleopatra_dbusaddons_libs}
kleopatraclientcore
${_kleopatra_platform_libs}
)
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/commands/importcertificatefromkeyservercommand.cpp b/src/commands/importcertificatefromkeyservercommand.cpp
new file mode 100644
index 000000000..d43740dce
--- /dev/null
+++ b/src/commands/importcertificatefromkeyservercommand.cpp
@@ -0,0 +1,81 @@
+/* commands/importcertificatefromkeyservercommand.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ SPDX-FileCopyrightText: 2022 g10 Code GmbH
+ SPDX-FileContributor: Ingo Klöcker
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#include
+
+#include "importcertificatefromkeyservercommand.h"
+#include "importcertificatescommand_p.h"
+
+#include
+
+#include "kleopatra_debug.h"
+
+using namespace Kleo;
+
+class ImportCertificateFromKeyserverCommand::Private : public ImportCertificatesCommand::Private
+{
+ friend class ::ImportCertificateFromKeyserverCommand;
+ ImportCertificateFromKeyserverCommand *q_func() const
+ {
+ return static_cast(q);
+ }
+public:
+ explicit Private(ImportCertificateFromKeyserverCommand *qq,
+ const QStringList &keyIds, const QString &id);
+ ~Private() override;
+
+private:
+ void start();
+
+private:
+ QStringList mKeyIds;
+ QString mId;
+};
+
+ImportCertificateFromKeyserverCommand::Private *ImportCertificateFromKeyserverCommand::d_func()
+{
+ return static_cast(d.get());
+}
+const ImportCertificateFromKeyserverCommand::Private *ImportCertificateFromKeyserverCommand::d_func() const
+{
+ return static_cast(d.get());
+}
+
+#define q q_func()
+#define d d_func()
+
+ImportCertificateFromKeyserverCommand::Private::Private(ImportCertificateFromKeyserverCommand *qq,
+ const QStringList &keyIds, const QString &id)
+ : ImportCertificatesCommand::Private{qq, nullptr}
+ , mKeyIds{keyIds}
+ , mId{id}
+{
+}
+
+ImportCertificateFromKeyserverCommand::Private::~Private() = default;
+
+void ImportCertificateFromKeyserverCommand::Private::start()
+{
+ startImport(GpgME::OpenPGP, mKeyIds, mId);
+}
+
+ImportCertificateFromKeyserverCommand::ImportCertificateFromKeyserverCommand(const QStringList &keyIds, const QString &id)
+ : ImportCertificatesCommand{new Private{this, keyIds, id}}
+{
+}
+
+ImportCertificateFromKeyserverCommand::~ImportCertificateFromKeyserverCommand() = default;
+
+void ImportCertificateFromKeyserverCommand::doStart()
+{
+ d->start();
+}
+
+#undef q_func
+#undef d_func
diff --git a/src/commands/importcertificatefromkeyservercommand.h b/src/commands/importcertificatefromkeyservercommand.h
new file mode 100644
index 000000000..59a757479
--- /dev/null
+++ b/src/commands/importcertificatefromkeyservercommand.h
@@ -0,0 +1,36 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ importcertificatefromkeyservercommand.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ SPDX-FileCopyrightText: 2022 g10 Code GmbH
+ SPDX-FileContributor: Ingo Klöcker
+
+ SPDX-License-Identifier: GPL-2.0-or-later
+*/
+
+#pragma once
+
+#include "importcertificatescommand.h"
+
+namespace Kleo
+{
+
+class ImportCertificateFromKeyserverCommand : public ImportCertificatesCommand
+{
+ Q_OBJECT
+public:
+ explicit ImportCertificateFromKeyserverCommand(const QStringList &keyIds,
+ const QString &id = {});
+ ~ImportCertificateFromKeyserverCommand() override;
+
+private:
+ void doStart() override;
+
+private:
+ class Private;
+ inline Private *d_func();
+ inline const Private *d_func() const;
+};
+}
+
+
diff --git a/src/commands/importcertificatescommand.cpp b/src/commands/importcertificatescommand.cpp
index c2c02a678..58c71f3f4 100644
--- a/src/commands/importcertificatescommand.cpp
+++ b/src/commands/importcertificatescommand.cpp
@@ -1,800 +1,845 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/importcertificatescommand.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007, 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
- SPDX-FileCopyrightText: 2021 g10 Code GmbH
+ SPDX-FileCopyrightText: 2021, 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include
#include "importcertificatescommand.h"
#include "importcertificatescommand_p.h"
#include "certifycertificatecommand.h"
#include "kleopatra_debug.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
+#ifdef QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID
+#include
+#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // for Qt::escape
#include
#include
#include
"};
}
report += QLatin1String{""};
return report;
}
// Returns false on error, true if please certify was shown.
bool ImportCertificatesCommand::Private::showPleaseCertify(const GpgME::Import &imp)
{
const char *fpr = imp.fingerprint();
if (!fpr) {
// WTF
qCWarning(KLEOPATRA_LOG) << "Import without fingerprint";
return false;
}
// Exactly one public key imported. Let's see if it is openpgp. We are async here so
// we can just fetch it.
auto ctx = GpgME::Context::createForProtocol(GpgME::OpenPGP);
if (!ctx) {
// WTF
qCWarning(KLEOPATRA_LOG) << "Failed to create OpenPGP proto";
return false;
}
GpgME::Error err;
auto key = ctx->key(fpr, err, false);
delete ctx;
if (key.isNull() || err) {
// No such key most likely not OpenPGP
return false;
}
for (const auto &uid: key.userIDs()) {
if (uid.validity() >= GpgME::UserID::Marginal) {
// Already marginal so don't bug the user
return false;
}
}
const QStringList suggestions = QStringList() << i18n("A phone call to the person.")
<< i18n("Using a business card.")
<< i18n("Confirming it on a trusted website.");
auto sel = KMessageBox::questionYesNo(parentWidgetOrView(),
i18n("In order to mark the certificate as valid (green) it needs to be certified.") + QStringLiteral("
") +
i18n("Certifying means that you check the Fingerprint.") + QStringLiteral("
") +
i18n("Some suggestions to do this are:") +
QStringLiteral("%1").arg(suggestions.join(QStringLiteral("
") +
i18n("Do you wish to start this process now?"),
i18nc("@title", "You have imported a new certificate (public key)"),
KStandardGuiItem::yes(), KStandardGuiItem::no(), QStringLiteral("CertifyQuestion"));
if (sel == KMessageBox::Yes) {
QEventLoop loop;
auto cmd = new Commands::CertifyCertificateCommand(key);
cmd->setParentWidget(parentWidgetOrView());
loop.connect(cmd, SIGNAL(finished()), SLOT(quit()));
QMetaObject::invokeMethod(cmd, &Commands::CertifyCertificateCommand::start, Qt::QueuedConnection);
loop.exec();
}
return true;
}
void ImportCertificatesCommand::Private::showDetails(const std::vector &res,
const std::vector &groups)
{
if (res.size() == 1 && res[0].result.numImported() == 1 && res[0].result.imports().size() == 1) {
if (showPleaseCertify(res[0].result.imports()[0])) {
return;
}
}
setImportResultProxyModel(res);
information(make_message_report(res, groups),
i18n("Certificate Import Result"));
}
static QString make_error_message(const Error &err, const QString &id)
{
Q_ASSERT(err);
Q_ASSERT(!err.isCanceled());
return id.isEmpty()
? i18n("An error occurred while trying "
"to import the certificate:
"
"%1
",
QString::fromLocal8Bit(err.asString()))
: i18n("An error occurred while trying "
"to import the certificate %1:
"
"%2
",
id, QString::fromLocal8Bit(err.asString()));
}
void ImportCertificatesCommand::Private::showError(QWidget *parent, const Error &err, const QString &id)
{
if (parent) {
KMessageBox::error(parent, make_error_message(err, id), i18n("Certificate Import Failed"));
} else {
showError(err, id);
}
}
void ImportCertificatesCommand::Private::showError(const Error &err, const QString &id)
{
error(make_error_message(err, id), i18n("Certificate Import Failed"));
}
void ImportCertificatesCommand::Private::setWaitForMoreJobs(bool wait)
{
if (wait == waitForMoreJobs) {
return;
}
waitForMoreJobs = wait;
if (!waitForMoreJobs) {
tryToFinish();
}
}
void ImportCertificatesCommand::Private::importResult(const ImportResult &result)
{
const auto finishedJob = q->sender();
auto it = std::find_if(std::cbegin(jobs), std::cend(jobs),
[finishedJob](const auto &job) { return job.job == finishedJob; });
Q_ASSERT(it != std::cend(jobs));
if (it == std::cend(jobs)) {
qCWarning(KLEOPATRA_LOG) << __func__ << "Error: Finished job not found";
}
const auto job = *it;
jobs.erase(std::remove(std::begin(jobs), std::end(jobs), job), std::end(jobs));
importResult({job.id, job.protocol, job.type, result});
}
void ImportCertificatesCommand::Private::importResult(const ImportResultData &result)
{
qCDebug(KLEOPATRA_LOG) << __func__ << result.id;
results.push_back(result);
tryToFinish();
}
static void handleOwnerTrust(const std::vector &results)
{
//iterate over all imported certificates
for (const auto &r: results) {
//when a new certificate got a secret key
if (r.result.numSecretKeysImported() >= 1) {
const char *fingerPr = r.result.imports()[0].fingerprint();
GpgME::Error err;
QScopedPointer
ctx(Context::createForProtocol(GpgME::Protocol::OpenPGP));
if (!ctx){
qCWarning(KLEOPATRA_LOG) << "Failed to get context";
continue;
}
const Key toTrustOwner = ctx->key(fingerPr, err , false);
if (toTrustOwner.isNull()) {
return;
}
QStringList uids;
const auto toTrustOwnerUserIDs{toTrustOwner.userIDs()};
uids.reserve(toTrustOwnerUserIDs.size());
for (const UserID &uid : toTrustOwnerUserIDs) {
uids << Formatting::prettyNameAndEMail(uid);
}
const QString str = xi18nc("@info",
"You have imported a Secret Key."
"The key has the fingerprint:"
"%1"
""
"And claims the User IDs:"
"- %2
"
""
"Is this your own key? (Set trust level to ultimate)",
QString::fromUtf8(fingerPr),
uids.join(QLatin1String("- ")));
int k = KMessageBox::questionYesNo(nullptr, str, i18nc("@title:window",
"Secret key imported"));
if (k == KMessageBox::Yes) {
//To use the ChangeOwnerTrustJob over
//the CryptoBackendFactory
const QGpgME::Protocol *const backend = QGpgME::openpgp();
if (!backend){
qCWarning(KLEOPATRA_LOG) << "Failed to get CryptoBackend";
return;
}
ChangeOwnerTrustJob *const j = backend->changeOwnerTrustJob();
j->start(toTrustOwner, Key::Ultimate);
}
}
}
}
static void validateImportedCertificate(const GpgME::Import &import)
{
if (const auto fpr = import.fingerprint()) {
auto key = KeyCache::instance()->findByFingerprint(fpr);
if (!key.isNull()) {
// this triggers a keylisting with validation for this certificate
key.update();
} else {
qCWarning(KLEOPATRA_LOG) << __func__ << "Certificate with fingerprint" << fpr << "not found";
}
}
}
static void handleExternalCMSImports(const std::vector &results)
{
// For external CMS Imports we have to manually do a keylist
// with validation to get the intermediate and root ca imported
// automatically if trusted-certs and extra-certs are used.
for (const auto &r : results) {
if (r.protocol == GpgME::CMS && r.type == ImportType::External
&& !importFailed(r) && !importWasCanceled(r)) {
const auto imports = r.result.imports();
std::for_each(std::begin(imports), std::end(imports), &validateImportedCertificate);
}
}
}
void ImportCertificatesCommand::Private::processResults()
{
handleExternalCMSImports(results);
handleOwnerTrust(results);
importGroups();
showDetails(results, importedGroups);
auto tv = dynamic_cast (view());
if (!tv) {
qCDebug(KLEOPATRA_LOG) << "Failed to find treeview";
} else {
tv->expandAll();
}
finished();
}
void ImportCertificatesCommand::Private::tryToFinish()
{
if (waitForMoreJobs || !jobs.empty()) {
return;
}
auto keyCache = KeyCache::mutableInstance();
keyListConnection = connect(keyCache.get(), &KeyCache::keyListingDone,
q, [this]() { keyCacheUpdated(); });
keyCache->startKeyListing();
}
void ImportCertificatesCommand::Private::keyCacheUpdated()
{
disconnect(keyListConnection);
keyCacheAutoRefreshSuspension.reset();
const auto allIds = std::accumulate(std::cbegin(results), std::cend(results),
std::set{},
[](auto &allIds, const auto &r) {
allIds.insert(r.id);
return allIds;
});
const auto canceledIds = std::accumulate(std::cbegin(results), std::cend(results),
std::set{},
[](auto &canceledIds, const auto &r) {
if (importWasCanceled(r)) {
canceledIds.insert(r.id);
}
return canceledIds;
});
const auto totalConsidered = std::accumulate(std::cbegin(results), std::cend(results),
0,
[](auto totalConsidered, const auto &r) {
return totalConsidered + r.result.numConsidered();
});
if (totalConsidered == 0 && canceledIds.size() == allIds.size()) {
// nothing was considered for import and at least one import per id was
// canceled => treat the command as canceled
canceled();
return;
}
if (std::any_of(std::cbegin(results), std::cend(results), &importFailed)) {
setImportResultProxyModel(results);
for (const auto &r : results) {
if (importFailed(r)) {
showError(r.result.error(), r.id);
}
}
finished();
return;
}
processResults();
}
static ImportedGroup storeGroup(const KeyGroup &group, const QString &id)
{
const auto status = KeyCache::instance()->group(group.id()).isNull() ?
ImportedGroup::Status::New :
ImportedGroup::Status::Updated;
if (status == ImportedGroup::Status::New) {
KeyCache::mutableInstance()->insert(group);
} else {
KeyCache::mutableInstance()->update(group);
}
return {id, group, status};
}
void ImportCertificatesCommand::Private::importGroups()
{
for (const auto &path : filesToImportGroupsFrom) {
const bool certificateImportSucceeded =
std::any_of(std::cbegin(results), std::cend(results),
[path](const auto &r) {
return r.id == path && !importFailed(r) && !importWasCanceled(r);
});
if (certificateImportSucceeded) {
qCDebug(KLEOPATRA_LOG) << __func__ << "Importing groups from file" << path;
const auto groups = readKeyGroups(path);
std::transform(std::begin(groups), std::end(groups),
std::back_inserter(importedGroups),
[path](const auto &group) {
return storeGroup(group, path);
});
}
}
}
static std::unique_ptr get_import_job(GpgME::Protocol protocol)
{
Q_ASSERT(protocol != UnknownProtocol);
if (const auto backend = (protocol == GpgME::OpenPGP ? QGpgME::openpgp() : QGpgME::smime())) {
return std::unique_ptr(backend->importJob());
} else {
return std::unique_ptr();
}
}
void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, const QByteArray &data, const QString &id, const ImportOptions &options)
{
Q_ASSERT(protocol != UnknownProtocol);
if (std::find(nonWorkingProtocols.cbegin(), nonWorkingProtocols.cend(), protocol) != nonWorkingProtocols.cend()) {
return;
}
std::unique_ptr job = get_import_job(protocol);
if (!job.get()) {
nonWorkingProtocols.push_back(protocol);
error(i18n("The type of this certificate (%1) is not supported by this Kleopatra installation.",
Formatting::displayName(protocol)),
i18n("Certificate Import Failed"));
importResult({id, protocol, ImportType::Local, ImportResult{}});
return;
}
keyCacheAutoRefreshSuspension = KeyCache::mutableInstance()->suspendAutoRefresh();
connect(job.get(), SIGNAL(result(GpgME::ImportResult)),
q, SLOT(importResult(GpgME::ImportResult)));
connect(job.get(), &Job::progress,
q, &Command::progress);
#ifdef QGPGME_SUPPORTS_IMPORT_WITH_FILTER
job->setImportFilter(options.importFilter);
#endif
#ifdef QGPGME_SUPPORTS_IMPORT_WITH_KEY_ORIGIN
job->setKeyOrigin(options.keyOrigin, options.keyOriginUrl);
#endif
const GpgME::Error err = job->start(data);
if (err.code()) {
importResult({id, protocol, ImportType::Local, ImportResult{err}});
} else {
jobs.push_back({id, protocol, ImportType::Local, job.release()});
}
}
static std::unique_ptr get_import_from_keyserver_job(GpgME::Protocol protocol)
{
Q_ASSERT(protocol != UnknownProtocol);
if (const auto backend = (protocol == GpgME::OpenPGP ? QGpgME::openpgp() : QGpgME::smime())) {
return std::unique_ptr(backend->importFromKeyserverJob());
} else {
return std::unique_ptr();
}
}
void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, const std::vector &keys, const QString &id)
{
Q_ASSERT(protocol != UnknownProtocol);
if (std::find(nonWorkingProtocols.cbegin(), nonWorkingProtocols.cend(), protocol) != nonWorkingProtocols.cend()) {
return;
}
std::unique_ptr job = get_import_from_keyserver_job(protocol);
if (!job.get()) {
nonWorkingProtocols.push_back(protocol);
error(i18n("The type of this certificate (%1) is not supported by this Kleopatra installation.",
Formatting::displayName(protocol)),
i18n("Certificate Import Failed"));
importResult({id, protocol, ImportType::External, ImportResult{}});
return;
}
keyCacheAutoRefreshSuspension = KeyCache::mutableInstance()->suspendAutoRefresh();
connect(job.get(), SIGNAL(result(GpgME::ImportResult)),
q, SLOT(importResult(GpgME::ImportResult)));
connect(job.get(), &Job::progress,
q, &Command::progress);
const GpgME::Error err = job->start(keys);
if (err.code()) {
importResult({id, protocol, ImportType::External, ImportResult{err}});
} else {
jobs.push_back({id, protocol, ImportType::External, job.release()});
}
}
+static auto get_receive_keys_job(GpgME::Protocol protocol)
+{
+ Q_ASSERT(protocol != UnknownProtocol);
+
+#ifdef QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID
+ std::unique_ptr job{};
+ if (const auto backend = (protocol == GpgME::OpenPGP ? QGpgME::openpgp() : QGpgME::smime())) {
+ job.reset(backend->receiveKeysJob());
+ }
+ return job;
+#else
+ return std::unique_ptr{};
+#endif
+}
+
+void ImportCertificatesCommand::Private::startImport(GpgME::Protocol protocol, const QStringList &keyIds, const QString &id)
+{
+ Q_ASSERT(protocol != UnknownProtocol);
+
+ auto job = get_receive_keys_job(protocol);
+ if (!job.get()) {
+ qCWarning(KLEOPATRA_LOG) << "Failed to get ReceiveKeysJob for protocol" << Formatting::displayName(protocol);
+ importResult({id, protocol, ImportType::External, ImportResult{}});
+ return;
+ }
+
+#ifdef QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID
+ keyCacheAutoRefreshSuspension = KeyCache::mutableInstance()->suspendAutoRefresh();
+
+ connect(job.get(), SIGNAL(result(GpgME::ImportResult)),
+ q, SLOT(importResult(GpgME::ImportResult)));
+ connect(job.get(), &Job::progress,
+ q, &Command::progress);
+ const GpgME::Error err = job->start(keyIds);
+ if (err.code()) {
+ importResult({id, protocol, ImportType::External, ImportResult{err}});
+ } else {
+ jobs.push_back({id, protocol, ImportType::External, job.release()});
+ }
+#endif
+}
+
void ImportCertificatesCommand::Private::importGroupsFromFile(const QString &filename)
{
filesToImportGroupsFrom.push_back(filename);
}
void ImportCertificatesCommand::doCancel()
{
std::for_each(std::cbegin(d->jobs), std::cend(d->jobs),
[](const auto &job) { job.job->slotCancel(); });
d->jobs.clear();
}
#undef d
#undef q
#include "moc_importcertificatescommand.cpp"
#include "importcertificatescommand.moc"
diff --git a/src/commands/importcertificatescommand_p.h b/src/commands/importcertificatescommand_p.h
index e947b6cf6..9caf3c9d9 100644
--- a/src/commands/importcertificatescommand_p.h
+++ b/src/commands/importcertificatescommand_p.h
@@ -1,150 +1,151 @@
/* -*- mode: c++; c-basic-offset:4 -*-
commands/importcertificatescommand_p.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007, 2008 Klarälvdalens Datakonsult AB
- SPDX-FileCopyrightText: 2021 g10 Code GmbH
+ SPDX-FileCopyrightText: 2021, 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "command_p.h"
#include "importcertificatescommand.h"
#include
#include
#include
#include
#include