dirmngr: After a connection failure log a hint if Tor is not running.
[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 <https://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.  If SRVTAG is NULL no service record
382  * lookup will be done, if it is set that service name is used.  The
383  * selected host is stored as a malloced string at R_HOST; on error
384  * NULL is stored.  If we know the port used by the selected host from
385  * a service record, a string representation is written to R_PORTSTR,
386  * otherwise it is left untouched.  If R_HTTPFLAGS is not NULL it will
387  * receive flags which are to be passed to http_open.  If R_POOLNAME
388  * is not NULL a malloced name of the pool is stored or NULL if it is
389  * not a pool. */
390 static gpg_error_t
391 map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
392           char **r_host, char *r_portstr,
393           unsigned int *r_httpflags, char **r_poolname)
394 {
395   gpg_error_t err = 0;
396   hostinfo_t hi;
397   int idx;
398
399   *r_host = NULL;
400   if (r_httpflags)
401     *r_httpflags = 0;
402   if (r_poolname)
403     *r_poolname = NULL;
404
405   /* No hostname means localhost.  */
406   if (!name || !*name)
407     {
408       *r_host = xtrystrdup ("localhost");
409       return *r_host? 0 : gpg_error_from_syserror ();
410     }
411
412   /* See whether the host is in our table.  */
413   idx = find_hostinfo (name);
414   if (idx == -1 && is_onion_address (name))
415     {
416       idx = create_new_hostinfo (name);
417       if (idx == -1)
418         return gpg_error_from_syserror ();
419       hi = hosttable[idx];
420       hi->onion = 1;
421     }
422   else if (idx == -1)
423     {
424       /* We never saw this host.  Allocate a new entry.  */
425       dns_addrinfo_t aibuf, ai;
426       int *reftbl;
427       size_t reftblsize;
428       int refidx;
429       int is_pool = 0;
430       char *cname;
431       struct srventry *srvs;
432       unsigned int srvscount;
433
434       reftblsize = 100;
435       reftbl = xtrymalloc (reftblsize * sizeof *reftbl);
436       if (!reftbl)
437         return gpg_error_from_syserror ();
438       refidx = 0;
439
440       idx = create_new_hostinfo (name);
441       if (idx == -1)
442         {
443           err = gpg_error_from_syserror ();
444           xfree (reftbl);
445           return err;
446         }
447       hi = hosttable[idx];
448
449       if (srvtag && !is_ip_address (name))
450         {
451           /* Check for SRV records.  */
452           err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount);
453           if (err)
454             {
455               xfree (reftbl);
456               return err;
457             }
458
459           if (srvscount > 0)
460             {
461               int i;
462               is_pool = srvscount > 1;
463
464               for (i = 0; i < srvscount; i++)
465                 {
466                   err = resolve_dns_name (srvs[i].target, 0,
467                                           AF_UNSPEC, SOCK_STREAM,
468                                           &ai, &cname);
469                   if (err)
470                     continue;
471                   dirmngr_tick (ctrl);
472                   add_host (name, is_pool, ai, srvs[i].port,
473                             reftbl, reftblsize, &refidx);
474                 }
475
476               xfree (srvs);
477             }
478         }
479
480       /* Find all A records for this entry and put them into the pool
481          list - if any.  */
482       err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
483       if (err)
484         {
485           log_error ("resolving '%s' failed: %s\n", name, gpg_strerror (err));
486           err = 0;
487         }
488       else
489         {
490           /* First figure out whether this is a pool.  For a pool we
491              use a different strategy than for a plain server: We use
492              the canonical name of the pool as the virtual host along
493              with the IP addresses.  If it is not a pool, we use the
494              specified name. */
495           if (! is_pool)
496             is_pool = arecords_is_pool (aibuf);
497           if (is_pool && cname)
498             {
499               hi->cname = cname;
500               cname = NULL;
501             }
502
503           for (ai = aibuf; ai; ai = ai->next)
504             {
505               if (ai->family != AF_INET && ai->family != AF_INET6)
506                 continue;
507               dirmngr_tick (ctrl);
508
509               add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
510             }
511         }
512       reftbl[refidx] = -1;
513       xfree (cname);
514       free_dns_addrinfo (aibuf);
515
516       if (refidx && is_pool)
517         {
518           assert (!hi->pool);
519           hi->pool = xtryrealloc (reftbl, (refidx+1) * sizeof *reftbl);
520           if (!hi->pool)
521             {
522               err = gpg_error_from_syserror ();
523               log_error ("shrinking index table in map_host failed: %s\n",
524                          gpg_strerror (err));
525               xfree (reftbl);
526               return err;
527             }
528           qsort (hi->pool, refidx, sizeof *reftbl, sort_hostpool);
529         }
530       else
531         xfree (reftbl);
532     }
533
534   hi = hosttable[idx];
535   if (hi->pool)
536     {
537       /* Deal with the pool name before selecting a host. */
538       if (r_poolname)
539         {
540           *r_poolname = xtrystrdup (hi->cname? hi->cname : hi->name);
541           if (!*r_poolname)
542             return gpg_error_from_syserror ();
543         }
544
545       /* If the currently selected host is now marked dead, force a
546          re-selection .  */
547       if (force_reselect)
548         hi->poolidx = -1;
549       else if (hi->poolidx >= 0 && hi->poolidx < hosttable_size
550                && hosttable[hi->poolidx] && hosttable[hi->poolidx]->dead)
551         hi->poolidx = -1;
552
553       /* Select a host if needed.  */
554       if (hi->poolidx == -1)
555         {
556           hi->poolidx = select_random_host (hi->pool);
557           if (hi->poolidx == -1)
558             {
559               log_error ("no alive host found in pool '%s'\n", name);
560               if (r_poolname)
561                 {
562                   xfree (*r_poolname);
563                   *r_poolname = NULL;
564                 }
565               return gpg_error (GPG_ERR_NO_KEYSERVER);
566             }
567         }
568
569       assert (hi->poolidx >= 0 && hi->poolidx < hosttable_size);
570       hi = hosttable[hi->poolidx];
571       assert (hi);
572     }
573
574   if (hi->dead)
575     {
576       log_error ("host '%s' marked as dead\n", hi->name);
577       if (r_poolname)
578         {
579           xfree (*r_poolname);
580           *r_poolname = NULL;
581         }
582       return gpg_error (GPG_ERR_NO_KEYSERVER);
583     }
584
585   if (r_httpflags)
586     {
587       /* If the hosttable does not indicate that a certain host
588          supports IPv<N>, we explicit set the corresponding http
589          flags.  The reason for this is that a host might be listed in
590          a pool as not v6 only but actually support v6 when later
591          the name is resolved by our http layer.  */
592       if (!hi->v4)
593         *r_httpflags |= HTTP_FLAG_IGNORE_IPv4;
594       if (!hi->v6)
595         *r_httpflags |= HTTP_FLAG_IGNORE_IPv6;
596
597       /* Note that we do not set the HTTP_FLAG_FORCE_TOR for onion
598          addresses because the http module detects this itself.  This
599          also allows us to use an onion address without Tor mode being
600          enabled.  */
601     }
602
603   *r_host = xtrystrdup (hi->name);
604   if (!*r_host)
605     {
606       err = gpg_error_from_syserror ();
607       if (r_poolname)
608         {
609           xfree (*r_poolname);
610           *r_poolname = NULL;
611         }
612       return err;
613     }
614   if (hi->port)
615     snprintf (r_portstr, 6 /* five digits and the sentinel */,
616               "%hu", hi->port);
617   return 0;
618 }
619
620
621 /* Mark the host NAME as dead.  NAME may be given as an URL.  Returns
622    true if a host was really marked as dead or was already marked dead
623    (e.g. by a concurrent session).  */
624 static int
625 mark_host_dead (const char *name)
626 {
627   const char *host;
628   char *host_buffer = NULL;
629   parsed_uri_t parsed_uri = NULL;
630   int done = 0;
631
632   if (name && *name && !http_parse_uri (&parsed_uri, name, 1))
633     {
634       if (parsed_uri->v6lit)
635         {
636           host_buffer = strconcat ("[", parsed_uri->host, "]", NULL);
637           if (!host_buffer)
638             log_error ("out of core in mark_host_dead");
639           host = host_buffer;
640         }
641       else
642         host = parsed_uri->host;
643     }
644   else
645     host = name;
646
647   if (host && *host && strcmp (host, "localhost"))
648     {
649       hostinfo_t hi;
650       int idx;
651
652       idx = find_hostinfo (host);
653       if (idx != -1)
654         {
655           hi = hosttable[idx];
656           log_info ("marking host '%s' as dead%s\n",
657                     hi->name, hi->dead? " (again)":"");
658           hi->dead = 1;
659           hi->died_at = gnupg_get_time ();
660           if (!hi->died_at)
661             hi->died_at = 1;
662           done = 1;
663         }
664     }
665
666   http_release_parsed_uri (parsed_uri);
667   xfree (host_buffer);
668   return done;
669 }
670
671
672 /* Mark a host in the hosttable as dead or - if ALIVE is true - as
673    alive.  */
674 gpg_error_t
675 ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
676 {
677   gpg_error_t err = 0;
678   hostinfo_t hi, hi2;
679   int idx, idx2, idx3, n;
680
681   if (!name || !*name || !strcmp (name, "localhost"))
682     return 0;
683
684   idx = find_hostinfo (name);
685   if (idx == -1)
686     return gpg_error (GPG_ERR_NOT_FOUND);
687
688   hi = hosttable[idx];
689   if (alive && hi->dead)
690     {
691       hi->dead = 0;
692       err = ks_printf_help (ctrl, "marking '%s' as alive", name);
693     }
694   else if (!alive && !hi->dead)
695     {
696       hi->dead = 1;
697       hi->died_at = 0; /* Manually set dead.  */
698       err = ks_printf_help (ctrl, "marking '%s' as dead", name);
699     }
700
701   /* If the host is a pool mark all member hosts. */
702   if (!err && hi->pool)
703     {
704       for (idx2=0; !err && (n=hi->pool[idx2]) != -1; idx2++)
705         {
706           assert (n >= 0 && n < hosttable_size);
707
708           if (!alive)
709             {
710               /* Do not mark a host from a pool dead if it is also a
711                  member in another pool.  */
712               for (idx3=0; idx3 < hosttable_size; idx3++)
713                 {
714                   if (hosttable[idx3]
715                       && hosttable[idx3]->pool
716                       && idx3 != idx
717                       && host_in_pool_p (hosttable[idx3]->pool, n))
718                     break;
719                 }
720               if (idx3 < hosttable_size)
721                 continue;  /* Host is also a member of another pool.  */
722             }
723
724           hi2 = hosttable[n];
725           if (!hi2)
726             ;
727           else if (alive && hi2->dead)
728             {
729               hi2->dead = 0;
730               err = ks_printf_help (ctrl, "marking '%s' as alive",
731                                     hi2->name);
732             }
733           else if (!alive && !hi2->dead)
734             {
735               hi2->dead = 1;
736               hi2->died_at = 0; /* Manually set dead. */
737               err = ks_printf_help (ctrl, "marking '%s' as dead",
738                                     hi2->name);
739             }
740         }
741     }
742
743   return err;
744 }
745
746
747 /* Debug function to print the entire hosttable.  */
748 gpg_error_t
749 ks_hkp_print_hosttable (ctrl_t ctrl)
750 {
751   gpg_error_t err;
752   int idx, idx2;
753   hostinfo_t hi;
754   membuf_t mb;
755   time_t curtime;
756   char *p, *died;
757   const char *diedstr;
758
759   err = ks_print_help (ctrl, "hosttable (idx, ipv6, ipv4, dead, name, time):");
760   if (err)
761     return err;
762
763   curtime = gnupg_get_time ();
764   for (idx=0; idx < hosttable_size; idx++)
765     if ((hi=hosttable[idx]))
766       {
767         if (hi->dead && hi->died_at)
768           {
769             died = elapsed_time_string (hi->died_at, curtime);
770             diedstr = died? died : "error";
771           }
772         else
773           diedstr = died = NULL;
774         err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s%s\n",
775                               idx,
776                               hi->onion? "O" : hi->v6? "6":" ",
777                               hi->v4? "4":" ",
778                               hi->dead? "d":" ",
779                               hi->name,
780                               hi->v6addr? " v6=":"",
781                               hi->v6addr? hi->v6addr:"",
782                               hi->v4addr? " v4=":"",
783                               hi->v4addr? hi->v4addr:"",
784                               diedstr? "  (":"",
785                               diedstr? diedstr:"",
786                               diedstr? ")":""   );
787         xfree (died);
788         if (err)
789           return err;
790
791         if (hi->cname)
792           err = ks_printf_help (ctrl, "  .       %s", hi->cname);
793         if (err)
794           return err;
795
796         if (hi->pool)
797           {
798             init_membuf (&mb, 256);
799             put_membuf_printf (&mb, "  .   -->");
800             for (idx2=0; hi->pool[idx2] != -1; idx2++)
801               {
802                 put_membuf_printf (&mb, " %d", hi->pool[idx2]);
803                 if (hi->poolidx == hi->pool[idx2])
804                   put_membuf_printf (&mb, "*");
805               }
806             put_membuf( &mb, "", 1);
807             p = get_membuf (&mb, NULL);
808             if (!p)
809               return gpg_error_from_syserror ();
810             err = ks_print_help (ctrl, p);
811             xfree (p);
812             if (err)
813               return err;
814           }
815       }
816   return 0;
817 }
818
819
820
821 /* Print a help output for the schemata supported by this module. */
822 gpg_error_t
823 ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
824 {
825   const char const data[] =
826     "Handler for HKP URLs:\n"
827     "  hkp://\n"
828 #if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
829     "  hkps://\n"
830 #endif
831     "Supported methods: search, get, put\n";
832   gpg_error_t err;
833
834 #if  HTTP_USE_GNUTLS || HTTP_USE_NTBTLS
835   const char data2[] = "  hkp\n  hkps";
836 #else
837   const char data2[] = "  hkp";
838 #endif
839
840   if (!uri)
841     err = ks_print_help (ctrl, data2);
842   else if (uri->is_http && (!strcmp (uri->scheme, "hkp")
843                             || !strcmp (uri->scheme, "hkps")))
844     err = ks_print_help (ctrl, data);
845   else
846     err = 0;
847
848   return err;
849 }
850
851
852 /* Build the remote part of the URL from SCHEME, HOST and an optional
853  * PORT.  If NO_SRV is set no SRV record lookup will be done.  Returns
854  * an allocated string at R_HOSTPORT or NULL on failure If R_POOLNAME
855  * is not NULL it receives a malloced string with the poolname.  */
856 static gpg_error_t
857 make_host_part (ctrl_t ctrl,
858                 const char *scheme, const char *host, unsigned short port,
859                 int force_reselect, int no_srv,
860                 char **r_hostport, unsigned int *r_httpflags, char **r_poolname)
861 {
862   gpg_error_t err;
863   const char *srvtag;
864   char portstr[10];
865   char *hostname;
866
867   *r_hostport = NULL;
868
869   if (!strcmp (scheme, "hkps") || !strcmp (scheme,"https"))
870     {
871       scheme = "https";
872       srvtag = no_srv? NULL : "pgpkey-https";
873     }
874   else /* HKP or HTTP.  */
875     {
876       scheme = "http";
877       srvtag = no_srv? NULL : "pgpkey-http";
878     }
879
880   portstr[0] = 0;
881   err = map_host (ctrl, host, srvtag, force_reselect,
882                   &hostname, portstr, r_httpflags, r_poolname);
883   if (err)
884     return err;
885
886   /* If map_host did not return a port (from a SRV record) but a port
887    * has been specified (implicitly or explicitly) then use that port.
888    * In the case that a port was not specified (which is probably a
889    * bug in https.c) we will set up defaults.  */
890   if (*portstr)
891     ;
892   else if (!*portstr && port)
893     snprintf (portstr, sizeof portstr, "%hu", port);
894   else if (!strcmp (scheme,"https"))
895     strcpy (portstr, "443");
896   else
897     strcpy (portstr, "11371");
898
899   *r_hostport = strconcat (scheme, "://", hostname, ":", portstr, NULL);
900   xfree (hostname);
901   if (!*r_hostport)
902     {
903       if (r_poolname)
904         {
905           xfree (*r_poolname);
906           *r_poolname = NULL;
907         }
908       return gpg_error_from_syserror ();
909     }
910   return 0;
911 }
912
913
914 /* Resolve all known keyserver names and update the hosttable.  This
915    is mainly useful for debugging because the resolving is anyway done
916    on demand.  */
917 gpg_error_t
918 ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
919 {
920   gpg_error_t err;
921   char *hostport = NULL;
922
923   /* NB: With an explicitly given port we do not want to consult a
924    * service record because that might be in conflict with the port
925    * from such a service record.  */
926   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
927                         1, uri->explicit_port,
928                         &hostport, NULL, NULL);
929   if (err)
930     {
931       err = ks_printf_help (ctrl, "%s://%s:%hu: resolve failed: %s",
932                             uri->scheme, uri->host, uri->port,
933                             gpg_strerror (err));
934     }
935   else
936     {
937       err = ks_printf_help (ctrl, "%s", hostport);
938       xfree (hostport);
939     }
940   return err;
941 }
942
943
944 /* Housekeeping function called from the housekeeping thread.  It is
945    used to mark dead hosts alive so that they may be tried again after
946    some time.  */
947 void
948 ks_hkp_housekeeping (time_t curtime)
949 {
950   int idx;
951   hostinfo_t hi;
952
953   for (idx=0; idx < hosttable_size; idx++)
954     {
955       hi = hosttable[idx];
956       if (!hi)
957         continue;
958       if (!hi->dead)
959         continue;
960       if (!hi->died_at)
961         continue; /* Do not resurrect manually shot hosts.  */
962       if (hi->died_at + RESURRECT_INTERVAL <= curtime
963           || hi->died_at > curtime)
964         {
965           hi->dead = 0;
966           log_info ("resurrected host '%s'", hi->name);
967         }
968     }
969 }
970
971
972 /* Send an HTTP request.  On success returns an estream object at
973    R_FP.  HOSTPORTSTR is only used for diagnostics.  If HTTPHOST is
974    not NULL it will be used as HTTP "Host" header.  If POST_CB is not
975    NULL a post request is used and that callback is called to allow
976    writing the post data.  If R_HTTP_STATUS is not NULL, the http
977    status code will be stored there.  */
978 static gpg_error_t
979 send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
980               const char *httphost, unsigned int httpflags,
981               gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value,
982               estream_t *r_fp, unsigned int *r_http_status)
983 {
984   gpg_error_t err;
985   http_session_t session = NULL;
986   http_t http = NULL;
987   int redirects_left = MAX_REDIRECTS;
988   estream_t fp = NULL;
989   char *request_buffer = NULL;
990
991   *r_fp = NULL;
992
993   err = http_session_new (&session, NULL, httphost, HTTP_FLAG_TRUST_DEF);
994   if (err)
995     goto leave;
996   http_session_set_log_cb (session, cert_log_cb);
997
998  once_more:
999   err = http_open (&http,
1000                    post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
1001                    request,
1002                    httphost,
1003                    /* fixme: AUTH */ NULL,
1004                    (httpflags
1005                     |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
1006                     |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
1007                    ctrl->http_proxy,
1008                    session,
1009                    NULL,
1010                    /*FIXME curl->srvtag*/NULL);
1011   if (!err)
1012     {
1013       fp = http_get_write_ptr (http);
1014       /* Avoid caches to get the most recent copy of the key.  We set
1015          both the Pragma and Cache-Control versions of the header, so
1016          we're good with both HTTP 1.0 and 1.1.  */
1017       es_fputs ("Pragma: no-cache\r\n"
1018                 "Cache-Control: no-cache\r\n", fp);
1019       if (post_cb)
1020         err = post_cb (post_cb_value, http);
1021       if (!err)
1022         {
1023           http_start_data (http);
1024           if (es_ferror (fp))
1025             err = gpg_error_from_syserror ();
1026         }
1027     }
1028   if (err)
1029     {
1030       /* Fixme: After a redirection we show the old host name.  */
1031       log_error (_("error connecting to '%s': %s\n"),
1032                  hostportstr, gpg_strerror (err));
1033       goto leave;
1034     }
1035
1036   /* Wait for the response.  */
1037   dirmngr_tick (ctrl);
1038   err = http_wait_response (http);
1039   if (err)
1040     {
1041       log_error (_("error reading HTTP response for '%s': %s\n"),
1042                  hostportstr, gpg_strerror (err));
1043       goto leave;
1044     }
1045
1046   if (http_get_tls_info (http, NULL))
1047     {
1048       /* Update the httpflags so that a redirect won't fallback to an
1049          unencrypted connection.  */
1050       httpflags |= HTTP_FLAG_FORCE_TLS;
1051     }
1052
1053   if (r_http_status)
1054     *r_http_status = http_get_status_code (http);
1055
1056   switch (http_get_status_code (http))
1057     {
1058     case 200:
1059       err = 0;
1060       break; /* Success.  */
1061
1062     case 301:
1063     case 302:
1064     case 307:
1065       {
1066         const char *s = http_get_header (http, "Location");
1067
1068         log_info (_("URL '%s' redirected to '%s' (%u)\n"),
1069                   request, s?s:"[none]", http_get_status_code (http));
1070         if (s && *s && redirects_left-- )
1071           {
1072             xfree (request_buffer);
1073             request_buffer = xtrystrdup (s);
1074             if (request_buffer)
1075               {
1076                 request = request_buffer;
1077                 http_close (http, 0);
1078                 http = NULL;
1079                 goto once_more;
1080               }
1081             err = gpg_error_from_syserror ();
1082           }
1083         else
1084           err = gpg_error (GPG_ERR_NO_DATA);
1085         log_error (_("too many redirections\n"));
1086       }
1087       goto leave;
1088
1089     case 501:
1090       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1091       goto leave;
1092
1093     default:
1094       log_error (_("error accessing '%s': http status %u\n"),
1095                  request, http_get_status_code (http));
1096       err = gpg_error (GPG_ERR_NO_DATA);
1097       goto leave;
1098     }
1099
1100   /* FIXME: We should register a permanent redirection and whether a
1101      host has ever used TLS so that future calls will always use
1102      TLS. */
1103
1104   fp = http_get_read_ptr (http);
1105   if (!fp)
1106     {
1107       err = gpg_error (GPG_ERR_BUG);
1108       goto leave;
1109     }
1110
1111   /* Return the read stream and close the HTTP context.  */
1112   *r_fp = fp;
1113   http_close (http, 1);
1114   http = NULL;
1115
1116  leave:
1117   http_close (http, 0);
1118   http_session_release (session);
1119   xfree (request_buffer);
1120   return err;
1121 }
1122
1123
1124 /* Helper to evaluate the error code ERR form a send_request() call
1125    with REQUEST.  The function returns true if the caller shall try
1126    again.  TRIES_LEFT points to a variable to track the number of
1127    retries; this function decrements it and won't return true if it is
1128    down to zero. */
1129 static int
1130 handle_send_request_error (gpg_error_t err, const char *request,
1131                            unsigned int *tries_left)
1132 {
1133   int retry = 0;
1134
1135   /* Fixme: Should we disable all hosts of a protocol family if a
1136    * request for an address of that familiy returned ENETDOWN?  */
1137
1138   switch (gpg_err_code (err))
1139     {
1140     case GPG_ERR_ECONNREFUSED:
1141       if (opt.use_tor)
1142         {
1143           assuan_fd_t sock;
1144
1145           sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
1146           if (sock == ASSUAN_INVALID_FD)
1147             log_info ("(it seems Tor is not running)\n");
1148           else
1149             assuan_sock_close (sock);
1150         }
1151       /*FALLTHRU*/
1152     case GPG_ERR_ENETUNREACH:
1153     case GPG_ERR_ENETDOWN:
1154     case GPG_ERR_UNKNOWN_HOST:
1155     case GPG_ERR_NETWORK:
1156       if (mark_host_dead (request) && *tries_left)
1157         retry = 1;
1158       break;
1159
1160     case GPG_ERR_ETIMEDOUT:
1161       if (*tries_left)
1162         {
1163           log_info ("selecting a different host due to a timeout\n");
1164           retry = 1;
1165         }
1166       break;
1167
1168     default:
1169       break;
1170     }
1171
1172   if (*tries_left)
1173     --*tries_left;
1174
1175   return retry;
1176 }
1177
1178 \f
1179 /* Search the keyserver identified by URI for keys matching PATTERN.
1180    On success R_FP has an open stream to read the data.  If
1181    R_HTTP_STATUS is not NULL, the http status code will be stored
1182    there.  */
1183 gpg_error_t
1184 ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
1185                estream_t *r_fp, unsigned int *r_http_status)
1186 {
1187   gpg_error_t err;
1188   KEYDB_SEARCH_DESC desc;
1189   char fprbuf[2+40+1];
1190   char *hostport = NULL;
1191   char *request = NULL;
1192   estream_t fp = NULL;
1193   int reselect;
1194   unsigned int httpflags;
1195   char *httphost = NULL;
1196   unsigned int tries = SEND_REQUEST_RETRIES;
1197
1198   *r_fp = NULL;
1199
1200   /* Remove search type indicator and adjust PATTERN accordingly.
1201      Note that HKP keyservers like the 0x to be present when searching
1202      by keyid.  We need to re-format the fingerprint and keyids so to
1203      remove the gpg specific force-use-of-this-key flag ("!").  */
1204   err = classify_user_id (pattern, &desc, 1);
1205   if (err)
1206     return err;
1207   switch (desc.mode)
1208     {
1209     case KEYDB_SEARCH_MODE_EXACT:
1210     case KEYDB_SEARCH_MODE_SUBSTR:
1211     case KEYDB_SEARCH_MODE_MAIL:
1212     case KEYDB_SEARCH_MODE_MAILSUB:
1213       pattern = desc.u.name;
1214       break;
1215     case KEYDB_SEARCH_MODE_SHORT_KID:
1216       snprintf (fprbuf, sizeof fprbuf, "0x%08lX", (ulong)desc.u.kid[1]);
1217       pattern = fprbuf;
1218       break;
1219     case KEYDB_SEARCH_MODE_LONG_KID:
1220       snprintf (fprbuf, sizeof fprbuf, "0x%08lX%08lX",
1221                 (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
1222       pattern = fprbuf;
1223       break;
1224     case KEYDB_SEARCH_MODE_FPR16:
1225       fprbuf[0] = '0';
1226       fprbuf[1] = 'x';
1227       bin2hex (desc.u.fpr, 16, fprbuf+2);
1228       pattern = fprbuf;
1229       break;
1230     case KEYDB_SEARCH_MODE_FPR20:
1231     case KEYDB_SEARCH_MODE_FPR:
1232       fprbuf[0] = '0';
1233       fprbuf[1] = 'x';
1234       bin2hex (desc.u.fpr, 20, fprbuf+2);
1235       pattern = fprbuf;
1236       break;
1237     default:
1238       return gpg_error (GPG_ERR_INV_USER_ID);
1239     }
1240
1241   /* Build the request string.  */
1242   reselect = 0;
1243  again:
1244   {
1245     char *searchkey;
1246
1247     xfree (hostport); hostport = NULL;
1248     xfree (httphost); httphost = NULL;
1249     err = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
1250                           reselect, uri->explicit_port,
1251                           &hostport, &httpflags, &httphost);
1252     if (err)
1253       goto leave;
1254
1255     searchkey = http_escape_string (pattern, EXTRA_ESCAPE_CHARS);
1256     if (!searchkey)
1257       {
1258         err = gpg_error_from_syserror ();
1259         goto leave;
1260       }
1261
1262     xfree (request);
1263     request = strconcat (hostport,
1264                          "/pks/lookup?op=index&options=mr&search=",
1265                          searchkey,
1266                          NULL);
1267     xfree (searchkey);
1268     if (!request)
1269       {
1270         err = gpg_error_from_syserror ();
1271         goto leave;
1272       }
1273   }
1274
1275   /* Send the request.  */
1276   err = send_request (ctrl, request, hostport, httphost, httpflags,
1277                       NULL, NULL, &fp, r_http_status);
1278   if (handle_send_request_error (err, request, &tries))
1279     {
1280       reselect = 1;
1281       goto again;
1282     }
1283   if (err)
1284     goto leave;
1285
1286   err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
1287   if (err)
1288     goto leave;
1289
1290   /* Peek at the response.  */
1291   {
1292     int c = es_getc (fp);
1293     if (c == -1)
1294       {
1295         err = es_ferror (fp)?gpg_error_from_syserror ():gpg_error (GPG_ERR_EOF);
1296         log_error ("error reading response: %s\n", gpg_strerror (err));
1297         goto leave;
1298       }
1299     if (c == '<')
1300       {
1301         /* The document begins with a '<': Assume a HTML response,
1302            which we don't support.  */
1303         err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1304         goto leave;
1305       }
1306     es_ungetc (c, fp);
1307   }
1308
1309   /* Return the read stream.  */
1310   *r_fp = fp;
1311   fp = NULL;
1312
1313  leave:
1314   es_fclose (fp);
1315   xfree (request);
1316   xfree (hostport);
1317   xfree (httphost);
1318   return err;
1319 }
1320
1321
1322 /* Get the key described key the KEYSPEC string from the keyserver
1323    identified by URI.  On success R_FP has an open stream to read the
1324    data.  The data will be provided in a format GnuPG can import
1325    (either a binary OpenPGP message or an armored one).  */
1326 gpg_error_t
1327 ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
1328 {
1329   gpg_error_t err;
1330   KEYDB_SEARCH_DESC desc;
1331   char kidbuf[2+40+1];
1332   const char *exactname = NULL;
1333   char *searchkey = NULL;
1334   char *hostport = NULL;
1335   char *request = NULL;
1336   estream_t fp = NULL;
1337   int reselect;
1338   char *httphost = NULL;
1339   unsigned int httpflags;
1340   unsigned int tries = SEND_REQUEST_RETRIES;
1341
1342   *r_fp = NULL;
1343
1344   /* Remove search type indicator and adjust PATTERN accordingly.
1345      Note that HKP keyservers like the 0x to be present when searching
1346      by keyid.  We need to re-format the fingerprint and keyids so to
1347      remove the gpg specific force-use-of-this-key flag ("!").  */
1348   err = classify_user_id (keyspec, &desc, 1);
1349   if (err)
1350     return err;
1351   switch (desc.mode)
1352     {
1353     case KEYDB_SEARCH_MODE_SHORT_KID:
1354       snprintf (kidbuf, sizeof kidbuf, "0x%08lX", (ulong)desc.u.kid[1]);
1355       break;
1356     case KEYDB_SEARCH_MODE_LONG_KID:
1357       snprintf (kidbuf, sizeof kidbuf, "0x%08lX%08lX",
1358                 (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]);
1359       break;
1360     case KEYDB_SEARCH_MODE_FPR20:
1361     case KEYDB_SEARCH_MODE_FPR:
1362       /* This is a v4 fingerprint. */
1363       kidbuf[0] = '0';
1364       kidbuf[1] = 'x';
1365       bin2hex (desc.u.fpr, 20, kidbuf+2);
1366       break;
1367
1368     case KEYDB_SEARCH_MODE_EXACT:
1369       exactname = desc.u.name;
1370       break;
1371
1372     case KEYDB_SEARCH_MODE_FPR16:
1373       log_error ("HKP keyservers do not support v3 fingerprints\n");
1374     default:
1375       return gpg_error (GPG_ERR_INV_USER_ID);
1376     }
1377
1378   searchkey = http_escape_string (exactname? exactname : kidbuf,
1379                                   EXTRA_ESCAPE_CHARS);
1380   if (!searchkey)
1381     {
1382       err = gpg_error_from_syserror ();
1383       goto leave;
1384     }
1385
1386   reselect = 0;
1387  again:
1388   /* Build the request string.  */
1389   xfree (hostport); hostport = NULL;
1390   xfree (httphost); httphost = NULL;
1391   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
1392                         reselect, uri->explicit_port,
1393                         &hostport, &httpflags, &httphost);
1394   if (err)
1395     goto leave;
1396
1397   xfree (request);
1398   request = strconcat (hostport,
1399                        "/pks/lookup?op=get&options=mr&search=",
1400                        searchkey,
1401                        exactname? "&exact=on":"",
1402                        NULL);
1403   if (!request)
1404     {
1405       err = gpg_error_from_syserror ();
1406       goto leave;
1407     }
1408
1409   /* Send the request.  */
1410   err = send_request (ctrl, request, hostport, httphost, httpflags,
1411                       NULL, NULL, &fp, NULL);
1412   if (handle_send_request_error (err, request, &tries))
1413     {
1414       reselect = 1;
1415       goto again;
1416     }
1417   if (err)
1418     goto leave;
1419
1420   err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
1421   if (err)
1422     goto leave;
1423
1424   /* Return the read stream and close the HTTP context.  */
1425   *r_fp = fp;
1426   fp = NULL;
1427
1428  leave:
1429   es_fclose (fp);
1430   xfree (request);
1431   xfree (hostport);
1432   xfree (httphost);
1433   xfree (searchkey);
1434   return err;
1435 }
1436
1437
1438
1439 \f
1440 /* Callback parameters for put_post_cb.  */
1441 struct put_post_parm_s
1442 {
1443   char *datastring;
1444 };
1445
1446
1447 /* Helper for ks_hkp_put.  */
1448 static gpg_error_t
1449 put_post_cb (void *opaque, http_t http)
1450 {
1451   struct put_post_parm_s *parm = opaque;
1452   gpg_error_t err = 0;
1453   estream_t fp;
1454   size_t len;
1455
1456   fp = http_get_write_ptr (http);
1457   len = strlen (parm->datastring);
1458
1459   es_fprintf (fp,
1460               "Content-Type: application/x-www-form-urlencoded\r\n"
1461               "Content-Length: %zu\r\n", len+8 /* 8 is for "keytext" */);
1462   http_start_data (http);
1463   if (es_fputs ("keytext=", fp) || es_write (fp, parm->datastring, len, NULL))
1464     err = gpg_error_from_syserror ();
1465   return err;
1466 }
1467
1468
1469 /* Send the key in {DATA,DATALEN} to the keyserver identified by URI.  */
1470 gpg_error_t
1471 ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
1472 {
1473   gpg_error_t err;
1474   char *hostport = NULL;
1475   char *request = NULL;
1476   estream_t fp = NULL;
1477   struct put_post_parm_s parm;
1478   char *armored = NULL;
1479   int reselect;
1480   char *httphost = NULL;
1481   unsigned int httpflags;
1482   unsigned int tries = SEND_REQUEST_RETRIES;
1483
1484   parm.datastring = NULL;
1485
1486   err = armor_data (&armored, data, datalen);
1487   if (err)
1488     goto leave;
1489
1490   parm.datastring = http_escape_string (armored, EXTRA_ESCAPE_CHARS);
1491   if (!parm.datastring)
1492     {
1493       err = gpg_error_from_syserror ();
1494       goto leave;
1495     }
1496   xfree (armored);
1497   armored = NULL;
1498
1499   /* Build the request string.  */
1500   reselect = 0;
1501  again:
1502   xfree (hostport); hostport = NULL;
1503   xfree (httphost); httphost = NULL;
1504   err = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
1505                         reselect, uri->explicit_port,
1506                         &hostport, &httpflags, &httphost);
1507   if (err)
1508     goto leave;
1509
1510   xfree (request);
1511   request = strconcat (hostport, "/pks/add", NULL);
1512   if (!request)
1513     {
1514       err = gpg_error_from_syserror ();
1515       goto leave;
1516     }
1517
1518   /* Send the request.  */
1519   err = send_request (ctrl, request, hostport, httphost, 0,
1520                       put_post_cb, &parm, &fp, NULL);
1521   if (handle_send_request_error (err, request, &tries))
1522     {
1523       reselect = 1;
1524       goto again;
1525     }
1526   if (err)
1527     goto leave;
1528
1529  leave:
1530   es_fclose (fp);
1531   xfree (parm.datastring);
1532   xfree (armored);
1533   xfree (request);
1534   xfree (hostport);
1535   xfree (httphost);
1536   return err;
1537 }