Page MenuHome GnuPG

No OneTemporary

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96fb5a6e..59f09217 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,96 +1,96 @@
cmake_minimum_required(VERSION 3.5)
-set(PIM_VERSION "5.13.41")
+set(PIM_VERSION "5.13.42")
project(libkleo VERSION ${PIM_VERSION})
set(KF5_MIN_VERSION "5.67.0")
find_package(ECM ${KF5_MIN_VERSION} CONFIG REQUIRED)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
set(LIBRARY_NAMELINK)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
include(GenerateExportHeader)
include(ECMSetupVersion)
include(ECMGenerateHeaders)
include(ECMGeneratePriFile)
include(ECMSetupVersion)
include(FeatureSummary)
include(ECMQtDeclareLoggingCategory)
include(ECMAddTests)
set(LIBKLEO_LIB_VERSION ${PIM_VERSION})
set(QT_REQUIRED_VERSION "5.12.0")
set(KDEPIMTEXTEDIT_VERSION "5.13.40")
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets)
find_package(KF5I18n ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5WidgetsAddons ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5Completion ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5CoreAddons ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5Codecs ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5ItemModels ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5PimTextEdit ${KDEPIMTEXTEDIT_VERSION} CONFIG)
set(GPGMEPP_LIB_VERSION "1.11.1")
find_package(Gpgmepp ${GPGMEPP_LIB_VERSION} CONFIG REQUIRED)
set_package_properties(Gpgmepp PROPERTIES DESCRIPTION "GpgME++ Library" URL "https://www.gnupg.org" TYPE REQUIRED PURPOSE "GpgME++ is required for OpenPGP support")
find_package(QGpgme ${GPGMEPP_LIB_VERSION} CONFIG REQUIRED)
message(STATUS "GPGME Version ${Gpgmepp_VERSION}")
find_package(Boost 1.34.0)
set_package_properties(Boost PROPERTIES DESCRIPTION "Boost C++ Libraries" URL "https://www.boost.org" TYPE REQUIRED PURPOSE "Boost is required for building most KDEPIM applications")
set_package_properties(KF5PimTextEdit PROPERTIES DESCRIPTION
"A textedit with PIM-specific features."
URL "https://commits.kde.org/kpimtextedit"
TYPE OPTIONAL PURPOSE "Improved audit log viewer.")
ecm_setup_version(PROJECT VARIABLE_PREFIX LIBKLEO
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/libkleo_version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfigVersion.cmake"
SOVERSION 5
)
########### Targets ###########
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
#add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x060000)
add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x060000)
remove_definitions(-DQT_NO_CAST_FROM_ASCII )
########### CMake Config Files ###########
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5Libkleo")
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/KF5LibkleoConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/KF5LibkleoConfigVersion.cmake"
DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
COMPONENT Devel
)
install(EXPORT KF5LibkleoTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5LibkleoTargets.cmake NAMESPACE KF5::)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/libkleo_version.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel
)
add_subdirectory(src)
install(FILES libkleo.renamecategories libkleo.categories DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR})
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a04dc395..dc30079c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,208 +1,211 @@
# target_include_directories does not handle empty include paths
include_directories(${GPGME_INCLUDES})
add_definitions(-DTRANSLATION_DOMAIN=\"libkleopatra\")
#add_definitions( -DQT_NO_CAST_FROM_ASCII )
#add_definitions( -DQT_NO_CAST_TO_ASCII )
kde_enable_exceptions()
add_definitions( -DGPGMEPP_ERR_SOURCE_DEFAULT=13 ) # 13 is GPG_ERR_SOURCE_KLEO, even if gpg-error's too old to know about
add_subdirectory( pics )
if (BUILD_TESTING)
add_subdirectory( tests )
endif()
########### next target ###############
set(libkleo_core_SRCS
kleo/checksumdefinition.cpp
kleo/defaultkeyfilter.cpp
kleo/defaultkeygenerationjob.cpp
kleo/dn.cpp
kleo/enum.cpp
kleo/exception.cpp
kleo/kconfigbasedkeyfilter.cpp
kleo/keyfiltermanager.cpp
kleo/keyresolver.cpp
models/keycache.cpp
models/keylistmodel.cpp
models/keylistsortfilterproxymodel.cpp
models/keyrearrangecolumnsproxymodel.cpp
models/subkeylistmodel.cpp
models/useridlistmodel.cpp
utils/filesystemwatcher.cpp
utils/formatting.cpp
utils/classify.cpp
+ utils/gnupg.cpp
+ utils/hex.cpp
)
ecm_qt_declare_logging_category(libkleo_core_SRCS HEADER libkleo_debug.h IDENTIFIER LIBKLEO_LOG CATEGORY_NAME org.kde.pim.libkleo)
set(libkleo_ui_common_SRCS
ui/dnattributeorderconfigwidget.cpp
ui/kdhorizontalline.cpp
ui/filenamerequester.cpp
ui/messagebox.cpp
ui/cryptoconfigmodule.cpp
ui/cryptoconfigdialog.cpp
ui/directoryserviceswidget.cpp
ui/progressbar.cpp
ui/progressdialog.cpp
ui/auditlogviewer.cpp
)
ecm_qt_declare_logging_category(libkleo_ui_common_SRCS HEADER kleo_ui_debug.h IDENTIFIER KLEO_UI_LOG CATEGORY_NAME org.kde.pim.kleo_ui)
set(libkleo_ui_SRCS # make this a separate lib.
ui/keylistview.cpp
ui/keyselectiondialog.cpp
ui/keyrequester.cpp
ui/keyapprovaldialog.cpp
ui/newkeyapprovaldialog.cpp
ui/keyselectioncombo.cpp
)
ki18n_wrap_ui(libkleo_ui_common_SRCS
ui/directoryserviceswidget.ui
)
set(kleo_LIB_SRCS ${libkleo_core_SRCS} ${libkleo_ui_SRCS}
${libkleo_ui_common_SRCS})
set(kleo_LIB_LIBS PUBLIC QGpgme Gpgmepp PRIVATE Qt5::Widgets
KF5::I18n
KF5::Completion
KF5::ConfigCore
KF5::CoreAddons
KF5::WidgetsAddons
KF5::ItemModels
KF5::Codecs)
if (KF5PimTextEdit_FOUND)
add_definitions(-DHAVE_PIMTEXTEDIT)
set(kleo_LIB_LIBS ${kleo_LIB_LIBS} PRIVATE KF5::PimTextEdit)
endif()
add_library(KF5Libkleo ${kleo_LIB_SRCS})
generate_export_header(KF5Libkleo BASE_NAME kleo)
add_library(KF5::Libkleo ALIAS KF5Libkleo)
if(WIN32)
target_link_libraries(KF5Libkleo ${kleo_LIB_LIBS} ${GPGME_VANILLA_LIBRARIES} )
else()
target_link_libraries(KF5Libkleo ${kleo_LIB_LIBS} )
endif()
set_target_properties(KF5Libkleo PROPERTIES
VERSION ${LIBKLEO_VERSION_STRING}
SOVERSION ${LIBKLEO_SOVERSION}
EXPORT_NAME Libkleo
)
install(TARGETS
KF5Libkleo
EXPORT KF5LibkleoTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} ${LIBRARY_NAMELINK}
)
target_include_directories(KF5Libkleo PUBLIC "$<BUILD_INTERFACE:${libkleo_SOURCE_DIR}/src;${libkleo_BINARY_DIR}/src>")
target_include_directories(KF5Libkleo INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo/;${KDE_INSTALL_INCLUDEDIR_KF5}/libkleo>")
ecm_generate_headers(libkleo_CamelCase_HEADERS
HEADER_NAMES
ChecksumDefinition
DefaultKeyFilter
DefaultKeyGenerationJob
Dn
Enum
Exception
KConfigBasedKeyFilter
KeyFilter
KeyFilterManager
KeyResolver
OidMap
Predicates
Stl_Util
REQUIRED_HEADERS libkleo_HEADERS
PREFIX Libkleo
RELATIVE kleo
)
ecm_generate_headers(libkleo_CamelCase_models_HEADERS
HEADER_NAMES
KeyCache
KeyListModel
KeyListModelInterface
KeyListSortFilterProxyModel
KeyRearrangeColumnsProxyModel
SubkeyListModel
UserIDListModel
REQUIRED_HEADERS libkleo_models_HEADERS
PREFIX Libkleo
RELATIVE models
)
ecm_generate_headers(libkleo_CamelCase_utils_HEADERS
HEADER_NAMES
Classify
FileSystemWatcher
Formatting
+ GnuPG
REQUIRED_HEADERS libkleo_utils_HEADERS
PREFIX Libkleo
RELATIVE utils
)
ecm_generate_headers(libkleo_CamelCase_ui_HEADERS
HEADER_NAMES
CryptoConfigDialog
CryptoConfigModule
DNAttributeOrderConfigWidget
DirectoryServicesWidget
FileNameRequester
KDHorizontalLine
KeyApprovalDialog
NewKeyApprovalDialog
KeyRequester
KeySelectionCombo
KeySelectionDialog
MessageBox
ProgressDialog
REQUIRED_HEADERS libkleo_ui_HEADERS
PREFIX Libkleo
RELATIVE ui
)
ecm_generate_pri_file(BASE_NAME Libkleo
LIB_NAME KF5Libkleo
DEPS "QGpgme" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo
)
install(FILES
${libkleo_CamelCase_HEADERS}
${libkleo_CamelCase_models_HEADERS}
${libkleo_CamelCase_ui_HEADERS}
${libkleo_CamelCase_utils_HEADERS}
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/Libkleo
COMPONENT Devel
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/kleo_export.h
${libkleo_HEADERS}
${libkleo_models_HEADERS}
${libkleo_ui_HEADERS}
${libkleo_utils_HEADERS}
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/libkleo
COMPONENT Devel
)
install(FILES
${PRI_FILENAME}
DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
if ( WIN32 )
install ( FILES libkleopatrarc-win32.desktop DESTINATION ${KDE_INSTALL_CONFDIR} RENAME libkleopatrarc )
else ()
install ( FILES libkleopatrarc.desktop DESTINATION ${KDE_INSTALL_CONFDIR} RENAME libkleopatrarc )
endif ()
diff --git a/src/utils/gnupg.cpp b/src/utils/gnupg.cpp
new file mode 100644
index 00000000..b3ab822a
--- /dev/null
+++ b/src/utils/gnupg.cpp
@@ -0,0 +1,426 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ utils/gnupg.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2008 Klarälvdalens Datakonsult AB
+ 2016 by Bundesamt für Sicherheit in der Informationstechnik
+ Software engineering by Intevation GmbH
+
+ Kleopatra 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.
+
+ Kleopatra 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "gnupg.h"
+
+#include "utils/hex.h"
+
+#include <gpgme++/engineinfo.h>
+#include <gpgme++/error.h>
+#include <gpgme++/key.h>
+
+#include <QGpgME/Protocol>
+#include <QGpgME/CryptoConfig>
+
+#include "libkleo_debug.h"
+
+#include <QDir>
+#include <QFile>
+#include <QString>
+#include <QProcess>
+#include <QByteArray>
+#include <QStandardPaths>
+#include <QCoreApplication>
+#include <gpg-error.h>
+
+#ifdef Q_OS_WIN
+#include "gnupg-registry.h"
+#endif // Q_OS_WIN
+
+#include <algorithm>
+#include <array>
+
+using namespace GpgME;
+
+QString Kleo::gnupgHomeDirectory()
+{
+#ifdef Q_OS_WIN
+ return QFile::decodeName(default_homedir());
+#else
+ const QByteArray gnupgHome = qgetenv("GNUPGHOME");
+ if (!gnupgHome.isEmpty()) {
+ return QFile::decodeName(gnupgHome);
+ } else {
+ return QDir::homePath() + QLatin1String("/.gnupg");
+ }
+#endif
+}
+
+int Kleo::makeGnuPGError(int code)
+{
+ return gpg_error(static_cast<gpg_err_code_t>(code));
+}
+
+static QString findGpgExe(GpgME::Engine engine, const QString &exe)
+{
+ const GpgME::EngineInfo info = GpgME::engineInfo(engine);
+ return info.fileName() ? QFile::decodeName(info.fileName()) : QStandardPaths::findExecutable(exe);
+}
+
+QString Kleo::gpgConfPath()
+{
+ static const auto path = findGpgExe(GpgME::GpgConfEngine, QStringLiteral("gpgconf"));
+ return path;
+}
+
+QString Kleo::gpgSmPath()
+{
+ static const auto path = findGpgExe(GpgME::GpgSMEngine, QStringLiteral("gpgsm"));
+ return path;
+}
+
+QString Kleo::gpgPath()
+{
+ static const auto path = findGpgExe(GpgME::GpgEngine, QStringLiteral("gpg"));
+ return path;
+}
+
+QStringList Kleo::gnupgFileWhitelist()
+{
+ return QStringList()
+ // The obvious pubring
+ << QStringLiteral("pubring.gpg")
+ // GnuPG 2.1 pubring
+ << QStringLiteral("pubring.kbx")
+ // Trust in X509 Certificates
+ << QStringLiteral("trustlist.txt")
+ // Trustdb controls ownertrust and thus WOT validity
+ << QStringLiteral("trustdb.gpg")
+ // We want to update when smartcard status changes
+ << QStringLiteral("reader*.status")
+ // No longer used in 2.1 but for 2.0 we want this
+ << QStringLiteral("secring.gpg")
+ // Changes to the trustmodel / compliance mode might
+ // affect validity so we check this, too.
+ // Globbing for gpg.conf* here will trigger too often
+ // as gpgconf creates files like gpg.conf.bak or
+ // gpg.conf.tmp12312.gpgconf that should not trigger
+ // a change.
+ << QStringLiteral("gpg.conf")
+ << QStringLiteral("gpg.conf-?")
+ << QStringLiteral("gpg.conf-?.?")
+ ;
+}
+
+QString Kleo::gpg4winVersion()
+{
+ QFile versionFile(gpg4winInstallPath() + QStringLiteral("/../VERSION"));
+ if (!versionFile.open(QIODevice::ReadOnly)) {
+ // No need to translate this should only be the case in development
+ // builds.
+ return QStringLiteral("Unknown (no VERSION file found)");
+ }
+ const QString g4wTag = QString::fromUtf8(versionFile.readLine());
+ if (!g4wTag.startsWith(QLatin1String("gpg4win"))) {
+ // Hu? Something unknown
+ return QStringLiteral("Unknown (invalid VERSION file found)");
+ }
+ // Next line is version.
+ return QString::fromUtf8(versionFile.readLine()).trimmed();
+}
+
+QString Kleo::gpg4winInstallPath()
+{
+#ifdef Q_OS_WIN
+ // QApplication::applicationDirPath is only used as a fallback
+ // to support the case where Kleopatra is not installed from
+ // Gpg4win but Gpg4win is also installed.
+ char *instDir = read_w32_registry_string("HKEY_LOCAL_MACHINE",
+ "Software\\GPG4Win",
+ "Install Directory");
+ if (!instDir) {
+ // Fallback to HKCU
+ instDir = read_w32_registry_string("HKEY_CURRENT_USER",
+ "Software\\GPG4Win",
+ "Install Directory");
+ }
+ if (instDir) {
+ QString ret = QString::fromLocal8Bit(instDir) + QStringLiteral("/bin");
+ free(instDir);
+ return ret;
+ }
+ qCDebug(LIBKLEO_LOG) << "Gpg4win not found. Falling back to Kleopatra instdir.";
+#endif
+ return QCoreApplication::applicationDirPath();
+}
+
+QString Kleo::gnupgInstallPath()
+{
+
+#ifdef Q_OS_WIN
+ // QApplication::applicationDirPath is only used as a fallback
+ // to support the case where Kleopatra is not installed from
+ // Gpg4win but Gpg4win is also installed.
+ char *instDir = read_w32_registry_string("HKEY_LOCAL_MACHINE",
+ "Software\\GnuPG",
+ "Install Directory");
+ if (!instDir) {
+ // Fallback to HKCU
+ instDir = read_w32_registry_string("HKEY_CURRENT_USER",
+ "Software\\GnuPG",
+ "Install Directory");
+ }
+ if (instDir) {
+ QString ret = QString::fromLocal8Bit(instDir) + QStringLiteral("/bin");
+ free(instDir);
+ return ret;
+ }
+ qCDebug(LIBKLEO_LOG) << "GnuPG not found. Falling back to gpgconf list dir.";
+#endif
+ return gpgConfListDir("bindir");
+}
+
+QString Kleo::gpgConfListDir(const char *which)
+{
+ if (!which || !*which) {
+ return QString();
+ }
+ const QString gpgConfPath = Kleo::gpgConfPath();
+ if (gpgConfPath.isEmpty()) {
+ return QString();
+ }
+ QProcess gpgConf;
+ qCDebug(LIBKLEO_LOG) << "gpgConfListDir: starting " << qPrintable(gpgConfPath) << " --list-dirs";
+ gpgConf.start(gpgConfPath, QStringList() << QStringLiteral("--list-dirs"));
+ if (!gpgConf.waitForFinished()) {
+ qCDebug(LIBKLEO_LOG) << "gpgConfListDir(): failed to execute gpgconf: " << qPrintable(gpgConf.errorString());
+ qCDebug(LIBKLEO_LOG) << "output was:\n" << gpgConf.readAllStandardError().constData();
+ return QString();
+ }
+ const QList<QByteArray> lines = gpgConf.readAllStandardOutput().split('\n');
+ for (const QByteArray &line : lines)
+ if (line.startsWith(which) && line[qstrlen(which)] == ':') {
+ const int begin = qstrlen(which) + 1;
+ int end = line.size();
+ while (end && (line[end - 1] == '\n' || line[end - 1] == '\r')) {
+ --end;
+ }
+ const QString result = QDir::fromNativeSeparators(QFile::decodeName(hexdecode(line.mid(begin, end - begin))));
+ qCDebug(LIBKLEO_LOG) << "gpgConfListDir: found " << qPrintable(result)
+ << " for '" << which << "'entry";
+ return result;
+ }
+ qCDebug(LIBKLEO_LOG) << "gpgConfListDir(): didn't find '" << which << "'"
+ << "entry in output:\n" << gpgConf.readAllStandardError().constData();
+ return QString();
+}
+
+static std::array<int, 3> getVersionFromString(const char *actual, bool &ok)
+{
+ std::array<int, 3> ret;
+ ok = false;
+
+ if (!actual) {
+ return ret;
+ }
+
+ QString versionString = QString::fromLatin1(actual);
+
+ // Try to fix it up
+ QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)\\.(\\d+)(?:-svn\\d+)?.*"));
+ for (int i = 0; i < 3; i++) {
+ if (!rx.exactMatch(versionString)) {
+ versionString += QStringLiteral(".0");
+ } else {
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok) {
+ qCDebug(LIBKLEO_LOG) << "Can't parse version " << actual;
+ return ret;
+ }
+
+ for (int i = 0; i < 3; ++i) {
+ ret[i] = rx.cap(i + 1).toUInt(&ok);
+ if (!ok) {
+ return ret;
+ }
+ }
+
+ ok = true;
+ return ret;
+}
+
+bool Kleo::versionIsAtLeast(const char *minimum, const char *actual)
+{
+ if (!minimum || !actual) {
+ return false;
+ }
+ bool ok;
+ const auto minimum_version = getVersionFromString(minimum, ok);
+ if (!ok) {
+ return false;
+ }
+ const auto actual_version = getVersionFromString(actual, ok);
+ if (!ok) {
+ return false;
+ }
+
+ return !std::lexicographical_compare(std::begin(actual_version), std::end(actual_version),
+ std::begin(minimum_version), std::end(minimum_version));
+
+}
+
+bool Kleo::engineIsVersion(int major, int minor, int patch, GpgME::Engine engine)
+{
+ static QMap<Engine, std::array<int, 3> > cachedVersions;
+ const int required_version[] = {major, minor, patch};
+ // Gpgconf means spawning processes which is expensive on windows.
+ std::array<int, 3> actual_version;
+ if (!cachedVersions.contains(engine)) {
+ const Error err = checkEngine(engine);
+ if (err.code() == GPG_ERR_INV_ENGINE) {
+ qCDebug(LIBKLEO_LOG) << "isVersion: invalid engine. '";
+ return false;
+ }
+
+ const char *actual = GpgME::engineInfo(engine).version();
+ bool ok;
+ actual_version = getVersionFromString(actual, ok);
+
+ qCDebug(LIBKLEO_LOG) << "Parsed" << actual << "as: "
+ << actual_version[0] << '.'
+ << actual_version[1] << '.'
+ << actual_version[2] << '.';
+ if (!ok) {
+ return false;
+ }
+ cachedVersions.insert(engine, actual_version);
+ } else {
+ actual_version = cachedVersions.value(engine);
+ }
+
+ // return ! ( actual_version < required_version )
+ return !std::lexicographical_compare(std::begin(actual_version), std::end(actual_version),
+ std::begin(required_version), std::end(required_version));
+}
+
+const QString& Kleo::paperKeyInstallPath()
+{
+ static const QString pkPath = QStandardPaths::findExecutable(QStringLiteral("paperkey"), QStringList() << QCoreApplication::applicationDirPath()).isEmpty() ?
+ QStandardPaths::findExecutable(QStringLiteral("paperkey")) :
+ QStandardPaths::findExecutable(QStringLiteral("paperkey"), QStringList() << QCoreApplication::applicationDirPath());
+ return pkPath;
+}
+
+bool Kleo::haveKeyserverConfigured()
+{
+ if (engineIsVersion(2, 1, 19)) {
+ // since 2.1.19 there is a builtin keyserver
+ return true;
+ }
+ const QGpgME::CryptoConfig *const config = QGpgME::cryptoConfig();
+ if (!config) {
+ return false;
+ }
+ const QGpgME::CryptoConfigEntry *const entry = config->entry(QStringLiteral("gpg"), QStringLiteral("Keyserver"), QStringLiteral("keyserver"));
+ return entry && !entry->stringValue().isEmpty();
+}
+
+bool Kleo::gpgComplianceP(const char *mode)
+{
+ const auto conf = QGpgME::cryptoConfig();
+ const auto entry = conf->entry(QStringLiteral("gpg"),
+ QStringLiteral("Configuration"),
+ QStringLiteral("compliance"));
+
+ return entry && entry->stringValue() == QString::fromLatin1(mode);
+}
+
+enum GpgME::UserID::Validity Kleo::keyValidity(const GpgME::Key &key)
+{
+ enum UserID::Validity validity = UserID::Validity::Unknown;
+
+ for (const auto &uid: key.userIDs()) {
+ if (validity == UserID::Validity::Unknown
+ || validity > uid.validity()) {
+ validity = uid.validity();
+ }
+ }
+
+ return validity;
+}
+
+#ifdef Q_OS_WIN
+static QString fromEncoding (unsigned int src_encoding, const char *data)
+{
+ int n = MultiByteToWideChar(src_encoding, 0, data, -1, NULL, 0);
+ if (n < 0) {
+ return QString();
+ }
+
+ wchar_t *result = (wchar_t *) malloc ((n+1) * sizeof *result);
+
+ n = MultiByteToWideChar(src_encoding, 0, data, -1, result, n);
+ if (n < 0) {
+ free(result);
+ return QString();
+ }
+ const auto ret = QString::fromWCharArray(result, n);
+ free(result);
+ return ret;
+}
+#endif
+
+QString Kleo::stringFromGpgOutput(const QByteArray &ba)
+{
+#ifdef Q_OS_WIN
+ /* Qt on Windows uses GetACP while GnuPG prefers
+ * GetConsoleOutputCP.
+ *
+ * As we are not a console application GetConsoleOutputCP
+ * usually returns 0.
+ * From experience the closest thing that let's us guess
+ * what GetConsoleOutputCP returns for a console application
+ * it appears to be the OEMCP.
+ */
+ unsigned int cpno = GetConsoleOutputCP ();
+ if (!cpno) {
+ cpno = GetOEMCP();
+ }
+ if (!cpno) {
+ cpno = GetACP();
+ }
+ if (!cpno) {
+ qCDebug(LIBKLEO_LOG) << "Failed to find native codepage";
+ return QString();
+ }
+
+ return fromEncoding(cpno, ba.constData());
+#else
+ return QString::fromLocal8Bit(ba);
+#endif
+}
diff --git a/src/utils/gnupg.h b/src/utils/gnupg.h
new file mode 100644
index 00000000..d25990c4
--- /dev/null
+++ b/src/utils/gnupg.h
@@ -0,0 +1,93 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ utils/gnupg.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2008 Klarälvdalens Datakonsult AB
+
+ Kleopatra 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.
+
+ Kleopatra 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEOPATRA_GNUPGHELPER_H__
+#define __KLEOPATRA_GNUPGHELPER_H__
+
+#include <gpgme++/engineinfo.h>
+#include <gpgme++/key.h>
+
+/* Support compilation with GPGME older than 1.9. */
+#include <gpgme++/gpgmepp_version.h>
+#if GPGMEPP_VERSION > 0x10900
+# define GPGME_HAS_KEY_IS_DEVS
+#endif
+
+/* Does the given object comply with DE_VS? This macro can be used to
+ ensure that we can still build against older versions of GPGME
+ without cluttering the code with preprocessor conditionals. */
+#ifdef GPGME_HAS_KEY_IS_DEVS
+# define IS_DE_VS(x) (x).isDeVs()
+#else
+# define IS_DE_VS(x) false
+#endif
+
+#include <kleo_export.h>
+
+class QString;
+class QStringList;
+class QByteArray;
+
+namespace Kleo
+{
+
+KLEO_EXPORT QString gnupgHomeDirectory();
+
+KLEO_EXPORT QString gpgConfPath();
+KLEO_EXPORT QString gpgSmPath();
+KLEO_EXPORT QString gpgPath();
+
+KLEO_EXPORT QString gpgConfListDir(const char *which);
+KLEO_EXPORT QString gpg4winInstallPath();
+KLEO_EXPORT QString gpg4winVersion();
+KLEO_EXPORT QString gnupgInstallPath();
+KLEO_EXPORT const QString& paperKeyInstallPath();
+
+KLEO_EXPORT QStringList gnupgFileWhitelist();
+KLEO_EXPORT int makeGnuPGError(int code);
+
+KLEO_EXPORT bool engineIsVersion(int major, int minor, int patch, GpgME::Engine = GpgME::GpgConfEngine);
+KLEO_EXPORT bool haveKeyserverConfigured();
+KLEO_EXPORT bool gpgComplianceP(const char *mode);
+KLEO_EXPORT enum GpgME::UserID::Validity keyValidity(const GpgME::Key &key);
+
+/* Convert GnuPG output to a QString with proper encoding.
+ * Takes Gpg Quirks into account and might handle future
+ * changes in GnuPG Output. */
+KLEO_EXPORT QString stringFromGpgOutput(const QByteArray &ba);
+
+/* Check if a minimum version is there. Strings should be in the format:
+ * 1.2.3 */
+KLEO_EXPORT bool versionIsAtLeast(const char *minimum, const char *actual);
+}
+
+#endif // __KLEOPATRA_GNUPGHELPER_H__
diff --git a/src/utils/hex.cpp b/src/utils/hex.cpp
new file mode 100644
index 00000000..2d05c285
--- /dev/null
+++ b/src/utils/hex.cpp
@@ -0,0 +1,153 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ utils/hex.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2007 Klarälvdalens Datakonsult AB
+
+ Kleopatra 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.
+
+ Kleopatra 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "hex.h"
+
+#include <Libkleo/Exception>
+
+#include <KLocalizedString>
+
+#include <QString>
+#include <QByteArray>
+
+using namespace Kleo;
+
+static unsigned char unhex(unsigned char ch)
+{
+ if (ch >= '0' && ch <= '9') {
+ return ch - '0';
+ }
+ if (ch >= 'A' && ch <= 'F') {
+ return ch - 'A' + 10;
+ }
+ if (ch >= 'a' && ch <= 'f') {
+ return ch - 'a' + 10;
+ }
+ const char cch = ch;
+ throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
+ i18n("Invalid hex char '%1' in input stream.",
+ QString::fromLatin1(&cch, 1)));
+}
+
+std::string Kleo::hexdecode(const std::string &in)
+{
+ std::string result;
+ result.reserve(in.size());
+ for (std::string::const_iterator it = in.begin(), end = in.end(); it != end; ++it)
+ if (*it == '%') {
+ ++it;
+ unsigned char ch = '\0';
+ if (it == end)
+ throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
+ i18n("Premature end of hex-encoded char in input stream"));
+ ch |= unhex(*it) << 4;
+ ++it;
+ if (it == end)
+ throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
+ i18n("Premature end of hex-encoded char in input stream"));
+ ch |= unhex(*it);
+ result.push_back(ch);
+ } else if (*it == '+') {
+ result += ' ';
+ } else {
+ result.push_back(*it);
+ }
+ return result;
+}
+
+std::string Kleo::hexencode(const std::string &in)
+{
+ std::string result;
+ result.reserve(3 * in.size());
+
+ static const char hex[] = "0123456789ABCDEF";
+
+ for (std::string::const_iterator it = in.begin(), end = in.end(); it != end; ++it)
+ switch (const unsigned char ch = *it) {
+ default:
+ if ((ch >= '!' && ch <= '~') || ch > 0xA0) {
+ result += ch;
+ break;
+ }
+ // else fall through
+ case ' ':
+ result += '+';
+ break;
+ case '"':
+ case '#':
+ case '$':
+ case '%':
+ case '\'':
+ case '+':
+ case '=':
+ result += '%';
+ result += hex[(ch & 0xF0) >> 4 ];
+ result += hex[(ch & 0x0F) ];
+ break;
+ }
+
+ return result;
+}
+
+std::string Kleo::hexdecode(const char *in)
+{
+ if (!in) {
+ return std::string();
+ }
+ return hexdecode(std::string(in));
+}
+
+std::string Kleo::hexencode(const char *in)
+{
+ if (!in) {
+ return std::string();
+ }
+ return hexencode(std::string(in));
+}
+
+QByteArray Kleo::hexdecode(const QByteArray &in)
+{
+ if (in.isNull()) {
+ return QByteArray();
+ }
+ const std::string result = hexdecode(std::string(in.constData()));
+ return QByteArray(result.data(), result.size());
+}
+
+QByteArray Kleo::hexencode(const QByteArray &in)
+{
+ if (in.isNull()) {
+ return QByteArray();
+ }
+ const std::string result = hexencode(std::string(in.constData()));
+ return QByteArray(result.data(), result.size());
+}
diff --git a/src/utils/hex.h b/src/utils/hex.h
new file mode 100644
index 00000000..aea14d51
--- /dev/null
+++ b/src/utils/hex.h
@@ -0,0 +1,54 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ utils/hex.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2007 Klarälvdalens Datakonsult AB
+
+ Kleopatra 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.
+
+ Kleopatra 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEOPATRA_UTILS_HEX_H__
+#define __KLEOPATRA_UTILS_HEX_H__
+
+#include <string>
+
+class QByteArray;
+
+namespace Kleo
+{
+
+std::string hexencode(const char *s);
+std::string hexdecode(const char *s);
+
+std::string hexencode(const std::string &s);
+std::string hexdecode(const std::string &s);
+
+QByteArray hexencode(const QByteArray &s);
+QByteArray hexdecode(const QByteArray &s);
+
+}
+
+#endif /* __KLEOPATRA_UTILS_HEX_H__ */

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:43 PM (2 h, 28 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
89/d7/3296ea9e39067c6db62730964e4c

Event Timeline