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