Explain the "server is older than xxx warning".
[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       /* Non-blocking connects do not work with our Tor proxy because
959        * we can't continue the Socks protocol after the EINPROGRESS.
960        * Disable the timeout to use a blocking connect.  */
961       timeout = 0;
962     }
963
964   /* Create the handle. */
965   hd = xtrycalloc (1, sizeof *hd);
966   if (!hd)
967     return gpg_error_from_syserror ();
968   hd->magic = HTTP_CONTEXT_MAGIC;
969   hd->req_type = HTTP_REQ_OPAQUE;
970   hd->flags = flags;
971
972   /* Connect.  */
973   {
974     assuan_fd_t sock;
975
976     err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
977     if (err)
978       {
979         xfree (hd);
980         return err;
981       }
982     hd->sock = my_socket_new (sock);
983     if (!hd->sock)
984       {
985         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
986         xfree (hd);
987         return err;
988       }
989   }
990
991   /* Setup estreams for reading and writing.  */
992   cookie = xtrycalloc (1, sizeof *cookie);
993   if (!cookie)
994     {
995       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
996       goto leave;
997     }
998   cookie->sock = my_socket_ref (hd->sock);
999   hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1000   if (!hd->fp_write)
1001     {
1002       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1003       my_socket_unref (cookie->sock, NULL, NULL);
1004       xfree (cookie);
1005       goto leave;
1006     }
1007   hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE.  */
1008
1009   cookie = xtrycalloc (1, sizeof *cookie);
1010   if (!cookie)
1011     {
1012       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1013       goto leave;
1014     }
1015   cookie->sock = my_socket_ref (hd->sock);
1016   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1017   if (!hd->fp_read)
1018     {
1019       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1020       my_socket_unref (cookie->sock, NULL, NULL);
1021       xfree (cookie);
1022       goto leave;
1023     }
1024   hd->read_cookie = cookie; /* Cookie now owned by FP_READ.  */
1025
1026   /* Register close notification to interlock the use of es_fclose in
1027      http_close and in user code.  */
1028   err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1029   if (!err)
1030     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1031
1032  leave:
1033   if (err)
1034     {
1035       if (hd->fp_read)
1036         es_fclose (hd->fp_read);
1037       if (hd->fp_write)
1038         es_fclose (hd->fp_write);
1039       my_socket_unref (hd->sock, NULL, NULL);
1040       xfree (hd);
1041     }
1042   else
1043     *r_hd = hd;
1044   return err;
1045 }
1046
1047
1048
1049
1050 void
1051 http_start_data (http_t hd)
1052 {
1053   if (!hd->in_data)
1054     {
1055       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1056         log_debug_with_string ("\r\n", "http.c:request-header:");
1057       es_fputs ("\r\n", hd->fp_write);
1058       es_fflush (hd->fp_write);
1059       hd->in_data = 1;
1060     }
1061   else
1062     es_fflush (hd->fp_write);
1063 }
1064
1065
1066 gpg_error_t
1067 http_wait_response (http_t hd)
1068 {
1069   gpg_error_t err;
1070   cookie_t cookie;
1071   int use_tls;
1072
1073   /* Make sure that we are in the data. */
1074   http_start_data (hd);
1075
1076   /* Close the write stream.  Note that the reference counted socket
1077      object keeps the actual system socket open.  */
1078   cookie = hd->write_cookie;
1079   if (!cookie)
1080     return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1081
1082   use_tls = cookie->use_tls;
1083   es_fclose (hd->fp_write);
1084   hd->fp_write = NULL;
1085   /* The close has released the cookie and thus we better set it to NULL.  */
1086   hd->write_cookie = NULL;
1087
1088   /* Shutdown one end of the socket is desired.  As per HTTP/1.0 this
1089      is not required but some very old servers (e.g. the original pksd
1090      keyserver didn't worked without it.  */
1091   if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1092     shutdown (FD2INT (hd->sock->fd), 1);
1093   hd->in_data = 0;
1094
1095   /* Create a new cookie and a stream for reading.  */
1096   cookie = xtrycalloc (1, sizeof *cookie);
1097   if (!cookie)
1098     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1099   cookie->sock = my_socket_ref (hd->sock);
1100   cookie->session = http_session_ref (hd->session);
1101   cookie->use_tls = use_tls;
1102
1103   hd->read_cookie = cookie;
1104   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1105   if (!hd->fp_read)
1106     {
1107       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1108       my_socket_unref (cookie->sock, NULL, NULL);
1109       http_session_unref (cookie->session);
1110       xfree (cookie);
1111       hd->read_cookie = NULL;
1112       return err;
1113     }
1114
1115   err = parse_response (hd);
1116
1117   if (!err)
1118     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1119
1120   return err;
1121 }
1122
1123
1124 /* Convenience function to send a request and wait for the response.
1125    Closes the handle on error.  If PROXY is not NULL, this value will
1126    be used as an HTTP proxy and any enabled $http_proxy gets
1127    ignored. */
1128 gpg_error_t
1129 http_open_document (http_t *r_hd, const char *document,
1130                     const char *auth, unsigned int flags, const char *proxy,
1131                     http_session_t session,
1132                     const char *srvtag, strlist_t headers)
1133 {
1134   gpg_error_t err;
1135
1136   err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1137                    proxy, session, srvtag, headers);
1138   if (err)
1139     return err;
1140
1141   err = http_wait_response (*r_hd);
1142   if (err)
1143     http_close (*r_hd, 0);
1144
1145   return err;
1146 }
1147
1148
1149 void
1150 http_close (http_t hd, int keep_read_stream)
1151 {
1152   if (!hd)
1153     return;
1154
1155   log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
1156
1157   /* First remove the close notifications for the streams.  */
1158   if (hd->fp_read)
1159     es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1160   if (hd->fp_write)
1161     es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1162
1163   /* Now we can close the streams.  */
1164   my_socket_unref (hd->sock, NULL, NULL);
1165   if (hd->fp_read && !keep_read_stream)
1166     es_fclose (hd->fp_read);
1167   if (hd->fp_write)
1168     es_fclose (hd->fp_write);
1169   http_session_unref (hd->session);
1170   hd->magic = 0xdeadbeef;
1171   http_release_parsed_uri (hd->uri);
1172   while (hd->headers)
1173     {
1174       header_t tmp = hd->headers->next;
1175       xfree (hd->headers->value);
1176       xfree (hd->headers);
1177       hd->headers = tmp;
1178     }
1179   xfree (hd->buffer);
1180   xfree (hd);
1181 }
1182
1183
1184 estream_t
1185 http_get_read_ptr (http_t hd)
1186 {
1187   return hd?hd->fp_read:NULL;
1188 }
1189
1190 estream_t
1191 http_get_write_ptr (http_t hd)
1192 {
1193   return hd?hd->fp_write:NULL;
1194 }
1195
1196 unsigned int
1197 http_get_status_code (http_t hd)
1198 {
1199   return hd?hd->status_code:0;
1200 }
1201
1202 /* Return information pertaining to TLS.  If TLS is not in use for HD,
1203    NULL is returned.  WHAT is used ask for specific information:
1204
1205      (NULL) := Only check whether TLS is in use.  Returns an
1206                unspecified string if TLS is in use.  That string may
1207                even be the empty string.
1208  */
1209 const char *
1210 http_get_tls_info (http_t hd, const char *what)
1211 {
1212   (void)what;
1213
1214   if (!hd)
1215     return NULL;
1216
1217   return hd->uri->use_tls? "":NULL;
1218 }
1219
1220
1221 \f
1222 static gpg_error_t
1223 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1224            int no_scheme_check, int force_tls)
1225 {
1226   gpg_err_code_t ec;
1227
1228   *ret_uri = xtrycalloc (1, sizeof **ret_uri + 2 * strlen (uri) + 1);
1229   if (!*ret_uri)
1230     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1231   strcpy ((*ret_uri)->buffer, uri);
1232   strcpy ((*ret_uri)->buffer + strlen (uri) + 1, uri);
1233   (*ret_uri)->original = (*ret_uri)->buffer + strlen (uri) + 1;
1234   ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1235   if (ec)
1236     {
1237       http_release_parsed_uri (*ret_uri);
1238       *ret_uri = NULL;
1239     }
1240   return gpg_err_make (default_errsource, ec);
1241 }
1242
1243
1244 /*
1245  * Parse an URI and put the result into the newly allocated RET_URI.
1246  * On success the caller must use http_release_parsed_uri() to
1247  * releases the resources.  If NO_SCHEME_CHECK is set, the function
1248  * tries to parse the URL in the same way it would do for an HTTP
1249  * style URI.
1250  */
1251 gpg_error_t
1252 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1253                 int no_scheme_check)
1254 {
1255   return parse_uri (ret_uri, uri, no_scheme_check, 0);
1256 }
1257
1258
1259 void
1260 http_release_parsed_uri (parsed_uri_t uri)
1261 {
1262   if (uri)
1263     {
1264       uri_tuple_t r, r2;
1265
1266       for (r = uri->params; r; r = r2)
1267         {
1268           r2 = r->next;
1269           xfree (r);
1270         }
1271       for (r = uri->query; r; r = r2)
1272         {
1273           r2 = r->next;
1274           xfree (r);
1275         }
1276       xfree (uri);
1277     }
1278 }
1279
1280
1281 static gpg_err_code_t
1282 do_parse_uri (parsed_uri_t uri, int only_local_part,
1283               int no_scheme_check, int force_tls)
1284 {
1285   uri_tuple_t *tail;
1286   char *p, *p2, *p3, *pp;
1287   int n;
1288
1289   p = uri->buffer;
1290   n = strlen (uri->buffer);
1291
1292   /* Initialize all fields to an empty string or an empty list. */
1293   uri->scheme = uri->host = uri->path = p + n;
1294   uri->port = 0;
1295   uri->params = uri->query = NULL;
1296   uri->use_tls = 0;
1297   uri->is_http = 0;
1298   uri->opaque = 0;
1299   uri->v6lit = 0;
1300   uri->onion = 0;
1301   uri->explicit_port = 0;
1302
1303   /* A quick validity check. */
1304   if (strspn (p, VALID_URI_CHARS) != n)
1305     return GPG_ERR_BAD_URI;     /* Invalid characters found. */
1306
1307   if (!only_local_part)
1308     {
1309       /* Find the scheme. */
1310       if (!(p2 = strchr (p, ':')) || p2 == p)
1311         return GPG_ERR_BAD_URI; /* No scheme. */
1312       *p2++ = 0;
1313       for (pp=p; *pp; pp++)
1314        *pp = tolower (*(unsigned char*)pp);
1315       uri->scheme = p;
1316       if (!strcmp (uri->scheme, "http") && !force_tls)
1317         {
1318           uri->port = 80;
1319           uri->is_http = 1;
1320         }
1321       else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1322         {
1323           uri->port = 11371;
1324           uri->is_http = 1;
1325         }
1326 #ifdef USE_TLS
1327       else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1328                || (force_tls && (!strcmp (uri->scheme, "http")
1329                                  || !strcmp (uri->scheme,"hkp"))))
1330         {
1331           uri->port = 443;
1332           uri->is_http = 1;
1333           uri->use_tls = 1;
1334         }
1335 #endif /*USE_TLS*/
1336       else if (!no_scheme_check)
1337         return GPG_ERR_INV_URI; /* Unsupported scheme */
1338
1339       p = p2;
1340
1341       if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1342         {
1343           p += 2;
1344           if ((p2 = strchr (p, '/')))
1345             *p2++ = 0;
1346
1347           /* Check for username/password encoding */
1348           if ((p3 = strchr (p, '@')))
1349             {
1350               uri->auth = p;
1351               *p3++ = '\0';
1352               p = p3;
1353             }
1354
1355           for (pp=p; *pp; pp++)
1356             *pp = tolower (*(unsigned char*)pp);
1357
1358           /* Handle an IPv6 literal */
1359           if( *p == '[' && (p3=strchr( p, ']' )) )
1360             {
1361               *p3++ = '\0';
1362               /* worst case, uri->host should have length 0, points to \0 */
1363               uri->host = p + 1;
1364               uri->v6lit = 1;
1365               p = p3;
1366             }
1367           else
1368             uri->host = p;
1369
1370           if ((p3 = strchr (p, ':')))
1371             {
1372               *p3++ = '\0';
1373               uri->port = atoi (p3);
1374               uri->explicit_port = 1;
1375             }
1376
1377           if ((n = remove_escapes (uri->host)) < 0)
1378             return GPG_ERR_BAD_URI;
1379           if (n != strlen (uri->host))
1380             return GPG_ERR_BAD_URI;     /* Hostname includes a Nul. */
1381           p = p2 ? p2 : NULL;
1382         }
1383       else if (uri->is_http)
1384         return GPG_ERR_INV_URI; /* No Leading double slash for HTTP.  */
1385       else
1386         {
1387           uri->opaque = 1;
1388           uri->path = p;
1389           if (is_onion_address (uri->path))
1390             uri->onion = 1;
1391           return 0;
1392         }
1393
1394     } /* End global URI part. */
1395
1396   /* Parse the pathname part if any.  */
1397   if (p && *p)
1398     {
1399       /* TODO: Here we have to check params. */
1400
1401       /* Do we have a query part? */
1402       if ((p2 = strchr (p, '?')))
1403         *p2++ = 0;
1404
1405       uri->path = p;
1406       if ((n = remove_escapes (p)) < 0)
1407         return GPG_ERR_BAD_URI;
1408       if (n != strlen (p))
1409         return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1410       p = p2 ? p2 : NULL;
1411
1412       /* Parse a query string if any.  */
1413       if (p && *p)
1414         {
1415           tail = &uri->query;
1416           for (;;)
1417             {
1418               uri_tuple_t elem;
1419
1420               if ((p2 = strchr (p, '&')))
1421                 *p2++ = 0;
1422               if (!(elem = parse_tuple (p)))
1423                 return GPG_ERR_BAD_URI;
1424               *tail = elem;
1425               tail = &elem->next;
1426
1427               if (!p2)
1428                 break; /* Ready. */
1429               p = p2;
1430             }
1431         }
1432     }
1433
1434   if (is_onion_address (uri->host))
1435     uri->onion = 1;
1436
1437   return 0;
1438 }
1439
1440
1441 /*
1442  * Remove all %xx escapes; this is done in-place.  Returns: New length
1443  * of the string.
1444  */
1445 static int
1446 remove_escapes (char *string)
1447 {
1448   int n = 0;
1449   unsigned char *p, *s;
1450
1451   for (p = s = (unsigned char*)string; *s; s++)
1452     {
1453       if (*s == '%')
1454         {
1455           if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1456             {
1457               s++;
1458               *p = *s >= '0' && *s <= '9' ? *s - '0' :
1459                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1460               *p <<= 4;
1461               s++;
1462               *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1463                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1464               p++;
1465               n++;
1466             }
1467           else
1468             {
1469               *p++ = *s++;
1470               if (*s)
1471                 *p++ = *s++;
1472               if (*s)
1473                 *p++ = *s++;
1474               if (*s)
1475                 *p = 0;
1476               return -1; /* Bad URI. */
1477             }
1478         }
1479       else
1480         {
1481           *p++ = *s;
1482           n++;
1483         }
1484     }
1485   *p = 0; /* Make sure to keep a string terminator. */
1486   return n;
1487 }
1488
1489
1490 /* If SPECIAL is NULL this function escapes in forms mode.  */
1491 static size_t
1492 escape_data (char *buffer, const void *data, size_t datalen,
1493              const char *special)
1494 {
1495   int forms = !special;
1496   const unsigned char *s;
1497   size_t n = 0;
1498
1499   if (forms)
1500     special = "%;?&=";
1501
1502   for (s = data; datalen; s++, datalen--)
1503     {
1504       if (forms && *s == ' ')
1505         {
1506           if (buffer)
1507             *buffer++ = '+';
1508           n++;
1509         }
1510       else if (forms && *s == '\n')
1511         {
1512           if (buffer)
1513             memcpy (buffer, "%0D%0A", 6);
1514           n += 6;
1515         }
1516       else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1517         {
1518           if (buffer)
1519             memcpy (buffer, "%0D%0A", 6);
1520           n += 6;
1521           s++;
1522           datalen--;
1523         }
1524       else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1525         {
1526           if (buffer)
1527             *(unsigned char*)buffer++ = *s;
1528           n++;
1529         }
1530       else
1531         {
1532           if (buffer)
1533             {
1534               snprintf (buffer, 4, "%%%02X", *s);
1535               buffer += 3;
1536             }
1537           n += 3;
1538         }
1539     }
1540   return n;
1541 }
1542
1543
1544 static int
1545 insert_escapes (char *buffer, const char *string,
1546                 const char *special)
1547 {
1548   return escape_data (buffer, string, strlen (string), special);
1549 }
1550
1551
1552 /* Allocate a new string from STRING using standard HTTP escaping as
1553    well as escaping of characters given in SPECIALS.  A common pattern
1554    for SPECIALS is "%;?&=". However it depends on the needs, for
1555    example "+" and "/: often needs to be escaped too.  Returns NULL on
1556    failure and sets ERRNO.  If SPECIAL is NULL a dedicated forms
1557    encoding mode is used. */
1558 char *
1559 http_escape_string (const char *string, const char *specials)
1560 {
1561   int n;
1562   char *buf;
1563
1564   n = insert_escapes (NULL, string, specials);
1565   buf = xtrymalloc (n+1);
1566   if (buf)
1567     {
1568       insert_escapes (buf, string, specials);
1569       buf[n] = 0;
1570     }
1571   return buf;
1572 }
1573
1574 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1575    escaping as well as escaping of characters given in SPECIALS.  A
1576    common pattern for SPECIALS is "%;?&=".  However it depends on the
1577    needs, for example "+" and "/: often needs to be escaped too.
1578    Returns NULL on failure and sets ERRNO.  If SPECIAL is NULL a
1579    dedicated forms encoding mode is used. */
1580 char *
1581 http_escape_data (const void *data, size_t datalen, const char *specials)
1582 {
1583   int n;
1584   char *buf;
1585
1586   n = escape_data (NULL, data, datalen, specials);
1587   buf = xtrymalloc (n+1);
1588   if (buf)
1589     {
1590       escape_data (buf, data, datalen, specials);
1591       buf[n] = 0;
1592     }
1593   return buf;
1594 }
1595
1596
1597 static uri_tuple_t
1598 parse_tuple (char *string)
1599 {
1600   char *p = string;
1601   char *p2;
1602   int n;
1603   uri_tuple_t tuple;
1604
1605   if ((p2 = strchr (p, '=')))
1606     *p2++ = 0;
1607   if ((n = remove_escapes (p)) < 0)
1608     return NULL; /* Bad URI. */
1609   if (n != strlen (p))
1610     return NULL; /* Name with a Nul in it. */
1611   tuple = xtrycalloc (1, sizeof *tuple);
1612   if (!tuple)
1613     return NULL; /* Out of core. */
1614   tuple->name = p;
1615   if (!p2) /* We have only the name, so we assume an empty value string. */
1616     {
1617       tuple->value = p + strlen (p);
1618       tuple->valuelen = 0;
1619       tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1620     }
1621   else /* Name and value. */
1622     {
1623       if ((n = remove_escapes (p2)) < 0)
1624         {
1625           xfree (tuple);
1626           return NULL; /* Bad URI. */
1627         }
1628       tuple->value = p2;
1629       tuple->valuelen = n;
1630     }
1631   return tuple;
1632 }
1633
1634
1635 /* Return true if STRING is likely "hostname:port" or only "hostname".  */
1636 static int
1637 is_hostname_port (const char *string)
1638 {
1639   int colons = 0;
1640
1641   if (!string || !*string)
1642     return 0;
1643   for (; *string; string++)
1644     {
1645       if (*string == ':')
1646         {
1647           if (colons)
1648             return 0;
1649           if (!string[1])
1650             return 0;
1651           colons++;
1652         }
1653       else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1654         return 0; /* Invalid characters in hostname. */
1655       else if (colons && !digitp (string))
1656         return 0; /* Not a digit in the port.  */
1657     }
1658   return 1;
1659 }
1660
1661
1662 /*
1663  * Send a HTTP request to the server
1664  * Returns 0 if the request was successful
1665  */
1666 static gpg_error_t
1667 send_request (http_t hd, const char *httphost, const char *auth,
1668               const char *proxy, const char *srvtag, unsigned int timeout,
1669               strlist_t headers)
1670 {
1671   gpg_error_t err;
1672   const char *server;
1673   char *request, *p;
1674   unsigned short port;
1675   const char *http_proxy = NULL;
1676   char *proxy_authstr = NULL;
1677   char *authstr = NULL;
1678   assuan_fd_t sock;
1679 #ifdef USE_TLS
1680   int have_http_proxy = 0;
1681 #endif
1682
1683   if (hd->uri->use_tls && !hd->session)
1684     {
1685       log_error ("TLS requested but no session object provided\n");
1686       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1687     }
1688 #ifdef USE_TLS
1689   if (hd->uri->use_tls && !hd->session->tls_session)
1690     {
1691       log_error ("TLS requested but no GNUTLS context available\n");
1692       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1693     }
1694 #endif /*USE_TLS*/
1695
1696   if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1697     {
1698       int mode;
1699
1700       if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1701         {
1702           log_error ("Tor support is not available\n");
1703           return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1704         }
1705       /* Non-blocking connects do not work with our Tor proxy because
1706        * we can't continue the Socks protocol after the EINPROGRESS.
1707        * Disable the timeout to use a blocking connect.  */
1708       timeout = 0;
1709     }
1710
1711   server = *hd->uri->host ? hd->uri->host : "localhost";
1712   port = hd->uri->port ? hd->uri->port : 80;
1713
1714   /* Try to use SNI.  */
1715 #ifdef USE_TLS
1716   if (hd->uri->use_tls)
1717     {
1718 # if HTTP_USE_GNUTLS
1719       int rc;
1720 # endif
1721
1722       xfree (hd->session->servername);
1723       hd->session->servername = xtrystrdup (httphost? httphost : server);
1724       if (!hd->session->servername)
1725         {
1726           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1727           return err;
1728         }
1729
1730 # if HTTP_USE_NTBTLS
1731       err = ntbtls_set_hostname (hd->session->tls_session,
1732                                  hd->session->servername);
1733       if (err)
1734         {
1735           log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1736           return err;
1737         }
1738 # elif HTTP_USE_GNUTLS
1739       rc = gnutls_server_name_set (hd->session->tls_session,
1740                                    GNUTLS_NAME_DNS,
1741                                    hd->session->servername,
1742                                    strlen (hd->session->servername));
1743       if (rc < 0)
1744         log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1745 # endif /*HTTP_USE_GNUTLS*/
1746     }
1747 #endif /*USE_TLS*/
1748
1749   if ( (proxy && *proxy)
1750        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1751             && (http_proxy = getenv (HTTP_PROXY_ENV))
1752             && *http_proxy ))
1753     {
1754       parsed_uri_t uri;
1755
1756       if (proxy)
1757         http_proxy = proxy;
1758
1759       err = parse_uri (&uri, http_proxy, 0, 0);
1760       if (gpg_err_code (err) == GPG_ERR_INV_URI
1761           && is_hostname_port (http_proxy))
1762         {
1763           /* Retry assuming a "hostname:port" string.  */
1764           char *tmpname = strconcat ("http://", http_proxy, NULL);
1765           if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1766             err = 0;
1767           xfree (tmpname);
1768         }
1769
1770       if (err)
1771         ;
1772 #ifdef USE_TLS
1773       else if (!strcmp (uri->scheme, "http"))
1774         have_http_proxy = 1;
1775 #endif
1776       else if (!strcmp (uri->scheme, "socks4")
1777                || !strcmp (uri->scheme, "socks5h"))
1778         err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1779       else
1780         err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1781
1782       if (err)
1783         {
1784           log_error ("invalid HTTP proxy (%s): %s\n",
1785                      http_proxy, gpg_strerror (err));
1786           return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1787         }
1788
1789       if (uri->auth)
1790         {
1791           remove_escapes (uri->auth);
1792           proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1793                                             "\r\n",
1794                                             uri->auth, strlen(uri->auth));
1795           if (!proxy_authstr)
1796             {
1797               err = gpg_err_make (default_errsource,
1798                                   gpg_err_code_from_syserror ());
1799               http_release_parsed_uri (uri);
1800               return err;
1801             }
1802         }
1803
1804       err = connect_server (*uri->host ? uri->host : "localhost",
1805                             uri->port ? uri->port : 80,
1806                             hd->flags, NULL, timeout, &sock);
1807       http_release_parsed_uri (uri);
1808     }
1809   else
1810     {
1811       err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
1812     }
1813
1814   if (err)
1815     {
1816       xfree (proxy_authstr);
1817       return err;
1818     }
1819   hd->sock = my_socket_new (sock);
1820   if (!hd->sock)
1821     {
1822       xfree (proxy_authstr);
1823       return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1824     }
1825
1826 #if USE_TLS
1827   if (have_http_proxy && hd->uri->use_tls)
1828     {
1829       int saved_flags;
1830       cookie_t cookie;
1831
1832       /* Try to use the CONNECT method to proxy our TLS stream.  */
1833       request = es_bsprintf
1834         ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s",
1835          httphost ? httphost : server,
1836          port,
1837          httphost ? httphost : server,
1838          port,
1839          proxy_authstr ? proxy_authstr : "");
1840       xfree (proxy_authstr);
1841       proxy_authstr = NULL;
1842
1843       if (! request)
1844         return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1845
1846       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1847         log_debug_with_string (request, "http.c:request:");
1848
1849       cookie = xtrycalloc (1, sizeof *cookie);
1850       if (! cookie)
1851         {
1852           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1853           xfree (request);
1854           return err;
1855         }
1856       cookie->sock = my_socket_ref (hd->sock);
1857       hd->write_cookie = cookie;
1858
1859       hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1860       if (! hd->fp_write)
1861         {
1862           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1863           my_socket_unref (cookie->sock, NULL, NULL);
1864           xfree (cookie);
1865           xfree (request);
1866           hd->write_cookie = NULL;
1867           return err;
1868         }
1869       else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1870         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1871
1872       xfree (request);
1873       request = NULL;
1874
1875       /* Make sure http_wait_response doesn't close the stream.  */
1876       saved_flags = hd->flags;
1877       hd->flags &= ~HTTP_FLAG_SHUTDOWN;
1878
1879       /* Get the response.  */
1880       err = http_wait_response (hd);
1881
1882       /* Restore flags, destroy stream.  */
1883       hd->flags = saved_flags;
1884       es_fclose (hd->fp_read);
1885       hd->fp_read = NULL;
1886       hd->read_cookie = NULL;
1887
1888       /* Reset state.  */
1889       hd->in_data = 0;
1890
1891       if (err)
1892         return err;
1893
1894       if (hd->status_code != 200)
1895         {
1896           request = es_bsprintf
1897             ("CONNECT %s:%hu",
1898              httphost ? httphost : server,
1899              port);
1900
1901           log_error (_("error accessing '%s': http status %u\n"),
1902                      request ? request : "out of core",
1903                      http_get_status_code (hd));
1904
1905           xfree (request);
1906           return gpg_error (GPG_ERR_NO_DATA);
1907         }
1908
1909       /* We are done with the proxy, the code below will establish a
1910        * TLS session and talk directly to the target server.  */
1911       http_proxy = NULL;
1912     }
1913 #endif  /* USE_TLS */
1914
1915 #if HTTP_USE_NTBTLS
1916   if (hd->uri->use_tls)
1917     {
1918       estream_t in, out;
1919
1920       my_socket_ref (hd->sock);
1921
1922       /* Until we support send/recv in estream under Windows we need
1923        * to use es_fopencookie.  */
1924 #ifdef HAVE_W32_SYSTEM
1925       in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb",
1926                            simple_cookie_functions);
1927 #else
1928       in = es_fdopen_nc (hd->sock->fd, "rb");
1929 #endif
1930       if (!in)
1931         {
1932           err = gpg_error_from_syserror ();
1933           xfree (proxy_authstr);
1934           return err;
1935         }
1936
1937 #ifdef HAVE_W32_SYSTEM
1938       out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb",
1939                             simple_cookie_functions);
1940 #else
1941       out = es_fdopen_nc (hd->sock->fd, "wb");
1942 #endif
1943       if (!out)
1944         {
1945           err = gpg_error_from_syserror ();
1946           es_fclose (in);
1947           xfree (proxy_authstr);
1948           return err;
1949         }
1950
1951       err = ntbtls_set_transport (hd->session->tls_session, in, out);
1952       if (err)
1953         {
1954           log_info ("TLS set_transport failed: %s <%s>\n",
1955                     gpg_strerror (err), gpg_strsource (err));
1956           xfree (proxy_authstr);
1957           return err;
1958         }
1959
1960 #ifdef HTTP_USE_NTBTLS
1961       if (hd->session->verify_cb)
1962         {
1963           err = ntbtls_set_verify_cb (hd->session->tls_session,
1964                                       my_ntbtls_verify_cb, hd);
1965           if (err)
1966             {
1967               log_error ("ntbtls_set_verify_cb failed: %s\n",
1968                          gpg_strerror (err));
1969               xfree (proxy_authstr);
1970               return err;
1971             }
1972         }
1973 #endif /*HTTP_USE_NTBTLS*/
1974
1975       while ((err = ntbtls_handshake (hd->session->tls_session)))
1976         {
1977           switch (err)
1978             {
1979             default:
1980               log_info ("TLS handshake failed: %s <%s>\n",
1981                         gpg_strerror (err), gpg_strsource (err));
1982               xfree (proxy_authstr);
1983               return err;
1984             }
1985         }
1986
1987       hd->session->verify.done = 0;
1988
1989       /* Try the available verify callbacks until one returns success
1990        * or a real error.  Note that NTBTLS does the verification
1991        * during the handshake via   */
1992 #ifdef HTTP_USE_NTBTLS
1993       err = 0; /* Fixme check that the CB has been called.  */
1994 #else
1995       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1996 #endif
1997
1998       if (hd->session->verify_cb
1999           && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2000           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2001         err = hd->session->verify_cb (hd->session->verify_cb_value,
2002                                       hd, hd->session,
2003                                       (hd->flags | hd->session->flags),
2004                                       hd->session->tls_session);
2005
2006       if (tls_callback
2007           && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2008           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2009         err = tls_callback (hd, hd->session, 0);
2010
2011       if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2012           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2013         err = http_verify_server_credentials (hd->session);
2014
2015       if (err)
2016         {
2017           log_info ("TLS connection authentication failed: %s <%s>\n",
2018                     gpg_strerror (err), gpg_strsource (err));
2019           xfree (proxy_authstr);
2020           return err;
2021         }
2022
2023     }
2024 #elif HTTP_USE_GNUTLS
2025   if (hd->uri->use_tls)
2026     {
2027       int rc;
2028
2029       my_socket_ref (hd->sock);
2030       gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
2031       gnutls_transport_set_pull_function (hd->session->tls_session,
2032                                           my_gnutls_read);
2033       gnutls_transport_set_push_function (hd->session->tls_session,
2034                                           my_gnutls_write);
2035
2036     handshake_again:
2037       do
2038         {
2039           rc = gnutls_handshake (hd->session->tls_session);
2040         }
2041       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
2042       if (rc < 0)
2043         {
2044           if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2045               || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
2046             {
2047               gnutls_alert_description_t alertno;
2048               const char *alertstr;
2049
2050               alertno = gnutls_alert_get (hd->session->tls_session);
2051               alertstr = gnutls_alert_get_name (alertno);
2052               log_info ("TLS handshake %s: %s (alert %d)\n",
2053                         rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2054                         ? "warning" : "failed",
2055                         alertstr, (int)alertno);
2056               if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
2057                 log_info ("  (sent server name '%s')\n", server);
2058
2059               if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
2060                 goto handshake_again;
2061             }
2062           else
2063             log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
2064           xfree (proxy_authstr);
2065           return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
2066         }
2067
2068       hd->session->verify.done = 0;
2069       if (tls_callback)
2070         err = tls_callback (hd, hd->session, 0);
2071       else
2072         err = http_verify_server_credentials (hd->session);
2073       if (err)
2074         {
2075           log_info ("TLS connection authentication failed: %s\n",
2076                     gpg_strerror (err));
2077           xfree (proxy_authstr);
2078           return err;
2079         }
2080     }
2081 #endif /*HTTP_USE_GNUTLS*/
2082
2083   if (auth || hd->uri->auth)
2084     {
2085       char *myauth;
2086
2087       if (auth)
2088         {
2089           myauth = xtrystrdup (auth);
2090           if (!myauth)
2091             {
2092               xfree (proxy_authstr);
2093               return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2094             }
2095           remove_escapes (myauth);
2096         }
2097       else
2098         {
2099           remove_escapes (hd->uri->auth);
2100           myauth = hd->uri->auth;
2101         }
2102
2103       authstr = make_header_line ("Authorization: Basic ", "\r\n",
2104                                   myauth, strlen (myauth));
2105       if (auth)
2106         xfree (myauth);
2107
2108       if (!authstr)
2109         {
2110           xfree (proxy_authstr);
2111           return gpg_err_make (default_errsource,
2112                                gpg_err_code_from_syserror ());
2113         }
2114     }
2115
2116   p = build_rel_path (hd->uri);
2117   if (!p)
2118     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2119
2120   if (http_proxy && *http_proxy)
2121     {
2122       request = es_bsprintf
2123         ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
2124          hd->req_type == HTTP_REQ_GET ? "GET" :
2125          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2126          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2127          hd->uri->use_tls? "https" : "http",
2128          httphost? httphost : server,
2129          port, *p == '/' ? "" : "/", p,
2130          authstr ? authstr : "",
2131          proxy_authstr ? proxy_authstr : "");
2132     }
2133   else
2134     {
2135       char portstr[35];
2136
2137       if (port == (hd->uri->use_tls? 443 : 80))
2138         *portstr = 0;
2139       else
2140         snprintf (portstr, sizeof portstr, ":%u", port);
2141
2142       request = es_bsprintf
2143         ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
2144          hd->req_type == HTTP_REQ_GET ? "GET" :
2145          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2146          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2147          *p == '/' ? "" : "/", p,
2148          httphost? httphost : server,
2149          portstr,
2150          authstr? authstr:"");
2151     }
2152   xfree (p);
2153   if (!request)
2154     {
2155       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2156       xfree (authstr);
2157       xfree (proxy_authstr);
2158       return err;
2159     }
2160
2161   if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2162     log_debug_with_string (request, "http.c:request:");
2163
2164   /* First setup estream so that we can write even the first line
2165      using estream.  This is also required for the sake of gnutls. */
2166   {
2167     cookie_t cookie;
2168
2169     cookie = xtrycalloc (1, sizeof *cookie);
2170     if (!cookie)
2171       {
2172         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2173         goto leave;
2174       }
2175     cookie->sock = my_socket_ref (hd->sock);
2176     hd->write_cookie = cookie;
2177     cookie->use_tls = hd->uri->use_tls;
2178     cookie->session = http_session_ref (hd->session);
2179
2180     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2181     if (!hd->fp_write)
2182       {
2183         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2184         my_socket_unref (cookie->sock, NULL, NULL);
2185         xfree (cookie);
2186         hd->write_cookie = NULL;
2187       }
2188     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2189       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2190     else
2191       err = 0;
2192
2193   if (!err)
2194     {
2195       for (;headers; headers=headers->next)
2196         {
2197           if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2198             log_debug_with_string (headers->d, "http.c:request-header:");
2199           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2200               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2201             {
2202               err = gpg_err_make (default_errsource,
2203                                   gpg_err_code_from_syserror ());
2204               break;
2205             }
2206         }
2207     }
2208   }
2209
2210  leave:
2211   es_free (request);
2212   xfree (authstr);
2213   xfree (proxy_authstr);
2214
2215   return err;
2216 }
2217
2218
2219 /*
2220  * Build the relative path from the parsed URI.  Minimal
2221  * implementation.  May return NULL in case of memory failure; errno
2222  * is then set accordingly.
2223  */
2224 static char *
2225 build_rel_path (parsed_uri_t uri)
2226 {
2227   uri_tuple_t r;
2228   char *rel_path, *p;
2229   int n;
2230
2231   /* Count the needed space. */
2232   n = insert_escapes (NULL, uri->path, "%;?&");
2233   /* TODO: build params. */
2234   for (r = uri->query; r; r = r->next)
2235     {
2236       n++; /* '?'/'&' */
2237       n += insert_escapes (NULL, r->name, "%;?&=");
2238       if (!r->no_value)
2239         {
2240           n++; /* '=' */
2241           n += insert_escapes (NULL, r->value, "%;?&=");
2242         }
2243     }
2244   n++;
2245
2246   /* Now allocate and copy. */
2247   p = rel_path = xtrymalloc (n);
2248   if (!p)
2249     return NULL;
2250   n = insert_escapes (p, uri->path, "%;?&");
2251   p += n;
2252   /* TODO: add params. */
2253   for (r = uri->query; r; r = r->next)
2254     {
2255       *p++ = r == uri->query ? '?' : '&';
2256       n = insert_escapes (p, r->name, "%;?&=");
2257       p += n;
2258       if (!r->no_value)
2259         {
2260           *p++ = '=';
2261           /* TODO: Use valuelen. */
2262           n = insert_escapes (p, r->value, "%;?&=");
2263           p += n;
2264         }
2265     }
2266   *p = 0;
2267   return rel_path;
2268 }
2269
2270
2271 /* Transform a header name into a standard capitalized format; e.g.
2272    "Content-Type".  Conversion stops at the colon.  As usual we don't
2273    use the localized versions of ctype.h. */
2274 static void
2275 capitalize_header_name (char *name)
2276 {
2277   int first = 1;
2278
2279   for (; *name && *name != ':'; name++)
2280     {
2281       if (*name == '-')
2282         first = 1;
2283       else if (first)
2284         {
2285           if (*name >= 'a' && *name <= 'z')
2286             *name = *name - 'a' + 'A';
2287           first = 0;
2288         }
2289       else if (*name >= 'A' && *name <= 'Z')
2290         *name = *name - 'A' + 'a';
2291     }
2292 }
2293
2294
2295 /* Store an HTTP header line in LINE away.  Line continuation is
2296    supported as well as merging of headers with the same name. This
2297    function may modify LINE. */
2298 static gpg_err_code_t
2299 store_header (http_t hd, char *line)
2300 {
2301   size_t n;
2302   char *p, *value;
2303   header_t h;
2304
2305   n = strlen (line);
2306   if (n && line[n-1] == '\n')
2307     {
2308       line[--n] = 0;
2309       if (n && line[n-1] == '\r')
2310         line[--n] = 0;
2311     }
2312   if (!n)  /* we are never called to hit this. */
2313     return GPG_ERR_BUG;
2314   if (*line == ' ' || *line == '\t')
2315     {
2316       /* Continuation. This won't happen too often as it is not
2317          recommended.  We use a straightforward implementation. */
2318       if (!hd->headers)
2319         return GPG_ERR_PROTOCOL_VIOLATION;
2320       n += strlen (hd->headers->value);
2321       p = xtrymalloc (n+1);
2322       if (!p)
2323         return gpg_err_code_from_syserror ();
2324       strcpy (stpcpy (p, hd->headers->value), line);
2325       xfree (hd->headers->value);
2326       hd->headers->value = p;
2327       return 0;
2328     }
2329
2330   capitalize_header_name (line);
2331   p = strchr (line, ':');
2332   if (!p)
2333     return GPG_ERR_PROTOCOL_VIOLATION;
2334   *p++ = 0;
2335   while (*p == ' ' || *p == '\t')
2336     p++;
2337   value = p;
2338
2339   for (h=hd->headers; h; h = h->next)
2340     if ( !strcmp (h->name, line) )
2341       break;
2342   if (h)
2343     {
2344       /* We have already seen a line with that name.  Thus we assume
2345        * it is a comma separated list and merge them.  */
2346       p = strconcat (h->value, ",", value, NULL);
2347       if (!p)
2348         return gpg_err_code_from_syserror ();
2349       xfree (h->value);
2350       h->value = p;
2351       return 0;
2352     }
2353
2354   /* Append a new header. */
2355   h = xtrymalloc (sizeof *h + strlen (line));
2356   if (!h)
2357     return gpg_err_code_from_syserror ();
2358   strcpy (h->name, line);
2359   h->value = xtrymalloc (strlen (value)+1);
2360   if (!h->value)
2361     {
2362       xfree (h);
2363       return gpg_err_code_from_syserror ();
2364     }
2365   strcpy (h->value, value);
2366   h->next = hd->headers;
2367   hd->headers = h;
2368
2369   return 0;
2370 }
2371
2372
2373 /* Return the header NAME from the last response.  The returned value
2374    is valid as along as HD has not been closed and no other request
2375    has been send. If the header was not found, NULL is returned.  NAME
2376    must be canonicalized, that is the first letter of each dash
2377    delimited part must be uppercase and all other letters lowercase.  */
2378 const char *
2379 http_get_header (http_t hd, const char *name)
2380 {
2381   header_t h;
2382
2383   for (h=hd->headers; h; h = h->next)
2384     if ( !strcmp (h->name, name) )
2385       return h->value;
2386   return NULL;
2387 }
2388
2389
2390 /* Return a newly allocated and NULL terminated array with pointers to
2391    header names.  The array must be released with xfree() and its
2392    content is only values as long as no other request has been
2393    send.  */
2394 const char **
2395 http_get_header_names (http_t hd)
2396 {
2397   const char **array;
2398   size_t n;
2399   header_t h;
2400
2401   for (n=0, h = hd->headers; h; h = h->next)
2402     n++;
2403   array = xtrycalloc (n+1, sizeof *array);
2404   if (array)
2405     {
2406       for (n=0, h = hd->headers; h; h = h->next)
2407         array[n++] = h->name;
2408     }
2409
2410   return array;
2411 }
2412
2413
2414 /*
2415  * Parse the response from a server.
2416  * Returns: Errorcode and sets some files in the handle
2417  */
2418 static gpg_err_code_t
2419 parse_response (http_t hd)
2420 {
2421   char *line, *p, *p2;
2422   size_t maxlen, len;
2423   cookie_t cookie = hd->read_cookie;
2424   const char *s;
2425
2426   /* Delete old header lines.  */
2427   while (hd->headers)
2428     {
2429       header_t tmp = hd->headers->next;
2430       xfree (hd->headers->value);
2431       xfree (hd->headers);
2432       hd->headers = tmp;
2433     }
2434
2435   /* Wait for the status line. */
2436   do
2437     {
2438       maxlen = MAX_LINELEN;
2439       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2440       line = hd->buffer;
2441       if (!line)
2442         return gpg_err_code_from_syserror (); /* Out of core. */
2443       if (!maxlen)
2444         return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2445       if (!len)
2446         return GPG_ERR_EOF;
2447
2448       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2449         log_debug_with_string (line, "http.c:response:\n");
2450     }
2451   while (!*line);
2452
2453   if ((p = strchr (line, '/')))
2454     *p++ = 0;
2455   if (!p || strcmp (line, "HTTP"))
2456     return 0; /* Assume http 0.9. */
2457
2458   if ((p2 = strpbrk (p, " \t")))
2459     {
2460       *p2++ = 0;
2461       p2 += strspn (p2, " \t");
2462     }
2463   if (!p2)
2464     return 0; /* Also assume http 0.9. */
2465   p = p2;
2466   /* TODO: Add HTTP version number check. */
2467   if ((p2 = strpbrk (p, " \t")))
2468     *p2++ = 0;
2469   if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2470       || !isdigit ((unsigned int)p[2]) || p[3])
2471     {
2472       /* Malformed HTTP status code - assume http 0.9. */
2473       hd->is_http_0_9 = 1;
2474       hd->status_code = 200;
2475       return 0;
2476     }
2477   hd->status_code = atoi (p);
2478
2479   /* Skip all the header lines and wait for the empty line. */
2480   do
2481     {
2482       maxlen = MAX_LINELEN;
2483       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2484       line = hd->buffer;
2485       if (!line)
2486         return gpg_err_code_from_syserror (); /* Out of core. */
2487       /* Note, that we can silently ignore truncated lines. */
2488       if (!len)
2489         return GPG_ERR_EOF;
2490       /* Trim line endings of empty lines. */
2491       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2492         *line = 0;
2493       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2494         log_info ("http.c:RESP: '%.*s'\n",
2495                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2496       if (*line)
2497         {
2498           gpg_err_code_t ec = store_header (hd, line);
2499           if (ec)
2500             return ec;
2501         }
2502     }
2503   while (len && *line);
2504
2505   cookie->content_length_valid = 0;
2506   if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2507     {
2508       s = http_get_header (hd, "Content-Length");
2509       if (s)
2510         {
2511           cookie->content_length_valid = 1;
2512           cookie->content_length = string_to_u64 (s);
2513         }
2514     }
2515
2516   return 0;
2517 }
2518
2519 #if 0
2520 static int
2521 start_server ()
2522 {
2523   struct sockaddr_in mya;
2524   struct sockaddr_in peer;
2525   int fd, client;
2526   fd_set rfds;
2527   int addrlen;
2528   int i;
2529
2530   if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2531     {
2532       log_error ("socket() failed: %s\n", strerror (errno));
2533       return -1;
2534     }
2535   i = 1;
2536   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2537     log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2538
2539   mya.sin_family = AF_INET;
2540   memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2541   mya.sin_port = htons (11371);
2542
2543   if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2544     {
2545       log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2546       sock_close (fd);
2547       return -1;
2548     }
2549
2550   if (listen (fd, 5))
2551     {
2552       log_error ("listen failed: %s\n", strerror (errno));
2553       sock_close (fd);
2554       return -1;
2555     }
2556
2557   for (;;)
2558     {
2559       FD_ZERO (&rfds);
2560       FD_SET (fd, &rfds);
2561
2562       if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2563         continue;               /* ignore any errors */
2564
2565       if (!FD_ISSET (fd, &rfds))
2566         continue;
2567
2568       addrlen = sizeof peer;
2569       client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2570       if (client == -1)
2571         continue;               /* oops */
2572
2573       log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2574
2575       fflush (stdout);
2576       fflush (stderr);
2577       if (!fork ())
2578         {
2579           int c;
2580           FILE *fp;
2581
2582           fp = fdopen (client, "r");
2583           while ((c = getc (fp)) != EOF)
2584             putchar (c);
2585           fclose (fp);
2586           exit (0);
2587         }
2588       sock_close (client);
2589     }
2590
2591
2592   return 0;
2593 }
2594 #endif
2595
2596
2597
2598 /* Return true if SOCKS shall be used.  This is the case if tor_mode
2599  * is enabled and the desired address is not the loopback address.
2600  * This function is basically a copy of the same internal function in
2601  * Libassuan.  */
2602 static int
2603 use_socks (struct sockaddr_storage *addr)
2604 {
2605   int mode;
2606
2607   if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2608     return 0;  /* Not in Tor mode.  */
2609   else if (addr->ss_family == AF_INET6)
2610     {
2611       struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2612       const unsigned char *s;
2613       int i;
2614
2615       s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2616       if (s[15] != 1)
2617         return 1;   /* Last octet is not 1 - not the loopback address.  */
2618       for (i=0; i < 15; i++, s++)
2619         if (*s)
2620           return 1; /* Non-zero octet found - not the loopback address.  */
2621
2622       return 0; /* This is the loopback address.  */
2623     }
2624   else if (addr->ss_family == AF_INET)
2625     {
2626       struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2627
2628       if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2629         return 0; /* Loopback (127.0.0.0/8) */
2630
2631       return 1;
2632     }
2633   else
2634     return 0;
2635 }
2636
2637
2638 /* Wrapper around assuan_sock_new which takes the domain from an
2639  * address parameter.  */
2640 static assuan_fd_t
2641 my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
2642 {
2643   int domain;
2644
2645   if (use_socks (addr))
2646     {
2647       /* Libassaun always uses 127.0.0.1 to connect to the socks
2648        * server (i.e. the Tor daemon).  */
2649       domain = AF_INET;
2650     }
2651   else
2652     domain = addr->ss_family;
2653
2654   return assuan_sock_new (domain, type, proto);
2655 }
2656
2657
2658 /* Call WSAGetLastError and map it to a libgpg-error.  */
2659 #ifdef HAVE_W32_SYSTEM
2660 static gpg_error_t
2661 my_wsagetlasterror (void)
2662 {
2663   int wsaerr;
2664   gpg_err_code_t ec;
2665
2666   wsaerr = WSAGetLastError ();
2667   switch (wsaerr)
2668     {
2669     case WSAENOTSOCK:        ec = GPG_ERR_EINVAL;       break;
2670     case WSAEWOULDBLOCK:     ec = GPG_ERR_EAGAIN;       break;
2671     case ERROR_BROKEN_PIPE:  ec = GPG_ERR_EPIPE;        break;
2672     case WSANOTINITIALISED:  ec = GPG_ERR_ENOSYS;       break;
2673     case WSAENOBUFS:         ec = GPG_ERR_ENOBUFS;      break;
2674     case WSAEMSGSIZE:        ec = GPG_ERR_EMSGSIZE;     break;
2675     case WSAECONNREFUSED:    ec = GPG_ERR_ECONNREFUSED; break;
2676     case WSAEISCONN:         ec = GPG_ERR_EISCONN;      break;
2677     case WSAEALREADY:        ec = GPG_ERR_EALREADY;     break;
2678     case WSAETIMEDOUT:       ec = GPG_ERR_ETIMEDOUT;    break;
2679     default:                 ec = GPG_ERR_EIO;          break;
2680     }
2681
2682   return gpg_err_make (default_errsource, ec);
2683 }
2684 #endif /*HAVE_W32_SYSTEM*/
2685
2686
2687 /* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
2688  * be established within TIMEOUT milliseconds.  0 indicates the
2689  * system's default timeout.  The other args are the usual connect
2690  * args.  On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
2691  * another error code for other errors.  On timeout the caller needs
2692  * to close the socket as soon as possible to stop an ongoing
2693  * handshake.
2694  *
2695  * This implementation is for well-behaving systems; see Stevens,
2696  * Network Programming, 2nd edition, Vol 1, 15.4.  */
2697 static gpg_error_t
2698 connect_with_timeout (assuan_fd_t sock,
2699                       struct sockaddr *addr, int addrlen,
2700                       unsigned int timeout)
2701 {
2702   gpg_error_t err;
2703   int syserr;
2704   socklen_t slen;
2705   fd_set rset, wset;
2706   struct timeval tval;
2707   int n;
2708
2709 #ifndef HAVE_W32_SYSTEM
2710   int oflags;
2711 # define RESTORE_BLOCKING()  do {  \
2712     fcntl (sock, F_SETFL, oflags); \
2713   } while (0)
2714 #else /*HAVE_W32_SYSTEM*/
2715 # define RESTORE_BLOCKING()  do {                       \
2716     unsigned long along = 0;                            \
2717     ioctlsocket (FD2INT (sock), FIONBIO, &along);       \
2718   } while (0)
2719 #endif /*HAVE_W32_SYSTEM*/
2720
2721
2722   if (!timeout)
2723     {
2724       /* Shortcut.  */
2725       if (assuan_sock_connect (sock, addr, addrlen))
2726         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2727       else
2728         err = 0;
2729       return err;
2730     }
2731
2732   /* Switch the socket into non-blocking mode.  */
2733 #ifdef HAVE_W32_SYSTEM
2734   {
2735     unsigned long along = 1;
2736     if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
2737       return my_wsagetlasterror ();
2738   }
2739 #else
2740   oflags = fcntl (sock, F_GETFL, 0);
2741   if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
2742     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2743 #endif
2744
2745   /* Do the connect.  */
2746   if (!assuan_sock_connect (sock, addr, addrlen))
2747     {
2748       /* Immediate connect.  Restore flags. */
2749       RESTORE_BLOCKING ();
2750       return 0; /* Success.  */
2751     }
2752   err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2753   if (gpg_err_code (err) != GPG_ERR_EINPROGRESS)
2754     {
2755       RESTORE_BLOCKING ();
2756       return err;
2757     }
2758
2759   FD_ZERO (&rset);
2760   FD_SET (FD2INT (sock), &rset);
2761   wset = rset;
2762   tval.tv_sec = timeout / 1000;
2763   tval.tv_usec = (timeout % 1000) * 1000;
2764
2765   n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
2766   if (n < 0)
2767     {
2768       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2769       RESTORE_BLOCKING ();
2770       return err;
2771     }
2772   if (!n)
2773     {
2774       /* Timeout: We do not restore the socket flags on timeout
2775        * because the caller is expected to close the socket.  */
2776       return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
2777     }
2778   if (!FD_ISSET (sock, &rset) && !FD_ISSET (sock, &wset))
2779     {
2780       /* select misbehaved.  */
2781       return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
2782     }
2783
2784   slen = sizeof (syserr);
2785   if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
2786                   (void*)&syserr, &slen) < 0)
2787     {
2788       /* Assume that this is Solaris which returns the error in ERRNO.  */
2789       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2790     }
2791   else if (syserr)
2792     err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
2793   else
2794     err = 0; /* Connected.  */
2795
2796   RESTORE_BLOCKING ();
2797
2798   return err;
2799
2800 #undef RESTORE_BLOCKING
2801 }
2802
2803
2804 /* Actually connect to a server.  On success 0 is returned and the
2805  * file descriptor for the socket is stored at R_SOCK; on error an
2806  * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
2807  * TIMEOUT is the connect timeout in milliseconds.  Note that the
2808  * function tries to connect to all known addresses and the timeout is
2809  * for each one. */
2810 static gpg_error_t
2811 connect_server (const char *server, unsigned short port,
2812                 unsigned int flags, const char *srvtag, unsigned int timeout,
2813                 assuan_fd_t *r_sock)
2814 {
2815   gpg_error_t err;
2816   assuan_fd_t sock = ASSUAN_INVALID_FD;
2817   unsigned int srvcount = 0;
2818   int hostfound = 0;
2819   int anyhostaddr = 0;
2820   int srv, connected;
2821   gpg_error_t last_err = 0;
2822   struct srventry *serverlist = NULL;
2823
2824   *r_sock = ASSUAN_INVALID_FD;
2825
2826 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2827   init_sockets ();
2828 #endif /*Windows*/
2829
2830   /* Onion addresses require special treatment.  */
2831   if (is_onion_address (server))
2832     {
2833 #ifdef ASSUAN_SOCK_TOR
2834
2835       if (opt_debug)
2836         log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2837                    server, port);
2838       sock = assuan_sock_connect_byname (server, port, 0, NULL,
2839                                          ASSUAN_SOCK_TOR);
2840       if (sock == ASSUAN_INVALID_FD)
2841         {
2842           err = gpg_err_make (default_errsource,
2843                               (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2844                               : gpg_err_code_from_syserror ());
2845           log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2846           return err;
2847         }
2848
2849       notify_netactivity ();
2850       *r_sock = sock;
2851       return 0;
2852
2853 #else /*!ASSUAN_SOCK_TOR*/
2854
2855       err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2856       return ASSUAN_INVALID_FD;
2857
2858 #endif /*!HASSUAN_SOCK_TOR*/
2859     }
2860
2861   /* Do the SRV thing */
2862   if (srvtag)
2863     {
2864       err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2865       if (err)
2866         log_info ("getting '%s' SRV for '%s' failed: %s\n",
2867                   srvtag, server, gpg_strerror (err));
2868       /* Note that on error SRVCOUNT is zero.  */
2869       err = 0;
2870     }
2871
2872   if (!serverlist)
2873     {
2874       /* Either we're not using SRV, or the SRV lookup failed.  Make
2875          up a fake SRV record. */
2876       serverlist = xtrycalloc (1, sizeof *serverlist);
2877       if (!serverlist)
2878         return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2879
2880       serverlist->port = port;
2881       strncpy (serverlist->target, server, DIMof (struct srventry, target));
2882       serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2883       srvcount = 1;
2884     }
2885
2886   connected = 0;
2887   for (srv=0; srv < srvcount && !connected; srv++)
2888     {
2889       dns_addrinfo_t aibuf, ai;
2890
2891       if (opt_debug)
2892         log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2893                    serverlist[srv].target, port);
2894       err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2895                               &aibuf, NULL);
2896       if (err)
2897         {
2898           log_info ("resolving '%s' failed: %s\n",
2899                     serverlist[srv].target, gpg_strerror (err));
2900           last_err = err;
2901           continue; /* Not found - try next one. */
2902         }
2903       hostfound = 1;
2904
2905       for (ai = aibuf; ai && !connected; ai = ai->next)
2906         {
2907           if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2908             continue;
2909           if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2910             continue;
2911
2912           if (sock != ASSUAN_INVALID_FD)
2913             assuan_sock_close (sock);
2914           sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2915           if (sock == ASSUAN_INVALID_FD)
2916             {
2917               err = gpg_err_make (default_errsource,
2918                                   gpg_err_code_from_syserror ());
2919               log_error ("error creating socket: %s\n", gpg_strerror (err));
2920               free_dns_addrinfo (aibuf);
2921               xfree (serverlist);
2922               return err;
2923             }
2924
2925           anyhostaddr = 1;
2926           err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
2927                                       ai->addrlen, timeout);
2928           if (err)
2929             {
2930               last_err = err;
2931             }
2932           else
2933             {
2934               connected = 1;
2935               notify_netactivity ();
2936             }
2937         }
2938       free_dns_addrinfo (aibuf);
2939     }
2940
2941   xfree (serverlist);
2942
2943   if (!connected)
2944     {
2945       if (!hostfound)
2946         log_error ("can't connect to '%s': %s\n",
2947                    server, "host not found");
2948       else if (!anyhostaddr)
2949         log_error ("can't connect to '%s': %s\n",
2950                    server, "no IP address for host");
2951       else
2952         {
2953 #ifdef HAVE_W32_SYSTEM
2954         log_error ("can't connect to '%s': ec=%d\n",
2955                    server, (int)WSAGetLastError());
2956 #else
2957         log_error ("can't connect to '%s': %s\n",
2958                    server, gpg_strerror (last_err));
2959 #endif
2960         }
2961       err = last_err? last_err : gpg_err_make (default_errsource,
2962                                                GPG_ERR_UNKNOWN_HOST);
2963       if (sock != ASSUAN_INVALID_FD)
2964         assuan_sock_close (sock);
2965       return err;
2966     }
2967
2968   *r_sock = sock;
2969   return 0;
2970 }
2971
2972
2973 /* Helper to read from a socket.  This handles npth things and
2974  * EINTR.  */
2975 static gpgrt_ssize_t
2976 read_server (assuan_fd_t sock, void *buffer, size_t size)
2977 {
2978   int nread;
2979
2980   do
2981     {
2982 #ifdef HAVE_W32_SYSTEM
2983       /* Under Windows we need to use recv for a socket.  */
2984 # if defined(USE_NPTH)
2985       npth_unprotect ();
2986 # endif
2987       nread = recv (FD2INT (sock), buffer, size, 0);
2988 # if defined(USE_NPTH)
2989       npth_protect ();
2990 # endif
2991
2992 #else /*!HAVE_W32_SYSTEM*/
2993
2994 # ifdef USE_NPTH
2995       nread = npth_read (sock, buffer, size);
2996 # else
2997       nread = read (sock, buffer, size);
2998 # endif
2999
3000 #endif /*!HAVE_W32_SYSTEM*/
3001     }
3002   while (nread == -1 && errno == EINTR);
3003
3004   return nread;
3005 }
3006
3007
3008 static gpg_error_t
3009 write_server (assuan_fd_t sock, const char *data, size_t length)
3010 {
3011   int nleft;
3012   int nwritten;
3013
3014   nleft = length;
3015   while (nleft > 0)
3016     {
3017 #if defined(HAVE_W32_SYSTEM)
3018 # if defined(USE_NPTH)
3019       npth_unprotect ();
3020 # endif
3021       nwritten = send (FD2INT (sock), data, nleft, 0);
3022 # if defined(USE_NPTH)
3023       npth_protect ();
3024 # endif
3025       if ( nwritten == SOCKET_ERROR )
3026         {
3027           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
3028           return gpg_error (GPG_ERR_NETWORK);
3029         }
3030 #else /*!HAVE_W32_SYSTEM*/
3031 # ifdef USE_NPTH
3032       nwritten = npth_write (sock, data, nleft);
3033 # else
3034       nwritten = write (sock, data, nleft);
3035 # endif
3036       if (nwritten == -1)
3037         {
3038           if (errno == EINTR)
3039             continue;
3040           if (errno == EAGAIN)
3041             {
3042               struct timeval tv;
3043
3044               tv.tv_sec = 0;
3045               tv.tv_usec = 50000;
3046               my_select (0, NULL, NULL, NULL, &tv);
3047               continue;
3048             }
3049           log_info ("network write failed: %s\n", strerror (errno));
3050           return gpg_error_from_syserror ();
3051         }
3052 #endif /*!HAVE_W32_SYSTEM*/
3053       nleft -= nwritten;
3054       data += nwritten;
3055     }
3056
3057   return 0;
3058 }
3059
3060
3061 \f
3062 /* Read handler for estream.  */
3063 static gpgrt_ssize_t
3064 cookie_read (void *cookie, void *buffer, size_t size)
3065 {
3066   cookie_t c = cookie;
3067   int nread;
3068
3069   if (c->content_length_valid)
3070     {
3071       if (!c->content_length)
3072         return 0; /* EOF */
3073       if (c->content_length < size)
3074         size = c->content_length;
3075     }
3076
3077 #if HTTP_USE_NTBTLS
3078   if (c->use_tls && c->session && c->session->tls_session)
3079     {
3080       estream_t in, out;
3081
3082       ntbtls_get_stream (c->session->tls_session, &in, &out);
3083       nread = es_fread (buffer, 1, size, in);
3084       if (opt_debug)
3085         log_debug ("TLS network read: %d/%zu\n", nread, size);
3086     }
3087   else
3088 #elif HTTP_USE_GNUTLS
3089   if (c->use_tls && c->session && c->session->tls_session)
3090     {
3091     again:
3092       nread = gnutls_record_recv (c->session->tls_session, buffer, size);
3093       if (nread < 0)
3094         {
3095           if (nread == GNUTLS_E_INTERRUPTED)
3096             goto again;
3097           if (nread == GNUTLS_E_AGAIN)
3098             {
3099               struct timeval tv;
3100
3101               tv.tv_sec = 0;
3102               tv.tv_usec = 50000;
3103               my_select (0, NULL, NULL, NULL, &tv);
3104               goto again;
3105             }
3106           if (nread == GNUTLS_E_REHANDSHAKE)
3107             goto again; /* A client is allowed to just ignore this request. */
3108           if (nread == GNUTLS_E_PREMATURE_TERMINATION)
3109             {
3110               /* The server terminated the connection.  Close the TLS
3111                  session, and indicate EOF using a short read.  */
3112               close_tls_session (c->session);
3113               return 0;
3114             }
3115           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
3116           gpg_err_set_errno (EIO);
3117           return -1;
3118         }
3119     }
3120   else
3121 #endif /*HTTP_USE_GNUTLS*/
3122     {
3123       nread = read_server (c->sock->fd, buffer, size);
3124     }
3125
3126   if (c->content_length_valid && nread > 0)
3127     {
3128       if (nread < c->content_length)
3129         c->content_length -= nread;
3130       else
3131         c->content_length = 0;
3132     }
3133
3134   return (gpgrt_ssize_t)nread;
3135 }
3136
3137 /* Write handler for estream.  */
3138 static gpgrt_ssize_t
3139 cookie_write (void *cookie, const void *buffer_arg, size_t size)
3140 {
3141   const char *buffer = buffer_arg;
3142   cookie_t c = cookie;
3143   int nwritten = 0;
3144
3145 #if HTTP_USE_NTBTLS
3146   if (c->use_tls && c->session && c->session->tls_session)
3147     {
3148       estream_t in, out;
3149
3150       ntbtls_get_stream (c->session->tls_session, &in, &out);
3151       if (size == 0)
3152         es_fflush (out);
3153       else
3154         nwritten = es_fwrite (buffer, 1, size, out);
3155       if (opt_debug)
3156         log_debug ("TLS network write: %d/%zu\n", nwritten, size);
3157     }
3158   else
3159 #elif HTTP_USE_GNUTLS
3160   if (c->use_tls && c->session && c->session->tls_session)
3161     {
3162       int nleft = size;
3163       while (nleft > 0)
3164         {
3165           nwritten = gnutls_record_send (c->session->tls_session,
3166                                          buffer, nleft);
3167           if (nwritten <= 0)
3168             {
3169               if (nwritten == GNUTLS_E_INTERRUPTED)
3170                 continue;
3171               if (nwritten == GNUTLS_E_AGAIN)
3172                 {
3173                   struct timeval tv;
3174
3175                   tv.tv_sec = 0;
3176                   tv.tv_usec = 50000;
3177                   my_select (0, NULL, NULL, NULL, &tv);
3178                   continue;
3179                 }
3180               log_info ("TLS network write failed: %s\n",
3181                         gnutls_strerror (nwritten));
3182               gpg_err_set_errno (EIO);
3183               return -1;
3184             }
3185           nleft -= nwritten;
3186           buffer += nwritten;
3187         }
3188     }
3189   else
3190 #endif /*HTTP_USE_GNUTLS*/
3191     {
3192       if ( write_server (c->sock->fd, buffer, size) )
3193         {
3194           gpg_err_set_errno (EIO);
3195           nwritten = -1;
3196         }
3197       else
3198         nwritten = size;
3199     }
3200
3201   return (gpgrt_ssize_t)nwritten;
3202 }
3203
3204
3205 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
3206 static gpgrt_ssize_t
3207 simple_cookie_read (void *cookie, void *buffer, size_t size)
3208 {
3209   assuan_fd_t sock = (assuan_fd_t)cookie;
3210   return read_server (sock, buffer, size);
3211 }
3212
3213 static gpgrt_ssize_t
3214 simple_cookie_write (void *cookie, const void *buffer_arg, size_t size)
3215 {
3216   assuan_fd_t sock = (assuan_fd_t)cookie;
3217   const char *buffer = buffer_arg;
3218   int nwritten;
3219
3220   if (write_server (sock, buffer, size))
3221     {
3222       gpg_err_set_errno (EIO);
3223       nwritten = -1;
3224     }
3225   else
3226     nwritten = size;
3227
3228   return (gpgrt_ssize_t)nwritten;
3229 }
3230 #endif /*HAVE_W32_SYSTEM*/
3231
3232
3233 #ifdef HTTP_USE_GNUTLS
3234 /* Wrapper for gnutls_bye used by my_socket_unref.  */
3235 static void
3236 send_gnutls_bye (void *opaque)
3237 {
3238   tls_session_t tls_session = opaque;
3239   int ret;
3240
3241  again:
3242   do
3243     ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
3244   while (ret == GNUTLS_E_INTERRUPTED);
3245   if (ret == GNUTLS_E_AGAIN)
3246     {
3247       struct timeval tv;
3248
3249       tv.tv_sec = 0;
3250       tv.tv_usec = 50000;
3251       my_select (0, NULL, NULL, NULL, &tv);
3252       goto again;
3253     }
3254 }
3255 #endif /*HTTP_USE_GNUTLS*/
3256
3257 /* Close handler for estream.  */
3258 static int
3259 cookie_close (void *cookie)
3260 {
3261   cookie_t c = cookie;
3262
3263   if (!c)
3264     return 0;
3265
3266 #if HTTP_USE_NTBTLS
3267   if (c->use_tls && c->session && c->session->tls_session)
3268     {
3269       /* FIXME!! Possibly call ntbtls_close_notify for close
3270          of write stream.  */
3271       my_socket_unref (c->sock, NULL, NULL);
3272     }
3273   else
3274 #elif HTTP_USE_GNUTLS
3275   if (c->use_tls && c->session && c->session->tls_session)
3276     my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
3277   else
3278 #endif /*HTTP_USE_GNUTLS*/
3279     if (c->sock)
3280       my_socket_unref (c->sock, NULL, NULL);
3281
3282   if (c->session)
3283     http_session_unref (c->session);
3284   xfree (c);
3285   return 0;
3286 }
3287
3288
3289
3290 \f
3291 /* Verify the credentials of the server.  Returns 0 on success and
3292    store the result in the session object.  */
3293 gpg_error_t
3294 http_verify_server_credentials (http_session_t sess)
3295 {
3296 #if HTTP_USE_GNUTLS
3297   static const char errprefix[] = "TLS verification of peer failed";
3298   int rc;
3299   unsigned int status;
3300   const char *hostname;
3301   const gnutls_datum_t *certlist;
3302   unsigned int certlistlen;
3303   gnutls_x509_crt_t cert;
3304   gpg_error_t err = 0;
3305
3306   sess->verify.done = 1;
3307   sess->verify.status = 0;
3308   sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
3309
3310   if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
3311     {
3312       log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
3313       sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
3314       return gpg_error (GPG_ERR_GENERAL);
3315     }
3316
3317   rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
3318   if (rc)
3319     {
3320       log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
3321       if (!err)
3322         err = gpg_error (GPG_ERR_GENERAL);
3323     }
3324   else if (status)
3325     {
3326       log_error ("%s: status=0x%04x\n", errprefix, status);
3327 #if GNUTLS_VERSION_NUMBER >= 0x030104
3328       {
3329         gnutls_datum_t statusdat;
3330
3331         if (!gnutls_certificate_verification_status_print
3332             (status, GNUTLS_CRT_X509, &statusdat, 0))
3333           {
3334             log_info ("%s: %s\n", errprefix, statusdat.data);
3335             gnutls_free (statusdat.data);
3336           }
3337       }
3338 #endif /*gnutls >= 3.1.4*/
3339
3340       sess->verify.status = status;
3341       if (!err)
3342         err = gpg_error (GPG_ERR_GENERAL);
3343     }
3344
3345   hostname = sess->servername;
3346   if (!hostname || !strchr (hostname, '.'))
3347     {
3348       log_error ("%s: %s\n", errprefix, "hostname missing");
3349       if (!err)
3350         err = gpg_error (GPG_ERR_GENERAL);
3351     }
3352
3353   certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
3354   if (!certlistlen)
3355     {
3356       log_error ("%s: %s\n", errprefix, "server did not send a certificate");
3357       if (!err)
3358         err = gpg_error (GPG_ERR_GENERAL);
3359
3360       /* Need to stop here.  */
3361       if (err)
3362         return err;
3363     }
3364
3365   rc = gnutls_x509_crt_init (&cert);
3366   if (rc < 0)
3367     {
3368       if (!err)
3369         err = gpg_error (GPG_ERR_GENERAL);
3370       if (err)
3371         return err;
3372     }
3373
3374   rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3375   if (rc < 0)
3376     {
3377       log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3378                  gnutls_strerror (rc));
3379       if (!err)
3380         err = gpg_error (GPG_ERR_GENERAL);
3381     }
3382
3383   if (!gnutls_x509_crt_check_hostname (cert, hostname))
3384     {
3385       log_error ("%s: %s\n", errprefix, "hostname does not match");
3386       if (!err)
3387         err = gpg_error (GPG_ERR_GENERAL);
3388     }
3389
3390   gnutls_x509_crt_deinit (cert);
3391
3392   if (!err)
3393     sess->verify.rc = 0;
3394
3395   if (sess->cert_log_cb)
3396     {
3397       const void *bufarr[10];
3398       size_t buflenarr[10];
3399       size_t n;
3400
3401       for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3402         {
3403           bufarr[n] = certlist[n].data;
3404           buflenarr[n] = certlist[n].size;
3405         }
3406       bufarr[n] = NULL;
3407       buflenarr[n] = 0;
3408       sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3409     }
3410
3411   return err;
3412 #else /*!HTTP_USE_GNUTLS*/
3413   (void)sess;
3414   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3415 #endif
3416 }
3417
3418 /* Return the first query variable with the specified key.  If there
3419    is no such variable, return NULL.  */
3420 struct uri_tuple_s *
3421 uri_query_lookup (parsed_uri_t uri, const char *key)
3422 {
3423   struct uri_tuple_s *t;
3424
3425   for (t = uri->query; t; t = t->next)
3426     if (strcmp (t->name, key) == 0)
3427       return t;
3428
3429   return NULL;
3430 }