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