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