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