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