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