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