dirmngr: Log http response in debug mode.
[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
1676   if (hd->uri->use_tls && !hd->session)
1677     {
1678       log_error ("TLS requested but no session object provided\n");
1679       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1680     }
1681 #ifdef USE_TLS
1682   if (hd->uri->use_tls && !hd->session->tls_session)
1683     {
1684       log_error ("TLS requested but no GNUTLS context available\n");
1685       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1686     }
1687 #endif /*USE_TLS*/
1688
1689   if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1690     {
1691       int mode;
1692
1693       if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1694         {
1695           log_error ("Tor support is not available\n");
1696           return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1697         }
1698     }
1699
1700   server = *hd->uri->host ? hd->uri->host : "localhost";
1701   port = hd->uri->port ? hd->uri->port : 80;
1702
1703   /* Try to use SNI.  */
1704 #ifdef USE_TLS
1705   if (hd->uri->use_tls)
1706     {
1707 # if HTTP_USE_GNUTLS
1708       int rc;
1709 # endif
1710
1711       xfree (hd->session->servername);
1712       hd->session->servername = xtrystrdup (httphost? httphost : server);
1713       if (!hd->session->servername)
1714         {
1715           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1716           return err;
1717         }
1718
1719 # if HTTP_USE_NTBTLS
1720       err = ntbtls_set_hostname (hd->session->tls_session,
1721                                  hd->session->servername);
1722       if (err)
1723         {
1724           log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1725           return err;
1726         }
1727 # elif HTTP_USE_GNUTLS
1728       rc = gnutls_server_name_set (hd->session->tls_session,
1729                                    GNUTLS_NAME_DNS,
1730                                    hd->session->servername,
1731                                    strlen (hd->session->servername));
1732       if (rc < 0)
1733         log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1734 # endif /*HTTP_USE_GNUTLS*/
1735     }
1736 #endif /*USE_TLS*/
1737
1738   if ( (proxy && *proxy)
1739        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1740             && (http_proxy = getenv (HTTP_PROXY_ENV))
1741             && *http_proxy ))
1742     {
1743       parsed_uri_t uri;
1744
1745       if (proxy)
1746         http_proxy = proxy;
1747
1748       err = parse_uri (&uri, http_proxy, 0, 0);
1749       if (gpg_err_code (err) == GPG_ERR_INV_URI
1750           && is_hostname_port (http_proxy))
1751         {
1752           /* Retry assuming a "hostname:port" string.  */
1753           char *tmpname = strconcat ("http://", http_proxy, NULL);
1754           if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1755             err = 0;
1756           xfree (tmpname);
1757         }
1758
1759       if (err)
1760         ;
1761       else if (!strcmp (uri->scheme, "http"))
1762         ;
1763       else if (!strcmp (uri->scheme, "socks4")
1764                || !strcmp (uri->scheme, "socks5h"))
1765         err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1766       else
1767         err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1768
1769       if (err)
1770         {
1771           log_error ("invalid HTTP proxy (%s): %s\n",
1772                      http_proxy, gpg_strerror (err));
1773           return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1774         }
1775
1776       if (uri->auth)
1777         {
1778           remove_escapes (uri->auth);
1779           proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1780                                             "\r\n",
1781                                             uri->auth, strlen(uri->auth));
1782           if (!proxy_authstr)
1783             {
1784               err = gpg_err_make (default_errsource,
1785                                   gpg_err_code_from_syserror ());
1786               http_release_parsed_uri (uri);
1787               return err;
1788             }
1789         }
1790
1791       err = connect_server (*uri->host ? uri->host : "localhost",
1792                             uri->port ? uri->port : 80,
1793                             hd->flags, NULL, timeout, &sock);
1794       http_release_parsed_uri (uri);
1795     }
1796   else
1797     {
1798       err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
1799     }
1800
1801   if (err)
1802     {
1803       xfree (proxy_authstr);
1804       return err;
1805     }
1806   hd->sock = my_socket_new (sock);
1807   if (!hd->sock)
1808     {
1809       xfree (proxy_authstr);
1810       return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1811     }
1812
1813
1814 #if HTTP_USE_NTBTLS
1815   if (hd->uri->use_tls)
1816     {
1817       estream_t in, out;
1818
1819       my_socket_ref (hd->sock);
1820
1821       /* Until we support send/recv in estream under Windows we need
1822        * to use es_fopencookie.  */
1823 #ifdef HAVE_W32_SYSTEM
1824       in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb",
1825                            simple_cookie_functions);
1826 #else
1827       in = es_fdopen_nc (hd->sock->fd, "rb");
1828 #endif
1829       if (!in)
1830         {
1831           err = gpg_error_from_syserror ();
1832           xfree (proxy_authstr);
1833           return err;
1834         }
1835
1836 #ifdef HAVE_W32_SYSTEM
1837       out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb",
1838                             simple_cookie_functions);
1839 #else
1840       out = es_fdopen_nc (hd->sock->fd, "wb");
1841 #endif
1842       if (!out)
1843         {
1844           err = gpg_error_from_syserror ();
1845           es_fclose (in);
1846           xfree (proxy_authstr);
1847           return err;
1848         }
1849
1850       err = ntbtls_set_transport (hd->session->tls_session, in, out);
1851       if (err)
1852         {
1853           log_info ("TLS set_transport failed: %s <%s>\n",
1854                     gpg_strerror (err), gpg_strsource (err));
1855           xfree (proxy_authstr);
1856           return err;
1857         }
1858
1859 #ifdef HTTP_USE_NTBTLS
1860       if (hd->session->verify_cb)
1861         {
1862           err = ntbtls_set_verify_cb (hd->session->tls_session,
1863                                       my_ntbtls_verify_cb, hd);
1864           if (err)
1865             {
1866               log_error ("ntbtls_set_verify_cb failed: %s\n",
1867                          gpg_strerror (err));
1868               xfree (proxy_authstr);
1869               return err;
1870             }
1871         }
1872 #endif /*HTTP_USE_NTBTLS*/
1873
1874       while ((err = ntbtls_handshake (hd->session->tls_session)))
1875         {
1876           switch (err)
1877             {
1878             default:
1879               log_info ("TLS handshake failed: %s <%s>\n",
1880                         gpg_strerror (err), gpg_strsource (err));
1881               xfree (proxy_authstr);
1882               return err;
1883             }
1884         }
1885
1886       hd->session->verify.done = 0;
1887
1888       /* Try the available verify callbacks until one returns success
1889        * or a real error.  Note that NTBTLS does the verification
1890        * during the handshake via   */
1891 #ifdef HTTP_USE_NTBTLS
1892       err = 0; /* Fixme check that the CB has been called.  */
1893 #else
1894       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1895 #endif
1896
1897       if (hd->session->verify_cb
1898           && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1899           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1900         err = hd->session->verify_cb (hd->session->verify_cb_value,
1901                                       hd, hd->session,
1902                                       (hd->flags | hd->session->flags),
1903                                       hd->session->tls_session);
1904
1905       if (tls_callback
1906           && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1907           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1908         err = tls_callback (hd, hd->session, 0);
1909
1910       if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1911           && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1912         err = http_verify_server_credentials (hd->session);
1913
1914       if (err)
1915         {
1916           log_info ("TLS connection authentication failed: %s <%s>\n",
1917                     gpg_strerror (err), gpg_strsource (err));
1918           xfree (proxy_authstr);
1919           return err;
1920         }
1921
1922     }
1923 #elif HTTP_USE_GNUTLS
1924   if (hd->uri->use_tls)
1925     {
1926       int rc;
1927
1928       my_socket_ref (hd->sock);
1929       gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1930       gnutls_transport_set_pull_function (hd->session->tls_session,
1931                                           my_gnutls_read);
1932       gnutls_transport_set_push_function (hd->session->tls_session,
1933                                           my_gnutls_write);
1934
1935     handshake_again:
1936       do
1937         {
1938           rc = gnutls_handshake (hd->session->tls_session);
1939         }
1940       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1941       if (rc < 0)
1942         {
1943           if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1944               || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1945             {
1946               gnutls_alert_description_t alertno;
1947               const char *alertstr;
1948
1949               alertno = gnutls_alert_get (hd->session->tls_session);
1950               alertstr = gnutls_alert_get_name (alertno);
1951               log_info ("TLS handshake %s: %s (alert %d)\n",
1952                         rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1953                         ? "warning" : "failed",
1954                         alertstr, (int)alertno);
1955               if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1956                 log_info ("  (sent server name '%s')\n", server);
1957
1958               if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
1959                 goto handshake_again;
1960             }
1961           else
1962             log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1963           xfree (proxy_authstr);
1964           return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1965         }
1966
1967       hd->session->verify.done = 0;
1968       if (tls_callback)
1969         err = tls_callback (hd, hd->session, 0);
1970       else
1971         err = http_verify_server_credentials (hd->session);
1972       if (err)
1973         {
1974           log_info ("TLS connection authentication failed: %s\n",
1975                     gpg_strerror (err));
1976           xfree (proxy_authstr);
1977           return err;
1978         }
1979     }
1980 #endif /*HTTP_USE_GNUTLS*/
1981
1982   if (auth || hd->uri->auth)
1983     {
1984       char *myauth;
1985
1986       if (auth)
1987         {
1988           myauth = xtrystrdup (auth);
1989           if (!myauth)
1990             {
1991               xfree (proxy_authstr);
1992               return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1993             }
1994           remove_escapes (myauth);
1995         }
1996       else
1997         {
1998           remove_escapes (hd->uri->auth);
1999           myauth = hd->uri->auth;
2000         }
2001
2002       authstr = make_header_line ("Authorization: Basic ", "\r\n",
2003                                   myauth, strlen (myauth));
2004       if (auth)
2005         xfree (myauth);
2006
2007       if (!authstr)
2008         {
2009           xfree (proxy_authstr);
2010           return gpg_err_make (default_errsource,
2011                                gpg_err_code_from_syserror ());
2012         }
2013     }
2014
2015   p = build_rel_path (hd->uri);
2016   if (!p)
2017     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2018
2019   if (http_proxy && *http_proxy)
2020     {
2021       request = es_bsprintf
2022         ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
2023          hd->req_type == HTTP_REQ_GET ? "GET" :
2024          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2025          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2026          hd->uri->use_tls? "https" : "http",
2027          httphost? httphost : server,
2028          port, *p == '/' ? "" : "/", p,
2029          authstr ? authstr : "",
2030          proxy_authstr ? proxy_authstr : "");
2031     }
2032   else
2033     {
2034       char portstr[35];
2035
2036       if (port == (hd->uri->use_tls? 443 : 80))
2037         *portstr = 0;
2038       else
2039         snprintf (portstr, sizeof portstr, ":%u", port);
2040
2041       request = es_bsprintf
2042         ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
2043          hd->req_type == HTTP_REQ_GET ? "GET" :
2044          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2045          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2046          *p == '/' ? "" : "/", p,
2047          httphost? httphost : server,
2048          portstr,
2049          authstr? authstr:"");
2050     }
2051   xfree (p);
2052   if (!request)
2053     {
2054       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2055       xfree (authstr);
2056       xfree (proxy_authstr);
2057       return err;
2058     }
2059
2060   if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2061     log_debug_with_string (request, "http.c:request:");
2062
2063   /* First setup estream so that we can write even the first line
2064      using estream.  This is also required for the sake of gnutls. */
2065   {
2066     cookie_t cookie;
2067
2068     cookie = xtrycalloc (1, sizeof *cookie);
2069     if (!cookie)
2070       {
2071         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2072         goto leave;
2073       }
2074     cookie->sock = my_socket_ref (hd->sock);
2075     hd->write_cookie = cookie;
2076     cookie->use_tls = hd->uri->use_tls;
2077     cookie->session = http_session_ref (hd->session);
2078
2079     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2080     if (!hd->fp_write)
2081       {
2082         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2083         my_socket_unref (cookie->sock, NULL, NULL);
2084         xfree (cookie);
2085         hd->write_cookie = NULL;
2086       }
2087     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2088       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2089     else
2090       err = 0;
2091
2092   if (!err)
2093     {
2094       for (;headers; headers=headers->next)
2095         {
2096           if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2097             log_debug_with_string (headers->d, "http.c:request-header:");
2098           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2099               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2100             {
2101               err = gpg_err_make (default_errsource,
2102                                   gpg_err_code_from_syserror ());
2103               break;
2104             }
2105         }
2106     }
2107   }
2108
2109  leave:
2110   es_free (request);
2111   xfree (authstr);
2112   xfree (proxy_authstr);
2113
2114   return err;
2115 }
2116
2117
2118 /*
2119  * Build the relative path from the parsed URI.  Minimal
2120  * implementation.  May return NULL in case of memory failure; errno
2121  * is then set accordingly.
2122  */
2123 static char *
2124 build_rel_path (parsed_uri_t uri)
2125 {
2126   uri_tuple_t r;
2127   char *rel_path, *p;
2128   int n;
2129
2130   /* Count the needed space. */
2131   n = insert_escapes (NULL, uri->path, "%;?&");
2132   /* TODO: build params. */
2133   for (r = uri->query; r; r = r->next)
2134     {
2135       n++; /* '?'/'&' */
2136       n += insert_escapes (NULL, r->name, "%;?&=");
2137       if (!r->no_value)
2138         {
2139           n++; /* '=' */
2140           n += insert_escapes (NULL, r->value, "%;?&=");
2141         }
2142     }
2143   n++;
2144
2145   /* Now allocate and copy. */
2146   p = rel_path = xtrymalloc (n);
2147   if (!p)
2148     return NULL;
2149   n = insert_escapes (p, uri->path, "%;?&");
2150   p += n;
2151   /* TODO: add params. */
2152   for (r = uri->query; r; r = r->next)
2153     {
2154       *p++ = r == uri->query ? '?' : '&';
2155       n = insert_escapes (p, r->name, "%;?&=");
2156       p += n;
2157       if (!r->no_value)
2158         {
2159           *p++ = '=';
2160           /* TODO: Use valuelen. */
2161           n = insert_escapes (p, r->value, "%;?&=");
2162           p += n;
2163         }
2164     }
2165   *p = 0;
2166   return rel_path;
2167 }
2168
2169
2170 /* Transform a header name into a standard capitalized format; e.g.
2171    "Content-Type".  Conversion stops at the colon.  As usual we don't
2172    use the localized versions of ctype.h. */
2173 static void
2174 capitalize_header_name (char *name)
2175 {
2176   int first = 1;
2177
2178   for (; *name && *name != ':'; name++)
2179     {
2180       if (*name == '-')
2181         first = 1;
2182       else if (first)
2183         {
2184           if (*name >= 'a' && *name <= 'z')
2185             *name = *name - 'a' + 'A';
2186           first = 0;
2187         }
2188       else if (*name >= 'A' && *name <= 'Z')
2189         *name = *name - 'A' + 'a';
2190     }
2191 }
2192
2193
2194 /* Store an HTTP header line in LINE away.  Line continuation is
2195    supported as well as merging of headers with the same name. This
2196    function may modify LINE. */
2197 static gpg_err_code_t
2198 store_header (http_t hd, char *line)
2199 {
2200   size_t n;
2201   char *p, *value;
2202   header_t h;
2203
2204   n = strlen (line);
2205   if (n && line[n-1] == '\n')
2206     {
2207       line[--n] = 0;
2208       if (n && line[n-1] == '\r')
2209         line[--n] = 0;
2210     }
2211   if (!n)  /* we are never called to hit this. */
2212     return GPG_ERR_BUG;
2213   if (*line == ' ' || *line == '\t')
2214     {
2215       /* Continuation. This won't happen too often as it is not
2216          recommended.  We use a straightforward implementation. */
2217       if (!hd->headers)
2218         return GPG_ERR_PROTOCOL_VIOLATION;
2219       n += strlen (hd->headers->value);
2220       p = xtrymalloc (n+1);
2221       if (!p)
2222         return gpg_err_code_from_syserror ();
2223       strcpy (stpcpy (p, hd->headers->value), line);
2224       xfree (hd->headers->value);
2225       hd->headers->value = p;
2226       return 0;
2227     }
2228
2229   capitalize_header_name (line);
2230   p = strchr (line, ':');
2231   if (!p)
2232     return GPG_ERR_PROTOCOL_VIOLATION;
2233   *p++ = 0;
2234   while (*p == ' ' || *p == '\t')
2235     p++;
2236   value = p;
2237
2238   for (h=hd->headers; h; h = h->next)
2239     if ( !strcmp (h->name, line) )
2240       break;
2241   if (h)
2242     {
2243       /* We have already seen a line with that name.  Thus we assume
2244        * it is a comma separated list and merge them.  */
2245       p = strconcat (h->value, ",", value, NULL);
2246       if (!p)
2247         return gpg_err_code_from_syserror ();
2248       xfree (h->value);
2249       h->value = p;
2250       return 0;
2251     }
2252
2253   /* Append a new header. */
2254   h = xtrymalloc (sizeof *h + strlen (line));
2255   if (!h)
2256     return gpg_err_code_from_syserror ();
2257   strcpy (h->name, line);
2258   h->value = xtrymalloc (strlen (value)+1);
2259   if (!h->value)
2260     {
2261       xfree (h);
2262       return gpg_err_code_from_syserror ();
2263     }
2264   strcpy (h->value, value);
2265   h->next = hd->headers;
2266   hd->headers = h;
2267
2268   return 0;
2269 }
2270
2271
2272 /* Return the header NAME from the last response.  The returned value
2273    is valid as along as HD has not been closed and no other request
2274    has been send. If the header was not found, NULL is returned.  NAME
2275    must be canonicalized, that is the first letter of each dash
2276    delimited part must be uppercase and all other letters lowercase.  */
2277 const char *
2278 http_get_header (http_t hd, const char *name)
2279 {
2280   header_t h;
2281
2282   for (h=hd->headers; h; h = h->next)
2283     if ( !strcmp (h->name, name) )
2284       return h->value;
2285   return NULL;
2286 }
2287
2288
2289 /* Return a newly allocated and NULL terminated array with pointers to
2290    header names.  The array must be released with xfree() and its
2291    content is only values as long as no other request has been
2292    send.  */
2293 const char **
2294 http_get_header_names (http_t hd)
2295 {
2296   const char **array;
2297   size_t n;
2298   header_t h;
2299
2300   for (n=0, h = hd->headers; h; h = h->next)
2301     n++;
2302   array = xtrycalloc (n+1, sizeof *array);
2303   if (array)
2304     {
2305       for (n=0, h = hd->headers; h; h = h->next)
2306         array[n++] = h->name;
2307     }
2308
2309   return array;
2310 }
2311
2312
2313 /*
2314  * Parse the response from a server.
2315  * Returns: Errorcode and sets some files in the handle
2316  */
2317 static gpg_err_code_t
2318 parse_response (http_t hd)
2319 {
2320   char *line, *p, *p2;
2321   size_t maxlen, len;
2322   cookie_t cookie = hd->read_cookie;
2323   const char *s;
2324
2325   /* Delete old header lines.  */
2326   while (hd->headers)
2327     {
2328       header_t tmp = hd->headers->next;
2329       xfree (hd->headers->value);
2330       xfree (hd->headers);
2331       hd->headers = tmp;
2332     }
2333
2334   /* Wait for the status line. */
2335   do
2336     {
2337       maxlen = MAX_LINELEN;
2338       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2339       line = hd->buffer;
2340       if (!line)
2341         return gpg_err_code_from_syserror (); /* Out of core. */
2342       if (!maxlen)
2343         return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2344       if (!len)
2345         return GPG_ERR_EOF;
2346
2347       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2348         log_debug_with_string (line, "http.c:response:\n");
2349     }
2350   while (!*line);
2351
2352   if ((p = strchr (line, '/')))
2353     *p++ = 0;
2354   if (!p || strcmp (line, "HTTP"))
2355     return 0; /* Assume http 0.9. */
2356
2357   if ((p2 = strpbrk (p, " \t")))
2358     {
2359       *p2++ = 0;
2360       p2 += strspn (p2, " \t");
2361     }
2362   if (!p2)
2363     return 0; /* Also assume http 0.9. */
2364   p = p2;
2365   /* TODO: Add HTTP version number check. */
2366   if ((p2 = strpbrk (p, " \t")))
2367     *p2++ = 0;
2368   if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2369       || !isdigit ((unsigned int)p[2]) || p[3])
2370     {
2371       /* Malformed HTTP status code - assume http 0.9. */
2372       hd->is_http_0_9 = 1;
2373       hd->status_code = 200;
2374       return 0;
2375     }
2376   hd->status_code = atoi (p);
2377
2378   /* Skip all the header lines and wait for the empty line. */
2379   do
2380     {
2381       maxlen = MAX_LINELEN;
2382       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2383       line = hd->buffer;
2384       if (!line)
2385         return gpg_err_code_from_syserror (); /* Out of core. */
2386       /* Note, that we can silently ignore truncated lines. */
2387       if (!len)
2388         return GPG_ERR_EOF;
2389       /* Trim line endings of empty lines. */
2390       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2391         *line = 0;
2392       if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2393         log_info ("http.c:RESP: '%.*s'\n",
2394                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2395       if (*line)
2396         {
2397           gpg_err_code_t ec = store_header (hd, line);
2398           if (ec)
2399             return ec;
2400         }
2401     }
2402   while (len && *line);
2403
2404   cookie->content_length_valid = 0;
2405   if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2406     {
2407       s = http_get_header (hd, "Content-Length");
2408       if (s)
2409         {
2410           cookie->content_length_valid = 1;
2411           cookie->content_length = string_to_u64 (s);
2412         }
2413     }
2414
2415   return 0;
2416 }
2417
2418 #if 0
2419 static int
2420 start_server ()
2421 {
2422   struct sockaddr_in mya;
2423   struct sockaddr_in peer;
2424   int fd, client;
2425   fd_set rfds;
2426   int addrlen;
2427   int i;
2428
2429   if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2430     {
2431       log_error ("socket() failed: %s\n", strerror (errno));
2432       return -1;
2433     }
2434   i = 1;
2435   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2436     log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2437
2438   mya.sin_family = AF_INET;
2439   memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2440   mya.sin_port = htons (11371);
2441
2442   if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2443     {
2444       log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2445       sock_close (fd);
2446       return -1;
2447     }
2448
2449   if (listen (fd, 5))
2450     {
2451       log_error ("listen failed: %s\n", strerror (errno));
2452       sock_close (fd);
2453       return -1;
2454     }
2455
2456   for (;;)
2457     {
2458       FD_ZERO (&rfds);
2459       FD_SET (fd, &rfds);
2460
2461       if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2462         continue;               /* ignore any errors */
2463
2464       if (!FD_ISSET (fd, &rfds))
2465         continue;
2466
2467       addrlen = sizeof peer;
2468       client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2469       if (client == -1)
2470         continue;               /* oops */
2471
2472       log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2473
2474       fflush (stdout);
2475       fflush (stderr);
2476       if (!fork ())
2477         {
2478           int c;
2479           FILE *fp;
2480
2481           fp = fdopen (client, "r");
2482           while ((c = getc (fp)) != EOF)
2483             putchar (c);
2484           fclose (fp);
2485           exit (0);
2486         }
2487       sock_close (client);
2488     }
2489
2490
2491   return 0;
2492 }
2493 #endif
2494
2495
2496
2497 /* Return true if SOCKS shall be used.  This is the case if tor_mode
2498  * is enabled and the desired address is not the loopback address.
2499  * This function is basically a copy of the same internal function in
2500  * Libassuan.  */
2501 static int
2502 use_socks (struct sockaddr_storage *addr)
2503 {
2504   int mode;
2505
2506   if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2507     return 0;  /* Not in Tor mode.  */
2508   else if (addr->ss_family == AF_INET6)
2509     {
2510       struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2511       const unsigned char *s;
2512       int i;
2513
2514       s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2515       if (s[15] != 1)
2516         return 1;   /* Last octet is not 1 - not the loopback address.  */
2517       for (i=0; i < 15; i++, s++)
2518         if (*s)
2519           return 1; /* Non-zero octet found - not the loopback address.  */
2520
2521       return 0; /* This is the loopback address.  */
2522     }
2523   else if (addr->ss_family == AF_INET)
2524     {
2525       struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2526
2527       if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2528         return 0; /* Loopback (127.0.0.0/8) */
2529
2530       return 1;
2531     }
2532   else
2533     return 0;
2534 }
2535
2536
2537 /* Wrapper around assuan_sock_new which takes the domain from an
2538  * address parameter.  */
2539 static assuan_fd_t
2540 my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
2541 {
2542   int domain;
2543
2544   if (use_socks (addr))
2545     {
2546       /* Libassaun always uses 127.0.0.1 to connect to the socks
2547        * server (i.e. the Tor daemon).  */
2548       domain = AF_INET;
2549     }
2550   else
2551     domain = addr->ss_family;
2552
2553   return assuan_sock_new (domain, type, proto);
2554 }
2555
2556
2557 /* Call WSAGetLastError and map it to a libgpg-error.  */
2558 #ifdef HAVE_W32_SYSTEM
2559 static gpg_error_t
2560 my_wsagetlasterror (void)
2561 {
2562   int wsaerr;
2563   gpg_err_code_t ec;
2564
2565   wsaerr = WSAGetLastError ();
2566   switch (wsaerr)
2567     {
2568     case WSAENOTSOCK:        ec = GPG_ERR_EINVAL;       break;
2569     case WSAEWOULDBLOCK:     ec = GPG_ERR_EAGAIN;       break;
2570     case ERROR_BROKEN_PIPE:  ec = GPG_ERR_EPIPE;        break;
2571     case WSANOTINITIALISED:  ec = GPG_ERR_ENOSYS;       break;
2572     case WSAENOBUFS:         ec = GPG_ERR_ENOBUFS;      break;
2573     case WSAEMSGSIZE:        ec = GPG_ERR_EMSGSIZE;     break;
2574     case WSAECONNREFUSED:    ec = GPG_ERR_ECONNREFUSED; break;
2575     case WSAEISCONN:         ec = GPG_ERR_EISCONN;      break;
2576     case WSAEALREADY:        ec = GPG_ERR_EALREADY;     break;
2577     case WSAETIMEDOUT:       ec = GPG_ERR_ETIMEDOUT;    break;
2578     default:                 ec = GPG_ERR_EIO;          break;
2579     }
2580
2581   return gpg_err_make (default_errsource, ec);
2582 }
2583 #endif /*HAVE_W32_SYSTEM*/
2584
2585
2586 /* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
2587  * be established within TIMEOUT milliseconds.  0 indicates the
2588  * system's default timeout.  The other args are the usual connect
2589  * args.  On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
2590  * another error code for other errors.  On timeout the caller needs
2591  * to close the socket as soon as possible to stop an ongoing
2592  * handshake.
2593  *
2594  * This implementation is for well-behaving systems; see Stevens,
2595  * Network Programming, 2nd edition, Vol 1, 15.4.  */
2596 static gpg_error_t
2597 connect_with_timeout (assuan_fd_t sock,
2598                       struct sockaddr *addr, int addrlen,
2599                       unsigned int timeout)
2600 {
2601   gpg_error_t err;
2602   int syserr;
2603   socklen_t slen;
2604   fd_set rset, wset;
2605   struct timeval tval;
2606   int n;
2607
2608 #ifndef HAVE_W32_SYSTEM
2609   int oflags;
2610 # define RESTORE_BLOCKING()  do {  \
2611     fcntl (sock, F_SETFL, oflags); \
2612   } while (0)
2613 #else /*HAVE_W32_SYSTEM*/
2614 # define RESTORE_BLOCKING()  do {                       \
2615     unsigned long along = 0;                            \
2616     ioctlsocket (FD2INT (sock), FIONBIO, &along);       \
2617   } while (0)
2618 #endif /*HAVE_W32_SYSTEM*/
2619
2620
2621   if (!timeout)
2622     {
2623       /* Shortcut.  */
2624       if (assuan_sock_connect (sock, addr, addrlen))
2625         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2626       else
2627         err = 0;
2628       return err;
2629     }
2630
2631   /* Switch the socket into non-blocking mode.  */
2632 #ifdef HAVE_W32_SYSTEM
2633   {
2634     unsigned long along = 1;
2635     if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
2636       return my_wsagetlasterror ();
2637   }
2638 #else
2639   oflags = fcntl (sock, F_GETFL, 0);
2640   if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
2641     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2642 #endif
2643
2644   /* Do the connect.  */
2645   if (!assuan_sock_connect (sock, addr, addrlen))
2646     {
2647       /* Immediate connect.  Restore flags. */
2648       RESTORE_BLOCKING ();
2649       return 0; /* Success.  */
2650     }
2651   err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2652   if (gpg_err_code (err) != GPG_ERR_EINPROGRESS)
2653     {
2654       RESTORE_BLOCKING ();
2655       return err;
2656     }
2657
2658   FD_ZERO (&rset);
2659   FD_SET (sock, &rset);
2660   wset = rset;
2661   tval.tv_sec = timeout / 1000;
2662   tval.tv_usec = (timeout % 1000) * 1000;
2663
2664   n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
2665   if (n < 0)
2666     {
2667       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2668       RESTORE_BLOCKING ();
2669       return err;
2670     }
2671   if (!n)
2672     {
2673       /* Timeout: We do not restore the socket flags on timeout
2674        * because the caller is expected to close the socket.  */
2675       return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
2676     }
2677   if (!FD_ISSET (sock, &rset) && !FD_ISSET (sock, &wset))
2678     {
2679       /* select misbehaved.  */
2680       return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
2681     }
2682
2683   slen = sizeof (syserr);
2684   if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
2685                   (void*)&syserr, &slen) < 0)
2686     {
2687       /* Assume that this is Solaris which returns the error in ERRNO.  */
2688       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2689     }
2690   else if (syserr)
2691     err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
2692   else
2693     err = 0; /* Connected.  */
2694
2695   RESTORE_BLOCKING ();
2696
2697   return err;
2698
2699 #undef RESTORE_BLOCKING
2700 }
2701
2702
2703 /* Actually connect to a server.  On success 0 is returned and the
2704  * file descriptor for the socket is stored at R_SOCK; on error an
2705  * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
2706  * TIMEOUT is the connect timeout in milliseconds.  Note that the
2707  * function tries to connect to all known addresses and the timeout is
2708  * for each one. */
2709 static gpg_error_t
2710 connect_server (const char *server, unsigned short port,
2711                 unsigned int flags, const char *srvtag, unsigned int timeout,
2712                 assuan_fd_t *r_sock)
2713 {
2714   gpg_error_t err;
2715   assuan_fd_t sock = ASSUAN_INVALID_FD;
2716   unsigned int srvcount = 0;
2717   int hostfound = 0;
2718   int anyhostaddr = 0;
2719   int srv, connected;
2720   gpg_error_t last_err = 0;
2721   struct srventry *serverlist = NULL;
2722
2723   *r_sock = ASSUAN_INVALID_FD;
2724
2725 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2726   init_sockets ();
2727 #endif /*Windows*/
2728
2729   /* Onion addresses require special treatment.  */
2730   if (is_onion_address (server))
2731     {
2732 #ifdef ASSUAN_SOCK_TOR
2733
2734       if (opt_debug)
2735         log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2736                    server, port);
2737       sock = assuan_sock_connect_byname (server, port, 0, NULL,
2738                                          ASSUAN_SOCK_TOR);
2739       if (sock == ASSUAN_INVALID_FD)
2740         {
2741           err = gpg_err_make (default_errsource,
2742                               (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2743                               : gpg_err_code_from_syserror ());
2744           log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2745           return err;
2746         }
2747
2748       notify_netactivity ();
2749       *r_sock = sock;
2750       return 0;
2751
2752 #else /*!ASSUAN_SOCK_TOR*/
2753
2754       err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2755       return ASSUAN_INVALID_FD;
2756
2757 #endif /*!HASSUAN_SOCK_TOR*/
2758     }
2759
2760   /* Do the SRV thing */
2761   if (srvtag)
2762     {
2763       err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2764       if (err)
2765         log_info ("getting '%s' SRV for '%s' failed: %s\n",
2766                   srvtag, server, gpg_strerror (err));
2767       /* Note that on error SRVCOUNT is zero.  */
2768       err = 0;
2769     }
2770
2771   if (!serverlist)
2772     {
2773       /* Either we're not using SRV, or the SRV lookup failed.  Make
2774          up a fake SRV record. */
2775       serverlist = xtrycalloc (1, sizeof *serverlist);
2776       if (!serverlist)
2777         return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2778
2779       serverlist->port = port;
2780       strncpy (serverlist->target, server, DIMof (struct srventry, target));
2781       serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2782       srvcount = 1;
2783     }
2784
2785   connected = 0;
2786   for (srv=0; srv < srvcount && !connected; srv++)
2787     {
2788       dns_addrinfo_t aibuf, ai;
2789
2790       if (opt_debug)
2791         log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2792                    serverlist[srv].target, port);
2793       err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2794                               &aibuf, NULL);
2795       if (err)
2796         {
2797           log_info ("resolving '%s' failed: %s\n",
2798                     serverlist[srv].target, gpg_strerror (err));
2799           last_err = err;
2800           continue; /* Not found - try next one. */
2801         }
2802       hostfound = 1;
2803
2804       for (ai = aibuf; ai && !connected; ai = ai->next)
2805         {
2806           if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2807             continue;
2808           if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2809             continue;
2810
2811           if (sock != ASSUAN_INVALID_FD)
2812             assuan_sock_close (sock);
2813           sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2814           if (sock == ASSUAN_INVALID_FD)
2815             {
2816               err = gpg_err_make (default_errsource,
2817                                   gpg_err_code_from_syserror ());
2818               log_error ("error creating socket: %s\n", gpg_strerror (err));
2819               free_dns_addrinfo (aibuf);
2820               xfree (serverlist);
2821               return err;
2822             }
2823
2824           anyhostaddr = 1;
2825           err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
2826                                       ai->addrlen, timeout);
2827           if (err)
2828             {
2829               last_err = err;
2830             }
2831           else
2832             {
2833               connected = 1;
2834               notify_netactivity ();
2835             }
2836         }
2837       free_dns_addrinfo (aibuf);
2838     }
2839
2840   xfree (serverlist);
2841
2842   if (!connected)
2843     {
2844       if (!hostfound)
2845         log_error ("can't connect to '%s': %s\n",
2846                    server, "host not found");
2847       else if (!anyhostaddr)
2848         log_error ("can't connect to '%s': %s\n",
2849                    server, "no IP address for host");
2850       else
2851         {
2852 #ifdef HAVE_W32_SYSTEM
2853         log_error ("can't connect to '%s': ec=%d\n",
2854                    server, (int)WSAGetLastError());
2855 #else
2856         log_error ("can't connect to '%s': %s\n",
2857                    server, gpg_strerror (last_err));
2858 #endif
2859         }
2860       err = last_err? last_err : gpg_err_make (default_errsource,
2861                                                GPG_ERR_UNKNOWN_HOST);
2862       if (sock != ASSUAN_INVALID_FD)
2863         assuan_sock_close (sock);
2864       return err;
2865     }
2866
2867   *r_sock = sock;
2868   return 0;
2869 }
2870
2871
2872 /* Helper to read from a socket.  This handles npth things and
2873  * EINTR.  */
2874 static gpgrt_ssize_t
2875 read_server (assuan_fd_t sock, void *buffer, size_t size)
2876 {
2877   int nread;
2878
2879   do
2880     {
2881 #ifdef HAVE_W32_SYSTEM
2882       /* Under Windows we need to use recv for a socket.  */
2883 # if defined(USE_NPTH)
2884       npth_unprotect ();
2885 # endif
2886       nread = recv (FD2INT (sock), buffer, size, 0);
2887 # if defined(USE_NPTH)
2888       npth_protect ();
2889 # endif
2890
2891 #else /*!HAVE_W32_SYSTEM*/
2892
2893 # ifdef USE_NPTH
2894       nread = npth_read (sock, buffer, size);
2895 # else
2896       nread = read (sock, buffer, size);
2897 # endif
2898
2899 #endif /*!HAVE_W32_SYSTEM*/
2900     }
2901   while (nread == -1 && errno == EINTR);
2902
2903   return nread;
2904 }
2905
2906
2907 static gpg_error_t
2908 write_server (assuan_fd_t sock, const char *data, size_t length)
2909 {
2910   int nleft;
2911   int nwritten;
2912
2913   nleft = length;
2914   while (nleft > 0)
2915     {
2916 #if defined(HAVE_W32_SYSTEM)
2917 # if defined(USE_NPTH)
2918       npth_unprotect ();
2919 # endif
2920       nwritten = send (FD2INT (sock), data, nleft, 0);
2921 # if defined(USE_NPTH)
2922       npth_protect ();
2923 # endif
2924       if ( nwritten == SOCKET_ERROR )
2925         {
2926           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2927           return gpg_error (GPG_ERR_NETWORK);
2928         }
2929 #else /*!HAVE_W32_SYSTEM*/
2930 # ifdef USE_NPTH
2931       nwritten = npth_write (sock, data, nleft);
2932 # else
2933       nwritten = write (sock, data, nleft);
2934 # endif
2935       if (nwritten == -1)
2936         {
2937           if (errno == EINTR)
2938             continue;
2939           if (errno == EAGAIN)
2940             {
2941               struct timeval tv;
2942
2943               tv.tv_sec = 0;
2944               tv.tv_usec = 50000;
2945               my_select (0, NULL, NULL, NULL, &tv);
2946               continue;
2947             }
2948           log_info ("network write failed: %s\n", strerror (errno));
2949           return gpg_error_from_syserror ();
2950         }
2951 #endif /*!HAVE_W32_SYSTEM*/
2952       nleft -= nwritten;
2953       data += nwritten;
2954     }
2955
2956   return 0;
2957 }
2958
2959
2960 \f
2961 /* Read handler for estream.  */
2962 static gpgrt_ssize_t
2963 cookie_read (void *cookie, void *buffer, size_t size)
2964 {
2965   cookie_t c = cookie;
2966   int nread;
2967
2968   if (c->content_length_valid)
2969     {
2970       if (!c->content_length)
2971         return 0; /* EOF */
2972       if (c->content_length < size)
2973         size = c->content_length;
2974     }
2975
2976 #if HTTP_USE_NTBTLS
2977   if (c->use_tls && c->session && c->session->tls_session)
2978     {
2979       estream_t in, out;
2980
2981       ntbtls_get_stream (c->session->tls_session, &in, &out);
2982       nread = es_fread (buffer, 1, size, in);
2983       if (opt_debug)
2984         log_debug ("TLS network read: %d/%zu\n", nread, size);
2985     }
2986   else
2987 #elif HTTP_USE_GNUTLS
2988   if (c->use_tls && c->session && c->session->tls_session)
2989     {
2990     again:
2991       nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2992       if (nread < 0)
2993         {
2994           if (nread == GNUTLS_E_INTERRUPTED)
2995             goto again;
2996           if (nread == GNUTLS_E_AGAIN)
2997             {
2998               struct timeval tv;
2999
3000               tv.tv_sec = 0;
3001               tv.tv_usec = 50000;
3002               my_select (0, NULL, NULL, NULL, &tv);
3003               goto again;
3004             }
3005           if (nread == GNUTLS_E_REHANDSHAKE)
3006             goto again; /* A client is allowed to just ignore this request. */
3007           if (nread == GNUTLS_E_PREMATURE_TERMINATION)
3008             {
3009               /* The server terminated the connection.  Close the TLS
3010                  session, and indicate EOF using a short read.  */
3011               close_tls_session (c->session);
3012               return 0;
3013             }
3014           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
3015           gpg_err_set_errno (EIO);
3016           return -1;
3017         }
3018     }
3019   else
3020 #endif /*HTTP_USE_GNUTLS*/
3021     {
3022       nread = read_server (c->sock->fd, buffer, size);
3023     }
3024
3025   if (c->content_length_valid && nread > 0)
3026     {
3027       if (nread < c->content_length)
3028         c->content_length -= nread;
3029       else
3030         c->content_length = 0;
3031     }
3032
3033   return (gpgrt_ssize_t)nread;
3034 }
3035
3036 /* Write handler for estream.  */
3037 static gpgrt_ssize_t
3038 cookie_write (void *cookie, const void *buffer_arg, size_t size)
3039 {
3040   const char *buffer = buffer_arg;
3041   cookie_t c = cookie;
3042   int nwritten = 0;
3043
3044 #if HTTP_USE_NTBTLS
3045   if (c->use_tls && c->session && c->session->tls_session)
3046     {
3047       estream_t in, out;
3048
3049       ntbtls_get_stream (c->session->tls_session, &in, &out);
3050       if (size == 0)
3051         es_fflush (out);
3052       else
3053         nwritten = es_fwrite (buffer, 1, size, out);
3054       if (opt_debug)
3055         log_debug ("TLS network write: %d/%zu\n", nwritten, size);
3056     }
3057   else
3058 #elif HTTP_USE_GNUTLS
3059   if (c->use_tls && c->session && c->session->tls_session)
3060     {
3061       int nleft = size;
3062       while (nleft > 0)
3063         {
3064           nwritten = gnutls_record_send (c->session->tls_session,
3065                                          buffer, nleft);
3066           if (nwritten <= 0)
3067             {
3068               if (nwritten == GNUTLS_E_INTERRUPTED)
3069                 continue;
3070               if (nwritten == GNUTLS_E_AGAIN)
3071                 {
3072                   struct timeval tv;
3073
3074                   tv.tv_sec = 0;
3075                   tv.tv_usec = 50000;
3076                   my_select (0, NULL, NULL, NULL, &tv);
3077                   continue;
3078                 }
3079               log_info ("TLS network write failed: %s\n",
3080                         gnutls_strerror (nwritten));
3081               gpg_err_set_errno (EIO);
3082               return -1;
3083             }
3084           nleft -= nwritten;
3085           buffer += nwritten;
3086         }
3087     }
3088   else
3089 #endif /*HTTP_USE_GNUTLS*/
3090     {
3091       if ( write_server (c->sock->fd, buffer, size) )
3092         {
3093           gpg_err_set_errno (EIO);
3094           nwritten = -1;
3095         }
3096       else
3097         nwritten = size;
3098     }
3099
3100   return (gpgrt_ssize_t)nwritten;
3101 }
3102
3103
3104 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
3105 static gpgrt_ssize_t
3106 simple_cookie_read (void *cookie, void *buffer, size_t size)
3107 {
3108   assuan_fd_t sock = (assuan_fd_t)cookie;
3109   return read_server (sock, buffer, size);
3110 }
3111
3112 static gpgrt_ssize_t
3113 simple_cookie_write (void *cookie, const void *buffer_arg, size_t size)
3114 {
3115   assuan_fd_t sock = (assuan_fd_t)cookie;
3116   const char *buffer = buffer_arg;
3117   int nwritten;
3118
3119   if (write_server (sock, buffer, size))
3120     {
3121       gpg_err_set_errno (EIO);
3122       nwritten = -1;
3123     }
3124   else
3125     nwritten = size;
3126
3127   return (gpgrt_ssize_t)nwritten;
3128 }
3129 #endif /*HAVE_W32_SYSTEM*/
3130
3131
3132 #ifdef HTTP_USE_GNUTLS
3133 /* Wrapper for gnutls_bye used by my_socket_unref.  */
3134 static void
3135 send_gnutls_bye (void *opaque)
3136 {
3137   tls_session_t tls_session = opaque;
3138   int ret;
3139
3140  again:
3141   do
3142     ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
3143   while (ret == GNUTLS_E_INTERRUPTED);
3144   if (ret == GNUTLS_E_AGAIN)
3145     {
3146       struct timeval tv;
3147
3148       tv.tv_sec = 0;
3149       tv.tv_usec = 50000;
3150       my_select (0, NULL, NULL, NULL, &tv);
3151       goto again;
3152     }
3153 }
3154 #endif /*HTTP_USE_GNUTLS*/
3155
3156 /* Close handler for estream.  */
3157 static int
3158 cookie_close (void *cookie)
3159 {
3160   cookie_t c = cookie;
3161
3162   if (!c)
3163     return 0;
3164
3165 #if HTTP_USE_NTBTLS
3166   if (c->use_tls && c->session && c->session->tls_session)
3167     {
3168       /* FIXME!! Possibly call ntbtls_close_notify for close
3169          of write stream.  */
3170       my_socket_unref (c->sock, NULL, NULL);
3171     }
3172   else
3173 #elif HTTP_USE_GNUTLS
3174   if (c->use_tls && c->session && c->session->tls_session)
3175     my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
3176   else
3177 #endif /*HTTP_USE_GNUTLS*/
3178     if (c->sock)
3179       my_socket_unref (c->sock, NULL, NULL);
3180
3181   if (c->session)
3182     http_session_unref (c->session);
3183   xfree (c);
3184   return 0;
3185 }
3186
3187
3188
3189 \f
3190 /* Verify the credentials of the server.  Returns 0 on success and
3191    store the result in the session object.  */
3192 gpg_error_t
3193 http_verify_server_credentials (http_session_t sess)
3194 {
3195 #if HTTP_USE_GNUTLS
3196   static const char const errprefix[] = "TLS verification of peer failed";
3197   int rc;
3198   unsigned int status;
3199   const char *hostname;
3200   const gnutls_datum_t *certlist;
3201   unsigned int certlistlen;
3202   gnutls_x509_crt_t cert;
3203   gpg_error_t err = 0;
3204
3205   sess->verify.done = 1;
3206   sess->verify.status = 0;
3207   sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
3208
3209   if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
3210     {
3211       log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
3212       sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
3213       return gpg_error (GPG_ERR_GENERAL);
3214     }
3215
3216   rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
3217   if (rc)
3218     {
3219       log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
3220       if (!err)
3221         err = gpg_error (GPG_ERR_GENERAL);
3222     }
3223   else if (status)
3224     {
3225       log_error ("%s: status=0x%04x\n", errprefix, status);
3226 #if GNUTLS_VERSION_NUMBER >= 0x030104
3227       {
3228         gnutls_datum_t statusdat;
3229
3230         if (!gnutls_certificate_verification_status_print
3231             (status, GNUTLS_CRT_X509, &statusdat, 0))
3232           {
3233             log_info ("%s: %s\n", errprefix, statusdat.data);
3234             gnutls_free (statusdat.data);
3235           }
3236       }
3237 #endif /*gnutls >= 3.1.4*/
3238
3239       sess->verify.status = status;
3240       if (!err)
3241         err = gpg_error (GPG_ERR_GENERAL);
3242     }
3243
3244   hostname = sess->servername;
3245   if (!hostname || !strchr (hostname, '.'))
3246     {
3247       log_error ("%s: %s\n", errprefix, "hostname missing");
3248       if (!err)
3249         err = gpg_error (GPG_ERR_GENERAL);
3250     }
3251
3252   certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
3253   if (!certlistlen)
3254     {
3255       log_error ("%s: %s\n", errprefix, "server did not send a certificate");
3256       if (!err)
3257         err = gpg_error (GPG_ERR_GENERAL);
3258
3259       /* Need to stop here.  */
3260       if (err)
3261         return err;
3262     }
3263
3264   rc = gnutls_x509_crt_init (&cert);
3265   if (rc < 0)
3266     {
3267       if (!err)
3268         err = gpg_error (GPG_ERR_GENERAL);
3269       if (err)
3270         return err;
3271     }
3272
3273   rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3274   if (rc < 0)
3275     {
3276       log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3277                  gnutls_strerror (rc));
3278       if (!err)
3279         err = gpg_error (GPG_ERR_GENERAL);
3280     }
3281
3282   if (!gnutls_x509_crt_check_hostname (cert, hostname))
3283     {
3284       log_error ("%s: %s\n", errprefix, "hostname does not match");
3285       if (!err)
3286         err = gpg_error (GPG_ERR_GENERAL);
3287     }
3288
3289   gnutls_x509_crt_deinit (cert);
3290
3291   if (!err)
3292     sess->verify.rc = 0;
3293
3294   if (sess->cert_log_cb)
3295     {
3296       const void *bufarr[10];
3297       size_t buflenarr[10];
3298       size_t n;
3299
3300       for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3301         {
3302           bufarr[n] = certlist[n].data;
3303           buflenarr[n] = certlist[n].size;
3304         }
3305       bufarr[n] = NULL;
3306       buflenarr[n] = 0;
3307       sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3308     }
3309
3310   return err;
3311 #else /*!HTTP_USE_GNUTLS*/
3312   (void)sess;
3313   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3314 #endif
3315 }
3316
3317 /* Return the first query variable with the specified key.  If there
3318    is no such variable, return NULL.  */
3319 struct uri_tuple_s *
3320 uri_query_lookup (parsed_uri_t uri, const char *key)
3321 {
3322   struct uri_tuple_s *t;
3323
3324   for (t = uri->query; t; t = t->next)
3325     if (strcmp (t->name, key) == 0)
3326       return t;
3327
3328   return NULL;
3329 }