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