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