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