Keyserver search and get basically works again.
[gnupg.git] / g10 / call-dirmngr.c
1 /* call-dirmngr.c - GPG operations to the Dirmngr.
2  * Copyright (C) 2011 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h> 
26 #include <time.h>
27 #include <assert.h>
28 #ifdef HAVE_LOCALE_H
29 # include <locale.h>
30 #endif
31
32 #include "gpg.h"
33 #include <assuan.h>
34 #include "util.h"
35 #include "membuf.h"
36 #include "options.h"
37 #include "i18n.h"
38 #include "asshelp.h"
39 #include "keyserver.h"
40 #include "call-dirmngr.h"
41
42
43 /* Parameter structure used with the KS_SEARCH command.  */
44 struct ks_search_parm_s
45 {
46   gpg_error_t lasterr;  /* Last error code.  */
47   membuf_t saveddata;   /* Buffer to build complete lines.  */
48   char *helpbuf;        /* NULL or malloced buffer.  */
49   size_t helpbufsize;   /* Allocated size of HELPBUF.  */
50   gpg_error_t (*data_cb)(void*, char*);  /* Callback.  */
51   void *data_cb_value;  /* First argument for DATA_CB.  */
52 };
53
54
55 /* Parameter structure used with the KS_GET command.  */
56 struct ks_get_parm_s
57 {
58   estream_t memfp;
59 };
60
61
62 /* Data used to associate an session with dirmngr contexts.  We can't
63    use a simple one to one mapping because we sometimes need two
64    connection s to the dirmngr; for example while doing a listing and
65    being in a data callback we may want to retrieve a key.  The local
66    dirmngr data takes care of this.  At the end of the session the
67    function dirmngr_deinit_session_data is called bu gpg.c to cleanup
68    these resources.  Note that gpg.h defines a typedef dirmngr_local_t
69    for this structure. */
70 struct dirmngr_local_s 
71 {
72   /* Link to other contexts which are used simultaneously.  */
73   struct dirmngr_local_s *next;
74
75   /* The active Assuan context. */
76   assuan_context_t ctx;
77
78   /* Flag set to true while an operation is running on CTX.  */
79   int is_active;
80 };
81
82
83 \f
84 /* Deinitialize all session data of dirmngr pertaining to CTRL.  */
85 void
86 gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
87 {
88   dirmngr_local_t dml;
89
90   while ((dml = ctrl->dirmngr_local))
91     {
92       ctrl->dirmngr_local = dml->next;
93       if (dml->is_active)
94         log_error ("oops: trying to cleanup an active dirmngr context\n");
95       else
96         assuan_release (dml->ctx);
97       xfree (dml);
98     }
99 }
100
101
102 /* Try to connect to the Dirmngr via a socket or fork it off if
103    possible.  Handle the server's initial greeting and set global
104    options.  */
105 static gpg_error_t
106 create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
107 {
108   gpg_error_t err;
109   assuan_context_t ctx;
110
111   *r_ctx = NULL;
112   err = start_new_dirmngr (&ctx,
113                            GPG_ERR_SOURCE_DEFAULT,
114                            opt.homedir,
115                            NULL,
116                            opt.verbose, DBG_ASSUAN,
117                            NULL /*gpg_status2*/, ctrl);
118   if (!err)
119     {
120       keyserver_spec_t ksi;
121
122       /* Tell the dirmngr that we want to collect audit event. */
123       /* err = assuan_transact (agent_ctx, "OPTION audit-events=1", */
124       /*                        NULL, NULL, NULL, NULL, NULL, NULL); */
125       
126       /* Set all configured keyservers.  We clear existing keyservers
127          so that any keyserver configured in GPG overrides keyservers
128          possibly configured in Dirmngr. */
129       for (ksi = opt.keyserver; !err && ksi; ksi = ksi->next)
130         {
131           char *line;
132           
133           line = xtryasprintf ("KEYSERVER%s %s",
134                                ksi == opt.keyserver? " --clear":"", ksi->uri);
135           if (!line)
136             err = gpg_error_from_syserror ();
137           else
138             {
139               err = assuan_transact (ctx, line,
140                                      NULL, NULL, NULL, NULL, NULL, NULL);
141               xfree (line);
142             }
143         }
144     }
145
146   if (err)
147     assuan_release (ctx);
148   else
149     {
150       /* audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); */
151       *r_ctx = ctx;
152     }
153   
154   return err;
155 }
156
157
158 /* Get a context for accessing dirmngr.  If no context is available a
159    new one is created and - if requred - dirmngr started.  On success
160    an assuan context is stored at R_CTX.  This Context may only be
161    released by means of close_context.  Note that NULL is stored at
162    R_CTX on error.  */
163 static gpg_error_t
164 open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
165 {
166   gpg_error_t err;
167   dirmngr_local_t dml;
168
169   *r_ctx = NULL;
170   for (;;)
171     {
172       for (dml = ctrl->dirmngr_local; dml && dml->is_active; dml = dml->next)
173         ;
174       if (dml)
175         {
176           /* Found an inactive local session - return that.  */
177           assert (!dml->is_active);
178           dml->is_active = 1;
179           *r_ctx = dml->ctx;
180           return 0;
181         }
182       
183       dml = xtrycalloc (1, sizeof *dml);
184       if (!dml)
185         return gpg_error_from_syserror ();
186       err = create_context (ctrl, &dml->ctx);
187       if (err)
188         {
189           xfree (dml);
190           return err;
191         }
192       /* To be on the Pth thread safe site we need to add it to a
193          list; this is far easier than to have a lock for this
194          function.  It should not happen anyway but the code is free
195          because we need it for the is_active check above.  */
196       dml->next = ctrl->dirmngr_local;
197       ctrl->dirmngr_local = dml;
198     }
199 }
200
201
202 /* Close the assuan context CTX or return it to a pool of unused
203    contexts.  If CTX is NULL, the function does nothing.  */
204 static void
205 close_context (ctrl_t ctrl, assuan_context_t ctx)
206 {
207   dirmngr_local_t dml;
208
209   if (!ctx)
210     return;
211
212   for (dml = ctrl->dirmngr_local; dml; dml = dml->next)
213     {
214       if (dml->ctx == ctx)
215         {
216           if (!dml->is_active)
217             log_fatal ("closing inactive dirmngr context %p\n", ctx);
218           dml->is_active = 0;
219           return;
220         }
221     }
222   log_fatal ("closing unknown dirmngr ctx %p\n", ctx);
223 }
224
225
226 \f
227 /* Data callback for the KS_SEARCH command. */
228 static gpg_error_t
229 ks_search_data_cb (void *opaque, const void *data, size_t datalen)
230 {
231   gpg_error_t err = 0;
232   struct ks_search_parm_s *parm = opaque;
233   const char *line, *s;
234   size_t rawlen, linelen;
235   char fixedbuf[256];
236
237   if (parm->lasterr)
238     return 0;
239
240   if (!data)
241     return 0;  /* Ignore END commands.  */
242
243   put_membuf (&parm->saveddata, data, datalen);
244
245  again:
246   line = peek_membuf (&parm->saveddata, &rawlen);
247   if (!line)
248     {
249       parm->lasterr = gpg_error_from_syserror ();
250       return parm->lasterr; /* Tell the server about our problem.  */
251     }
252   if ((s = memchr (line, '\n', rawlen)))
253     {
254       linelen = s - line;  /* That is the length excluding the LF.  */
255       if (linelen + 1 < sizeof fixedbuf)
256         {
257           /* We can use the static buffer.  */
258           memcpy (fixedbuf, line, linelen);
259           fixedbuf[linelen] = 0;
260           if (linelen && fixedbuf[linelen-1] == '\r')
261             fixedbuf[linelen-1] = 0;
262           err = parm->data_cb (parm->data_cb_value, fixedbuf);
263         }
264       else 
265         {
266           if (linelen + 1 >= parm->helpbufsize)
267             {
268               xfree (parm->helpbuf);
269               parm->helpbufsize = linelen + 1 + 1024;
270               parm->helpbuf = xtrymalloc (parm->helpbufsize);
271               if (!parm->helpbuf)
272                 {
273                   parm->lasterr = gpg_error_from_syserror ();
274                   return parm->lasterr;
275                 }
276             }
277           memcpy (parm->helpbuf, line, linelen);
278           parm->helpbuf[linelen] = 0;
279           if (linelen && parm->helpbuf[linelen-1] == '\r')
280             parm->helpbuf[linelen-1] = 0;
281           err = parm->data_cb (parm->data_cb_value, parm->helpbuf);
282         }
283       if (err)
284         parm->lasterr = err;
285       else
286         {
287           clear_membuf (&parm->saveddata, linelen+1);
288           goto again;  /* There might be another complete line.  */
289         }
290     }
291
292   return err;
293 }
294
295
296 /* Run the KS_SEARCH command using the search string SEARCHSTR.  All
297    data lines are passed to the CB function.  That function is called
298    with CB_VALUE as its first argument and the decoded data line as
299    second argument.  The callback function may modify the data line
300    and it is guaranteed that this data line is a complete line with a
301    terminating 0 character but without the linefeed.  NULL is passed
302    to the callback to indicate EOF.  */
303 gpg_error_t
304 gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
305                        gpg_error_t (*cb)(void*, char *), void *cb_value)
306
307   gpg_error_t err;
308   assuan_context_t ctx;
309   struct ks_search_parm_s parm;
310   char line[ASSUAN_LINELENGTH];
311
312   err = open_context (ctrl, &ctx);
313   if (err)
314     return err;
315
316   {
317     char *escsearchstr = percent_plus_escape (searchstr);
318     if (!escsearchstr)
319       {
320         err = gpg_error_from_syserror ();
321         close_context (ctrl, ctx);
322         return err;
323       }
324     snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
325     xfree (escsearchstr);
326   }
327
328   memset (&parm, 0, sizeof parm);
329   init_membuf (&parm.saveddata, 1024);
330   parm.data_cb = cb;
331   parm.data_cb_value = cb_value;
332
333   err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
334                         NULL, NULL, NULL, NULL);
335   if (!err)
336     err = cb (cb_value, NULL);  /* Send EOF.  */
337
338   xfree (get_membuf (&parm.saveddata, NULL));
339   xfree (parm.helpbuf);
340
341   close_context (ctrl, ctx);
342   return err;
343 }
344
345
346 \f
347 /* Data callback for the KS_GET command. */
348 static gpg_error_t
349 ks_get_data_cb (void *opaque, const void *data, size_t datalen)
350 {
351   gpg_error_t err = 0;
352   struct ks_get_parm_s *parm = opaque;
353   size_t nwritten;
354
355   if (!data)
356     return 0;  /* Ignore END commands.  */
357
358   if (es_write (parm->memfp, data, datalen, &nwritten))
359     err = gpg_error_from_syserror ();
360
361   return err;
362 }
363
364
365 /* Run the KS_GET command using the patterns in the array PATTERN.  On
366    success an estream object is returned to retrieve the keys.  On
367    error an error code is returned and NULL stored at R_FP.
368
369    The pattern may only use search specification which a keyserver can
370    use to retriev keys.  Because we know the format of the pattern we
371    don't need to escape the patterns before sending them to the
372    server.
373
374    If there are too many patterns the function returns an error.  That
375    could be fixed by issuing several search commands or by
376    implementing a different interface.  However with long keyids we
377    are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once.  */
378 gpg_error_t
379 gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern, estream_t *r_fp)
380
381   gpg_error_t err;
382   assuan_context_t ctx;
383   struct ks_get_parm_s parm;
384   char *line = NULL;
385   size_t linelen;
386   membuf_t mb;
387   int idx;
388
389   memset (&parm, 0, sizeof parm);
390
391   *r_fp = NULL;
392
393   err = open_context (ctrl, &ctx);
394   if (err)
395     return err;
396
397   /* Lump all patterns into one string.  */
398   init_membuf (&mb, 1024);
399   put_membuf_str (&mb, "KS_GET --");
400   for (idx=0; pattern[idx]; idx++)
401     {
402       put_membuf (&mb, " ", 1); /* Append Delimiter.  */
403       put_membuf_str (&mb, pattern[idx]);
404     }
405   put_membuf (&mb, "", 1); /* Append Nul.  */
406   line = get_membuf (&mb, &linelen);
407   if (!line)
408     {
409       err = gpg_error_from_syserror ();
410       goto leave;
411     }
412   if (linelen + 2 >= ASSUAN_LINELENGTH)
413     {
414       err = gpg_error (GPG_ERR_TOO_MANY);
415       goto leave;
416     }
417
418   parm.memfp = es_fopenmem (0, "rwb");
419   if (!parm.memfp)
420     {
421       err = gpg_error_from_syserror ();
422       goto leave;
423     }
424   err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
425                          NULL, NULL, NULL, NULL);
426   if (err)
427     goto leave;
428
429   es_rewind (parm.memfp);
430   *r_fp = parm.memfp;
431   parm.memfp = NULL;
432
433  leave:
434   es_fclose (parm.memfp);
435   xfree (line);
436   close_context (ctrl, ctx);
437   return err;
438 }