common: Add 'free_strlist_wipe' which wipes memory.
[gnupg.git] / dirmngr / ks-engine-hkp.c
1 /* ks-engine-hkp.c - HKP keyserver engine
2  * Copyright (C) 2011, 2012 Free Software Foundation, Inc.
3  * Copyright (C) 2011, 2012, 2014 Werner Koch
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
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #ifdef HAVE_W32_SYSTEM
28 # ifdef HAVE_WINSOCK2_H
29 #  include <winsock2.h>
30 # endif
31 # include <windows.h>
32 #else /*!HAVE_W32_SYSTEM*/
33 # include <sys/types.h>
34 # include <sys/socket.h>
35 # include <netdb.h>
36 #endif /*!HAVE_W32_SYSTEM*/
37
38 #include "dirmngr.h"
39 #include "misc.h"
40 #include "userids.h"
41 #include "dns-stuff.h"
42 #include "ks-engine.h"
43
44 /* Substitutes for missing Mingw macro.  The EAI_SYSTEM mechanism
45    seems not to be available (probably because there is only one set
46    of error codes anyway).  For now we use WSAEINVAL. */
47 #ifndef EAI_OVERFLOW
48 # define EAI_OVERFLOW EAI_FAIL
49 #endif
50 #ifdef HAVE_W32_SYSTEM
51 # ifndef EAI_SYSTEM
52 #  define EAI_SYSTEM WSAEINVAL
53 # endif
54 #endif
55
56
57 /* Number of seconds after a host is marked as resurrected.  */
58 #define RESURRECT_INTERVAL  (3600*3)  /* 3 hours */
59
60 /* To match the behaviour of our old gpgkeys helper code we escape
61    more characters than actually needed. */
62 #define EXTRA_ESCAPE_CHARS "@!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
63
64 /* How many redirections do we allow.  */
65 #define MAX_REDIRECTS 2
66
67 /* Number of retries done for a dead host etc.  */
68 #define SEND_REQUEST_RETRIES 3
69
70 /* Objects used to maintain information about hosts.  */
71 struct hostinfo_s;
72 typedef struct hostinfo_s *hostinfo_t;
73 struct hostinfo_s
74 {
75   time_t lastfail;   /* Time we tried to connect and failed.  */
76   time_t lastused;   /* Time of last use.  */
77   int *pool;         /* A -1 terminated array with indices into
78                         HOSTTABLE or NULL if NAME is not a pool
79                         name.  */
80   int poolidx;       /* Index into POOL with the used host.  -1 if not set.  */
81   unsigned int v4:1; /* Host supports AF_INET.  */
82   unsigned int v6:1; /* Host supports AF_INET6.  */
83   unsigned int onion:1;/* NAME is an onion (Tor HS) address.  */
84   unsigned int dead:1; /* Host is currently unresponsive.  */
85   time_t died_at;    /* The time the host was marked dead.  If this is
86                         0 the host has been manually marked dead.  */
87   char *cname;       /* Canonical name of the host.  Only set if this
88                         is a pool.  */
89   char *v4addr;      /* A string with the v4 IP address of the host.
90                         NULL if NAME has a numeric IP address or no v4
91                         address is available.  */
92   char *v6addr;      /* A string with the v6 IP address of the host.
93                         NULL if NAME has a numeric IP address or no v6
94                         address is available.  */
95   unsigned short port; /* The port used by the host, 0 if unknown.  */
96   char name[1];      /* The hostname.  */
97 };
98
99
100 /* An array of hostinfo_t for all hosts requested by the caller or
101    resolved from a pool name and its allocated size.*/
102 static hostinfo_t *hosttable;
103 static int hosttable_size;
104
105 /* The number of host slots we initially allocate for HOSTTABLE.  */
106 #define INITIAL_HOSTTABLE_SIZE 10
107
108
109 /* Create a new hostinfo object, fill in NAME and put it into
110    HOSTTABLE.  Return the index into hosttable on success or -1 on
111    error. */
112 static int
113 create_new_hostinfo (const char *name)
114 {
115   hostinfo_t hi, *newtable;
116   int newsize;
117   int idx, rc;
118
119   hi = xtrymalloc (sizeof *hi + strlen (name));
120   if (!hi)
121     return -1;
122   strcpy (hi->name, name);
123   hi->pool = NULL;
124   hi->poolidx = -1;
125   hi->lastused = (time_t)(-1);
126   hi->lastfail = (time_t)(-1);
127   hi->v4 = 0;
128   hi->v6 = 0;
129   hi->onion = 0;
130   hi->dead = 0;
131   hi->died_at = 0;
132   hi->cname = NULL;
133   hi->v4addr = NULL;
134   hi->v6addr = NULL;
135   hi->port = 0;
136
137   /* Add it to the hosttable. */
138   for (idx=0; idx < hosttable_size; idx++)
139     if (!hosttable[idx])
140       {
141         hosttable[idx] = hi;
142         return idx;
143       }
144   /* Need to extend the hosttable.  */
145   newsize = hosttable_size + INITIAL_HOSTTABLE_SIZE;
146   newtable = xtryrealloc (hosttable, newsize * sizeof *hosttable);
147   if (!newtable)
148     {
149       xfree (hi);
150       return -1;
151     }
152   hosttable = newtable;
153   idx = hosttable_size;
154   hosttable_size = newsize;
155   rc = idx;
156   hosttable[idx++] = hi;
157   while (idx < hosttable_size)
158     hosttable[idx++] = NULL;
159
160   return rc;
161 }
162
163
164 /* Find the host NAME in our table.  Return the index into the
165    hosttable or -1 if not found.  */
166 static int
167 find_hostinfo (const char *name)
168 {
169   int idx;
170
171   for (idx=0; idx < hosttable_size; idx++)
172     if (hosttable[idx] && !ascii_strcasecmp (hosttable[idx]->name, name))
173       return idx;
174   return -1;
175 }
176
177
178 static int
179 sort_hostpool (const void *xa, const void *xb)
180 {
181   int a = *(int *)xa;
182   int b = *(int *)xb;
183
184   assert (a >= 0 && a < hosttable_size);
185   assert (b >= 0 && b < hosttable_size);
186   assert (hosttable[a]);
187   assert (hosttable[b]);
188
189   return ascii_strcasecmp (hosttable[a]->name, hosttable[b]->name);
190 }
191
192
193 /* Return true if the host with the hosttable index TBLIDX is in POOL.  */
194 static int
195 host_in_pool_p (int *pool, int tblidx)
196 {
197   int i, pidx;
198
199   for (i=0; (pidx = pool[i]) != -1; i++)
200     if (pidx == tblidx && hosttable[pidx])
201       return 1;
202   return 0;
203 }
204
205
206 /* Select a random host.  Consult TABLE which indices into the global
207    hosttable.  Returns index into TABLE or -1 if no host could be
208    selected.  */
209 static int
210 select_random_host (int *table)
211 {
212   int *tbl;
213   size_t tblsize;
214   int pidx, idx;
215
216   /* We create a new table so that we randomly select only from
217      currently alive hosts.  */
218   for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
219     if (hosttable[pidx] && !hosttable[pidx]->dead)
220       tblsize++;
221   if (!tblsize)
222     return -1; /* No hosts.  */
223
224   tbl = xtrymalloc (tblsize * sizeof *tbl);
225   if (!tbl)
226     return -1;
227   for (idx=0, tblsize=0; (pidx = table[idx]) != -1; idx++)
228     if (hosttable[pidx] && !hosttable[pidx]->dead)
229       tbl[tblsize++] = pidx;
230
231   if (tblsize == 1)  /* Save a get_uint_nonce.  */
232     pidx = tbl[0];
233   else
234     pidx = tbl[get_uint_nonce () % tblsize];
235
236   xfree (tbl);
237   return pidx;
238 }
239
240
241 /* Figure out if a set of DNS records looks like a pool.  */
242 static int
243 arecords_is_pool (dns_addrinfo_t aibuf)
244 {
245   dns_addrinfo_t ai;
246   int n_v6, n_v4;
247
248   n_v6 = n_v4 = 0;
249   for (ai = aibuf; ai; ai = ai->next)
250     {
251       if (ai->family == AF_INET6)
252         n_v6++;
253       else if (ai->family == AF_INET)
254         n_v4++;
255     }
256
257   return n_v6 > 1 || n_v4 > 1;
258 }
259
260
261 /* Add the host AI under the NAME into the HOSTTABLE.  If PORT is not
262    zero, it specifies which port to use to talk to the host.  If NAME
263    specifies a pool (as indicated by IS_POOL), update the given
264    reference table accordingly.  */
265 static void
266 add_host (const char *name, int is_pool,
267           const dns_addrinfo_t ai, unsigned short port,
268           int *reftbl, size_t reftblsize, int *refidx)
269 {
270   gpg_error_t tmperr;
271   char *tmphost;
272   int idx, tmpidx;
273   int is_numeric = 0;
274   int i;
275
276   idx = find_hostinfo (name);
277
278   if (!is_pool && !is_ip_address (name))
279     {
280       /* This is a hostname but not a pool.  Use the name
281          as given without going through resolve_dns_addr.  */
282       tmphost = xtrystrdup (name);
283       if (!tmphost)
284         tmperr = gpg_error_from_syserror ();
285       else
286         tmperr = 0;
287     }
288   else
289     {
290       tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
291                                  DNS_WITHBRACKET, &tmphost);
292       if (tmphost && is_ip_address (tmphost))
293         is_numeric = 1;
294     }
295
296   if (tmperr)
297     {
298       log_info ("resolve_dns_addr failed while checking '%s': %s\n",
299                 name, gpg_strerror (tmperr));
300     }
301   else if ((*refidx) + 1 >= reftblsize)
302     {
303       log_error ("resolve_dns_addr for '%s': '%s'"
304                  " [index table full - ignored]\n", name, tmphost);
305     }
306   else
307     {
308       if (!is_pool && is_ip_address (name))
309         /* Update the original entry.  */
310         tmpidx = idx;
311       else
312         tmpidx = find_hostinfo (tmphost);
313       log_info ("resolve_dns_addr for '%s': '%s'%s\n",
314                 name, tmphost,
315                 tmpidx == -1? "" : " [already known]");
316
317       if (tmpidx == -1) /* Create a new entry.  */
318         tmpidx = create_new_hostinfo (tmphost);
319
320       if (tmpidx == -1)
321         {
322           log_error ("map_host for '%s' problem: %s - '%s'"
323                      " [ignored]\n",
324                      name, strerror (errno), tmphost);
325         }
326       else  /* Set or update the entry. */
327         {
328           char *ipaddr = NULL;
329
330           if (port)
331             hosttable[tmpidx]->port = port;
332
333           if (!is_numeric)
334             {
335               xfree (tmphost);
336               tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
337                                          (DNS_NUMERICHOST
338                                           | DNS_WITHBRACKET),
339                                          &tmphost);
340               if (tmperr)
341                 log_info ("resolve_dns_addr failed: %s\n",
342                           gpg_strerror (tmperr));
343               else
344                 {
345                   ipaddr = tmphost;
346                   tmphost = NULL;
347                 }
348             }
349
350           if (ai->family == AF_INET6)
351             {
352               hosttable[tmpidx]->v6 = 1;
353               xfree (hosttable[tmpidx]->v6addr);
354               hosttable[tmpidx]->v6addr = ipaddr;
355             }
356           else if (ai->family == AF_INET)
357             {
358               hosttable[tmpidx]->v4 = 1;
359               xfree (hosttable[tmpidx]->v4addr);
360               hosttable[tmpidx]->v4addr = ipaddr;
361             }
362           else
363             BUG ();
364
365           for (i=0; i < *refidx; i++)
366             if (reftbl[i] == tmpidx)
367               break;
368           if (!(i < *refidx) && tmpidx != idx)
369             reftbl[(*refidx)++] = tmpidx;
370         }
371     }
372   xfree (tmphost);
373 }
374
375
376 /* Map the host name NAME to the actual to be used host name.  This
377    allows us to manage round robin DNS names.  We use our own strategy
378    to choose one of the hosts.  For example we skip those hosts which
379    failed for some time and we stick to one host for a time
380    independent of DNS retry times.  If FORCE_RESELECT is true a new
381    host is always selected.  The selected host is stored as a malloced
382    string at R_HOST; on error NULL is stored.  If we know the port
383    used by the selected host, a string representation is written to
384    R_PORTSTR, otherwise it is left untouched.  If R_HTTPFLAGS is not
385    NULL it will receive flags which are to be passed to http_open.  If
386    R_POOLNAME is not NULL a malloced name of the pool is stored or
387    NULL if it is not a pool. */
388 static gpg_error_t
389 map_host (ctrl_t ctrl, const char *name, int force_reselect,
390           char **r_host, char *r_portstr,
391           unsigned int *r_httpflags, char **r_poolname)
392 {
393   gpg_error_t err = 0;
394   hostinfo_t hi;
395   int idx;
396
397   *r_host = NULL;
398   if (r_httpflags)
399     *r_httpflags = 0;
400   if (r_poolname)
401     *r_poolname = NULL;
402
403   /* No hostname means localhost.  */
404   if (!name || !*name)
405     {
406       *r_host = xtrystrdup ("localhost");
407       return *r_host? 0 : gpg_error_from_syserror ();
408     }
409
410   /* See whether the host is in our table.  */
411   idx = find_hostinfo (name);
412   if (idx == -1 && is_onion_address (name))
413     {
414       idx = create_new_hostinfo (name);
415       if (idx == -1)
416         return gpg_error_from_syserror ();
417       hi = hosttable[idx];
418       hi->onion = 1;
419     }
420   else if (idx == -1)
421     {
422       /* We never saw this host.  Allocate a new entry.  */
423       dns_addrinfo_t aibuf, ai;
424       int *reftbl;
425       size_t reftblsize;
426       int refidx;
427       int is_pool = 0;
428       char *cname;
429 #ifdef  USE_DNS_SRV
430       char *srvrecord;
431       struct srventry *srvs;
432       int srvscount;
433 #endif  /* USE_DNS_SRV */
434
435       reftblsize = 100;
436       reftbl = xtrymalloc (reftblsize * sizeof *reftbl);
437       if (!reftbl)
438         return gpg_error_from_syserror ();
439       refidx = 0;
440
441       idx = create_new_hostinfo (name);
442       if (idx == -1)
443         {
444           err = gpg_error_from_syserror ();
445           xfree (reftbl);
446           return err;
447         }
448       hi = hosttable[idx];
449
450 #ifdef  USE_DNS_SRV
451       /* Check for SRV records.  */
452       srvrecord = xtryasprintf ("_hkp._tcp.%s", name);
453       if (srvrecord == NULL)
454         {
455           err = gpg_error_from_syserror ();
456           xfree (reftbl);
457           return err;
458         }
459
460       srvscount = getsrv (srvrecord, &srvs);
461       xfree (srvrecord);
462       if (srvscount < 0)
463         {
464           err = gpg_error_from_syserror ();
465           xfree (reftbl);
466           return err;
467         }
468
469       if (srvscount > 0)
470         {
471           int i;
472           is_pool = srvscount > 1;
473
474           for (i = 0; i < srvscount; i++)
475             {
476               err = resolve_dns_name (srvs[i].target, 0,
477                                       AF_UNSPEC, SOCK_STREAM,
478                                       &ai, &cname);
479               if (err)
480                 continue;
481               dirmngr_tick (ctrl);
482               add_host (name, is_pool, ai, srvs[i].port,
483                         reftbl, reftblsize, &refidx);
484             }
485
486           xfree (srvs);
487         }
488 #endif  /* USE_DNS_SRV */
489
490       /* Find all A records for this entry and put them into the pool
491          list - if any.  */
492       err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
493       if (err)
494         {
495           log_error ("resolving '%s' failed: %s\n", name, gpg_strerror (err));
496           err = 0;
497         }
498       else
499         {
500           /* First figure out whether this is a pool.  For a pool we
501              use a different strategy than for a plain server: We use
502              the canonical name of the pool as the virtual host along
503              with the IP addresses.  If it is not a pool, we use the
504              specified name. */
505           if (! is_pool)
506             is_pool = arecords_is_pool (aibuf);
507           if (is_pool && cname)
508             {
509               hi->cname = cname;
510               cname = NULL;
511             }
512
513           for (ai = aibuf; ai; ai = ai->next)
514             {
515               if (ai->family != AF_INET && ai->family != AF_INET6)
516                 continue;
517               dirmngr_tick (ctrl);
518
519               add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
520             }
521         }
522       reftbl[refidx] = -1;
523       xfree (cname);
524       free_dns_addrinfo (aibuf);
525
526       if (refidx && is_pool)
527         {
528           assert (!hi->pool);
529           hi->pool = xtryrealloc (reftbl, (refidx+1) * sizeof *reftbl);
530           if (!hi->pool)
531             {
532               err = gpg_error_from_syserror ();
533               log_error ("shrinking index table in map_host failed: %s\n",
534                          gpg_strerror (err));
535               xfree (reftbl);
536               return err;
537             }
538           qsort (hi->pool, refidx, sizeof *reftbl, sort_hostpool);
539         }
540       else
541         xfree (reftbl);
542     }
543
544   hi = hosttable[idx];
545   if (hi->pool)
546     {
547       /* Deal with the pool name before selecting a host. */
548       if (r_poolname)
549         {
550           *r_poolname = xtrystrdup (hi->cname? hi->cname : hi->name);
551           if (!*r_poolname)
552             return gpg_error_from_syserror ();
553         }
554
555       /* If the currently selected host is now marked dead, force a
556          re-selection .  */
557       if (force_reselect)
558         hi->poolidx = -1;
559       else if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
560                && hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
561         hi->poolidx = -1;
562
563       /* Select a host if needed.  */
564       if (hi->poolidx == -1)
565         {
566           hi->poolidx = select_random_host (hi->pool);
567           if (hi->poolidx == -1)
568             {
569               log_error ("no alive host found in pool '%s'\n", name);
570               if (r_poolname)
571                 {
572                   xfree (*r_poolname);
573                   *r_poolname = NULL;
574                 }
575               return gpg_error (GPG_ERR_NO_KEYSERVER);
576             }
577         }
578
579       assert (hi->poolidx >= 0 && hi->poolidx < hosttable_size);
580       hi = hosttable[hi->poolidx];
581       assert (hi);
582     }
583
584   if (hi->dead)
585     {
586       log_error ("host '%s' marked as dead\n", hi->name);
587       if (r_poolname)
588         {
589           xfree (*r_poolname);
590           *r_poolname = NULL;
591         }
592       return gpg_error (GPG_ERR_NO_KEYSERVER);
593     }
594
595   if (r_httpflags)
596     {
597       /* If the hosttable does not indicate that a certain host
598          supports IPv<N>, we explicit set the corresponding http
599          flags.  The reason for this is that a host might be listed in
600          a pool as not v6 only but actually support v6 when later
601          the name is resolved by our http layer.  */
602       if (!hi->v4)
603         *r_httpflags |= HTTP_FLAG_IGNORE_IPv4;
604       if (!hi->v6)
605         *r_httpflags |= HTTP_FLAG_IGNORE_IPv6;
606
607       /* Note that we do not set the HTTP_FLAG_FORCE_TOR for onion
608          addresses because the http module detects this itself.  This
609          also allows us to use an onion address without Tor mode being
610          enabled.  */
611     }
612
613   *r_host = xtrystrdup (hi->name);
614   if (!*r_host)
615     {
616       err = gpg_error_from_syserror ();
617       if (r_poolname)
618         {
619           xfree (*r_poolname);
620           *r_poolname = NULL;
621         }
622       return err;
623     }
624   if (hi->port)
625     snprintf (r_portstr, 6 /* five digits and the sentinel */,
626               "%hu", hi->port);
627   return 0;
628 }
629
630
631 /* Mark the host NAME as dead.  NAME may be given as an URL.  Returns
632    true if a host was really marked as dead or was already marked dead
633    (e.g. by a concurrent session).  */
634 static int
635 mark_host_dead (const char *name)
636 {
637   const char *host;
638   char *host_buffer = NULL;
639   parsed_uri_t parsed_uri = NULL;
640   int done = 0;
641
642   if (name && *name && !http_parse_uri (&parsed_uri, name, 1))
643     {
644       if (parsed_uri->v6lit)
645         {
646           host_buffer = strconcat ("[", parsed_uri->host, "]", NULL);
647           if (!host_buffer)
648             log_error ("out of core in mark_host_dead");
649           host = host_buffer;
650         }
651       else
652         host = parsed_uri->host;
653     }
654   else
655     host = name;
656
657   if (host && *host && strcmp (host, "localhost"))
658     {
659       hostinfo_t hi;
660       int idx;
661
662       idx = find_hostinfo (host);
663       if (idx != -1)
664         {
665           hi = hosttable[idx];
666           log_info ("marking host '%s' as dead%s\n",
667                     hi->name, hi->dead? " (again)":"");
668           hi->dead = 1;
669           hi->died_at = gnupg_get_time ();
670           if (!hi->died_at)
671             hi->died_at = 1;
672           done = 1;
673         }
674     }
675
676   http_release_parsed_uri (parsed_uri);
677   xfree (host_buffer);
678   return done;
679 }
680
681
682 /* Mark a host in the hosttable as dead or - if ALIVE is true - as
683    alive.  */
684 gpg_error_t
685 ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
686 {
687   gpg_error_t err = 0;
688   hostinfo_t hi, hi2;
689   int idx, idx2, idx3, n;
690
691   if (!name || !*name || !strcmp (name, "localhost"))
692     return 0;
693
694   idx = find_hostinfo (name);
695   if (idx == -1)
696     return gpg_error (GPG_ERR_NOT_FOUND);
697
698   hi = hosttable[idx];
699   if (alive && hi->dead)
700     {
701       hi->dead = 0;
702       err = ks_printf_help (ctrl, "marking '%s' as alive", name);
703     }
704   else if (!alive && !hi->dead)
705     {
706       hi->dead = 1;
707       hi->died_at = 0; /* Manually set dead.  */
708       err = ks_printf_help (ctrl, "marking '%s' as dead", name);
709     }
710
711   /* If the host is a pool mark all member hosts. */
712   if (!err && hi->pool)
713     {
714       for (idx2=0; !err && (n=hi->pool[idx2]) != -1; idx2++)
715         {
716           assert (n >= 0 && n < hosttable_size);
717
718           if (!alive)
719             {
720               /* Do not mark a host from a pool dead if it is also a
721                  member in another pool.  */
722               for (idx3=0; idx3 < hosttable_size; idx3++)
723                 {
724                   if (hosttable[idx3]
725                       && hosttable[idx3]->pool
726                       && idx3 != idx
727                       && host_in_pool_p (hosttable[idx3]->pool, n))
728                     break;
729                 }
730               if (idx3 < hosttable_size)
731                 continue;  /* Host is also a member of another pool.  */
732             }
733
734           hi2 = hosttable[n];
735           if (!hi2)
736             ;
737           else if (alive && hi2->dead)
738             {
739               hi2->dead = 0;
740               err = ks_printf_help (ctrl, "marking '%s' as alive",
741                                     hi2->name);
742             }
743           else if (!alive && !hi2->dead)
744             {
745               hi2->dead = 1;
746               hi2->died_at = 0; /* Manually set dead. */
747               err = ks_printf_help (ctrl, "marking '%s' as dead",
748                                     hi2->name);
749             }
750         }
751     }
752
753   return err;
754 }
755
756
757 /* Debug function to print the entire hosttable.  */
758 gpg_error_t
759 ks_hkp_print_hosttable (ctrl_t ctrl)
760 {
761   gpg_error_t err;
762   int idx, idx2;
763   hostinfo_t hi;
764   membuf_t mb;
765   time_t curtime;
766   char *p, *died;
767   const char *diedstr;
768
769   err = ks_print_help (ctrl, "hosttable (idx, ipv6, ipv4, dead, name, time):");
770   if (err)
771     return err;
772
773   curtime = gnupg_get_time ();
774   for (idx=0; idx < hosttable_size; idx++)
775     if ((hi=hosttable[idx]))
776       {
777         if (hi->dead && hi->died_at)
778           {
779             died = elapsed_time_string (hi->died_at, curtime);
780             diedstr = died? died : "error";
781           }
782         else
783           diedstr = died = NULL;
784         err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s%s\n",
785                               idx,
786                               hi->onion? "O" : hi->v6? "6":" ",
787                               hi->v4? "4":" ",
788                               hi->dead? "d":" ",
789                               hi->name,
790                               hi->v6addr? " v6=":"",
791                               hi->v6addr? hi->v6addr:"",
792                               hi->v4addr? " v4=":"",
793                               hi->v4addr? hi->v4addr:"",
794                               diedstr? "  (":"",
795                               diedstr? diedstr:"",
796                               diedstr? ")":""   );
797         xfree (died);
798         if (err)
799           return err;
800
801         if (hi->cname)
802           err = ks_printf_help (ctrl, "  .       %s", hi->cname);
803         if (err)
804           return err;
805
806         if (hi->pool)
807           {
808             init_membuf (&mb, 256);
809             put_membuf_printf (&mb, "  .   -->");
810             for (idx2=0; hi->pool[idx2] != -1; idx2++)
811               {
812                 put_membuf_printf (&mb, " %d", hi->pool[idx2]);
813                 if (hi->poolidx == hi->pool[idx2])
814                   put_membuf_printf (&mb, "*");
815               }
816             put_membuf( &mb, "", 1);
817             p = get_membuf (&mb, NULL);
818             if (!p)
819               return gpg_error_from_syserror ();
820             err = ks_print_help (ctrl, p);
821             xfree (p);
822             if (err)
823               return err;
824           }
825       }
826   return 0;
827 }
828
829
830
831 /* Print a help output for the schemata supported by this module. */
832 gpg_error_t
833 ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
834 {
835   const char const data[] =
836     "Handler for HKP URLs:\n"
837     "  hkp://\n"
838 #if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
839     "  hkps://\n"
840 #endif
841     "Supported methods: search, get, put\n";
842   gpg_error_t err;
843
844 #if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
845   const char data2[] = "  hkp\n  hkps";
846 #else
847   const char data2[] = "  hkp";
848 #endif
849
850   if (!uri)
851     err = ks_print_help (ctrl, data2);
852   else if (uri->is_http && (!strcmp (uri->scheme, "hkp")
853                             || !strcmp (uri->scheme, "hkps")))
854     err = ks_print_help (ctrl, data);
855   else
856     err = 0;
857
858   return err;
859 }
860
861
862 /* Build the remote part of the URL from SCHEME, HOST and an optional
863    PORT.  Returns an allocated string at R_HOSTPORT or NULL on failure
864    If R_POOLNAME is not NULL it receives a malloced string with the
865    poolname.  */
866 static gpg_error_t
867 make_host_part (ctrl_t ctrl,
868                 const char *scheme, const char *host, unsigned short port,
869                 int force_reselect,
870                 char **r_hostport, unsigned int *r_httpflags, char **r_poolname)
871 {
872   gpg_error_t err;
873   char portstr[10];
874   char *hostname;
875
876   *r_hostport = NULL;
877
878   portstr[0] = 0;
879   err = map_host (ctrl, host, force_reselect,
880                   &hostname, portstr, r_httpflags, r_poolname);
881   if (err)
882     return err;
883
884   /* Map scheme and port.  */
885   if (!strcmp (scheme, "hkps") || !strcmp (scheme,"https"))
886     {
887       scheme = "https";
888       if (! *portstr)
889         strcpy (portstr, "443");
890     }
891   else /* HKP or HTTP.  */
892     {
893       scheme = "http";
894       if (! *portstr)
895         strcpy (portstr, "11371");
896     }
897   if (port)
898     snprintf (portstr, sizeof portstr, "%hu", port);
899   else
900     {
901       /*fixme_do_srv_lookup ()*/
902     }
903
904   *r_hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL);
905   xfree (hostname);
906   if (!*r_hostport)
907     {
908       if (r_poolname)
909         {
910           xfree (*r_poolname);
911           *r_poolname = NULL;
912         }
913       return gpg_error_from_syserror ();
914     }
915   return 0;
916 }
917
918
919 /* Resolve all known keyserver names and update the hosttable.  This
920    is mainly useful for debugging because the resolving is anyway done
921    on demand.  */
922 gpg_error_t
923 ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
924 {
925   gpg_error_t err;
926   char *hostport = NULL;
927
928   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1,
929                         &hostport, NULL, NULL);
930   if (err)
931     {
932       err = ks_printf_help (ctrl, "%s://%s:%hu: resolve failed: %s",
933                             uri->scheme, uri->host, uri->port,
934                             gpg_strerror (err));
935     }
936   else
937     {
938       err = ks_printf_help (ctrl, "%s", hostport);
939       xfree (hostport);
940     }
941   return err;
942 }
943
944
945 /* Housekeeping function called from the housekeeping thread.  It is
946    used to mark dead hosts alive so that they may be tried again after
947    some time.  */
948 void
949 ks_hkp_housekeeping (time_t curtime)
950 {
951   int idx;
952   hostinfo_t hi;
953
954   for (idx=0; idx < hosttable_size; idx++)
955     {
956       hi = hosttable[idx];
957       if (!hi)
958         continue;
959       if (!hi->dead)
960         continue;
961       if (!hi->died_at)
962         continue; /* Do not resurrect manually shot hosts.  */
963       if (hi->died_at + RESURRECT_INTERVAL <= curtime
964           || hi->died_at > curtime)
965         {
966           hi->dead = 0;
967           log_info ("resurrected host '%s'", hi->name);
968         }
969     }
970 }
971
972
973 /* Send an HTTP request.  On success returns an estream object at
974    R_FP.  HOSTPORTSTR is only used for diagnostics.  If HTTPHOST is
975    not NULL it will be used as HTTP "Host" header.  If POST_CB is not
976    NULL a post request is used and that callback is called to allow
977    writing the post data.  If R_HTTP_STATUS is not NULL, the http
978    status code will be stored there.  */
979 static gpg_error_t
980 send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
981               const char *httphost, unsigned int httpflags,
982               gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value,
983               estream_t *r_fp, unsigned int *r_http_status)
984 {
985   gpg_error_t err;
986   http_session_t session = NULL;
987   http_t http = NULL;
988   int redirects_left = MAX_REDIRECTS;
989   estream_t fp = NULL;
990   char *request_buffer = NULL;
991
992   *r_fp = NULL;
993
994   err = http_session_new (&session, NULL, httphost);
995   if (err)
996     goto leave;
997   http_session_set_log_cb (session, cert_log_cb);
998
999  once_more:
1000   err = http_open (&http,
1001                    post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
1002                    request,
1003                    httphost,
1004                    /* fixme: AUTH */ NULL,
1005                    (httpflags
1006                     |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
1007                     |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
1008                    ctrl->http_proxy,
1009                    session,
1010                    NULL,
1011                    /*FIXME curl->srvtag*/NULL);
1012   if (!err)
1013     {
1014       fp = http_get_write_ptr (http);
1015       /* Avoid caches to get the most recent copy of the key.  We set
1016          both the Pragma and Cache-Control versions of the header, so
1017          we're good with both HTTP 1.0 and 1.1.  */
1018       es_fputs ("Pragma: no-cache\r\n"
1019                 "Cache-Control: no-cache\r\n", fp);
1020       if (post_cb)
1021         err = post_cb (post_cb_value, http);
1022       if (!err)
1023         {
1024           http_start_data (http);
1025           if (es_ferror (fp))
1026             err = gpg_error_from_syserror ();
1027         }
1028     }
1029   if (err)
1030     {
1031       /* Fixme: After a redirection we show the old host name.  */
1032       log_error (_("error connecting to '%s': %s\n"),
1033                  hostportstr, gpg_strerror (err));
1034       goto leave;
1035     }
1036
1037   /* Wait for the response.  */
1038   dirmngr_tick (ctrl);
1039   err = http_wait_response (http);
1040   if (err)
1041     {
1042       log_error (_("error reading HTTP response for '%s': %s\n"),
1043                  hostportstr, gpg_strerror (err));
1044       goto leave;
1045     }
1046
1047   if (http_get_tls_info (http, NULL))
1048     {
1049       /* Update the httpflags so that a redirect won't fallback to an
1050          unencrypted connection.  */
1051       httpflags |= HTTP_FLAG_FORCE_TLS;
1052     }
1053
1054   if (r_http_status)
1055     *r_http_status = http_get_status_code (http);
1056
1057   switch (http_get_status_code (http))
1058     {
1059     case 200:
1060       err = 0;
1061       break; /* Success.  */
1062
1063     case 301:
1064     case 302:
1065     case 307:
1066       {
1067         const char *s = http_get_header (http, "Location");
1068
1069         log_info (_("URL '%s' redirected to '%s' (%u)\n"),
1070                   request, s?s:"[none]", http_get_status_code (http));
1071         if (s && *s && redirects_left-- )
1072           {
1073             xfree (request_buffer);
1074             request_buffer = xtrystrdup (s);
1075             if (request_buffer)
1076               {
1077                 request = request_buffer;
1078                 http_close (http, 0);
1079                 http = NULL;
1080                 goto once_more;
1081               }
1082             err = gpg_error_from_syserror ();
1083           }
1084         else
1085           err = gpg_error (GPG_ERR_NO_DATA);
1086         log_error (_("too many redirections\n"));
1087       }
1088       goto leave;
1089
1090     case 501:
1091       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1092       goto leave;
1093
1094     default:
1095       log_error (_("error accessing '%s': http status %u\n"),
1096                  request, http_get_status_code (http));
1097       err = gpg_error (GPG_ERR_NO_DATA);
1098       goto leave;
1099     }
1100
1101   /* FIXME: We should register a permanent redirection and whether a
1102      host has ever used TLS so that future calls will always use
1103      TLS. */
1104
1105   fp = http_get_read_ptr (http);
1106   if (!fp)
1107     {
1108       err = gpg_error (GPG_ERR_BUG);
1109       goto leave;
1110     }
1111
1112   /* Return the read stream and close the HTTP context.  */
1113   *r_fp = fp;
1114   http_close (http, 1);
1115   http = NULL;
1116
1117  leave:
1118   http_close (http, 0);
1119   http_session_release (session);
1120   xfree (request_buffer);
1121   return err;
1122 }
1123
1124
1125 /* Helper to evaluate the error code ERR form a send_request() call
1126    with REQUEST.  The function returns true if the caller shall try
1127    again.  TRIES_LEFT points to a variable to track the number of
1128    retries; this function decrements it and won't return true if it is
1129    down to zero. */
1130 static int
1131 handle_send_request_error (gpg_error_t err, const char *request,
1132                            unsigned int *tries_left)
1133 {
1134   int retry = 0;
1135
1136   switch (gpg_err_code (err))
1137     {
1138     case GPG_ERR_ECONNREFUSED:
1139     case GPG_ERR_ENETUNREACH:
1140     case GPG_ERR_UNKNOWN_HOST:
1141     case GPG_ERR_NETWORK:
1142       if (mark_host_dead (request) && *tries_left)
1143         retry = 1;
1144       break;
1145
1146     case GPG_ERR_ETIMEDOUT:
1147       if (*tries_left)
1148         {
1149           log_info ("selecting a different host due to a timeout\n");
1150           retry = 1;
1151         }
1152
1153     default:
1154       break;
1155     }
1156
1157   if (*tries_left)
1158     --*tries_left;
1159
1160   return retry;
1161 }
1162
1163 \f
1164 /* Search the keyserver identified by URI for keys matching PATTERN.
1165    On success R_FP has an open stream to read the data.  If
1166    R_HTTP_STATUS is not NULL, the http status code will be stored
1167    there.  */
1168 gpg_error_t
1169 ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
1170                estream_t *r_fp, unsigned int *r_http_status)
1171 {
1172   gpg_error_t err;
1173   KEYDB_SEARCH_DESC desc;
1174   char fprbuf[2+40+1];
1175   char *hostport = NULL;
1176   char *request = NULL;
1177   estream_t fp = NULL;
1178   int reselect;
1179   unsigned int httpflags;
1180   char *httphost = NULL;
1181   unsigned int tries = SEND_REQUEST_RETRIES;
1182
1183   *r_fp = NULL;
1184
1185   /* Remove search type indicator and adjust PATTERN accordingly.
1186      Note that HKP keyservers like the 0x to be present when searching
1187      by keyid.  We need to re-format the fingerprint and keyids so to
1188      remove the gpg specific force-use-of-this-key flag ("!").  */
1189   err = classify_user_id (pattern, &desc, 1);
1190   if (err)
1191     return err;
1192   switch (desc.mode)
1193     {
1194     case KEYDB_SEARCH_MODE_EXACT:
1195     case KEYDB_SEARCH_MODE_SUBSTR:
1196     case KEYDB_SEARCH_MODE_MAIL:
1197     case KEYDB_SEARCH_MODE_MAILSUB:
1198       pattern = desc.u.name;
1199       break;
1200     case KEYDB_SEARCH_MODE_SHORT_KID:
1201       snprintf (fprbuf, sizeof fprbuf, "0x%08lX", (ulong)desc.u.kid[1]);
1202       pattern = fprbuf;
1203       break;
1204     case KEYDB_SEARCH_MODE_LONG_KID:
1205       snprintf (fprbuf, sizeof fprbuf, "0x%08lX%08lX",
1206                 (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
1207       pattern = fprbuf;
1208       break;
1209     case KEYDB_SEARCH_MODE_FPR16:
1210       bin2hex (desc.u.fpr, 16, fprbuf);
1211       pattern = fprbuf;
1212       break;
1213     case KEYDB_SEARCH_MODE_FPR20:
1214     case KEYDB_SEARCH_MODE_FPR:
1215       bin2hex (desc.u.fpr, 20, fprbuf);
1216       pattern = fprbuf;
1217       break;
1218     default:
1219       return gpg_error (GPG_ERR_INV_USER_ID);
1220     }
1221
1222   /* Build the request string.  */
1223   reselect = 0;
1224  again:
1225   {
1226     char *searchkey;
1227
1228     xfree (hostport); hostport = NULL;
1229     xfree (httphost); httphost = NULL;
1230     err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect,
1231                           &hostport, &httpflags, &httphost);
1232     if (err)
1233       goto leave;
1234
1235     searchkey = http_escape_string (pattern, EXTRA_ESCAPE_CHARS);
1236     if (!searchkey)
1237       {
1238         err = gpg_error_from_syserror ();
1239         goto leave;
1240       }
1241
1242     xfree (request);
1243     request = strconcat (hostport,
1244                          "/pks/lookup?op=index&options=mr&search=",
1245                          searchkey,
1246                          NULL);
1247     xfree (searchkey);
1248     if (!request)
1249       {
1250         err = gpg_error_from_syserror ();
1251         goto leave;
1252       }
1253   }
1254
1255   /* Send the request.  */
1256   err = send_request (ctrl, request, hostport, httphost, httpflags,
1257                       NULL, NULL, &fp, r_http_status);
1258   if (handle_send_request_error (err, request, &tries))
1259     {
1260       reselect = 1;
1261       goto again;
1262     }
1263   if (err)
1264     goto leave;
1265
1266   err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
1267   if (err)
1268     goto leave;
1269
1270   /* Peek at the response.  */
1271   {
1272     int c = es_getc (fp);
1273     if (c == -1)
1274       {
1275         err = es_ferror (fp)?gpg_error_from_syserror ():gpg_error (GPG_ERR_EOF);
1276         log_error ("error reading response: %s\n", gpg_strerror (err));
1277         goto leave;
1278       }
1279     if (c == '<')
1280       {
1281         /* The document begins with a '<': Assume a HTML response,
1282            which we don't support.  */
1283         err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1284         goto leave;
1285       }
1286     es_ungetc (c, fp);
1287   }
1288
1289   /* Return the read stream.  */
1290   *r_fp = fp;
1291   fp = NULL;
1292
1293  leave:
1294   es_fclose (fp);
1295   xfree (request);
1296   xfree (hostport);
1297   xfree (httphost);
1298   return err;
1299 }
1300
1301
1302 /* Get the key described key the KEYSPEC string from the keyserver
1303    identified by URI.  On success R_FP has an open stream to read the
1304    data.  The data will be provided in a format GnuPG can import
1305    (either a binary OpenPGP message or an armored one).  */
1306 gpg_error_t
1307 ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
1308 {
1309   gpg_error_t err;
1310   KEYDB_SEARCH_DESC desc;
1311   char kidbuf[2+40+1];
1312   const char *exactname = NULL;
1313   char *searchkey = NULL;
1314   char *hostport = NULL;
1315   char *request = NULL;
1316   estream_t fp = NULL;
1317   int reselect;
1318   char *httphost = NULL;
1319   unsigned int httpflags;
1320   unsigned int tries = SEND_REQUEST_RETRIES;
1321
1322   *r_fp = NULL;
1323
1324   /* Remove search type indicator and adjust PATTERN accordingly.
1325      Note that HKP keyservers like the 0x to be present when searching
1326      by keyid.  We need to re-format the fingerprint and keyids so to
1327      remove the gpg specific force-use-of-this-key flag ("!").  */
1328   err = classify_user_id (keyspec, &desc, 1);
1329   if (err)
1330     return err;
1331   switch (desc.mode)
1332     {
1333     case KEYDB_SEARCH_MODE_SHORT_KID:
1334       snprintf (kidbuf, sizeof kidbuf, "0x%08lX", (ulong)desc.u.kid[1]);
1335       break;
1336     case KEYDB_SEARCH_MODE_LONG_KID:
1337       snprintf (kidbuf, sizeof kidbuf, "0x%08lX%08lX",
1338                 (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
1339       break;
1340     case KEYDB_SEARCH_MODE_FPR20:
1341     case KEYDB_SEARCH_MODE_FPR:
1342       /* This is a v4 fingerprint. */
1343       kidbuf[0] = '0';
1344       kidbuf[1] = 'x';
1345       bin2hex (desc.u.fpr, 20, kidbuf+2);
1346       break;
1347
1348     case KEYDB_SEARCH_MODE_EXACT:
1349       exactname = desc.u.name;
1350       break;
1351
1352     case KEYDB_SEARCH_MODE_FPR16:
1353       log_error ("HKP keyservers do not support v3 fingerprints\n");
1354     default:
1355       return gpg_error (GPG_ERR_INV_USER_ID);
1356     }
1357
1358   searchkey = http_escape_string (exactname? exactname : kidbuf,
1359                                   EXTRA_ESCAPE_CHARS);
1360   if (!searchkey)
1361     {
1362       err = gpg_error_from_syserror ();
1363       goto leave;
1364     }
1365
1366   reselect = 0;
1367  again:
1368   /* Build the request string.  */
1369   xfree (hostport); hostport = NULL;
1370   xfree (httphost); httphost = NULL;
1371   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect,
1372                         &hostport, &httpflags, &httphost);
1373   if (err)
1374     goto leave;
1375
1376   xfree (request);
1377   request = strconcat (hostport,
1378                        "/pks/lookup?op=get&options=mr&search=",
1379                        searchkey,
1380                        exactname? "&exact=on":"",
1381                        NULL);
1382   if (!request)
1383     {
1384       err = gpg_error_from_syserror ();
1385       goto leave;
1386     }
1387
1388   /* Send the request.  */
1389   err = send_request (ctrl, request, hostport, httphost, httpflags,
1390                       NULL, NULL, &fp, NULL);
1391   if (handle_send_request_error (err, request, &tries))
1392     {
1393       reselect = 1;
1394       goto again;
1395     }
1396   if (err)
1397     goto leave;
1398
1399   err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
1400   if (err)
1401     goto leave;
1402
1403   /* Return the read stream and close the HTTP context.  */
1404   *r_fp = fp;
1405   fp = NULL;
1406
1407  leave:
1408   es_fclose (fp);
1409   xfree (request);
1410   xfree (hostport);
1411   xfree (httphost);
1412   xfree (searchkey);
1413   return err;
1414 }
1415
1416
1417
1418 \f
1419 /* Callback parameters for put_post_cb.  */
1420 struct put_post_parm_s
1421 {
1422   char *datastring;
1423 };
1424
1425
1426 /* Helper for ks_hkp_put.  */
1427 static gpg_error_t
1428 put_post_cb (void *opaque, http_t http)
1429 {
1430   struct put_post_parm_s *parm = opaque;
1431   gpg_error_t err = 0;
1432   estream_t fp;
1433   size_t len;
1434
1435   fp = http_get_write_ptr (http);
1436   len = strlen (parm->datastring);
1437
1438   es_fprintf (fp,
1439               "Content-Type: application/x-www-form-urlencoded\r\n"
1440               "Content-Length: %zu\r\n", len+8 /* 8 is for "keytext" */);
1441   http_start_data (http);
1442   if (es_fputs ("keytext=", fp) || es_write (fp, parm->datastring, len, NULL))
1443     err = gpg_error_from_syserror ();
1444   return err;
1445 }
1446
1447
1448 /* Send the key in {DATA,DATALEN} to the keyserver identified by URI.  */
1449 gpg_error_t
1450 ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
1451 {
1452   gpg_error_t err;
1453   char *hostport = NULL;
1454   char *request = NULL;
1455   estream_t fp = NULL;
1456   struct put_post_parm_s parm;
1457   char *armored = NULL;
1458   int reselect;
1459   char *httphost = NULL;
1460   unsigned int httpflags;
1461   unsigned int tries = SEND_REQUEST_RETRIES;
1462
1463   parm.datastring = NULL;
1464
1465   err = armor_data (&armored, data, datalen);
1466   if (err)
1467     goto leave;
1468
1469   parm.datastring = http_escape_string (armored, EXTRA_ESCAPE_CHARS);
1470   if (!parm.datastring)
1471     {
1472       err = gpg_error_from_syserror ();
1473       goto leave;
1474     }
1475   xfree (armored);
1476   armored = NULL;
1477
1478   /* Build the request string.  */
1479   reselect = 0;
1480  again:
1481   xfree (hostport); hostport = NULL;
1482   xfree (httphost); httphost = NULL;
1483   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect,
1484                         &hostport, &httpflags, &httphost);
1485   if (err)
1486     goto leave;
1487
1488   xfree (request);
1489   request = strconcat (hostport, "/pks/add", NULL);
1490   if (!request)
1491     {
1492       err = gpg_error_from_syserror ();
1493       goto leave;
1494     }
1495
1496   /* Send the request.  */
1497   err = send_request (ctrl, request, hostport, httphost, 0,
1498                       put_post_cb, &parm, &fp, NULL);
1499   if (handle_send_request_error (err, request, &tries))
1500     {
1501       reselect = 1;
1502       goto again;
1503     }
1504   if (err)
1505     goto leave;
1506
1507  leave:
1508   es_fclose (fp);
1509   xfree (parm.datastring);
1510   xfree (armored);
1511   xfree (request);
1512   xfree (hostport);
1513   xfree (httphost);
1514   return err;
1515 }