summaryrefslogtreecommitdiff
path: root/lang/cpp/tests/run-wkdlookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lang/cpp/tests/run-wkdlookup.cpp')
-rw-r--r--lang/cpp/tests/run-wkdlookup.cpp156
1 files changed, 156 insertions, 0 deletions
diff --git a/lang/cpp/tests/run-wkdlookup.cpp b/lang/cpp/tests/run-wkdlookup.cpp
new file mode 100644
index 0000000..71c4e70
--- /dev/null
+++ b/lang/cpp/tests/run-wkdlookup.cpp
@@ -0,0 +1,156 @@
+/*
+ run-wkdlookup.cpp
+
+ This file is part of GpgMEpp's test suite.
+ Copyright (c) 2021 g10 Code GmbH
+ Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
+
+ GPGME++ is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ GPGME++ 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 Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with GPGME++; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "context.h"
+#include "data.h"
+#include "defaultassuantransaction.h"
+#include "key.h"
+
+#include <memory>
+#include <sstream>
+#include <iostream>
+#include <thread>
+
+using namespace GpgME;
+
+static int
+show_usage (int ex)
+{
+ fputs ("usage: run-wkdlookup <email address>\n\n"
+ , stderr);
+ exit (ex);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+
+ if (argc) {
+ argc--; argv++;
+ }
+
+ while (argc && last_argc != argc ) {
+ last_argc = argc;
+ if (!strcmp (*argv, "--")) {
+ argc--; argv++;
+ break;
+ } else if (!strcmp (*argv, "--help")) {
+ show_usage (0);
+ } else if (!strncmp (*argv, "--", 2)) {
+ show_usage (1);
+ }
+ }
+
+ if (argc != 1) {
+ show_usage (1);
+ }
+
+ const std::string email{*argv};
+
+ GpgME::initializeLibrary();
+ Error err;
+ auto ctx = std::unique_ptr<Context>{Context::createForEngine(AssuanEngine, &err)};
+ if (!ctx) {
+ std::cerr << "Failed to get context (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+
+ const std::string dirmngrSocket = GpgME::dirInfo("dirmngr-socket");
+ if ((err = ctx->setEngineFileName(dirmngrSocket.c_str()))) {
+ std::cerr << "Failed to set engine file name (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+ if ((err = ctx->setEngineHomeDirectory(""))) {
+ std::cerr << "Failed to set engine home directory (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+
+ // try do connect to dirmngr
+ err = ctx->assuanTransact("GETINFO version");
+ if (err && err.code() != GPG_ERR_ASS_CONNECT_FAILED) {
+ std::cerr << "Failed to start assuan transaction (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+ if (err.code() == GPG_ERR_ASS_CONNECT_FAILED) {
+ std::cerr << "Starting dirmngr ...\n";
+ auto spawnCtx = std::unique_ptr<Context>{Context::createForEngine(SpawnEngine, &err)};
+ if (!spawnCtx) {
+ std::cerr << "Failed to get context for spawn engine (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+
+ const auto dirmngrProgram = GpgME::dirInfo("dirmngr-name");
+ const auto homedir = GpgME::dirInfo("homedir");
+ const char *argv[] = {
+ dirmngrProgram,
+ "--homedir",
+ homedir,
+ "--daemon",
+ NULL
+ };
+ auto ignoreIO = Data{Data::null};
+ err = spawnCtx->spawnAsync(dirmngrProgram, argv,
+ ignoreIO, ignoreIO, ignoreIO,
+ Context::SpawnDetached);
+ if (err) {
+ std::cerr << "Failed to start dirmngr (Error: " << err.asString() << ")\n";
+ return -1;
+ }
+
+ // wait for socket to become available
+ int cnt = 0;
+ do {
+ ++cnt;
+ std::cerr << "Waiting for dirmngr to start ...\n";
+ std::this_thread::sleep_for(std::chrono::milliseconds{250 * cnt});
+ err = ctx->assuanTransact("GETINFO version");
+ } while (err.code() == GPG_ERR_ASS_CONNECT_FAILED && cnt < 5);
+ }
+
+ const auto cmd = std::string{"WKD_GET "} + email;
+ err = ctx->assuanTransact(cmd.c_str());
+ if (err && err.code() != GPG_ERR_NO_NAME && err.code() != GPG_ERR_NO_DATA) {
+ std::cerr << "Error: WKD_GET returned " << err.asString() << "\n";
+ return -1;
+ }
+
+ const auto transaction = std::unique_ptr<DefaultAssuanTransaction>(dynamic_cast<DefaultAssuanTransaction*>(ctx->takeLastAssuanTransaction().release()));
+ const auto source = transaction->firstStatusLine("SOURCE");
+ const auto rawData = transaction->data();
+ if (rawData.size() == 0) {
+ std::cout << "No key found for " << email << "\n";
+ } else {
+ const auto data = GpgME::Data{rawData.c_str(), rawData.size()};
+ const auto keys = data.toKeys(GpgME::OpenPGP);
+ for (const auto &key : keys) {
+ std::cout << "Found key for " << email << " at " << source << ":\n" << key << "\n";
+ }
+ }
+
+ return 0;
+}