dirmngr: Print a WARNING status for DNS config problems.
[gnupg.git] / g10 / call-dirmngr.c
1 /* call-dirmngr.c - GPG operations to the Dirmngr.
2  * Copyright (C) 2011 Free Software Foundation, Inc.
3  * Copyright (C) 2015  g10 Code GmbH
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <time.h>
28 #ifdef HAVE_LOCALE_H
29 # include <locale.h>
30 #endif
31
32 #include "gpg.h"
33 #include <assuan.h>
34 #include "../common/util.h"
35 #include "../common/membuf.h"
36 #include "options.h"
37 #include "../common/i18n.h"
38 #include "../common/asshelp.h"
39 #include "../common/keyserver.h"
40 #include "../common/status.h"
41 #include "call-dirmngr.h"
42
43
44 /* Parameter structure used to gather status info.  Note that it is
45  * also used for WKD requests.  */
46 struct ks_status_parm_s
47 {
48   const char *keyword; /* Look for this keyword or NULL for "SOURCE". */
49   char *source;
50 };
51
52
53 /* Parameter structure used with the KS_SEARCH command.  */
54 struct ks_search_parm_s
55 {
56   gpg_error_t lasterr;  /* Last error code.  */
57   membuf_t saveddata;   /* Buffer to build complete lines.  */
58   char *helpbuf;        /* NULL or malloced buffer.  */
59   size_t helpbufsize;   /* Allocated size of HELPBUF.  */
60   gpg_error_t (*data_cb)(void*, int, char*);  /* Callback.  */
61   void *data_cb_value;  /* First argument for DATA_CB.  */
62   struct ks_status_parm_s *stparm; /* Link to the status parameter.  */
63 };
64
65
66 /* Parameter structure used with the KS_GET command.  */
67 struct ks_get_parm_s
68 {
69   estream_t memfp;
70 };
71
72
73 /* Parameter structure used with the KS_PUT command.  */
74 struct ks_put_parm_s
75 {
76   assuan_context_t ctx;
77   kbnode_t keyblock;  /* The optional keyblock.  */
78   const void *data;   /* The key in OpenPGP binary format.  */
79   size_t datalen;     /* The length of DATA.  */
80 };
81
82
83 /* Parameter structure used with the DNS_CERT command.  */
84 struct dns_cert_parm_s
85 {
86   estream_t memfp;
87   unsigned char *fpr;
88   size_t fprlen;
89   char *url;
90 };
91
92
93 /* Data used to associate an session with dirmngr contexts.  We can't
94    use a simple one to one mapping because we sometimes need two
95    connections to the dirmngr; for example while doing a listing and
96    being in a data callback we may want to retrieve a key.  The local
97    dirmngr data takes care of this.  At the end of the session the
98    function dirmngr_deinit_session_data is called by gpg.c to cleanup
99    these resources.  Note that gpg.h defines a typedef dirmngr_local_t
100    for this structure. */
101 struct dirmngr_local_s
102 {
103   /* Link to other contexts which are used simultaneously.  */
104   struct dirmngr_local_s *next;
105
106   /* The active Assuan context. */
107   assuan_context_t ctx;
108
109   /* Flag set when the keyserver names have been send.  */
110   int set_keyservers_done;
111
112   /* Flag set to true while an operation is running on CTX.  */
113   int is_active;
114 };
115
116
117 \f
118 /* Deinitialize all session data of dirmngr pertaining to CTRL.  */
119 void
120 gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
121 {
122   dirmngr_local_t dml;
123
124   while ((dml = ctrl->dirmngr_local))
125     {
126       ctrl->dirmngr_local = dml->next;
127       if (dml->is_active)
128         log_error ("oops: trying to cleanup an active dirmngr context\n");
129       else
130         assuan_release (dml->ctx);
131       xfree (dml);
132     }
133 }
134
135
136 /* Print a warning if the server's version number is less than our
137    version number.  Returns an error code on a connection problem.  */
138 static gpg_error_t
139 warn_version_mismatch (assuan_context_t ctx, const char *servername)
140 {
141   gpg_error_t err;
142   char *serverversion;
143   const char *myversion = strusage (13);
144
145   err = get_assuan_server_version (ctx, 0, &serverversion);
146   if (err)
147     log_error (_("error getting version from '%s': %s\n"),
148                servername, gpg_strerror (err));
149   else if (compare_version_strings (serverversion, myversion) < 0)
150     {
151       char *warn;
152
153       warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
154                            servername, serverversion, myversion);
155       if (!warn)
156         err = gpg_error_from_syserror ();
157       else
158         {
159           log_info (_("WARNING: %s\n"), warn);
160           if (!opt.quiet)
161             {
162               log_info (_("Note: Outdated servers may lack important"
163                           " security fixes.\n"));
164               log_info (_("Note: Use the command \"%s\" to restart them.\n"),
165                         "gpgconf --kill all");
166             }
167
168           write_status_strings (STATUS_WARNING, "server_version_mismatch 0",
169                                 " ", warn, NULL);
170           xfree (warn);
171         }
172     }
173   xfree (serverversion);
174   return err;
175 }
176
177
178 /* Try to connect to the Dirmngr via a socket or spawn it if possible.
179    Handle the server's initial greeting and set global options.  */
180 static gpg_error_t
181 create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
182 {
183   gpg_error_t err;
184   assuan_context_t ctx;
185
186   *r_ctx = NULL;
187
188   if (opt.disable_dirmngr)
189     return gpg_error (GPG_ERR_NO_DIRMNGR);
190
191   err = start_new_dirmngr (&ctx,
192                            GPG_ERR_SOURCE_DEFAULT,
193                            opt.dirmngr_program,
194                            opt.autostart, opt.verbose, DBG_IPC,
195                            NULL /*gpg_status2*/, ctrl);
196   if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR)
197     {
198       static int shown;
199
200       if (!shown)
201         {
202           shown = 1;
203           log_info (_("no dirmngr running in this session\n"));
204         }
205     }
206   else if (!err && !(err = warn_version_mismatch (ctx, DIRMNGR_NAME)))
207     {
208       char *line;
209
210       /* Tell the dirmngr that we want to collect audit event. */
211       /* err = assuan_transact (agent_ctx, "OPTION audit-events=1", */
212       /*                        NULL, NULL, NULL, NULL, NULL, NULL); */
213       if (opt.keyserver_options.http_proxy)
214         {
215           line = xtryasprintf ("OPTION http-proxy=%s",
216                                opt.keyserver_options.http_proxy);
217           if (!line)
218             err = gpg_error_from_syserror ();
219           else
220             {
221               err = assuan_transact (ctx, line, NULL, NULL, NULL,
222                                      NULL, NULL, NULL);
223               xfree (line);
224             }
225         }
226
227       if (err)
228         ;
229       else if ((opt.keyserver_options.options & KEYSERVER_HONOR_KEYSERVER_URL))
230         {
231           /* Tell the dirmngr that this possibly privacy invading
232              option is in use.  If Dirmngr is running in Tor mode, it
233              will return an error.  */
234           err = assuan_transact (ctx, "OPTION honor-keyserver-url-used",
235                                  NULL, NULL, NULL, NULL, NULL, NULL);
236           if (gpg_err_code (err) == GPG_ERR_FORBIDDEN)
237             log_error (_("keyserver option \"honor-keyserver-url\""
238                          " may not be used in Tor mode\n"));
239           else if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
240             err = 0; /* Old dirmngr versions do not support this option.  */
241         }
242     }
243
244   if (err)
245     assuan_release (ctx);
246   else
247     {
248       /* audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); */
249       *r_ctx = ctx;
250     }
251
252   return err;
253 }
254
255
256 /* Get a context for accessing dirmngr.  If no context is available a
257    new one is created and - if required - dirmngr started.  On success
258    an assuan context is stored at R_CTX.  This context may only be
259    released by means of close_context.  Note that NULL is stored at
260    R_CTX on error.  */
261 static gpg_error_t
262 open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
263 {
264   gpg_error_t err;
265   dirmngr_local_t dml;
266
267   *r_ctx = NULL;
268   for (;;)
269     {
270       for (dml = ctrl->dirmngr_local; dml && dml->is_active; dml = dml->next)
271         ;
272       if (dml)
273         {
274           /* Found an inactive local session - return that.  */
275           log_assert (!dml->is_active);
276
277           /* But first do the per session init if not yet done.  */
278           if (!dml->set_keyservers_done)
279             {
280               keyserver_spec_t ksi;
281
282               /* Set all configured keyservers.  We clear existing
283                  keyservers so that any keyserver configured in GPG
284                  overrides keyservers possibly still configured in Dirmngr
285                  for the session (Note that the keyserver list of a
286                  session in Dirmngr survives a RESET. */
287               for (ksi = opt.keyserver; ksi; ksi = ksi->next)
288                 {
289                   char *line;
290
291                   line = xtryasprintf
292                     ("KEYSERVER%s %s",
293                      ksi == opt.keyserver? " --clear":"", ksi->uri);
294                   if (!line)
295                     err = gpg_error_from_syserror ();
296                   else
297                     {
298                       err = assuan_transact (dml->ctx, line, NULL, NULL, NULL,
299                                              NULL, NULL, NULL);
300                       xfree (line);
301                     }
302
303                   if (err)
304                     return err;
305                 }
306
307               dml->set_keyservers_done = 1;
308             }
309
310           dml->is_active = 1;
311
312           *r_ctx = dml->ctx;
313           return 0;
314         }
315
316       dml = xtrycalloc (1, sizeof *dml);
317       if (!dml)
318         return gpg_error_from_syserror ();
319       err = create_context (ctrl, &dml->ctx);
320       if (err)
321         {
322           xfree (dml);
323           return err;
324         }
325
326       /* To be on the nPth thread safe site we need to add it to a
327          list; this is far easier than to have a lock for this
328          function.  It should not happen anyway but the code is free
329          because we need it for the is_active check above.  */
330       dml->next = ctrl->dirmngr_local;
331       ctrl->dirmngr_local = dml;
332     }
333 }
334
335
336 /* Close the assuan context CTX or return it to a pool of unused
337    contexts.  If CTX is NULL, the function does nothing.  */
338 static void
339 close_context (ctrl_t ctrl, assuan_context_t ctx)
340 {
341   dirmngr_local_t dml;
342
343   if (!ctx)
344     return;
345
346   for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
347     {
348       if (dml->ctx == ctx)
349         {
350           if (!dml->is_active)
351             log_fatal ("closing inactive dirmngr context %p\n", ctx);
352           dml->is_active = 0;
353           return;
354         }
355     }
356   log_fatal ("closing unknown dirmngr ctx %p\n", ctx);
357 }
358
359
360 /* Clear the set_keyservers_done flag on context CTX.  */
361 static void
362 clear_context_flags (ctrl_t ctrl, assuan_context_t ctx)
363 {
364   dirmngr_local_t dml;
365
366   if (!ctx)
367     return;
368
369   for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
370     {
371       if (dml->ctx == ctx)
372         {
373           if (!dml->is_active)
374             log_fatal ("clear_context_flags on inactive dirmngr ctx %p\n", ctx);
375           dml->set_keyservers_done = 0;
376           return;
377         }
378     }
379   log_fatal ("clear_context_flags on unknown dirmngr ctx %p\n", ctx);
380 }
381
382
383 \f
384 /* Status callback for ks_list, ks_get, ks_search, and wkd_get  */
385 static gpg_error_t
386 ks_status_cb (void *opaque, const char *line)
387 {
388   struct ks_status_parm_s *parm = opaque;
389   gpg_error_t err = 0;
390   const char *s, *s2;
391   const char *warn;
392
393   if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE")))
394     {
395       /* Note that the arg for "S SOURCE" is the URL of a keyserver.  */
396       if (!parm->source)
397         {
398           parm->source = xtrystrdup (s);
399           if (!parm->source)
400             err = gpg_error_from_syserror ();
401         }
402     }
403   else if ((s = has_leading_keyword (line, "WARNING")))
404     {
405       if ((s2 = has_leading_keyword (s, "tor_not_running")))
406         warn = _("Tor is not running");
407       else if ((s2 = has_leading_keyword (s, "tor_config_problem")))
408         warn = _("Tor is not properly configured");
409       else if ((s2 = has_leading_keyword (s, "dns_config_problem")))
410         warn = _("DNS is not properly configured");
411       else
412         warn = NULL;
413
414       if (warn)
415         {
416           log_info (_("WARNING: %s\n"), warn);
417           if (s2)
418             {
419               while (*s2 && !spacep (s2))
420                 s2++;
421               while (*s2 && spacep (s2))
422                 s2++;
423               if (*s2)
424                 print_further_info ("%s", s2);
425             }
426         }
427     }
428
429   return err;
430 }
431
432
433 \f
434 /* Run the "KEYSERVER" command to return the name of the used
435    keyserver at R_KEYSERVER.  */
436 gpg_error_t
437 gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver)
438 {
439   gpg_error_t err;
440   assuan_context_t ctx;
441   struct ks_status_parm_s stparm;
442
443   memset (&stparm, 0, sizeof stparm);
444   stparm.keyword = "KEYSERVER";
445   if (r_keyserver)
446     *r_keyserver = NULL;
447
448   err = open_context (ctrl, &ctx);
449   if (err)
450     return err;
451
452   err = assuan_transact (ctx, "KEYSERVER", NULL, NULL,
453                          NULL, NULL, ks_status_cb, &stparm);
454   if (err)
455     goto leave;
456   if (!stparm.source)
457     {
458       err = gpg_error (GPG_ERR_NO_KEYSERVER);
459       goto leave;
460     }
461
462   if (r_keyserver)
463     *r_keyserver = stparm.source;
464   else
465     xfree (stparm.source);
466   stparm.source = NULL;
467
468  leave:
469   xfree (stparm.source);
470   close_context (ctrl, ctx);
471   return err;
472 }
473
474
475 \f
476 /* Data callback for the KS_SEARCH command. */
477 static gpg_error_t
478 ks_search_data_cb (void *opaque, const void *data, size_t datalen)
479 {
480   gpg_error_t err = 0;
481   struct ks_search_parm_s *parm = opaque;
482   const char *line, *s;
483   size_t rawlen, linelen;
484   char fixedbuf[256];
485
486   if (parm->lasterr)
487     return 0;
488
489   if (parm->stparm->source)
490     {
491       err = parm->data_cb (parm->data_cb_value, 1, parm->stparm->source);
492       if (err)
493         {
494           parm->lasterr = err;
495           return err;
496         }
497       /* Clear it so that we won't get back here unless the server
498          accidentally sends a second source status line.  Note that
499          will not see all accidentally sent source lines because it
500          depends on whether data lines have been send in between.  */
501       xfree (parm->stparm->source);
502       parm->stparm->source = NULL;
503     }
504
505   if (!data)
506     return 0;  /* Ignore END commands.  */
507
508   put_membuf (&parm->saveddata, data, datalen);
509
510  again:
511   line = peek_membuf (&parm->saveddata, &rawlen);
512   if (!line)
513     {
514       parm->lasterr = gpg_error_from_syserror ();
515       return parm->lasterr; /* Tell the server about our problem.  */
516     }
517   if ((s = memchr (line, '\n', rawlen)))
518     {
519       linelen = s - line;  /* That is the length excluding the LF.  */
520       if (linelen + 1 < sizeof fixedbuf)
521         {
522           /* We can use the static buffer.  */
523           memcpy (fixedbuf, line, linelen);
524           fixedbuf[linelen] = 0;
525           if (linelen && fixedbuf[linelen-1] == '\r')
526             fixedbuf[linelen-1] = 0;
527           err = parm->data_cb (parm->data_cb_value, 0, fixedbuf);
528         }
529       else
530         {
531           if (linelen + 1 >= parm->helpbufsize)
532             {
533               xfree (parm->helpbuf);
534               parm->helpbufsize = linelen + 1 + 1024;
535               parm->helpbuf = xtrymalloc (parm->helpbufsize);
536               if (!parm->helpbuf)
537                 {
538                   parm->lasterr = gpg_error_from_syserror ();
539                   return parm->lasterr;
540                 }
541             }
542           memcpy (parm->helpbuf, line, linelen);
543           parm->helpbuf[linelen] = 0;
544           if (linelen && parm->helpbuf[linelen-1] == '\r')
545             parm->helpbuf[linelen-1] = 0;
546           err = parm->data_cb (parm->data_cb_value, 0, parm->helpbuf);
547         }
548       if (err)
549         parm->lasterr = err;
550       else
551         {
552           clear_membuf (&parm->saveddata, linelen+1);
553           goto again;  /* There might be another complete line.  */
554         }
555     }
556
557   return err;
558 }
559
560
561 /* Run the KS_SEARCH command using the search string SEARCHSTR.  All
562    data lines are passed to the CB function.  That function is called
563    with CB_VALUE as its first argument, a 0 as second argument, and
564    the decoded data line as third argument.  The callback function may
565    modify the data line and it is guaranteed that this data line is a
566    complete line with a terminating 0 character but without the
567    linefeed.  NULL is passed to the callback to indicate EOF.  */
568 gpg_error_t
569 gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
570                        gpg_error_t (*cb)(void*, int, char *), void *cb_value)
571 {
572   gpg_error_t err;
573   assuan_context_t ctx;
574   struct ks_status_parm_s stparm;
575   struct ks_search_parm_s parm;
576   char line[ASSUAN_LINELENGTH];
577
578   err = open_context (ctrl, &ctx);
579   if (err)
580     return err;
581
582   {
583     char *escsearchstr = percent_plus_escape (searchstr);
584     if (!escsearchstr)
585       {
586         err = gpg_error_from_syserror ();
587         close_context (ctrl, ctx);
588         return err;
589       }
590     snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
591     xfree (escsearchstr);
592   }
593
594   memset (&stparm, 0, sizeof stparm);
595   memset (&parm, 0, sizeof parm);
596   init_membuf (&parm.saveddata, 1024);
597   parm.data_cb = cb;
598   parm.data_cb_value = cb_value;
599   parm.stparm = &stparm;
600
601   err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
602                         NULL, NULL, ks_status_cb, &stparm);
603   if (!err)
604     err = cb (cb_value, 0, NULL);  /* Send EOF.  */
605
606   xfree (get_membuf (&parm.saveddata, NULL));
607   xfree (parm.helpbuf);
608   xfree (stparm.source);
609
610   close_context (ctrl, ctx);
611   return err;
612 }
613
614
615 \f
616 /* Data callback for the KS_GET and KS_FETCH commands. */
617 static gpg_error_t
618 ks_get_data_cb (void *opaque, const void *data, size_t datalen)
619 {
620   gpg_error_t err = 0;
621   struct ks_get_parm_s *parm = opaque;
622   size_t nwritten;
623
624   if (!data)
625     return 0;  /* Ignore END commands.  */
626
627   if (es_write (parm->memfp, data, datalen, &nwritten))
628     err = gpg_error_from_syserror ();
629
630   return err;
631 }
632
633
634 /* Run the KS_GET command using the patterns in the array PATTERN.  On
635    success an estream object is returned to retrieve the keys.  On
636    error an error code is returned and NULL stored at R_FP.
637
638    The pattern may only use search specification which a keyserver can
639    use to retrieve keys.  Because we know the format of the pattern we
640    don't need to escape the patterns before sending them to the
641    server.
642
643    If QUICK is set the dirmngr is advised to use a shorter timeout.
644
645    If R_SOURCE is not NULL the source of the data is stored as a
646    malloced string there.  If a source is not known NULL is stored.
647
648    If there are too many patterns the function returns an error.  That
649    could be fixed by issuing several search commands or by
650    implementing a different interface.  However with long keyids we
651    are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once.  */
652 gpg_error_t
653 gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern,
654                     keyserver_spec_t override_keyserver, int quick,
655                     estream_t *r_fp, char **r_source)
656 {
657   gpg_error_t err;
658   assuan_context_t ctx;
659   struct ks_status_parm_s stparm;
660   struct ks_get_parm_s parm;
661   char *line = NULL;
662   size_t linelen;
663   membuf_t mb;
664   int idx;
665
666   memset (&stparm, 0, sizeof stparm);
667   memset (&parm, 0, sizeof parm);
668
669   *r_fp = NULL;
670   if (r_source)
671     *r_source = NULL;
672
673   err = open_context (ctrl, &ctx);
674   if (err)
675     return err;
676
677   /* If we have an override keyserver we first indicate that the next
678      user of the context needs to again setup the global keyservers and
679      them we send the override keyserver.  */
680   if (override_keyserver)
681     {
682       clear_context_flags (ctrl, ctx);
683       line = xtryasprintf ("KEYSERVER --clear %s", override_keyserver->uri);
684       if (!line)
685         {
686           err = gpg_error_from_syserror ();
687           goto leave;
688         }
689       err = assuan_transact (ctx, line, NULL, NULL, NULL,
690                              NULL, NULL, NULL);
691       if (err)
692         goto leave;
693
694       xfree (line);
695       line = NULL;
696     }
697
698   /* Lump all patterns into one string.  */
699   init_membuf (&mb, 1024);
700   put_membuf_str (&mb, quick? "KS_GET --quick --" : "KS_GET --");
701   for (idx=0; pattern[idx]; idx++)
702     {
703       put_membuf (&mb, " ", 1); /* Append Delimiter.  */
704       put_membuf_str (&mb, pattern[idx]);
705     }
706   put_membuf (&mb, "", 1); /* Append Nul.  */
707   line = get_membuf (&mb, &linelen);
708   if (!line)
709     {
710       err = gpg_error_from_syserror ();
711       goto leave;
712     }
713   if (linelen + 2 >= ASSUAN_LINELENGTH)
714     {
715       err = gpg_error (GPG_ERR_TOO_MANY);
716       goto leave;
717     }
718
719   parm.memfp = es_fopenmem (0, "rwb");
720   if (!parm.memfp)
721     {
722       err = gpg_error_from_syserror ();
723       goto leave;
724     }
725   err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
726                          NULL, NULL, ks_status_cb, &stparm);
727   if (err)
728     goto leave;
729
730   es_rewind (parm.memfp);
731   *r_fp = parm.memfp;
732   parm.memfp = NULL;
733
734   if (r_source)
735     {
736       *r_source = stparm.source;
737       stparm.source = NULL;
738     }
739
740  leave:
741   es_fclose (parm.memfp);
742   xfree (stparm.source);
743   xfree (line);
744   close_context (ctrl, ctx);
745   return err;
746 }
747
748
749 /* Run the KS_FETCH and pass URL as argument.  On success an estream
750    object is returned to retrieve the keys.  On error an error code is
751    returned and NULL stored at R_FP.
752
753    The url is expected to point to a small set of keys; in many cases
754    only to one key.  However, schemes like finger may return several
755    keys.  Note that the configured keyservers are ignored by the
756    KS_FETCH command.  */
757 gpg_error_t
758 gpg_dirmngr_ks_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
759 {
760   gpg_error_t err;
761   assuan_context_t ctx;
762   struct ks_get_parm_s parm;
763   char *line = NULL;
764
765   memset (&parm, 0, sizeof parm);
766
767   *r_fp = NULL;
768
769   err = open_context (ctrl, &ctx);
770   if (err)
771     return err;
772
773   line = strconcat ("KS_FETCH -- ", url, NULL);
774   if (!line)
775     {
776       err = gpg_error_from_syserror ();
777       goto leave;
778     }
779   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
780     {
781       err = gpg_error (GPG_ERR_TOO_LARGE);
782       goto leave;
783     }
784
785   parm.memfp = es_fopenmem (0, "rwb");
786   if (!parm.memfp)
787     {
788       err = gpg_error_from_syserror ();
789       goto leave;
790     }
791   err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
792                          NULL, NULL, NULL, NULL);
793   if (err)
794     goto leave;
795
796   es_rewind (parm.memfp);
797   *r_fp = parm.memfp;
798   parm.memfp = NULL;
799
800  leave:
801   es_fclose (parm.memfp);
802   xfree (line);
803   close_context (ctrl, ctx);
804   return err;
805 }
806
807
808 \f
809 static void
810 record_output (estream_t output,
811                pkttype_t type,
812                const char *validity,
813                /* The public key length or -1.  */
814                int pub_key_length,
815                /* The public key algo or -1.  */
816                int pub_key_algo,
817                /* 2 ulongs or NULL.  */
818                const u32 *keyid,
819                /* The creation / expiration date or 0.  */
820                u32 creation_date,
821                u32 expiration_date,
822                const char *userid)
823 {
824   const char *type_str = NULL;
825   char *pub_key_length_str = NULL;
826   char *pub_key_algo_str = NULL;
827   char *keyid_str = NULL;
828   char *creation_date_str = NULL;
829   char *expiration_date_str = NULL;
830   char *userid_escaped = NULL;
831
832   switch (type)
833     {
834     case PKT_PUBLIC_KEY:
835       type_str = "pub";
836       break;
837     case PKT_PUBLIC_SUBKEY:
838       type_str = "sub";
839       break;
840     case PKT_USER_ID:
841       type_str = "uid";
842       break;
843     case PKT_SIGNATURE:
844       type_str = "sig";
845       break;
846     default:
847       log_assert (! "Unhandled type.");
848     }
849
850   if (pub_key_length > 0)
851     pub_key_length_str = xasprintf ("%d", pub_key_length);
852
853   if (pub_key_algo != -1)
854     pub_key_algo_str = xasprintf ("%d", pub_key_algo);
855
856   if (keyid)
857     keyid_str = xasprintf ("%08lX%08lX", (ulong) keyid[0], (ulong) keyid[1]);
858
859   if (creation_date)
860     creation_date_str = xstrdup (colon_strtime (creation_date));
861
862   if (expiration_date)
863     expiration_date_str = xstrdup (colon_strtime (expiration_date));
864
865   /* Quote ':', '%', and any 8-bit characters.  */
866   if (userid)
867     {
868       int r;
869       int w = 0;
870
871       int len = strlen (userid);
872       /* A 100k character limit on the uid should be way more than
873          enough.  */
874       if (len > 100 * 1024)
875         len = 100 * 1024;
876
877       /* The minimum amount of space that we need.  */
878       userid_escaped = xmalloc (len * 3 + 1);
879
880       for (r = 0; r < len; r++)
881         {
882           if (userid[r] == ':' || userid[r]== '%' || (userid[r] & 0x80))
883             {
884               sprintf (&userid_escaped[w], "%%%02X", (byte) userid[r]);
885               w += 3;
886             }
887           else
888             userid_escaped[w ++] = userid[r];
889         }
890       userid_escaped[w] = '\0';
891     }
892
893   es_fprintf (output, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
894               type_str,
895               validity ?: "",
896               pub_key_length_str ?: "",
897               pub_key_algo_str ?: "",
898               keyid_str ?: "",
899               creation_date_str ?: "",
900               expiration_date_str ?: "",
901               "" /* Certificate S/N */,
902               "" /* Ownertrust.  */,
903               userid_escaped ?: "",
904               "" /* Signature class.  */,
905               "" /* Key capabilities.  */,
906               "" /* Issuer certificate fingerprint.  */,
907               "" /* Flag field.  */,
908               "" /* S/N of a token.  */,
909               "" /* Hash algo.  */,
910               "" /* Curve name.  */);
911
912   xfree (userid_escaped);
913   xfree (expiration_date_str);
914   xfree (creation_date_str);
915   xfree (keyid_str);
916   xfree (pub_key_algo_str);
917   xfree (pub_key_length_str);
918 }
919
920 /* Handle the KS_PUT inquiries. */
921 static gpg_error_t
922 ks_put_inq_cb (void *opaque, const char *line)
923 {
924   struct ks_put_parm_s *parm = opaque;
925   gpg_error_t err = 0;
926
927   if (has_leading_keyword (line, "KEYBLOCK"))
928     {
929       if (parm->data)
930         err = assuan_send_data (parm->ctx, parm->data, parm->datalen);
931     }
932   else if (has_leading_keyword (line, "KEYBLOCK_INFO"))
933     {
934       kbnode_t node;
935       estream_t fp;
936
937       /* Parse the keyblock and send info lines back to the server.  */
938       fp = es_fopenmem (0, "rw,samethread");
939       if (!fp)
940         err = gpg_error_from_syserror ();
941
942       /* Note: the output format for the INFO block follows the colon
943          format as described in doc/DETAILS.  We don't actually reuse
944          the functionality from g10/keylist.c to produce the output,
945          because we don't need all of it and some of it is quite
946          expensive to generate.
947
948          The fields are (the starred fields are the ones we need):
949
950            * Field 1 - Type of record
951            * Field 2 - Validity
952            * Field 3 - Key length
953            * Field 4 - Public key algorithm
954            * Field 5 - KeyID
955            * Field 6 - Creation date
956            * Field 7 - Expiration date
957              Field 8 - Certificate S/N, UID hash, trust signature info
958              Field 9 -  Ownertrust
959            * Field 10 - User-ID
960              Field 11 - Signature class
961              Field 12 - Key capabilities
962              Field 13 - Issuer certificate fingerprint or other info
963              Field 14 - Flag field
964              Field 15 - S/N of a token
965              Field 16 - Hash algorithm
966              Field 17 - Curve name
967        */
968       for (node = parm->keyblock; !err && node; node=node->next)
969         {
970           switch (node->pkt->pkttype)
971             {
972             case PKT_PUBLIC_KEY:
973             case PKT_PUBLIC_SUBKEY:
974               {
975                 PKT_public_key *pk = node->pkt->pkt.public_key;
976
977                 char validity[3];
978                 int i;
979
980                 i = 0;
981                 if (pk->flags.revoked)
982                   validity[i ++] = 'r';
983                 if (pk->has_expired)
984                   validity[i ++] = 'e';
985                 validity[i] = '\0';
986
987                 keyid_from_pk (pk, NULL);
988
989                 record_output (fp, node->pkt->pkttype, validity,
990                                nbits_from_pk (pk), pk->pubkey_algo,
991                                pk->keyid, pk->timestamp, pk->expiredate,
992                                NULL);
993               }
994               break;
995
996             case PKT_USER_ID:
997               {
998                 PKT_user_id *uid = node->pkt->pkt.user_id;
999
1000                 if (!uid->attrib_data)
1001                   {
1002                     char validity[3];
1003                     int i;
1004
1005                     i = 0;
1006                     if (uid->flags.revoked)
1007                       validity[i ++] = 'r';
1008                     if (uid->flags.expired)
1009                       validity[i ++] = 'e';
1010                     validity[i] = '\0';
1011
1012                     record_output (fp, node->pkt->pkttype, validity,
1013                                    -1, -1, NULL,
1014                                    uid->created, uid->expiredate,
1015                                    uid->name);
1016                   }
1017               }
1018               break;
1019
1020               /* This bit is really for the benefit of people who
1021                  store their keys in LDAP servers.  It makes it easy
1022                  to do queries for things like "all keys signed by
1023                  Isabella".  */
1024             case PKT_SIGNATURE:
1025               {
1026                 PKT_signature *sig = node->pkt->pkt.signature;
1027
1028                 if (IS_UID_SIG (sig))
1029                   record_output (fp, node->pkt->pkttype, NULL,
1030                                  -1, -1, sig->keyid,
1031                                  sig->timestamp, sig->expiredate, NULL);
1032               }
1033               break;
1034
1035             default:
1036               continue;
1037             }
1038           /* Given that the last operation was an es_fprintf we should
1039              get the correct ERRNO if ferror indicates an error.  */
1040           if (es_ferror (fp))
1041             err = gpg_error_from_syserror ();
1042         }
1043
1044       /* Without an error and if we have an keyblock at all, send the
1045          data back.  */
1046       if (!err && parm->keyblock)
1047         {
1048           int rc;
1049           char buffer[512];
1050           size_t nread;
1051
1052           es_rewind (fp);
1053           while (!(rc=es_read (fp, buffer, sizeof buffer, &nread)) && nread)
1054             {
1055               err = assuan_send_data (parm->ctx, buffer, nread);
1056               if (err)
1057                 break;
1058             }
1059           if (!err && rc)
1060             err = gpg_error_from_syserror ();
1061         }
1062       es_fclose (fp);
1063     }
1064   else
1065     return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1066
1067   return err;
1068 }
1069
1070
1071 /* Send a key to the configured server.  {DATA,DATLEN} contains the
1072    key in OpenPGP binary transport format.  If KEYBLOCK is not NULL it
1073    has the internal representaion of that key; this is for example
1074    used to convey meta data to LDAP keyservers.  */
1075 gpg_error_t
1076 gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen, kbnode_t keyblock)
1077 {
1078   gpg_error_t err;
1079   assuan_context_t ctx;
1080   struct ks_put_parm_s parm;
1081
1082   memset (&parm, 0, sizeof parm);
1083
1084   /* We are going to parse the keyblock, thus we better make sure the
1085      all information is readily available.  */
1086   if (keyblock)
1087     merge_keys_and_selfsig (ctrl, keyblock);
1088
1089   err = open_context (ctrl, &ctx);
1090   if (err)
1091     return err;
1092
1093   parm.ctx = ctx;
1094   parm.keyblock = keyblock;
1095   parm.data = data;
1096   parm.datalen = datalen;
1097
1098   err = assuan_transact (ctx, "KS_PUT", NULL, NULL,
1099                          ks_put_inq_cb, &parm, NULL, NULL);
1100
1101   close_context (ctrl, ctx);
1102   return err;
1103 }
1104
1105
1106 \f
1107 /* Data callback for the DNS_CERT and WKD_GET commands. */
1108 static gpg_error_t
1109 dns_cert_data_cb (void *opaque, const void *data, size_t datalen)
1110 {
1111   struct dns_cert_parm_s *parm = opaque;
1112   gpg_error_t err = 0;
1113   size_t nwritten;
1114
1115   if (!data)
1116     return 0;  /* Ignore END commands.  */
1117   if (!parm->memfp)
1118     return 0;  /* Data is not required.  */
1119
1120   if (es_write (parm->memfp, data, datalen, &nwritten))
1121     err = gpg_error_from_syserror ();
1122
1123   return err;
1124 }
1125
1126
1127 /* Status callback for the DNS_CERT command.  */
1128 static gpg_error_t
1129 dns_cert_status_cb (void *opaque, const char *line)
1130 {
1131   struct dns_cert_parm_s *parm = opaque;
1132   gpg_error_t err = 0;
1133   const char *s;
1134   size_t nbytes;
1135
1136   if ((s = has_leading_keyword (line, "FPR")))
1137     {
1138       char *buf;
1139
1140       if (!(buf = xtrystrdup (s)))
1141         err = gpg_error_from_syserror ();
1142       else if (parm->fpr)
1143         err = gpg_error (GPG_ERR_DUP_KEY);
1144       else if (!hex2str (buf, buf, strlen (buf)+1, &nbytes))
1145         err = gpg_error_from_syserror ();
1146       else if (nbytes < 20)
1147         err = gpg_error (GPG_ERR_TOO_SHORT);
1148       else
1149         {
1150           parm->fpr = xtrymalloc (nbytes);
1151           if (!parm->fpr)
1152             err = gpg_error_from_syserror ();
1153           else
1154             memcpy (parm->fpr, buf, (parm->fprlen = nbytes));
1155         }
1156       xfree (buf);
1157     }
1158   else if ((s = has_leading_keyword (line, "URL")) && *s)
1159     {
1160       if (parm->url)
1161         err = gpg_error (GPG_ERR_DUP_KEY);
1162       else if (!(parm->url = xtrystrdup (s)))
1163         err = gpg_error_from_syserror ();
1164     }
1165
1166   return err;
1167 }
1168
1169 /* Ask the dirmngr for a DNS CERT record.  Depending on the found
1170    subtypes different return values are set:
1171
1172    - For a PGP subtype a new estream with that key will be returned at
1173      R_KEY and the other return parameters are set to NULL/0.
1174
1175    - For an IPGP subtype the fingerprint is stored as a malloced block
1176      at (R_FPR,R_FPRLEN).  If an URL is available it is stored as a
1177      malloced string at R_URL; NULL is stored if there is no URL.
1178
1179    If CERTTYPE is DNS_CERTTYPE_ANY this function returns the first
1180    CERT record found with a supported type; it is expected that only
1181    one CERT record is used.  If CERTTYPE is one of the supported
1182    certtypes, only records with this certtype are considered and the
1183    first one found is returned.  All R_* args are optional.
1184
1185    If CERTTYPE is NULL the DANE method is used to fetch the key.
1186  */
1187 gpg_error_t
1188 gpg_dirmngr_dns_cert (ctrl_t ctrl, const char *name, const char *certtype,
1189                       estream_t *r_key,
1190                       unsigned char **r_fpr, size_t *r_fprlen,
1191                       char **r_url)
1192 {
1193   gpg_error_t err;
1194   assuan_context_t ctx;
1195   struct dns_cert_parm_s parm;
1196   char *line = NULL;
1197
1198   memset (&parm, 0, sizeof parm);
1199   if (r_key)
1200     *r_key = NULL;
1201   if (r_fpr)
1202     *r_fpr = NULL;
1203   if (r_fprlen)
1204     *r_fprlen = 0;
1205   if (r_url)
1206     *r_url = NULL;
1207
1208   err = open_context (ctrl, &ctx);
1209   if (err)
1210     return err;
1211
1212   line = es_bsprintf ("DNS_CERT %s %s", certtype? certtype : "--dane", name);
1213   if (!line)
1214     {
1215       err = gpg_error_from_syserror ();
1216       goto leave;
1217     }
1218   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1219     {
1220       err = gpg_error (GPG_ERR_TOO_LARGE);
1221       goto leave;
1222     }
1223
1224   parm.memfp = es_fopenmem (0, "rwb");
1225   if (!parm.memfp)
1226     {
1227       err = gpg_error_from_syserror ();
1228       goto leave;
1229     }
1230   err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1231                          NULL, NULL, dns_cert_status_cb, &parm);
1232   if (err)
1233     goto leave;
1234
1235   if (r_key)
1236     {
1237       es_rewind (parm.memfp);
1238       *r_key = parm.memfp;
1239       parm.memfp = NULL;
1240     }
1241
1242   if (r_fpr && parm.fpr)
1243     {
1244       *r_fpr = parm.fpr;
1245       parm.fpr = NULL;
1246     }
1247   if (r_fprlen)
1248     *r_fprlen = parm.fprlen;
1249
1250   if (r_url && parm.url)
1251     {
1252       *r_url = parm.url;
1253       parm.url = NULL;
1254     }
1255
1256  leave:
1257   xfree (parm.fpr);
1258   xfree (parm.url);
1259   es_fclose (parm.memfp);
1260   xfree (line);
1261   close_context (ctrl, ctx);
1262   return err;
1263 }
1264
1265
1266 /* Ask the dirmngr for PKA info.  On success the retrieved fingerprint
1267    is returned in a malloced buffer at R_FPR and its length is stored
1268    at R_FPRLEN.  If an URL is available it is stored as a malloced
1269    string at R_URL.  On error all return values are set to NULL/0.  */
1270 gpg_error_t
1271 gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
1272                      unsigned char **r_fpr, size_t *r_fprlen,
1273                      char **r_url)
1274 {
1275   gpg_error_t err;
1276   assuan_context_t ctx;
1277   struct dns_cert_parm_s parm;
1278   char *line = NULL;
1279
1280   memset (&parm, 0, sizeof parm);
1281   if (r_fpr)
1282     *r_fpr = NULL;
1283   if (r_fprlen)
1284     *r_fprlen = 0;
1285   if (r_url)
1286     *r_url = NULL;
1287
1288   err = open_context (ctrl, &ctx);
1289   if (err)
1290     return err;
1291
1292   line = es_bsprintf ("DNS_CERT --pka -- %s", userid);
1293   if (!line)
1294     {
1295       err = gpg_error_from_syserror ();
1296       goto leave;
1297     }
1298   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1299     {
1300       err = gpg_error (GPG_ERR_TOO_LARGE);
1301       goto leave;
1302     }
1303
1304   err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1305                          NULL, NULL, dns_cert_status_cb, &parm);
1306   if (err)
1307     goto leave;
1308
1309   if (r_fpr && parm.fpr)
1310     {
1311       *r_fpr = parm.fpr;
1312       parm.fpr = NULL;
1313     }
1314   if (r_fprlen)
1315     *r_fprlen = parm.fprlen;
1316
1317   if (r_url && parm.url)
1318     {
1319       *r_url = parm.url;
1320       parm.url = NULL;
1321     }
1322
1323  leave:
1324   xfree (parm.fpr);
1325   xfree (parm.url);
1326   xfree (line);
1327   close_context (ctrl, ctx);
1328   return err;
1329 }
1330
1331
1332 \f
1333 /* Ask the dirmngr to retrieve a key via the Web Key Directory
1334  * protocol.  If QUICK is set the dirmngr is advised to use a shorter
1335  * timeout.  On success a new estream with the key stored at R_KEY and the
1336  * url of the lookup (if any) stored at R_URL.  Note that
1337  */
1338 gpg_error_t
1339 gpg_dirmngr_wkd_get (ctrl_t ctrl, const char *name, int quick,
1340                      estream_t *r_key, char **r_url)
1341 {
1342   gpg_error_t err;
1343   assuan_context_t ctx;
1344   struct ks_status_parm_s stparm = { NULL };
1345   struct dns_cert_parm_s parm = { NULL };
1346   char *line = NULL;
1347
1348   if (r_key)
1349     *r_key = NULL;
1350
1351   if (r_url)
1352     *r_url = NULL;
1353
1354   err = open_context (ctrl, &ctx);
1355   if (err)
1356     return err;
1357
1358   line = es_bsprintf ("WKD_GET%s -- %s", quick?" --quick":"", name);
1359   if (!line)
1360     {
1361       err = gpg_error_from_syserror ();
1362       goto leave;
1363     }
1364   if (strlen (line) + 2 >= ASSUAN_LINELENGTH)
1365     {
1366       err = gpg_error (GPG_ERR_TOO_LARGE);
1367       goto leave;
1368     }
1369
1370   parm.memfp = es_fopenmem (0, "rwb");
1371   if (!parm.memfp)
1372     {
1373       err = gpg_error_from_syserror ();
1374       goto leave;
1375     }
1376   err = assuan_transact (ctx, line, dns_cert_data_cb, &parm,
1377                          NULL, NULL, ks_status_cb, &stparm);
1378   if (err)
1379     goto leave;
1380
1381   if (r_key)
1382     {
1383       es_rewind (parm.memfp);
1384       *r_key = parm.memfp;
1385       parm.memfp = NULL;
1386     }
1387
1388   if (r_url)
1389     {
1390       *r_url = stparm.source;
1391       stparm.source = NULL;
1392     }
1393
1394  leave:
1395   xfree (stparm.source);
1396   xfree (parm.fpr);
1397   xfree (parm.url);
1398   es_fclose (parm.memfp);
1399   xfree (line);
1400   close_context (ctrl, ctx);
1401   return err;
1402 }