diff --git a/src/resolver/CMakeLists.txt b/src/resolver/CMakeLists.txt index 3905f4c..e8ff3d4 100644 --- a/src/resolver/CMakeLists.txt +++ b/src/resolver/CMakeLists.txt @@ -1,28 +1,29 @@ # Copyright (C) 2018 Intevation GmbH # # This file is Free Software under the GNU GPL (v>=2) # and comes with ABSOLUTELY NO WARRANTY! # See LICENSE.txt for details. set(EXECUTABLE_NAME "resolver") set(EXECUTABLE_SRC main.cpp resolver.cpp ${CMAKE_SOURCE_DIR}/src//util/strhelp.c ) add_executable(${EXECUTABLE_NAME} ${_add_executable_params} ${EXECUTABLE_SRC} ) target_link_libraries(${EXECUTABLE_NAME} Qt5::Widgets + KF5::Libkleo Gpgmepp QGpgme ) if (WIN32) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-municode") endif(WIN32) diff --git a/src/resolver/main.cpp b/src/resolver/main.cpp index e6cc83f..4e3c703 100644 --- a/src/resolver/main.cpp +++ b/src/resolver/main.cpp @@ -1,149 +1,152 @@ /* Copyright (C) 2018 by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ /** @file Main entry point for the application. */ #include "strhelp.h" #include "resolver-options.h" #include "resolver.h" #include #include #include #include #include +#include #include #ifdef Q_OS_WIN #include #include #endif #ifndef APPNAME #define APPNAME "Resolver" #endif #ifndef VERSION #define VERSION "0.0" #endif bool g_debug = false; QtMessageHandler g_default_msg_handler = NULL; void filterDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { if (!g_debug && type == QtDebugMsg) { return; } if (g_default_msg_handler) { (*g_default_msg_handler)(type, context, msg); } } int realMain(int argc, char **argv); #if defined(WIN32) && defined(UNICODE) /** @brief Unicode entry point. * * Converts arguments to UTF-8 and executes the real * entry point realMain. */ int wmain(int argc, wchar_t **argv, wchar_t **envp) { char **utf8args = NULL; utf8args = (char**) xmalloc0 ((argc + 1) * sizeof(char*)); for (int i = 0; i < argc; i++) { utf8args[i] = wchar_to_utf8(argv[i], wcslen(argv[i])); if (utf8args[i] == NULL) { printf ("Fatal: could not convert arguments to UTF-8.\n"); exit(-1); } } int ret = realMain(argc, utf8args); strv_free(utf8args); return ret; } #else int main(int argc, char **argv) { return realMain(argc, argv); } #endif /** @brief The real entry point to the application. * * @param [in] argc the count of the arguments. * @param [in] argv On GNU/Linux this function expects argv to be in the * native system encoding. On Windows the arguments * shall be UTF-8 * * @returns 0 on success an error code otherwise. */ int realMain(int argc, char **argv) { /* QApplication setup */ Resolver app(argc, argv); QApplication::setOrganizationName(QStringLiteral(APPNAME)); QApplication::setApplicationName(QStringLiteral(APPNAME)); QApplication::setApplicationVersion(QStringLiteral(VERSION)); #if 0 /* Setup translations */ QTranslator translator; if (QLocale::system().name() == "C") { /* Useful for testing / development as the primary target is german */ translator.load(":/l10n/main_de_DE"); } else { translator.load(":/l10n/main_" + QLocale::system().name()); } app.installTranslator(&translator); #endif /* Parse the command line */ QCommandLineParser parser; options(parser); #ifdef Q_OS_WIN auto oldCodec = QTextCodec::codecForLocale(); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); #endif parser.process(app); #ifdef Q_OS_WIN QTextCodec::setCodecForLocale(oldCodec); #endif g_debug = parser.isSet("debug"); g_default_msg_handler = qInstallMessageHandler(filterDebugOutput); // Initialize GpgME const GpgME::Error gpgmeInitError = GpgME::initializeLibrary(0); if (gpgmeInitError) { QMessageBox::critical(nullptr, QObject::tr("Installation Error"), QObject::tr("Could not initialize GPGME.") + "
" + QObject::tr("Please reinstall") + " " APPNAME "."); return EXIT_FAILURE; } // Go with the app - const QString err = app.newInstance(parser); - if (!err.isEmpty()) { - std::cerr << QObject::tr("Invalid arguments: %1").arg(err).toLocal8Bit().constData() << "\n"; - return EXIT_FAILURE; - } - + QTimer::singleShot(0, [&parser, &app]() { + const QString err = app.newInstance(parser); + if (!err.isEmpty()) { + std::cerr << QObject::tr("Invalid arguments: %1").arg(err).toLocal8Bit().constData() << "\n"; + exit(EXIT_FAILURE); + } + }); app.exec(); + return EXIT_SUCCESS; } diff --git a/src/resolver/resolver-options.h b/src/resolver/resolver-options.h index e588e01..5df65f4 100644 --- a/src/resolver/resolver-options.h +++ b/src/resolver/resolver-options.h @@ -1,40 +1,42 @@ #ifndef RESOLVER_OPTIONS #define RESOLVER_OPTIONS /* Copyright (C) 2018 by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include #include /** @file Commandline options*/ static void options(QCommandLineParser &parser) { QList options; options << QCommandLineOption(QStringList() << QStringLiteral("debug"), QStringLiteral("Print debug output.")) << QCommandLineOption(QStringLiteral("protocol"), QStringLiteral("Specify a forced protocol"), QStringLiteral("pgp or cms")) << QCommandLineOption(QStringLiteral("sender"), QStringLiteral("The sender"), QStringLiteral("sender mailbox")) << QCommandLineOption(QStringLiteral("sign"), - QStringLiteral("Should be signed")); + QStringLiteral("Should be signed")) + << QCommandLineOption(QStringLiteral("alwaysShow"), + QStringLiteral("Should always be shown")); for (const auto &opt: options) { parser.addOption(opt); } parser.addVersionOption(); parser.addHelpOption(); parser.addPositionalArgument(QStringLiteral("recipients"), QStringLiteral("Recipient Mailboxes"), QStringLiteral("[recipients]")); } #endif // RESOLVER_OPTIONS diff --git a/src/resolver/resolver.cpp b/src/resolver/resolver.cpp index 4e06fdb..4a6c176 100644 --- a/src/resolver/resolver.cpp +++ b/src/resolver/resolver.cpp @@ -1,34 +1,94 @@ /* Copyright (C) 2018 by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include "resolver.h" +#include +#include #include +#include +#include + +#include + class Resolver::Private { public: - Private(Resolver *qq): q(qq) - { + Private(Resolver *qq): q(qq) { + } + void printResolvedKeys(const Kleo::KeyResolver *kr) { + qDebug() << "Printing resolved keys."; + const auto sigMap = kr->signingKeys(); + for (const auto fmt: sigMap.keys()) { + for (const auto key: sigMap[fmt]) { + std::cout << "sig:" << Kleo::cryptoMessageFormatToString(fmt) << ":" + << key.primaryFingerprint() << std::endl; + } + } + const auto encMap = kr->encryptionKeys(); + for (const auto fmt: encMap.keys()) { + for (const auto mbox: encMap[fmt].keys()) { + for (const auto key: encMap[fmt][mbox]) { + std::cout << "enc:" << Kleo::cryptoMessageFormatToString(fmt) << ":" + << key.primaryFingerprint() << std::endl; + } + } + } } + void newResolver(const QCommandLineParser &parser) { + const auto proto = parser.value(QStringLiteral("protocol")).toLower(); + Kleo::CryptoMessageFormat format; + if (proto == QStringLiteral("cms")) { + format = Kleo::AnySMIME; + } else if (proto == QStringLiteral("pgp")) { + format = Kleo::AnyOpenPGP; + } else { + format = Kleo::AutoFormat; + } + + const auto recps = parser.positionalArguments(); + auto *kr = new Kleo::KeyResolver (!recps.isEmpty() /* encrypt */, + parser.isSet(QStringLiteral("sign")) /*sign*/, + format /* CryptoMesssageFormat */, + false /* AllowMixed */); + + kr->setRecipients(recps); + kr->setSender(parser.value("sender")); + kr->enableNagging(true); + + connect (kr, &Kleo::KeyResolver::keysResolved, q, [this, kr] (bool success, bool sendUnencrypted) { + if (!success) { + std::cout << "cancel" << std::endl; + } else if (sendUnencrypted) { + std::cout << "unencrypted" << std::endl; + } else { + printResolvedKeys(kr); + } + delete kr; + qApp->quit(); + }); + kr->start(parser.isSet(QStringLiteral("alwaysShow"))); + } Resolver *q; }; Resolver::Resolver(int &argc, char *argv[]) : QApplication(argc, argv), d(new Private(this)) { } QString Resolver::newInstance(const QCommandLineParser &parser, const QString &workingDirectry) { + d->newResolver(parser); return QString(); }