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