aboutsummaryrefslogtreecommitdiffstats
path: root/tools/call-dirmngr.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2016-06-29 10:00:22 +0000
committerWerner Koch <[email protected]>2016-06-29 10:04:11 +0000
commit5d6c83deaa11327366b0038928200b9f9f85b426 (patch)
treeeb9ea558716455ebea601d56abe18077be387be5 /tools/call-dirmngr.c
parentbuild: Improve GNUPG_BUILD_PROGRAM macro. (diff)
downloadgnupg-5d6c83deaa11327366b0038928200b9f9f85b426.tar.gz
gnupg-5d6c83deaa11327366b0038928200b9f9f85b426.zip
tools: Add gpg-wks-client and gpg-wks-server.
* configure.ac: Add option --enable-wks-tools * tools/gpg-wks-client.c: New. * tools/gpg-wks-server.c: New. * tools/gpg-wks.h: new. * tools/wks-receive.c: New. * tools/call-dirmngr.c, tools/call-dirmngr.h: New. -- Note that this is just a starting point and not a finished implementation. Here is how to test the system using [email protected] as example. Prepare: mkdir /var/lib/gnupg/wks chmod o-rwx /var/lib/gnupg/wks mkdir /var/lib/gnupg/wks/test.gnupg.org Run the protocol: ./gpg-wks-client -v --send FPR USERID >x ./gpg-wks-server -v --receive <x >y ./gpg-wks-client --receive <y >z ./gpg-wks-server -v --receive <z You should also setup a cron job to rsync /var/lib/gnupg/wks/test.gnupg.org/hu/* to the webserver. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'tools/call-dirmngr.c')
-rw-r--r--tools/call-dirmngr.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/tools/call-dirmngr.c b/tools/call-dirmngr.c
new file mode 100644
index 000000000..0e591dd6d
--- /dev/null
+++ b/tools/call-dirmngr.c
@@ -0,0 +1,205 @@
+/* call-dirmngr.c - Interact with the Dirmngr.
+ * Copyright (C) 2016 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#include <assuan.h>
+#include "util.h"
+#include "i18n.h"
+#include "asshelp.h"
+#include "mbox-util.h"
+#include "./call-dirmngr.h"
+
+static struct
+{
+ int verbose;
+ int debug_ipc;
+ int autostart;
+} opt;
+
+
+
+void
+set_dirmngr_options (int verbose, int debug_ipc, int autostart)
+{
+ opt.verbose = verbose;
+ opt.debug_ipc = debug_ipc;
+ opt.autostart = autostart;
+}
+
+
+/* Connect to the Dirmngr and return an assuan context. */
+static gpg_error_t
+connect_dirmngr (assuan_context_t *r_ctx)
+{
+ gpg_error_t err;
+ assuan_context_t ctx;
+
+ *r_ctx = NULL;
+ err = start_new_dirmngr (&ctx,
+ GPG_ERR_SOURCE_DEFAULT,
+ NULL,
+ opt.autostart, opt.verbose, opt.debug_ipc,
+ NULL, NULL);
+ if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
+ {
+ static int shown;
+
+ if (!shown)
+ {
+ shown = 1;
+ log_info (_("no dirmngr running in this session\n"));
+ }
+ }
+
+ if (err)
+ assuan_release (ctx);
+ else
+ {
+ *r_ctx = ctx;
+ }
+
+ return err;
+}
+
+
+
+
+/* Parameter structure used with the WKD_GET command. */
+struct wkd_get_parm_s
+{
+ estream_t memfp;
+};
+
+
+/* Data callback for the WKD_GET command. */
+static gpg_error_t
+wkd_get_data_cb (void *opaque, const void *data, size_t datalen)
+{
+ struct wkd_get_parm_s *parm = opaque;
+ gpg_error_t err = 0;
+ size_t nwritten;
+
+ if (!data)
+ return 0; /* Ignore END commands. */
+ if (!parm->memfp)
+ return 0; /* Data is not required. */
+
+ if (es_write (parm->memfp, data, datalen, &nwritten))
+ err = gpg_error_from_syserror ();
+
+ return err;
+}
+
+
+/* Status callback for the WKD_GET command. */
+static gpg_error_t
+wkd_get_status_cb (void *opaque, const char *line)
+{
+ struct wkd_get_parm_s *parm = opaque;
+ gpg_error_t err = 0;
+
+ (void)line;
+ (void)parm;
+
+ return err;
+}
+
+
+/* Ask the dirmngr for the submission address of a WKD server for the
+ * mail address ADDRSPEC. On success the submission address is stored
+ * at R_ADDRSPEC. */
+gpg_error_t
+wkd_get_submission_address (const char *addrspec, char **r_addrspec)
+{
+ gpg_error_t err;
+ assuan_context_t ctx;
+ struct wkd_get_parm_s parm;
+ char *line = NULL;
+ void *vp;
+ char *buffer = NULL;
+ char *p;
+
+ memset (&parm, 0, sizeof parm);
+ *r_addrspec = NULL;
+
+ err = connect_dirmngr (&ctx);
+ if (err)
+ return err;
+
+ line = es_bsprintf ("WKD_GET --submission-address -- %s", addrspec);
+ if (!line)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
+ {
+ err = gpg_error (GPG_ERR_TOO_LARGE);
+ goto leave;
+ }
+
+ parm.memfp = es_fopenmem (0, "rwb");
+ if (!parm.memfp)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ err = assuan_transact (ctx, line, wkd_get_data_cb, &parm,
+ NULL, NULL, wkd_get_status_cb, &parm);
+ if (err)
+ goto leave;
+
+ es_fputc (0, parm.memfp);
+ if (es_fclose_snatch (parm.memfp, &vp, NULL))
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ buffer = vp;
+ parm.memfp = NULL;
+ p = strchr (buffer, '\n');
+ if (p)
+ *p = 0;
+ trim_spaces (buffer);
+ if (!is_valid_mailbox (buffer))
+ {
+ err = gpg_error (GPG_ERR_INV_USER_ID);
+ goto leave;
+ }
+ *r_addrspec = xtrystrdup (buffer);
+ if (!*r_addrspec)
+ err = gpg_error_from_syserror ();
+
+ leave:
+ es_free (buffer);
+ es_fclose (parm.memfp);
+ xfree (line);
+ assuan_release (ctx);
+ return err;
+}