dirmngr: Fix the ks_fetch command for the http scheme.
[gnupg.git] / common / http.c
1 /* http.c  -  HTTP protocol handler
2  * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
3  *               2011 Free Software Foundation, Inc.
4  * Copyright (C) 2014 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * This file is free software; you can redistribute it and/or modify
9  * it under the terms of either
10  *
11  *   - the GNU Lesser General Public License as published by the Free
12  *     Software Foundation; either version 3 of the License, or (at
13  *     your option) any later version.
14  *
15  * or
16  *
17  *   - the GNU General Public License as published by the Free
18  *     Software Foundation; either version 2 of the License, or (at
19  *     your option) any later version.
20  *
21  * or both in parallel, as here.
22  *
23  * This file is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <http://www.gnu.org/licenses/>.
30  */
31
32 /* Simple HTTP client implementation.  We try to keep the code as
33    self-contained as possible.  There are some contraints however:
34
35   - estream is required.  We now require estream because it provides a
36     very useful and portable asprintf implementation and the fopencookie
37     function.
38   - stpcpy is required
39   - fixme: list other requirements.
40
41
42   - With HTTP_USE_GNUTLS or HTTP_USE_POLARSSL support for https is
43     provided (this also requires estream).
44
45   - With HTTP_NO_WSASTARTUP the socket initialization is not done
46     under Windows.  This is useful if the socket layer has already
47     been initialized elsewhere.  This also avoids the installation of
48     an exit handler to cleanup the socket layer.
49 */
50
51 #ifdef HAVE_CONFIG_H
52 # include <config.h>
53 #endif
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <stdarg.h>
57 #include <string.h>
58 #include <ctype.h>
59 #include <errno.h>
60 #include <unistd.h>
61
62 #ifdef HAVE_W32_SYSTEM
63 # ifdef HAVE_WINSOCK2_H
64 #  include <winsock2.h>
65 # endif
66 # include <windows.h>
67 #else /*!HAVE_W32_SYSTEM*/
68 # include <sys/types.h>
69 # include <sys/socket.h>
70 # include <sys/time.h>
71 # include <time.h>
72 # include <netinet/in.h>
73 # include <arpa/inet.h>
74 # include <netdb.h>
75 #endif /*!HAVE_W32_SYSTEM*/
76
77 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
78 # undef USE_NPTH
79 #endif
80
81 #ifdef USE_NPTH
82 # include <npth.h>
83 #endif
84
85 #if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_POLARSSL)
86 # error Both, HTTP_USE_GNUTLS and HTTP_USE_POLARSSL, are defined.
87 #endif
88
89 #ifdef HTTP_USE_GNUTLS
90 # include <gnutls/gnutls.h>
91 # include <gnutls/x509.h>
92 #endif /*HTTP_USE_GNUTLS*/
93 #ifdef HTTP_USE_POLARSSL
94 # error Support for PolarSSL has not yet been added
95 #endif
96
97
98 #include "util.h"
99 #include "i18n.h"
100 #include "http.h"
101 #ifdef USE_DNS_SRV
102 # include "srv.h"
103 #else /*!USE_DNS_SRV*/
104   /* If we are not compiling with SRV record support we provide stub
105      data structures. */
106 # ifndef MAXDNAME
107 #  define MAXDNAME 1025
108 # endif
109 struct srventry
110 {
111   unsigned short priority;
112   unsigned short weight;
113   unsigned short port;
114   int run_count;
115   char target[MAXDNAME];
116 };
117 #endif/*!USE_DNS_SRV*/
118
119
120 #ifdef USE_NPTH
121 # define my_select(a,b,c,d,e)  npth_select ((a), (b), (c), (d), (e))
122 # define my_connect(a,b,c)     npth_connect ((a), (b), (c))
123 # define my_accept(a,b,c)      npth_accept ((a), (b), (c))
124 #else
125 # define my_select(a,b,c,d,e)  select ((a), (b), (c), (d), (e))
126 # define my_connect(a,b,c)     connect ((a), (b), (c))
127 # define my_accept(a,b,c)      accept ((a), (b), (c))
128 #endif
129
130 #ifdef HAVE_W32_SYSTEM
131 #define sock_close(a)  closesocket(a)
132 #else
133 #define sock_close(a)  close(a)
134 #endif
135
136 #ifndef EAGAIN
137 #define EAGAIN  EWOULDBLOCK
138 #endif
139 #ifndef INADDR_NONE  /* Slowaris is missing that.  */
140 #define INADDR_NONE  ((unsigned long)(-1))
141 #endif /*INADDR_NONE*/
142
143 #define HTTP_PROXY_ENV           "http_proxy"
144 #define MAX_LINELEN 20000  /* Max. length of a HTTP header line. */
145 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz"   \
146                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"   \
147                         "01234567890@"                 \
148                         "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
149
150 /* A long counter type.  */
151 #ifdef HAVE_STRTOULL
152 typedef unsigned long long longcounter_t;
153 # define counter_strtoul(a) strtoull ((a), NULL, 10)
154 #else
155 typedef unsigned long longcounter_t;
156 # define counter_strtoul(a) strtoul ((a), NULL, 10)
157 #endif
158
159 #ifndef HTTP_USE_GNUTLS
160 typedef void * gnutls_session_t;
161 #endif
162
163 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
164                                     int no_scheme_check, int force_tls);
165 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
166                               int no_scheme_check, int force_tls);
167 static int remove_escapes (char *string);
168 static int insert_escapes (char *buffer, const char *string,
169                            const char *special);
170 static uri_tuple_t parse_tuple (char *string);
171 static gpg_error_t send_request (http_t hd, const char *httphost,
172                                  const char *auth,const char *proxy,
173                                  const char *srvtag,strlist_t headers);
174 static char *build_rel_path (parsed_uri_t uri);
175 static gpg_error_t parse_response (http_t hd);
176
177 static int connect_server (const char *server, unsigned short port,
178                            unsigned int flags, const char *srvtag,
179                            int *r_host_not_found);
180 static gpg_error_t write_server (int sock, const char *data, size_t length);
181
182 static ssize_t cookie_read (void *cookie, void *buffer, size_t size);
183 static ssize_t cookie_write (void *cookie, const void *buffer, size_t size);
184 static int cookie_close (void *cookie);
185
186
187 /* A socket object used to a allow ref counting of sockets.  */
188 struct my_socket_s
189 {
190   int fd;       /* The actual socket - shall never be -1.  */
191   int refcount; /* Number of references to this socket.  */
192 };
193 typedef struct my_socket_s *my_socket_t;
194
195
196 /* Cookie function structure and cookie object.  */
197 static es_cookie_io_functions_t cookie_functions =
198   {
199     cookie_read,
200     cookie_write,
201     NULL,
202     cookie_close
203   };
204
205 struct cookie_s
206 {
207   /* Socket object or NULL if already closed. */
208   my_socket_t sock;
209
210   /* The session object or NULL if not used. */
211   http_session_t session;
212
213   /* True if TLS is to be used.  */
214   int use_tls;
215
216   /* The remaining content length and a flag telling whether to use
217      the content length.  */
218   longcounter_t content_length;
219   unsigned int content_length_valid:1;
220 };
221 typedef struct cookie_s *cookie_t;
222
223 /* The session object. */
224 struct http_session_s
225 {
226   int refcount;    /* Number of references to this object.  */
227 #ifdef HTTP_USE_GNUTLS
228   gnutls_certificate_credentials_t certcred;
229   gnutls_session_t tls_session;
230   struct {
231     int done;      /* Verifciation has been done.  */
232     int rc;        /* GnuTLS verification return code.  */
233     unsigned int status; /* Verification status.  */
234   } verify;
235   char *servername; /* Malloced server name.  */
236 #endif /*HTTP_USE_GNUTLS*/
237   /* A callback function to log details of TLS certifciates.  */
238   void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
239                        const void **, size_t *);
240 };
241
242
243 /* An object to save header lines. */
244 struct header_s
245 {
246   struct header_s *next;
247   char *value;    /* The value of the header (malloced).  */
248   char name[1];   /* The name of the header (canonicalized). */
249 };
250 typedef struct header_s *header_t;
251
252
253 /* Our handle context. */
254 struct http_context_s
255 {
256   unsigned int status_code;
257   my_socket_t sock;
258   unsigned int in_data:1;
259   unsigned int is_http_0_9:1;
260   estream_t fp_read;
261   estream_t fp_write;
262   void *write_cookie;
263   void *read_cookie;
264   http_session_t session;
265   parsed_uri_t uri;
266   http_req_t req_type;
267   char *buffer;          /* Line buffer. */
268   size_t buffer_size;
269   unsigned int flags;
270   header_t headers;      /* Received headers. */
271 };
272
273
274 /* The global callback for the verification fucntion.  */
275 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
276
277 /* The list of files with trusted CA certificates.  */
278 static strlist_t tls_ca_certlist;
279
280
281 \f
282 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
283
284 #if GNUPG_MAJOR_VERSION == 1
285 #define REQ_WINSOCK_MAJOR  1
286 #define REQ_WINSOCK_MINOR  1
287 #else
288 #define REQ_WINSOCK_MAJOR  2
289 #define REQ_WINSOCK_MINOR  2
290 #endif
291
292
293 static void
294 deinit_sockets (void)
295 {
296   WSACleanup();
297 }
298
299 static void
300 init_sockets (void)
301 {
302   static int initialized;
303   static WSADATA wsdata;
304
305   if (initialized)
306     return;
307
308   if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
309     {
310       log_error ("error initializing socket library: ec=%d\n",
311                  (int)WSAGetLastError () );
312       return;
313     }
314   if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
315        || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
316     {
317       log_error ("socket library version is %x.%x - but %d.%d needed\n",
318                  LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
319                  REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
320       WSACleanup();
321       return;
322     }
323   atexit ( deinit_sockets );
324   initialized = 1;
325 }
326 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
327
328
329 /* Create a new socket object.  Returns NULL and closes FD if not
330    enough memory is available.  */
331 static my_socket_t
332 _my_socket_new (int lnr, int fd)
333 {
334   my_socket_t so;
335
336   so = xtrymalloc (sizeof *so);
337   if (!so)
338     {
339       int save_errno = errno;
340       sock_close (fd);
341       gpg_err_set_errno (save_errno);
342       return NULL;
343     }
344   so->fd = fd;
345   so->refcount = 1;
346   /* log_debug ("http.c:socket_new(%d): object %p for fd %d created\n", */
347   /*            lnr, so, so->fd); */
348   (void)lnr;
349   return so;
350 }
351 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
352
353 /* Bump up the reference counter for the socket object SO.  */
354 static my_socket_t
355 _my_socket_ref (int lnr, my_socket_t so)
356 {
357   so->refcount++;
358   /* log_debug ("http.c:socket_ref(%d) object %p for fd %d refcount now %d\n", */
359   /*            lnr, so, so->fd, so->refcount); */
360   (void)lnr;
361   return so;
362 }
363 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
364
365
366 /* Bump down the reference counter for the socket object SO.  If SO
367    has no more references, close the socket and release the
368    object.  */
369 static void
370 _my_socket_unref (int lnr, my_socket_t so,
371                   void (*preclose)(void*), void *preclosearg)
372 {
373   if (so)
374     {
375       so->refcount--;
376       /* log_debug ("http.c:socket_unref(%d): object %p for fd %d ref now %d\n", */
377       /*            lnr, so, so->fd, so->refcount); */
378       (void)lnr;
379       if (!so->refcount)
380         {
381           if (preclose)
382             preclose (preclosearg);
383           sock_close (so->fd);
384           xfree (so);
385         }
386     }
387 }
388 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
389
390
391 #if defined (USE_NPTH) && defined(HTTP_USE_GNUTLS)
392 static ssize_t
393 my_npth_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
394 {
395   my_socket_t sock = ptr;
396   return npth_read (sock->fd, buffer, size);
397 }
398 static ssize_t
399 my_npth_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
400 {
401   my_socket_t sock = ptr;
402   return npth_write (sock->fd, buffer, size);
403 }
404 #endif /*USE_NPTH && HTTP_USE_GNUTLS*/
405
406
407
408 \f
409 /* This notification function is called by estream whenever stream is
410    closed.  Its purpose is to mark the closing in the handle so
411    that a http_close won't accidentally close the estream.  The function
412    http_close removes this notification so that it won't be called if
413    http_close was used before an es_fclose.  */
414 static void
415 fp_onclose_notification (estream_t stream, void *opaque)
416 {
417   http_t hd = opaque;
418
419   if (hd->fp_read && hd->fp_read == stream)
420     hd->fp_read = NULL;
421   else if (hd->fp_write && hd->fp_write == stream)
422     hd->fp_write = NULL;
423 }
424
425
426 /*
427  * Helper function to create an HTTP header with hex encoded data.  A
428  * new buffer is returned.  This buffer is the concatenation of the
429  * string PREFIX, the hex-encoded DATA of length LEN and the string
430  * SUFFIX.  On error NULL is returned and ERRNO set.
431  */
432 static char *
433 make_header_line (const char *prefix, const char *suffix,
434                   const void *data, size_t len )
435 {
436   static unsigned char bintoasc[] =
437     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
438     "abcdefghijklmnopqrstuvwxyz"
439     "0123456789+/";
440   const unsigned char *s = data;
441   char *buffer, *p;
442
443   buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
444   if (!buffer)
445     return NULL;
446   p = stpcpy (buffer, prefix);
447   for ( ; len >= 3 ; len -= 3, s += 3 )
448     {
449       *p++ = bintoasc[(s[0] >> 2) & 077];
450       *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
451       *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
452       *p++ = bintoasc[s[2]&077];
453       *p = 0;
454     }
455   if ( len == 2 )
456     {
457       *p++ = bintoasc[(s[0] >> 2) & 077];
458       *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
459       *p++ = bintoasc[((s[1]<<2)&074)];
460       *p++ = '=';
461     }
462   else if ( len == 1 )
463     {
464       *p++ = bintoasc[(s[0] >> 2) & 077];
465       *p++ = bintoasc[(s[0] <<4)&060];
466       *p++ = '=';
467       *p++ = '=';
468     }
469   *p = 0;
470   strcpy (p, suffix);
471   return buffer;
472 }
473
474
475
476 \f
477 /* Register a non-standard global TLS callback function.  If no
478    verification is desired a callback needs to be registered which
479    always returns NULL.  */
480 void
481 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
482 {
483   tls_callback = cb;
484 }
485
486
487 /* Register a CA certificate for future use.  The certificate is
488    expected to be in FNAME.  PEM format is assume if FNAME has a
489    suffix of ".pem".  If FNAME is NULL the list of CA files is
490    removed.  */
491 void
492 http_register_tls_ca (const char *fname)
493 {
494   strlist_t sl;
495
496   if (!fname)
497     {
498       free_strlist (tls_ca_certlist);
499       tls_ca_certlist = NULL;
500     }
501   else
502     {
503       sl = add_to_strlist (&tls_ca_certlist, fname);
504       if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
505         sl->flags = 1;
506     }
507 }
508
509
510 /* Release a session.  Take care not to release it while it is being
511    used by a http context object.  */
512 static void
513 session_unref (int lnr, http_session_t sess)
514 {
515   if (!sess)
516     return;
517
518   sess->refcount--;
519   /* log_debug ("http.c:session_unref(%d): sess %p ref now %d\n", */
520   /*            lnr, sess, sess->refcount); */
521   (void)lnr;
522   if (sess->refcount)
523     return;
524
525 #ifdef HTTP_USE_GNUTLS
526   if (sess->tls_session)
527     {
528       my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
529       my_socket_unref (sock, NULL, NULL);
530       gnutls_deinit (sess->tls_session);
531     }
532   if (sess->certcred)
533     gnutls_certificate_free_credentials (sess->certcred);
534   xfree (sess->servername);
535 #endif /*HTTP_USE_GNUTLS*/
536
537   xfree (sess);
538 }
539 #define http_session_unref(a) session_unref (__LINE__, (a))
540
541 void
542 http_session_release (http_session_t sess)
543 {
544   http_session_unref (sess);
545 }
546
547
548 /* Create a new session object which is currently used to enable TLS
549    support.  It may eventually allow reusing existing connections.  */
550 gpg_error_t
551 http_session_new (http_session_t *r_session, const char *tls_priority)
552 {
553   gpg_error_t err;
554   http_session_t sess;
555
556   *r_session = NULL;
557
558   sess = xtrycalloc (1, sizeof *sess);
559   if (!sess)
560     return gpg_error_from_syserror ();
561   sess->refcount = 1;
562
563 #ifdef HTTP_USE_GNUTLS
564   {
565     const char *errpos;
566     int rc;
567     strlist_t sl;
568
569     rc = gnutls_certificate_allocate_credentials (&sess->certcred);
570     if (rc < 0)
571       {
572         log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
573                    gnutls_strerror (rc));
574         err = gpg_error (GPG_ERR_GENERAL);
575         goto leave;
576       }
577
578     for (sl = tls_ca_certlist; sl; sl = sl->next)
579       {
580         rc = gnutls_certificate_set_x509_trust_file
581           (sess->certcred, sl->d,
582            (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
583         if (rc < 0)
584           log_info ("setting CA from file '%s' failed: %s\n",
585                     sl->d, gnutls_strerror (rc));
586       }
587
588     rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
589     if (rc < 0)
590       {
591         log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
592         err = gpg_error (GPG_ERR_GENERAL);
593         goto leave;
594       }
595     /* A new session has the transport ptr set to (void*(-1), we need
596        it to be NULL.  */
597     gnutls_transport_set_ptr (sess->tls_session, NULL);
598
599     rc = gnutls_priority_set_direct (sess->tls_session,
600                                      tls_priority? tls_priority : "NORMAL",
601                                      &errpos);
602     if (rc < 0)
603       {
604         log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
605                    errpos, gnutls_strerror (rc));
606         err = gpg_error (GPG_ERR_GENERAL);
607         goto leave;
608       }
609
610     rc = gnutls_credentials_set (sess->tls_session,
611                                  GNUTLS_CRD_CERTIFICATE, sess->certcred);
612     if (rc < 0)
613       {
614         log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
615         err = gpg_error (GPG_ERR_GENERAL);
616         goto leave;
617       }
618   }
619
620 #else /*!HTTP_USE_GNUTLS*/
621   (void)tls_priority;
622 #endif /*!HTTP_USE_GNUTLS*/
623
624   /* log_debug ("http.c:session_new: sess %p created\n", sess); */
625   err = 0;
626
627 #ifdef HTTP_USE_GNUTLS
628  leave:
629 #endif /*HTTP_USE_GNUTLS*/
630   if (err)
631     http_session_unref (sess);
632   else
633     *r_session = sess;
634
635   return err;
636 }
637
638
639 /* Increment the reference count for session SESS.  Passing NULL for
640    SESS is allowed. */
641 http_session_t
642 http_session_ref (http_session_t sess)
643 {
644   if (sess)
645     {
646       sess->refcount++;
647       /* log_debug ("http.c:session_ref: sess %p ref now %d\n", sess, */
648       /*            sess->refcount); */
649     }
650   return sess;
651 }
652
653
654 void
655 http_session_set_log_cb (http_session_t sess,
656                          void (*cb)(http_session_t, gpg_error_t,
657                                     const char *hostname,
658                                     const void **certs, size_t *certlens))
659 {
660   sess->cert_log_cb = cb;
661 }
662
663
664
665 \f
666 /* Start a HTTP retrieval and on success store at R_HD a context
667    pointer for completing the request and to wait for the response.
668    If HTTPHOST is not NULL it is used hor the Host header instead of a
669    Host header derived from the URL. */
670 gpg_error_t
671 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
672            const char *httphost,
673            const char *auth, unsigned int flags, const char *proxy,
674            http_session_t session, const char *srvtag, strlist_t headers)
675 {
676   gpg_error_t err;
677   http_t hd;
678
679   *r_hd = NULL;
680
681   if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
682     return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
683
684   /* Create the handle. */
685   hd = xtrycalloc (1, sizeof *hd);
686   if (!hd)
687     return gpg_error_from_syserror ();
688   hd->req_type = reqtype;
689   hd->flags = flags;
690   hd->session = http_session_ref (session);
691
692   err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
693   if (!err)
694     err = send_request (hd, httphost, auth, proxy, srvtag, headers);
695
696   if (err)
697     {
698       my_socket_unref (hd->sock, NULL, NULL);
699       if (hd->fp_read)
700         es_fclose (hd->fp_read);
701       if (hd->fp_write)
702         es_fclose (hd->fp_write);
703       http_session_unref (hd->session);
704       xfree (hd);
705     }
706   else
707     *r_hd = hd;
708   return err;
709 }
710
711
712 /* This function is useful to connect to a generic TCP service using
713    this http abstraction layer.  This has the advantage of providing
714    service tags and an estream interface.  */
715 gpg_error_t
716 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
717                   unsigned int flags, const char *srvtag)
718 {
719   gpg_error_t err = 0;
720   int sock;
721   http_t hd;
722   cookie_t cookie;
723   int hnf;
724
725   *r_hd = NULL;
726
727   /* Create the handle. */
728   hd = xtrycalloc (1, sizeof *hd);
729   if (!hd)
730     return gpg_error_from_syserror ();
731   hd->req_type = HTTP_REQ_OPAQUE;
732   hd->flags = flags;
733
734   /* Connect.  */
735   sock = connect_server (server, port, hd->flags, srvtag, &hnf);
736   if (sock == -1)
737     {
738       err = gpg_err_make (default_errsource,
739                           (hnf? GPG_ERR_UNKNOWN_HOST
740                               : gpg_err_code_from_syserror ()));
741       xfree (hd);
742       return err;
743     }
744   hd->sock = my_socket_new (sock);
745   if (!hd->sock)
746     {
747       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
748       xfree (hd);
749       return err;
750     }
751
752   /* Setup estreams for reading and writing.  */
753   cookie = xtrycalloc (1, sizeof *cookie);
754   if (!cookie)
755     {
756       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
757       goto leave;
758     }
759   cookie->sock = my_socket_ref (hd->sock);
760   hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
761   if (!hd->fp_write)
762     {
763       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
764       my_socket_unref (cookie->sock, NULL, NULL);
765       xfree (cookie);
766       goto leave;
767     }
768   hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE.  */
769
770   cookie = xtrycalloc (1, sizeof *cookie);
771   if (!cookie)
772     {
773       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
774       goto leave;
775     }
776   cookie->sock = my_socket_ref (hd->sock);
777   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
778   if (!hd->fp_read)
779     {
780       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
781       my_socket_unref (cookie->sock, NULL, NULL);
782       xfree (cookie);
783       goto leave;
784     }
785   hd->read_cookie = cookie; /* Cookie now owned by FP_READ.  */
786
787   /* Register close notification to interlock the use of es_fclose in
788      http_close and in user code.  */
789   err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
790   if (!err)
791     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
792
793  leave:
794   if (err)
795     {
796       if (hd->fp_read)
797         es_fclose (hd->fp_read);
798       if (hd->fp_write)
799         es_fclose (hd->fp_write);
800       my_socket_unref (hd->sock, NULL, NULL);
801       xfree (hd);
802     }
803   else
804     *r_hd = hd;
805   return err;
806 }
807
808
809
810
811 void
812 http_start_data (http_t hd)
813 {
814   if (!hd->in_data)
815     {
816       es_fputs ("\r\n", hd->fp_write);
817       es_fflush (hd->fp_write);
818       hd->in_data = 1;
819     }
820   else
821     es_fflush (hd->fp_write);
822 }
823
824
825 gpg_error_t
826 http_wait_response (http_t hd)
827 {
828   gpg_error_t err;
829   cookie_t cookie;
830
831   /* Make sure that we are in the data. */
832   http_start_data (hd);
833
834   /* Close the write stream.  Note that the reference counted socket
835      object keeps the actual system socket open.  */
836   cookie = hd->write_cookie;
837   if (!cookie)
838     return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
839
840   es_fclose (hd->fp_write);
841   hd->fp_write = NULL;
842   /* The close has released the cookie and thus we better set it to NULL.  */
843   hd->write_cookie = NULL;
844
845   /* Shutdown one end of the socket is desired.  As per HTTP/1.0 this
846      is not required but some very old servers (e.g. the original pksd
847      key server didn't worked without it.  */
848   if ((hd->flags & HTTP_FLAG_SHUTDOWN))
849     shutdown (hd->sock->fd, 1);
850   hd->in_data = 0;
851
852   /* Create a new cookie and a stream for reading.  */
853   cookie = xtrycalloc (1, sizeof *cookie);
854   if (!cookie)
855     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
856   cookie->sock = my_socket_ref (hd->sock);
857   cookie->session = http_session_ref (hd->session);
858   cookie->use_tls = hd->uri->use_tls;
859
860   hd->read_cookie = cookie;
861   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
862   if (!hd->fp_read)
863     {
864       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
865       my_socket_unref (cookie->sock, NULL, NULL);
866       http_session_unref (cookie->session);
867       xfree (cookie);
868       hd->read_cookie = NULL;
869       return err;
870     }
871
872   err = parse_response (hd);
873
874   if (!err)
875     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
876
877   return err;
878 }
879
880
881 /* Convenience function to send a request and wait for the response.
882    Closes the handle on error.  If PROXY is not NULL, this value will
883    be used as an HTTP proxy and any enabled $http_proxy gets
884    ignored. */
885 gpg_error_t
886 http_open_document (http_t *r_hd, const char *document,
887                     const char *auth, unsigned int flags, const char *proxy,
888                     http_session_t session,
889                     const char *srvtag, strlist_t headers)
890 {
891   gpg_error_t err;
892
893   err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
894                    proxy, session, srvtag, headers);
895   if (err)
896     return err;
897
898   err = http_wait_response (*r_hd);
899   if (err)
900     http_close (*r_hd, 0);
901
902   return err;
903 }
904
905
906 void
907 http_close (http_t hd, int keep_read_stream)
908 {
909   if (!hd)
910     return;
911
912   /* First remove the close notifications for the streams.  */
913   if (hd->fp_read)
914     es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
915   if (hd->fp_write)
916     es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
917
918   /* Now we can close the streams.  */
919   my_socket_unref (hd->sock, NULL, NULL);
920   if (hd->fp_read && !keep_read_stream)
921     es_fclose (hd->fp_read);
922   if (hd->fp_write)
923     es_fclose (hd->fp_write);
924   http_session_unref (hd->session);
925   http_release_parsed_uri (hd->uri);
926   while (hd->headers)
927     {
928       header_t tmp = hd->headers->next;
929       xfree (hd->headers->value);
930       xfree (hd->headers);
931       hd->headers = tmp;
932     }
933   xfree (hd->buffer);
934   xfree (hd);
935 }
936
937
938 estream_t
939 http_get_read_ptr (http_t hd)
940 {
941   return hd?hd->fp_read:NULL;
942 }
943
944 estream_t
945 http_get_write_ptr (http_t hd)
946 {
947   return hd?hd->fp_write:NULL;
948 }
949
950 unsigned int
951 http_get_status_code (http_t hd)
952 {
953   return hd?hd->status_code:0;
954 }
955
956 /* Return information pertaining to TLS.  If TLS is not in use for HD,
957    NULL is returned.  WHAT is used ask for specific information:
958
959      (NULL) := Only check whether TLS is is use.  Returns an
960                unspecified string if TLS is in use.  That string may
961                even be the empty string.
962  */
963 const char *
964 http_get_tls_info (http_t hd, const char *what)
965 {
966   (void)what;
967
968   if (!hd)
969     return NULL;
970
971   return hd->uri->use_tls? "":NULL;
972 }
973
974
975 \f
976 static gpg_error_t
977 parse_uri (parsed_uri_t *ret_uri, const char *uri,
978            int no_scheme_check, int force_tls)
979 {
980   gpg_err_code_t ec;
981
982   *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
983   if (!*ret_uri)
984     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
985   strcpy ((*ret_uri)->buffer, uri);
986   ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
987   if (ec)
988     {
989       xfree (*ret_uri);
990       *ret_uri = NULL;
991     }
992   return gpg_err_make (default_errsource, ec);
993 }
994
995
996 /*
997  * Parse an URI and put the result into the newly allocated RET_URI.
998  * On success the caller must use release_parsed_uri() to releases the
999  * resources.  If NO_SCHEME_CHECK is set, the function tries to parse
1000  * the URL in the same way it would do for an HTTP style URI.
1001  */
1002 gpg_error_t
1003 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1004                 int no_scheme_check)
1005 {
1006   return parse_uri (ret_uri, uri, no_scheme_check, 0);
1007 }
1008
1009
1010 void
1011 http_release_parsed_uri (parsed_uri_t uri)
1012 {
1013   if (uri)
1014     {
1015       uri_tuple_t r, r2;
1016
1017       for (r = uri->query; r; r = r2)
1018         {
1019           r2 = r->next;
1020           xfree (r);
1021         }
1022       xfree (uri);
1023     }
1024 }
1025
1026
1027 static gpg_err_code_t
1028 do_parse_uri (parsed_uri_t uri, int only_local_part,
1029               int no_scheme_check, int force_tls)
1030 {
1031   uri_tuple_t *tail;
1032   char *p, *p2, *p3, *pp;
1033   int n;
1034
1035   p = uri->buffer;
1036   n = strlen (uri->buffer);
1037
1038   /* Initialize all fields to an empty string or an empty list. */
1039   uri->scheme = uri->host = uri->path = p + n;
1040   uri->port = 0;
1041   uri->params = uri->query = NULL;
1042   uri->use_tls = 0;
1043   uri->is_http = 0;
1044   uri->opaque = 0;
1045   uri->v6lit = 0;
1046
1047   /* A quick validity check. */
1048   if (strspn (p, VALID_URI_CHARS) != n)
1049     return GPG_ERR_BAD_URI;     /* Invalid characters found. */
1050
1051   if (!only_local_part)
1052     {
1053       /* Find the scheme. */
1054       if (!(p2 = strchr (p, ':')) || p2 == p)
1055         return GPG_ERR_BAD_URI; /* No scheme. */
1056       *p2++ = 0;
1057       for (pp=p; *pp; pp++)
1058        *pp = tolower (*(unsigned char*)pp);
1059       uri->scheme = p;
1060       if (!strcmp (uri->scheme, "http") && !force_tls)
1061         {
1062           uri->port = 80;
1063           uri->is_http = 1;
1064         }
1065       else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1066         {
1067           uri->port = 11371;
1068           uri->is_http = 1;
1069         }
1070 #ifdef HTTP_USE_GNUTLS
1071       else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1072                || (force_tls && (!strcmp (uri->scheme, "http")
1073                                  || !strcmp (uri->scheme,"hkp"))))
1074         {
1075           uri->port = 443;
1076           uri->is_http = 1;
1077           uri->use_tls = 1;
1078         }
1079 #endif
1080       else if (!no_scheme_check)
1081         return GPG_ERR_INV_URI; /* Unsupported scheme */
1082
1083       p = p2;
1084
1085       if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1086         {
1087           p += 2;
1088           if ((p2 = strchr (p, '/')))
1089             *p2++ = 0;
1090
1091           /* Check for username/password encoding */
1092           if ((p3 = strchr (p, '@')))
1093             {
1094               uri->auth = p;
1095               *p3++ = '\0';
1096               p = p3;
1097             }
1098
1099           for (pp=p; *pp; pp++)
1100             *pp = tolower (*(unsigned char*)pp);
1101
1102           /* Handle an IPv6 literal */
1103           if( *p == '[' && (p3=strchr( p, ']' )) )
1104             {
1105               *p3++ = '\0';
1106               /* worst case, uri->host should have length 0, points to \0 */
1107               uri->host = p + 1;
1108               uri->v6lit = 1;
1109               p = p3;
1110             }
1111           else
1112             uri->host = p;
1113
1114           if ((p3 = strchr (p, ':')))
1115             {
1116               *p3++ = '\0';
1117               uri->port = atoi (p3);
1118             }
1119
1120           if ((n = remove_escapes (uri->host)) < 0)
1121             return GPG_ERR_BAD_URI;
1122           if (n != strlen (uri->host))
1123             return GPG_ERR_BAD_URI;     /* Hostname incudes a Nul. */
1124           p = p2 ? p2 : NULL;
1125         }
1126       else if (uri->is_http)
1127         return GPG_ERR_INV_URI; /* No Leading double slash for HTTP.  */
1128       else
1129         {
1130           uri->opaque = 1;
1131           uri->path = p;
1132           return 0;
1133         }
1134
1135     } /* End global URI part. */
1136
1137   /* Parse the pathname part */
1138   if (!p || !*p)
1139     return 0;  /* We don't have a path.  Okay. */
1140
1141   /* TODO: Here we have to check params. */
1142
1143   /* Do we have a query part? */
1144   if ((p2 = strchr (p, '?')))
1145     *p2++ = 0;
1146
1147   uri->path = p;
1148   if ((n = remove_escapes (p)) < 0)
1149     return GPG_ERR_BAD_URI;
1150   if (n != strlen (p))
1151     return GPG_ERR_BAD_URI;     /* Path includes a Nul. */
1152   p = p2 ? p2 : NULL;
1153
1154   if (!p || !*p)
1155     return 0; /* We don't have a query string.  Okay. */
1156
1157   /* Now parse the query string. */
1158   tail = &uri->query;
1159   for (;;)
1160     {
1161       uri_tuple_t elem;
1162
1163       if ((p2 = strchr (p, '&')))
1164         *p2++ = 0;
1165       if (!(elem = parse_tuple (p)))
1166         return GPG_ERR_BAD_URI;
1167       *tail = elem;
1168       tail = &elem->next;
1169
1170       if (!p2)
1171         break; /* Ready. */
1172       p = p2;
1173     }
1174
1175   return 0;
1176 }
1177
1178
1179 /*
1180  * Remove all %xx escapes; this is done in-place.  Returns: New length
1181  * of the string.
1182  */
1183 static int
1184 remove_escapes (char *string)
1185 {
1186   int n = 0;
1187   unsigned char *p, *s;
1188
1189   for (p = s = (unsigned char*)string; *s; s++)
1190     {
1191       if (*s == '%')
1192         {
1193           if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1194             {
1195               s++;
1196               *p = *s >= '0' && *s <= '9' ? *s - '0' :
1197                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1198               *p <<= 4;
1199               s++;
1200               *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1201                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1202               p++;
1203               n++;
1204             }
1205           else
1206             {
1207               *p++ = *s++;
1208               if (*s)
1209                 *p++ = *s++;
1210               if (*s)
1211                 *p++ = *s++;
1212               if (*s)
1213                 *p = 0;
1214               return -1; /* Bad URI. */
1215             }
1216         }
1217       else
1218         {
1219           *p++ = *s;
1220           n++;
1221         }
1222     }
1223   *p = 0; /* Make sure to keep a string terminator. */
1224   return n;
1225 }
1226
1227
1228 /* If SPECIAL is NULL this function escapes in forms mode.  */
1229 static size_t
1230 escape_data (char *buffer, const void *data, size_t datalen,
1231              const char *special)
1232 {
1233   int forms = !special;
1234   const unsigned char *s;
1235   size_t n = 0;
1236
1237   if (forms)
1238     special = "%;?&=";
1239
1240   for (s = data; datalen; s++, datalen--)
1241     {
1242       if (forms && *s == ' ')
1243         {
1244           if (buffer)
1245             *buffer++ = '+';
1246           n++;
1247         }
1248       else if (forms && *s == '\n')
1249         {
1250           if (buffer)
1251             memcpy (buffer, "%0D%0A", 6);
1252           n += 6;
1253         }
1254       else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1255         {
1256           if (buffer)
1257             memcpy (buffer, "%0D%0A", 6);
1258           n += 6;
1259           s++;
1260           datalen--;
1261         }
1262       else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1263         {
1264           if (buffer)
1265             *(unsigned char*)buffer++ = *s;
1266           n++;
1267         }
1268       else
1269         {
1270           if (buffer)
1271             {
1272               snprintf (buffer, 4, "%%%02X", *s);
1273               buffer += 3;
1274             }
1275           n += 3;
1276         }
1277     }
1278   return n;
1279 }
1280
1281
1282 static int
1283 insert_escapes (char *buffer, const char *string,
1284                 const char *special)
1285 {
1286   return escape_data (buffer, string, strlen (string), special);
1287 }
1288
1289
1290 /* Allocate a new string from STRING using standard HTTP escaping as
1291    well as escaping of characters given in SPECIALS.  A common pattern
1292    for SPECIALS is "%;?&=". However it depends on the needs, for
1293    example "+" and "/: often needs to be escaped too.  Returns NULL on
1294    failure and sets ERRNO.  If SPECIAL is NULL a dedicated forms
1295    encoding mode is used. */
1296 char *
1297 http_escape_string (const char *string, const char *specials)
1298 {
1299   int n;
1300   char *buf;
1301
1302   n = insert_escapes (NULL, string, specials);
1303   buf = xtrymalloc (n+1);
1304   if (buf)
1305     {
1306       insert_escapes (buf, string, specials);
1307       buf[n] = 0;
1308     }
1309   return buf;
1310 }
1311
1312 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1313    escaping as well as escaping of characters given in SPECIALS.  A
1314    common pattern for SPECIALS is "%;?&=".  However it depends on the
1315    needs, for example "+" and "/: often needs to be escaped too.
1316    Returns NULL on failure and sets ERRNO.  If SPECIAL is NULL a
1317    dedicated forms encoding mode is used. */
1318 char *
1319 http_escape_data (const void *data, size_t datalen, const char *specials)
1320 {
1321   int n;
1322   char *buf;
1323
1324   n = escape_data (NULL, data, datalen, specials);
1325   buf = xtrymalloc (n+1);
1326   if (buf)
1327     {
1328       escape_data (buf, data, datalen, specials);
1329       buf[n] = 0;
1330     }
1331   return buf;
1332 }
1333
1334
1335 static uri_tuple_t
1336 parse_tuple (char *string)
1337 {
1338   char *p = string;
1339   char *p2;
1340   int n;
1341   uri_tuple_t tuple;
1342
1343   if ((p2 = strchr (p, '=')))
1344     *p2++ = 0;
1345   if ((n = remove_escapes (p)) < 0)
1346     return NULL; /* Bad URI. */
1347   if (n != strlen (p))
1348     return NULL; /* Name with a Nul in it. */
1349   tuple = xtrycalloc (1, sizeof *tuple);
1350   if (!tuple)
1351     return NULL; /* Out of core. */
1352   tuple->name = p;
1353   if (!p2) /* We have only the name, so we assume an empty value string. */
1354     {
1355       tuple->value = p + strlen (p);
1356       tuple->valuelen = 0;
1357       tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1358     }
1359   else /* Name and value. */
1360     {
1361       if ((n = remove_escapes (p2)) < 0)
1362         {
1363           xfree (tuple);
1364           return NULL; /* Bad URI. */
1365         }
1366       tuple->value = p2;
1367       tuple->valuelen = n;
1368     }
1369   return tuple;
1370 }
1371
1372
1373 /*
1374  * Send a HTTP request to the server
1375  * Returns 0 if the request was successful
1376  */
1377 static gpg_error_t
1378 send_request (http_t hd, const char *httphost, const char *auth,
1379               const char *proxy, const char *srvtag, strlist_t headers)
1380 {
1381   gpg_error_t err;
1382   const char *server;
1383   char *request, *p;
1384   unsigned short port;
1385   const char *http_proxy = NULL;
1386   char *proxy_authstr = NULL;
1387   char *authstr = NULL;
1388   int sock;
1389   int hnf;
1390
1391   if (hd->uri->use_tls && !hd->session)
1392     {
1393       log_error ("TLS requested but no session object provided\n");
1394       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1395     }
1396 #ifdef HTTP_USE_GNUTLS
1397   if (hd->uri->use_tls && !hd->session->tls_session)
1398     {
1399       log_error ("TLS requested but no GNUTLS context available\n");
1400       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1401     }
1402 #endif /*HTTP_USE_GNUTLS*/
1403
1404   server = *hd->uri->host ? hd->uri->host : "localhost";
1405   port = hd->uri->port ? hd->uri->port : 80;
1406
1407   /* Try to use SNI.  */
1408 #ifdef HTTP_USE_GNUTLS
1409   if (hd->uri->use_tls)
1410     {
1411       int rc;
1412
1413       xfree (hd->session->servername);
1414       hd->session->servername = xtrystrdup (httphost? httphost : server);
1415       if (!hd->session->servername)
1416         {
1417           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1418           return err;
1419         }
1420
1421       rc = gnutls_server_name_set (hd->session->tls_session,
1422                                    GNUTLS_NAME_DNS,
1423                                    server, strlen (server));
1424       if (rc < 0)
1425         log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1426     }
1427 #endif /*HTTP_USE_GNUTLS*/
1428
1429   if ( (proxy && *proxy)
1430        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1431             && (http_proxy = getenv (HTTP_PROXY_ENV))
1432             && *http_proxy ))
1433     {
1434       parsed_uri_t uri;
1435       int save_errno;
1436
1437       if (proxy)
1438         http_proxy = proxy;
1439
1440       err = parse_uri (&uri, http_proxy, 0,
1441                        !!(hd->flags & HTTP_FLAG_FORCE_TLS));
1442       if (err)
1443         {
1444           log_error ("invalid HTTP proxy (%s): %s\n",
1445                      http_proxy, gpg_strerror (err));
1446           return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1447         }
1448
1449       if (uri->auth)
1450         {
1451           remove_escapes (uri->auth);
1452           proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1453                                             "\r\n",
1454                                             uri->auth, strlen(uri->auth));
1455           if (!proxy_authstr)
1456             {
1457               err = gpg_err_make (default_errsource,
1458                                   gpg_err_code_from_syserror ());
1459               http_release_parsed_uri (uri);
1460               return err;
1461             }
1462         }
1463
1464       sock = connect_server (*uri->host ? uri->host : "localhost",
1465                              uri->port ? uri->port : 80,
1466                              hd->flags, srvtag, &hnf);
1467       save_errno = errno;
1468       http_release_parsed_uri (uri);
1469       if (sock == -1)
1470         gpg_err_set_errno (save_errno);
1471     }
1472   else
1473     {
1474       sock = connect_server (server, port, hd->flags, srvtag, &hnf);
1475     }
1476
1477   if (sock == -1)
1478     {
1479       xfree (proxy_authstr);
1480       return gpg_err_make (default_errsource,
1481                            (hnf? GPG_ERR_UNKNOWN_HOST
1482                                : gpg_err_code_from_syserror ()));
1483     }
1484   hd->sock = my_socket_new (sock);
1485   if (!hd->sock)
1486     {
1487       xfree (proxy_authstr);
1488       return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1489     }
1490
1491
1492
1493 #ifdef HTTP_USE_GNUTLS
1494   if (hd->uri->use_tls)
1495     {
1496       int rc;
1497
1498       my_socket_ref (hd->sock);
1499       gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1500 #ifdef USE_NPTH
1501       gnutls_transport_set_pull_function (hd->session->tls_session,
1502                                           my_npth_read);
1503       gnutls_transport_set_push_function (hd->session->tls_session,
1504                                           my_npth_write);
1505 #endif
1506
1507       do
1508         {
1509           rc = gnutls_handshake (hd->session->tls_session);
1510         }
1511       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1512       if (rc < 0)
1513         {
1514           log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1515           xfree (proxy_authstr);
1516           return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1517         }
1518
1519       hd->session->verify.done = 0;
1520       if (tls_callback)
1521         err = tls_callback (hd, hd->session, 0);
1522       else
1523         err = http_verify_server_credentials (hd->session);
1524       if (err)
1525         {
1526           log_info ("TLS connection authentication failed: %s\n",
1527                     gpg_strerror (err));
1528           xfree (proxy_authstr);
1529           return err;
1530         }
1531     }
1532 #endif /*HTTP_USE_GNUTLS*/
1533
1534   if (auth || hd->uri->auth)
1535     {
1536       char *myauth;
1537
1538       if (auth)
1539         {
1540           myauth = xtrystrdup (auth);
1541           if (!myauth)
1542             {
1543               xfree (proxy_authstr);
1544               return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1545             }
1546           remove_escapes (myauth);
1547         }
1548       else
1549         {
1550           remove_escapes (hd->uri->auth);
1551           myauth = hd->uri->auth;
1552         }
1553
1554       authstr = make_header_line ("Authorization: Basic ", "\r\n",
1555                                   myauth, strlen (myauth));
1556       if (auth)
1557         xfree (myauth);
1558
1559       if (!authstr)
1560         {
1561           xfree (proxy_authstr);
1562           return gpg_err_make (default_errsource,
1563                                gpg_err_code_from_syserror ());
1564         }
1565     }
1566
1567   p = build_rel_path (hd->uri);
1568   if (!p)
1569     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1570
1571   if (http_proxy && *http_proxy)
1572     {
1573       request = es_bsprintf
1574         ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1575          hd->req_type == HTTP_REQ_GET ? "GET" :
1576          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1577          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1578          hd->uri->use_tls? "https" : "http",
1579          httphost? httphost : server,
1580          port, *p == '/' ? "" : "/", p,
1581          authstr ? authstr : "",
1582          proxy_authstr ? proxy_authstr : "");
1583     }
1584   else
1585     {
1586       char portstr[35];
1587
1588       if (port == 80)
1589         *portstr = 0;
1590       else
1591         snprintf (portstr, sizeof portstr, ":%u", port);
1592
1593       request = es_bsprintf
1594         ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1595          hd->req_type == HTTP_REQ_GET ? "GET" :
1596          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1597          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1598          *p == '/' ? "" : "/", p,
1599          httphost? httphost : server,
1600          portstr,
1601          authstr? authstr:"");
1602     }
1603   xfree (p);
1604   if (!request)
1605     {
1606       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1607       xfree (authstr);
1608       xfree (proxy_authstr);
1609       return err;
1610     }
1611
1612   /* log_debug ("request:\n%s\nEND request\n", request); */
1613
1614   /* First setup estream so that we can write even the first line
1615      using estream.  This is also required for the sake of gnutls. */
1616   {
1617     cookie_t cookie;
1618
1619     cookie = xtrycalloc (1, sizeof *cookie);
1620     if (!cookie)
1621       {
1622         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1623         goto leave;
1624       }
1625     cookie->sock = my_socket_ref (hd->sock);
1626     hd->write_cookie = cookie;
1627     cookie->use_tls = hd->uri->use_tls;
1628     cookie->session = http_session_ref (hd->session);
1629
1630     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1631     if (!hd->fp_write)
1632       {
1633         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1634         my_socket_unref (cookie->sock, NULL, NULL);
1635         xfree (cookie);
1636         hd->write_cookie = NULL;
1637       }
1638     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1639       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1640     else
1641       err = 0;
1642
1643   if (!err)
1644     {
1645       for (;headers; headers=headers->next)
1646         {
1647           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
1648               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
1649             {
1650               err = gpg_err_make (default_errsource,
1651                                   gpg_err_code_from_syserror ());
1652               break;
1653             }
1654         }
1655     }
1656   }
1657
1658  leave:
1659   es_free (request);
1660   xfree (authstr);
1661   xfree (proxy_authstr);
1662
1663   return err;
1664 }
1665
1666
1667 /*
1668  * Build the relative path from the parsed URI.  Minimal
1669  * implementation.  May return NULL in case of memory failure; errno
1670  * is then set accordingly.
1671  */
1672 static char *
1673 build_rel_path (parsed_uri_t uri)
1674 {
1675   uri_tuple_t r;
1676   char *rel_path, *p;
1677   int n;
1678
1679   /* Count the needed space. */
1680   n = insert_escapes (NULL, uri->path, "%;?&");
1681   /* TODO: build params. */
1682   for (r = uri->query; r; r = r->next)
1683     {
1684       n++; /* '?'/'&' */
1685       n += insert_escapes (NULL, r->name, "%;?&=");
1686       if (!r->no_value)
1687         {
1688           n++; /* '=' */
1689           n += insert_escapes (NULL, r->value, "%;?&=");
1690         }
1691     }
1692   n++;
1693
1694   /* Now allocate and copy. */
1695   p = rel_path = xtrymalloc (n);
1696   if (!p)
1697     return NULL;
1698   n = insert_escapes (p, uri->path, "%;?&");
1699   p += n;
1700   /* TODO: add params. */
1701   for (r = uri->query; r; r = r->next)
1702     {
1703       *p++ = r == uri->query ? '?' : '&';
1704       n = insert_escapes (p, r->name, "%;?&=");
1705       p += n;
1706       if (!r->no_value)
1707         {
1708           *p++ = '=';
1709           /* TODO: Use valuelen. */
1710           n = insert_escapes (p, r->value, "%;?&=");
1711           p += n;
1712         }
1713     }
1714   *p = 0;
1715   return rel_path;
1716 }
1717
1718
1719 /* Transform a header name into a standard capitalized format; e.g.
1720    "Content-Type".  Conversion stops at the colon.  As usual we don't
1721    use the localized versions of ctype.h. */
1722 static void
1723 capitalize_header_name (char *name)
1724 {
1725   int first = 1;
1726
1727   for (; *name && *name != ':'; name++)
1728     {
1729       if (*name == '-')
1730         first = 1;
1731       else if (first)
1732         {
1733           if (*name >= 'a' && *name <= 'z')
1734             *name = *name - 'a' + 'A';
1735           first = 0;
1736         }
1737       else if (*name >= 'A' && *name <= 'Z')
1738         *name = *name - 'A' + 'a';
1739     }
1740 }
1741
1742
1743 /* Store an HTTP header line in LINE away.  Line continuation is
1744    supported as well as merging of headers with the same name. This
1745    function may modify LINE. */
1746 static gpg_err_code_t
1747 store_header (http_t hd, char *line)
1748 {
1749   size_t n;
1750   char *p, *value;
1751   header_t h;
1752
1753   n = strlen (line);
1754   if (n && line[n-1] == '\n')
1755     {
1756       line[--n] = 0;
1757       if (n && line[n-1] == '\r')
1758         line[--n] = 0;
1759     }
1760   if (!n)  /* we are never called to hit this. */
1761     return GPG_ERR_BUG;
1762   if (*line == ' ' || *line == '\t')
1763     {
1764       /* Continuation. This won't happen too often as it is not
1765          recommended.  We use a straightforward implementaion. */
1766       if (!hd->headers)
1767         return GPG_ERR_PROTOCOL_VIOLATION;
1768       n += strlen (hd->headers->value);
1769       p = xtrymalloc (n+1);
1770       if (!p)
1771         return gpg_err_code_from_syserror ();
1772       strcpy (stpcpy (p, hd->headers->value), line);
1773       xfree (hd->headers->value);
1774       hd->headers->value = p;
1775       return 0;
1776     }
1777
1778   capitalize_header_name (line);
1779   p = strchr (line, ':');
1780   if (!p)
1781     return GPG_ERR_PROTOCOL_VIOLATION;
1782   *p++ = 0;
1783   while (*p == ' ' || *p == '\t')
1784     p++;
1785   value = p;
1786
1787   for (h=hd->headers; h; h = h->next)
1788     if ( !strcmp (h->name, line) )
1789       break;
1790   if (h)
1791     {
1792       /* We have already seen a line with that name.  Thus we assume
1793          it is a comma separated list and merge them.  */
1794       p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
1795       if (!p)
1796         return gpg_err_code_from_syserror ();
1797       strcpy (stpcpy (stpcpy (p, h->value), ","), value);
1798       xfree (h->value);
1799       h->value = p;
1800       return 0;
1801     }
1802
1803   /* Append a new header. */
1804   h = xtrymalloc (sizeof *h + strlen (line));
1805   if (!h)
1806     return gpg_err_code_from_syserror ();
1807   strcpy (h->name, line);
1808   h->value = xtrymalloc (strlen (value)+1);
1809   if (!h->value)
1810     {
1811       xfree (h);
1812       return gpg_err_code_from_syserror ();
1813     }
1814   strcpy (h->value, value);
1815   h->next = hd->headers;
1816   hd->headers = h;
1817
1818   return 0;
1819 }
1820
1821
1822 /* Return the header NAME from the last response.  The returned value
1823    is valid as along as HD has not been closed and no other request
1824    has been send. If the header was not found, NULL is returned.  NAME
1825    must be canonicalized, that is the first letter of each dash
1826    delimited part must be uppercase and all other letters lowercase.  */
1827 const char *
1828 http_get_header (http_t hd, const char *name)
1829 {
1830   header_t h;
1831
1832   for (h=hd->headers; h; h = h->next)
1833     if ( !strcmp (h->name, name) )
1834       return h->value;
1835   return NULL;
1836 }
1837
1838
1839 /* Return a newly allocated and NULL terminated array with pointers to
1840    header names.  The array must be released with xfree() and its
1841    content is only values as long as no other request has been
1842    send.  */
1843 const char **
1844 http_get_header_names (http_t hd)
1845 {
1846   const char **array;
1847   size_t n;
1848   header_t h;
1849
1850   for (n=0, h = hd->headers; h; h = h->next)
1851     n++;
1852   array = xtrycalloc (n+1, sizeof *array);
1853   if (array)
1854     {
1855       for (n=0, h = hd->headers; h; h = h->next)
1856         array[n++] = h->name;
1857     }
1858
1859   return array;
1860 }
1861
1862
1863 /*
1864  * Parse the response from a server.
1865  * Returns: Errorcode and sets some files in the handle
1866  */
1867 static gpg_err_code_t
1868 parse_response (http_t hd)
1869 {
1870   char *line, *p, *p2;
1871   size_t maxlen, len;
1872   cookie_t cookie = hd->read_cookie;
1873   const char *s;
1874
1875   /* Delete old header lines.  */
1876   while (hd->headers)
1877     {
1878       header_t tmp = hd->headers->next;
1879       xfree (hd->headers->value);
1880       xfree (hd->headers);
1881       hd->headers = tmp;
1882     }
1883
1884   /* Wait for the status line. */
1885   do
1886     {
1887       maxlen = MAX_LINELEN;
1888       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
1889       line = hd->buffer;
1890       if (!line)
1891         return gpg_err_code_from_syserror (); /* Out of core. */
1892       if (!maxlen)
1893         return GPG_ERR_TRUNCATED; /* Line has been truncated. */
1894       if (!len)
1895         return GPG_ERR_EOF;
1896
1897       if ((hd->flags & HTTP_FLAG_LOG_RESP))
1898         log_info ("RESP: '%.*s'\n",
1899                   (int)strlen(line)-(*line&&line[1]?2:0),line);
1900     }
1901   while (!*line);
1902
1903   if ((p = strchr (line, '/')))
1904     *p++ = 0;
1905   if (!p || strcmp (line, "HTTP"))
1906     return 0; /* Assume http 0.9. */
1907
1908   if ((p2 = strpbrk (p, " \t")))
1909     {
1910       *p2++ = 0;
1911       p2 += strspn (p2, " \t");
1912     }
1913   if (!p2)
1914     return 0; /* Also assume http 0.9. */
1915   p = p2;
1916   /* TODO: Add HTTP version number check. */
1917   if ((p2 = strpbrk (p, " \t")))
1918     *p2++ = 0;
1919   if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
1920       || !isdigit ((unsigned int)p[2]) || p[3])
1921     {
1922       /* Malformed HTTP status code - assume http 0.9. */
1923       hd->is_http_0_9 = 1;
1924       hd->status_code = 200;
1925       return 0;
1926     }
1927   hd->status_code = atoi (p);
1928
1929   /* Skip all the header lines and wait for the empty line. */
1930   do
1931     {
1932       maxlen = MAX_LINELEN;
1933       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
1934       line = hd->buffer;
1935       if (!line)
1936         return gpg_err_code_from_syserror (); /* Out of core. */
1937       /* Note, that we can silently ignore truncated lines. */
1938       if (!len)
1939         return GPG_ERR_EOF;
1940       /* Trim line endings of empty lines. */
1941       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
1942         *line = 0;
1943       if ((hd->flags & HTTP_FLAG_LOG_RESP))
1944         log_info ("RESP: '%.*s'\n",
1945                   (int)strlen(line)-(*line&&line[1]?2:0),line);
1946       if (*line)
1947         {
1948           gpg_err_code_t ec = store_header (hd, line);
1949           if (ec)
1950             return ec;
1951         }
1952     }
1953   while (len && *line);
1954
1955   cookie->content_length_valid = 0;
1956   if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
1957     {
1958       s = http_get_header (hd, "Content-Length");
1959       if (s)
1960         {
1961           cookie->content_length_valid = 1;
1962           cookie->content_length = counter_strtoul (s);
1963         }
1964     }
1965
1966   return 0;
1967 }
1968
1969 #if 0
1970 static int
1971 start_server ()
1972 {
1973   struct sockaddr_in mya;
1974   struct sockaddr_in peer;
1975   int fd, client;
1976   fd_set rfds;
1977   int addrlen;
1978   int i;
1979
1980   if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
1981     {
1982       log_error ("socket() failed: %s\n", strerror (errno));
1983       return -1;
1984     }
1985   i = 1;
1986   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
1987     log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
1988
1989   mya.sin_family = AF_INET;
1990   memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
1991   mya.sin_port = htons (11371);
1992
1993   if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
1994     {
1995       log_error ("bind to port 11371 failed: %s\n", strerror (errno));
1996       sock_close (fd);
1997       return -1;
1998     }
1999
2000   if (listen (fd, 5))
2001     {
2002       log_error ("listen failed: %s\n", strerror (errno));
2003       sock_close (fd);
2004       return -1;
2005     }
2006
2007   for (;;)
2008     {
2009       FD_ZERO (&rfds);
2010       FD_SET (fd, &rfds);
2011
2012       if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2013         continue;               /* ignore any errors */
2014
2015       if (!FD_ISSET (fd, &rfds))
2016         continue;
2017
2018       addrlen = sizeof peer;
2019       client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2020       if (client == -1)
2021         continue;               /* oops */
2022
2023       log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2024
2025       fflush (stdout);
2026       fflush (stderr);
2027       if (!fork ())
2028         {
2029           int c;
2030           FILE *fp;
2031
2032           fp = fdopen (client, "r");
2033           while ((c = getc (fp)) != EOF)
2034             putchar (c);
2035           fclose (fp);
2036           exit (0);
2037         }
2038       sock_close (client);
2039     }
2040
2041
2042   return 0;
2043 }
2044 #endif
2045
2046 /* Actually connect to a server.  Returns the file descriptor or -1 on
2047    error.  ERRNO is set on error. */
2048 static int
2049 connect_server (const char *server, unsigned short port,
2050                 unsigned int flags, const char *srvtag, int *r_host_not_found)
2051 {
2052   int sock = -1;
2053   int srvcount = 0;
2054   int hostfound = 0;
2055   int srv, connected;
2056   int last_errno = 0;
2057   struct srventry *serverlist = NULL;
2058 #ifdef HAVE_W32_SYSTEM
2059   unsigned long inaddr;
2060 #endif
2061
2062   *r_host_not_found = 0;
2063 #ifdef HAVE_W32_SYSTEM
2064
2065 #ifndef HTTP_NO_WSASTARTUP
2066   init_sockets ();
2067 #endif
2068   /* Win32 gethostbyname doesn't handle IP addresses internally, so we
2069      try inet_addr first on that platform only. */
2070   inaddr = inet_addr(server);
2071   if ( inaddr != INADDR_NONE )
2072     {
2073       struct sockaddr_in addr;
2074
2075       memset(&addr,0,sizeof(addr));
2076
2077       sock = socket(AF_INET,SOCK_STREAM,0);
2078       if ( sock==INVALID_SOCKET )
2079         {
2080           log_error("error creating socket: ec=%d\n",(int)WSAGetLastError());
2081           return -1;
2082         }
2083
2084       addr.sin_family = AF_INET;
2085       addr.sin_port = htons(port);
2086       memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr));
2087
2088       if (!my_connect (sock,(struct sockaddr *)&addr,sizeof(addr)) )
2089         return sock;
2090       sock_close(sock);
2091       return -1;
2092     }
2093 #endif /*HAVE_W32_SYSTEM*/
2094
2095 #ifdef USE_DNS_SRV
2096   /* Do the SRV thing */
2097   if (srvtag)
2098     {
2099       /* We're using SRV, so append the tags. */
2100       if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME)
2101         {
2102           char srvname[MAXDNAME];
2103
2104           stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
2105                            "._tcp."), server);
2106           srvcount = getsrv (srvname, &serverlist);
2107         }
2108     }
2109 #else
2110   (void)flags;
2111   (void)srvtag;
2112 #endif /*USE_DNS_SRV*/
2113
2114   if (!serverlist)
2115     {
2116       /* Either we're not using SRV, or the SRV lookup failed.  Make
2117          up a fake SRV record. */
2118       serverlist = xtrycalloc (1, sizeof *serverlist);
2119       if (!serverlist)
2120         return -1; /* Out of core.  */
2121       serverlist->port = port;
2122       strncpy (serverlist->target, server, MAXDNAME);
2123       serverlist->target[MAXDNAME-1] = '\0';
2124       srvcount = 1;
2125     }
2126
2127 #ifdef HAVE_GETADDRINFO
2128   connected = 0;
2129   for (srv=0; srv < srvcount && !connected; srv++)
2130     {
2131       struct addrinfo hints, *res, *ai;
2132       char portstr[35];
2133
2134       snprintf (portstr, sizeof portstr, "%hu", port);
2135       memset (&hints, 0, sizeof (hints));
2136       hints.ai_socktype = SOCK_STREAM;
2137       if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res))
2138         continue; /* Not found - try next one. */
2139       hostfound = 1;
2140
2141       for (ai = res; ai && !connected; ai = ai->ai_next)
2142         {
2143           if (ai->ai_family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2144             continue;
2145           if (ai->ai_family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2146             continue;
2147
2148           if (sock != -1)
2149             sock_close (sock);
2150           sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
2151           if (sock == -1)
2152             {
2153               int save_errno = errno;
2154               log_error ("error creating socket: %s\n", strerror (errno));
2155               freeaddrinfo (res);
2156               xfree (serverlist);
2157               errno = save_errno;
2158               return -1;
2159             }
2160
2161           if (my_connect (sock, ai->ai_addr, ai->ai_addrlen))
2162             last_errno = errno;
2163           else
2164             connected = 1;
2165         }
2166       freeaddrinfo (res);
2167     }
2168 #else /* !HAVE_GETADDRINFO */
2169   connected = 0;
2170   for (srv=0; srv < srvcount && !connected; srv++)
2171     {
2172       int i;
2173       struct hostent *host = NULL;
2174       struct sockaddr_in addr;
2175
2176       /* Note: This code is not thread-safe.  */
2177
2178       memset (&addr, 0, sizeof (addr));
2179       host = gethostbyname (serverlist[srv].target);
2180       if (!host)
2181         continue;
2182       hostfound = 1;
2183
2184       if (sock != -1)
2185         sock_close (sock);
2186       sock = socket (host->h_addrtype, SOCK_STREAM, 0);
2187       if (sock == -1)
2188         {
2189           log_error ("error creating socket: %s\n", strerror (errno));
2190           xfree (serverlist);
2191           return -1;
2192         }
2193
2194       addr.sin_family = host->h_addrtype;
2195       if (addr.sin_family != AF_INET)
2196         {
2197           log_error ("unknown address family for '%s'\n",
2198                      serverlist[srv].target);
2199           xfree (serverlist);
2200           return -1;
2201         }
2202       addr.sin_port = htons (serverlist[srv].port);
2203       if (host->h_length != 4)
2204         {
2205           log_error ("illegal address length for '%s'\n",
2206                      serverlist[srv].target);
2207           xfree (serverlist);
2208           return -1;
2209         }
2210
2211       /* Try all A records until one responds. */
2212       for (i = 0; host->h_addr_list[i] && !connected; i++)
2213         {
2214           memcpy (&addr.sin_addr, host->h_addr_list[i], host->h_length);
2215           if (my_connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
2216             last_errno = errno;
2217           else
2218             {
2219               connected = 1;
2220               break;
2221             }
2222         }
2223     }
2224 #endif /* !HAVE_GETADDRINFO */
2225
2226   xfree (serverlist);
2227
2228   if (!connected)
2229     {
2230 #ifdef HAVE_W32_SYSTEM
2231       log_error ("can't connect to '%s': %s%sec=%d\n",
2232                    server,
2233                    hostfound? "":"host not found",
2234                    hostfound? "":" - ", (int)WSAGetLastError());
2235 #else
2236       log_error ("can't connect to '%s': %s\n",
2237                  server,
2238                  hostfound? strerror (last_errno):"host not found");
2239 #endif
2240       if (!hostfound)
2241         *r_host_not_found = 1;
2242       if (sock != -1)
2243         sock_close (sock);
2244       gpg_err_set_errno (last_errno);
2245       return -1;
2246     }
2247   return sock;
2248 }
2249
2250
2251 static gpg_error_t
2252 write_server (int sock, const char *data, size_t length)
2253 {
2254   int nleft;
2255   int nwritten;
2256
2257   nleft = length;
2258   while (nleft > 0)
2259     {
2260 #if defined(HAVE_W32_SYSTEM) && !defined(USE_NPTH)
2261       nwritten = send (sock, data, nleft, 0);
2262       if ( nwritten == SOCKET_ERROR )
2263         {
2264           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2265           return gpg_error (GPG_ERR_NETWORK);
2266         }
2267 #else /*!HAVE_W32_SYSTEM || USE_NPTH*/
2268 # ifdef USE_NPTH
2269       nwritten = npth_write (sock, data, nleft);
2270 # else
2271       nwritten = write (sock, data, nleft);
2272 # endif
2273       if (nwritten == -1)
2274         {
2275           if (errno == EINTR)
2276             continue;
2277           if (errno == EAGAIN)
2278             {
2279               struct timeval tv;
2280
2281               tv.tv_sec = 0;
2282               tv.tv_usec = 50000;
2283               my_select (0, NULL, NULL, NULL, &tv);
2284               continue;
2285             }
2286           log_info ("network write failed: %s\n", strerror (errno));
2287           return gpg_error_from_syserror ();
2288         }
2289 #endif /*!HAVE_W32_SYSTEM || USE_NPTH*/
2290       nleft -= nwritten;
2291       data += nwritten;
2292     }
2293
2294   return 0;
2295 }
2296
2297
2298 \f
2299 /* Read handler for estream.  */
2300 static ssize_t
2301 cookie_read (void *cookie, void *buffer, size_t size)
2302 {
2303   cookie_t c = cookie;
2304   int nread;
2305
2306   if (c->content_length_valid)
2307     {
2308       if (!c->content_length)
2309         return 0; /* EOF */
2310       if (c->content_length < size)
2311         size = c->content_length;
2312     }
2313
2314 #ifdef HTTP_USE_GNUTLS
2315   if (c->use_tls && c->session && c->session->tls_session)
2316     {
2317     again:
2318       nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2319       if (nread < 0)
2320         {
2321           if (nread == GNUTLS_E_INTERRUPTED)
2322             goto again;
2323           if (nread == GNUTLS_E_AGAIN)
2324             {
2325               struct timeval tv;
2326
2327               tv.tv_sec = 0;
2328               tv.tv_usec = 50000;
2329               my_select (0, NULL, NULL, NULL, &tv);
2330               goto again;
2331             }
2332           if (nread == GNUTLS_E_REHANDSHAKE)
2333             goto again; /* A client is allowed to just ignore this request. */
2334           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2335           gpg_err_set_errno (EIO);
2336           return -1;
2337         }
2338     }
2339   else
2340 #endif /*HTTP_USE_GNUTLS*/
2341     {
2342       do
2343         {
2344 #ifdef USE_NPTH
2345           nread = npth_read (c->sock->fd, buffer, size);
2346 #elif defined(HAVE_W32_SYSTEM)
2347           /* Under Windows we need to use recv for a socket.  */
2348           nread = recv (c->sock->fd, buffer, size, 0);
2349 #else
2350           nread = read (c->sock->fd, buffer, size);
2351 #endif
2352         }
2353       while (nread == -1 && errno == EINTR);
2354     }
2355
2356   if (c->content_length_valid && nread > 0)
2357     {
2358       if (nread < c->content_length)
2359         c->content_length -= nread;
2360       else
2361         c->content_length = 0;
2362     }
2363
2364   return nread;
2365 }
2366
2367 /* Write handler for estream.  */
2368 static ssize_t
2369 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2370 {
2371   const char *buffer = buffer_arg;
2372   cookie_t c = cookie;
2373   int nwritten = 0;
2374
2375 #ifdef HTTP_USE_GNUTLS
2376   if (c->use_tls && c->session && c->session->tls_session)
2377     {
2378       int nleft = size;
2379       while (nleft > 0)
2380         {
2381           nwritten = gnutls_record_send (c->session->tls_session,
2382                                          buffer, nleft);
2383           if (nwritten <= 0)
2384             {
2385               if (nwritten == GNUTLS_E_INTERRUPTED)
2386                 continue;
2387               if (nwritten == GNUTLS_E_AGAIN)
2388                 {
2389                   struct timeval tv;
2390
2391                   tv.tv_sec = 0;
2392                   tv.tv_usec = 50000;
2393                   my_select (0, NULL, NULL, NULL, &tv);
2394                   continue;
2395                 }
2396               log_info ("TLS network write failed: %s\n",
2397                         gnutls_strerror (nwritten));
2398               gpg_err_set_errno (EIO);
2399               return -1;
2400             }
2401           nleft -= nwritten;
2402           buffer += nwritten;
2403         }
2404     }
2405   else
2406 #endif /*HTTP_USE_GNUTLS*/
2407     {
2408       if ( write_server (c->sock->fd, buffer, size) )
2409         {
2410           gpg_err_set_errno (EIO);
2411           nwritten = -1;
2412         }
2413       else
2414         nwritten = size;
2415     }
2416
2417   return nwritten;
2418 }
2419
2420
2421 #ifdef HTTP_USE_GNUTLS
2422 /* Wrapper for gnutls_bye used by my_socket_unref.  */
2423 static void
2424 send_gnutls_bye (void *opaque)
2425 {
2426   gnutls_session_t tls_session = opaque;
2427   int ret;
2428
2429  again:
2430   do
2431     ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2432   while (ret == GNUTLS_E_INTERRUPTED);
2433   if (ret == GNUTLS_E_AGAIN)
2434     {
2435       struct timeval tv;
2436
2437       tv.tv_sec = 0;
2438       tv.tv_usec = 50000;
2439       my_select (0, NULL, NULL, NULL, &tv);
2440       goto again;
2441     }
2442 }
2443 #endif /*HTTP_USE_GNUTLS*/
2444
2445 /* Close handler for estream.  */
2446 static int
2447 cookie_close (void *cookie)
2448 {
2449   cookie_t c = cookie;
2450
2451   if (!c)
2452     return 0;
2453
2454 #ifdef HTTP_USE_GNUTLS
2455   if (c->use_tls && c->session && c->session->tls_session)
2456     my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2457   else
2458 #endif /*HTTP_USE_GNUTLS*/
2459     if (c->sock)
2460       my_socket_unref (c->sock, NULL, NULL);
2461
2462   if (c->session)
2463     http_session_unref (c->session);
2464   xfree (c);
2465   return 0;
2466 }
2467
2468
2469
2470 \f
2471 /* Verify the credentials of the server.  Returns 0 on success and
2472    store the result in the session object.  */
2473 gpg_error_t
2474 http_verify_server_credentials (http_session_t sess)
2475 {
2476 #ifdef HTTP_USE_GNUTLS
2477   static const char const errprefix[] = "TLS verification of peer failed";
2478   int rc;
2479   unsigned int status;
2480   const char *hostname;
2481   const gnutls_datum_t *certlist;
2482   unsigned int certlistlen;
2483   gnutls_x509_crt_t cert;
2484   gpg_error_t err = 0;
2485
2486   sess->verify.done = 1;
2487   sess->verify.status = 0;
2488   sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2489
2490   if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2491     {
2492       log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2493       sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2494       return gpg_error (GPG_ERR_GENERAL);
2495     }
2496
2497   rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2498   if (rc)
2499     {
2500       log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2501       if (!err)
2502         err = gpg_error (GPG_ERR_GENERAL);
2503     }
2504   else if (status)
2505     {
2506       log_error ("%s: status=0x%04x\n", errprefix, status);
2507 #if GNUTLS_VERSION_NUMBER >= 0x030104
2508       {
2509         gnutls_datum_t statusdat;
2510
2511         if (!gnutls_certificate_verification_status_print
2512             (status, GNUTLS_CRT_X509, &statusdat, 0))
2513           {
2514             log_info ("%s: %s\n", errprefix, statusdat.data);
2515             gnutls_free (statusdat.data);
2516           }
2517       }
2518 #endif /*gnutls >= 3.1.4*/
2519
2520       sess->verify.status = status;
2521       if (!err)
2522         err = gpg_error (GPG_ERR_GENERAL);
2523     }
2524
2525   hostname = sess->servername;
2526   if (!hostname || !strchr (hostname, '.'))
2527     {
2528       log_error ("%s: %s\n", errprefix, "hostname missing");
2529       if (!err)
2530         err = gpg_error (GPG_ERR_GENERAL);
2531     }
2532
2533   certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2534   if (!certlistlen)
2535     {
2536       log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2537       if (!err)
2538         err = gpg_error (GPG_ERR_GENERAL);
2539
2540       /* Need to stop here.  */
2541       if (err)
2542         return err;
2543     }
2544
2545   rc = gnutls_x509_crt_init (&cert);
2546   if (rc < 0)
2547     {
2548       if (!err)
2549         err = gpg_error (GPG_ERR_GENERAL);
2550       if (err)
2551         return err;
2552     }
2553
2554   rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2555   if (rc < 0)
2556     {
2557       log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
2558                  gnutls_strerror (rc));
2559       if (!err)
2560         err = gpg_error (GPG_ERR_GENERAL);
2561     }
2562
2563   if (!gnutls_x509_crt_check_hostname (cert, hostname))
2564     {
2565       log_error ("%s: %s\n", errprefix, "hostname does not match");
2566       if (!err)
2567         err = gpg_error (GPG_ERR_GENERAL);
2568     }
2569
2570   gnutls_x509_crt_deinit (cert);
2571
2572   if (!err)
2573     sess->verify.rc = 0;
2574
2575   if (sess->cert_log_cb)
2576     {
2577       const void *bufarr[10];
2578       size_t buflenarr[10];
2579       size_t n;
2580
2581       for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
2582         {
2583           bufarr[n] = certlist[n].data;
2584           buflenarr[n] = certlist[n].size;
2585         }
2586       bufarr[n] = NULL;
2587       buflenarr[n] = 0;
2588       sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
2589     }
2590
2591   return err;
2592 #else /*!HTTP_USE_GNUTLS*/
2593   (void)sess;
2594   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2595 #endif
2596 }