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