90682fa46f53e5fcecda973b353bbb3bc55f9c90
[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
617     rc = gnutls_certificate_allocate_credentials (&sess->certcred);
618     if (rc < 0)
619       {
620         log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
621                    gnutls_strerror (rc));
622         err = gpg_error (GPG_ERR_GENERAL);
623         goto leave;
624       }
625
626     /* If the user has not specified a CA list, and they are looking
627      * for the hkps pool from sks-keyservers.net, then default to
628      * Kristian's certificate authority:  */
629     if (!tls_ca_certlist
630         && intended_hostname
631         && !ascii_strcasecmp (intended_hostname,
632                               "hkps.pool.sks-keyservers.net"))
633       {
634         char *pemname = make_filename_try (gnupg_datadir (),
635                                            "sks-keyservers.netCA.pem", NULL);
636         if (!pemname)
637           {
638             err = gpg_error_from_syserror ();
639             log_error ("setting CA from file '%s' failed: %s\n",
640                        pemname, gpg_strerror (err));
641           }
642         else
643           {
644             rc = gnutls_certificate_set_x509_trust_file
645               (sess->certcred, pemname, GNUTLS_X509_FMT_PEM);
646             if (rc < 0)
647               log_info ("setting CA from file '%s' failed: %s\n",
648                         pemname, gnutls_strerror (rc));
649             xfree (pemname);
650           }
651       }
652
653     /* Add configured certificates to the session.  */
654     if ((flags & HTTP_FLAG_TRUST_DEF))
655       {
656         for (sl = tls_ca_certlist; sl; sl = sl->next)
657           {
658             rc = gnutls_certificate_set_x509_trust_file
659               (sess->certcred, sl->d,
660                (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
661             if (rc < 0)
662               log_info ("setting CA from file '%s' failed: %s\n",
663                         sl->d, gnutls_strerror (rc));
664           }
665       }
666
667     /* Add system certificates to the session.  */
668     if ((flags & HTTP_FLAG_TRUST_SYS))
669       {
670 #if GNUTLS_VERSION_NUMBER >= 0x030014
671         static int shown;
672
673         rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
674         if (rc < 0)
675           log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
676         else if (!shown)
677           {
678             shown = 1;
679             log_info ("number of system provided CAs: %d\n", rc);
680           }
681 #endif /* gnutls >= 3.0.20 */
682       }
683
684     rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
685     if (rc < 0)
686       {
687         log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
688         err = gpg_error (GPG_ERR_GENERAL);
689         goto leave;
690       }
691     /* A new session has the transport ptr set to (void*(-1), we need
692        it to be NULL.  */
693     gnutls_transport_set_ptr (sess->tls_session, NULL);
694
695     rc = gnutls_priority_set_direct (sess->tls_session,
696                                      tls_priority? tls_priority : "NORMAL",
697                                      &errpos);
698     if (rc < 0)
699       {
700         log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
701                    errpos, gnutls_strerror (rc));
702         err = gpg_error (GPG_ERR_GENERAL);
703         goto leave;
704       }
705
706     rc = gnutls_credentials_set (sess->tls_session,
707                                  GNUTLS_CRD_CERTIFICATE, sess->certcred);
708     if (rc < 0)
709       {
710         log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
711         err = gpg_error (GPG_ERR_GENERAL);
712         goto leave;
713       }
714   }
715 #else /*!HTTP_USE_GNUTLS*/
716   {
717     (void)tls_priority;
718   }
719 #endif /*!HTTP_USE_GNUTLS*/
720
721   /* log_debug ("http.c:session_new: sess %p created\n", sess); */
722   err = 0;
723
724 #if USE_TLS
725  leave:
726 #endif /*USE_TLS*/
727   if (err)
728     http_session_unref (sess);
729   else
730     *r_session = sess;
731
732   return err;
733 }
734
735
736 /* Increment the reference count for session SESS.  Passing NULL for
737    SESS is allowed. */
738 http_session_t
739 http_session_ref (http_session_t sess)
740 {
741   if (sess)
742     {
743       sess->refcount++;
744       /* log_debug ("http.c:session_ref: sess %p ref now %d\n", sess, */
745       /*            sess->refcount); */
746     }
747   return sess;
748 }
749
750
751 void
752 http_session_set_log_cb (http_session_t sess,
753                          void (*cb)(http_session_t, gpg_error_t,
754                                     const char *hostname,
755                                     const void **certs, size_t *certlens))
756 {
757   sess->cert_log_cb = cb;
758 }
759
760
761
762 \f
763 /* Start a HTTP retrieval and on success store at R_HD a context
764    pointer for completing the request and to wait for the response.
765    If HTTPHOST is not NULL it is used for the Host header instead of a
766    Host header derived from the URL. */
767 gpg_error_t
768 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
769            const char *httphost,
770            const char *auth, unsigned int flags, const char *proxy,
771            http_session_t session, const char *srvtag, strlist_t headers)
772 {
773   gpg_error_t err;
774   http_t hd;
775
776   *r_hd = NULL;
777
778   if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
779     return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
780
781   /* Create the handle. */
782   hd = xtrycalloc (1, sizeof *hd);
783   if (!hd)
784     return gpg_error_from_syserror ();
785   hd->req_type = reqtype;
786   hd->flags = flags;
787   hd->session = http_session_ref (session);
788
789   err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
790   if (!err)
791     err = send_request (hd, httphost, auth, proxy, srvtag, headers);
792
793   if (err)
794     {
795       my_socket_unref (hd->sock, NULL, NULL);
796       if (hd->fp_read)
797         es_fclose (hd->fp_read);
798       if (hd->fp_write)
799         es_fclose (hd->fp_write);
800       http_session_unref (hd->session);
801       xfree (hd);
802     }
803   else
804     *r_hd = hd;
805   return err;
806 }
807
808
809 /* This function is useful to connect to a generic TCP service using
810    this http abstraction layer.  This has the advantage of providing
811    service tags and an estream interface.  */
812 gpg_error_t
813 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
814                   unsigned int flags, const char *srvtag)
815 {
816   gpg_error_t err = 0;
817   http_t hd;
818   cookie_t cookie;
819   int hnf;
820
821   *r_hd = NULL;
822
823   if ((flags & HTTP_FLAG_FORCE_TOR))
824     {
825       int mode;
826
827       if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
828         {
829           log_error ("Tor support is not available\n");
830           return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
831         }
832     }
833
834   /* Create the handle. */
835   hd = xtrycalloc (1, sizeof *hd);
836   if (!hd)
837     return gpg_error_from_syserror ();
838   hd->req_type = HTTP_REQ_OPAQUE;
839   hd->flags = flags;
840
841   /* Connect.  */
842   {
843     assuan_fd_t sock;
844
845     sock = connect_server (server, port, hd->flags, srvtag, &hnf);
846     if (sock == ASSUAN_INVALID_FD)
847       {
848         err = gpg_err_make (default_errsource,
849                             (hnf? GPG_ERR_UNKNOWN_HOST
850                              : gpg_err_code_from_syserror ()));
851         xfree (hd);
852         return err;
853       }
854     hd->sock = my_socket_new (sock);
855     if (!hd->sock)
856       {
857         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
858         xfree (hd);
859         return err;
860       }
861   }
862
863   /* Setup estreams for reading and writing.  */
864   cookie = xtrycalloc (1, sizeof *cookie);
865   if (!cookie)
866     {
867       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
868       goto leave;
869     }
870   cookie->sock = my_socket_ref (hd->sock);
871   hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
872   if (!hd->fp_write)
873     {
874       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
875       my_socket_unref (cookie->sock, NULL, NULL);
876       xfree (cookie);
877       goto leave;
878     }
879   hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE.  */
880
881   cookie = xtrycalloc (1, sizeof *cookie);
882   if (!cookie)
883     {
884       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
885       goto leave;
886     }
887   cookie->sock = my_socket_ref (hd->sock);
888   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
889   if (!hd->fp_read)
890     {
891       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
892       my_socket_unref (cookie->sock, NULL, NULL);
893       xfree (cookie);
894       goto leave;
895     }
896   hd->read_cookie = cookie; /* Cookie now owned by FP_READ.  */
897
898   /* Register close notification to interlock the use of es_fclose in
899      http_close and in user code.  */
900   err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
901   if (!err)
902     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
903
904  leave:
905   if (err)
906     {
907       if (hd->fp_read)
908         es_fclose (hd->fp_read);
909       if (hd->fp_write)
910         es_fclose (hd->fp_write);
911       my_socket_unref (hd->sock, NULL, NULL);
912       xfree (hd);
913     }
914   else
915     *r_hd = hd;
916   return err;
917 }
918
919
920
921
922 void
923 http_start_data (http_t hd)
924 {
925   if (!hd->in_data)
926     {
927       es_fputs ("\r\n", hd->fp_write);
928       es_fflush (hd->fp_write);
929       hd->in_data = 1;
930     }
931   else
932     es_fflush (hd->fp_write);
933 }
934
935
936 gpg_error_t
937 http_wait_response (http_t hd)
938 {
939   gpg_error_t err;
940   cookie_t cookie;
941
942   /* Make sure that we are in the data. */
943   http_start_data (hd);
944
945   /* Close the write stream.  Note that the reference counted socket
946      object keeps the actual system socket open.  */
947   cookie = hd->write_cookie;
948   if (!cookie)
949     return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
950
951   es_fclose (hd->fp_write);
952   hd->fp_write = NULL;
953   /* The close has released the cookie and thus we better set it to NULL.  */
954   hd->write_cookie = NULL;
955
956   /* Shutdown one end of the socket is desired.  As per HTTP/1.0 this
957      is not required but some very old servers (e.g. the original pksd
958      keyserver didn't worked without it.  */
959   if ((hd->flags & HTTP_FLAG_SHUTDOWN))
960     shutdown (hd->sock->fd, 1);
961   hd->in_data = 0;
962
963   /* Create a new cookie and a stream for reading.  */
964   cookie = xtrycalloc (1, sizeof *cookie);
965   if (!cookie)
966     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
967   cookie->sock = my_socket_ref (hd->sock);
968   cookie->session = http_session_ref (hd->session);
969   cookie->use_tls = hd->uri->use_tls;
970
971   hd->read_cookie = cookie;
972   hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
973   if (!hd->fp_read)
974     {
975       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
976       my_socket_unref (cookie->sock, NULL, NULL);
977       http_session_unref (cookie->session);
978       xfree (cookie);
979       hd->read_cookie = NULL;
980       return err;
981     }
982
983   err = parse_response (hd);
984
985   if (!err)
986     err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
987
988   return err;
989 }
990
991
992 /* Convenience function to send a request and wait for the response.
993    Closes the handle on error.  If PROXY is not NULL, this value will
994    be used as an HTTP proxy and any enabled $http_proxy gets
995    ignored. */
996 gpg_error_t
997 http_open_document (http_t *r_hd, const char *document,
998                     const char *auth, unsigned int flags, const char *proxy,
999                     http_session_t session,
1000                     const char *srvtag, strlist_t headers)
1001 {
1002   gpg_error_t err;
1003
1004   err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1005                    proxy, session, srvtag, headers);
1006   if (err)
1007     return err;
1008
1009   err = http_wait_response (*r_hd);
1010   if (err)
1011     http_close (*r_hd, 0);
1012
1013   return err;
1014 }
1015
1016
1017 void
1018 http_close (http_t hd, int keep_read_stream)
1019 {
1020   if (!hd)
1021     return;
1022
1023   /* First remove the close notifications for the streams.  */
1024   if (hd->fp_read)
1025     es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1026   if (hd->fp_write)
1027     es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1028
1029   /* Now we can close the streams.  */
1030   my_socket_unref (hd->sock, NULL, NULL);
1031   if (hd->fp_read && !keep_read_stream)
1032     es_fclose (hd->fp_read);
1033   if (hd->fp_write)
1034     es_fclose (hd->fp_write);
1035   http_session_unref (hd->session);
1036   http_release_parsed_uri (hd->uri);
1037   while (hd->headers)
1038     {
1039       header_t tmp = hd->headers->next;
1040       xfree (hd->headers->value);
1041       xfree (hd->headers);
1042       hd->headers = tmp;
1043     }
1044   xfree (hd->buffer);
1045   xfree (hd);
1046 }
1047
1048
1049 estream_t
1050 http_get_read_ptr (http_t hd)
1051 {
1052   return hd?hd->fp_read:NULL;
1053 }
1054
1055 estream_t
1056 http_get_write_ptr (http_t hd)
1057 {
1058   return hd?hd->fp_write:NULL;
1059 }
1060
1061 unsigned int
1062 http_get_status_code (http_t hd)
1063 {
1064   return hd?hd->status_code:0;
1065 }
1066
1067 /* Return information pertaining to TLS.  If TLS is not in use for HD,
1068    NULL is returned.  WHAT is used ask for specific information:
1069
1070      (NULL) := Only check whether TLS is is use.  Returns an
1071                unspecified string if TLS is in use.  That string may
1072                even be the empty string.
1073  */
1074 const char *
1075 http_get_tls_info (http_t hd, const char *what)
1076 {
1077   (void)what;
1078
1079   if (!hd)
1080     return NULL;
1081
1082   return hd->uri->use_tls? "":NULL;
1083 }
1084
1085
1086 \f
1087 static gpg_error_t
1088 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1089            int no_scheme_check, int force_tls)
1090 {
1091   gpg_err_code_t ec;
1092
1093   *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1094   if (!*ret_uri)
1095     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1096   strcpy ((*ret_uri)->buffer, uri);
1097   ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1098   if (ec)
1099     {
1100       xfree (*ret_uri);
1101       *ret_uri = NULL;
1102     }
1103   return gpg_err_make (default_errsource, ec);
1104 }
1105
1106
1107 /*
1108  * Parse an URI and put the result into the newly allocated RET_URI.
1109  * On success the caller must use http_release_parsed_uri() to
1110  * releases the resources.  If NO_SCHEME_CHECK is set, the function
1111  * tries to parse the URL in the same way it would do for an HTTP
1112  * style URI.
1113  */
1114 gpg_error_t
1115 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1116                 int no_scheme_check)
1117 {
1118   return parse_uri (ret_uri, uri, no_scheme_check, 0);
1119 }
1120
1121
1122 void
1123 http_release_parsed_uri (parsed_uri_t uri)
1124 {
1125   if (uri)
1126     {
1127       uri_tuple_t r, r2;
1128
1129       for (r = uri->query; r; r = r2)
1130         {
1131           r2 = r->next;
1132           xfree (r);
1133         }
1134       xfree (uri);
1135     }
1136 }
1137
1138
1139 static gpg_err_code_t
1140 do_parse_uri (parsed_uri_t uri, int only_local_part,
1141               int no_scheme_check, int force_tls)
1142 {
1143   uri_tuple_t *tail;
1144   char *p, *p2, *p3, *pp;
1145   int n;
1146
1147   p = uri->buffer;
1148   n = strlen (uri->buffer);
1149
1150   /* Initialize all fields to an empty string or an empty list. */
1151   uri->scheme = uri->host = uri->path = p + n;
1152   uri->port = 0;
1153   uri->params = uri->query = NULL;
1154   uri->use_tls = 0;
1155   uri->is_http = 0;
1156   uri->opaque = 0;
1157   uri->v6lit = 0;
1158   uri->onion = 0;
1159
1160   /* A quick validity check. */
1161   if (strspn (p, VALID_URI_CHARS) != n)
1162     return GPG_ERR_BAD_URI;     /* Invalid characters found. */
1163
1164   if (!only_local_part)
1165     {
1166       /* Find the scheme. */
1167       if (!(p2 = strchr (p, ':')) || p2 == p)
1168         return GPG_ERR_BAD_URI; /* No scheme. */
1169       *p2++ = 0;
1170       for (pp=p; *pp; pp++)
1171        *pp = tolower (*(unsigned char*)pp);
1172       uri->scheme = p;
1173       if (!strcmp (uri->scheme, "http") && !force_tls)
1174         {
1175           uri->port = 80;
1176           uri->is_http = 1;
1177         }
1178       else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1179         {
1180           uri->port = 11371;
1181           uri->is_http = 1;
1182         }
1183 #ifdef USE_TLS
1184       else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1185                || (force_tls && (!strcmp (uri->scheme, "http")
1186                                  || !strcmp (uri->scheme,"hkp"))))
1187         {
1188           uri->port = 443;
1189           uri->is_http = 1;
1190           uri->use_tls = 1;
1191         }
1192 #endif /*USE_TLS*/
1193       else if (!no_scheme_check)
1194         return GPG_ERR_INV_URI; /* Unsupported scheme */
1195
1196       p = p2;
1197
1198       if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1199         {
1200           p += 2;
1201           if ((p2 = strchr (p, '/')))
1202             *p2++ = 0;
1203
1204           /* Check for username/password encoding */
1205           if ((p3 = strchr (p, '@')))
1206             {
1207               uri->auth = p;
1208               *p3++ = '\0';
1209               p = p3;
1210             }
1211
1212           for (pp=p; *pp; pp++)
1213             *pp = tolower (*(unsigned char*)pp);
1214
1215           /* Handle an IPv6 literal */
1216           if( *p == '[' && (p3=strchr( p, ']' )) )
1217             {
1218               *p3++ = '\0';
1219               /* worst case, uri->host should have length 0, points to \0 */
1220               uri->host = p + 1;
1221               uri->v6lit = 1;
1222               p = p3;
1223             }
1224           else
1225             uri->host = p;
1226
1227           if ((p3 = strchr (p, ':')))
1228             {
1229               *p3++ = '\0';
1230               uri->port = atoi (p3);
1231             }
1232
1233           if ((n = remove_escapes (uri->host)) < 0)
1234             return GPG_ERR_BAD_URI;
1235           if (n != strlen (uri->host))
1236             return GPG_ERR_BAD_URI;     /* Hostname incudes a Nul. */
1237           p = p2 ? p2 : NULL;
1238         }
1239       else if (uri->is_http)
1240         return GPG_ERR_INV_URI; /* No Leading double slash for HTTP.  */
1241       else
1242         {
1243           uri->opaque = 1;
1244           uri->path = p;
1245           if (is_onion_address (uri->path))
1246             uri->onion = 1;
1247           return 0;
1248         }
1249
1250     } /* End global URI part. */
1251
1252   /* Parse the pathname part if any.  */
1253   if (p && *p)
1254     {
1255       /* TODO: Here we have to check params. */
1256
1257       /* Do we have a query part? */
1258       if ((p2 = strchr (p, '?')))
1259         *p2++ = 0;
1260
1261       uri->path = p;
1262       if ((n = remove_escapes (p)) < 0)
1263         return GPG_ERR_BAD_URI;
1264       if (n != strlen (p))
1265         return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1266       p = p2 ? p2 : NULL;
1267
1268       /* Parse a query string if any.  */
1269       if (p && *p)
1270         {
1271           tail = &uri->query;
1272           for (;;)
1273             {
1274               uri_tuple_t elem;
1275
1276               if ((p2 = strchr (p, '&')))
1277                 *p2++ = 0;
1278               if (!(elem = parse_tuple (p)))
1279                 return GPG_ERR_BAD_URI;
1280               *tail = elem;
1281               tail = &elem->next;
1282
1283               if (!p2)
1284                 break; /* Ready. */
1285               p = p2;
1286             }
1287         }
1288     }
1289
1290   if (is_onion_address (uri->host))
1291     uri->onion = 1;
1292
1293   return 0;
1294 }
1295
1296
1297 /*
1298  * Remove all %xx escapes; this is done in-place.  Returns: New length
1299  * of the string.
1300  */
1301 static int
1302 remove_escapes (char *string)
1303 {
1304   int n = 0;
1305   unsigned char *p, *s;
1306
1307   for (p = s = (unsigned char*)string; *s; s++)
1308     {
1309       if (*s == '%')
1310         {
1311           if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1312             {
1313               s++;
1314               *p = *s >= '0' && *s <= '9' ? *s - '0' :
1315                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1316               *p <<= 4;
1317               s++;
1318               *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1319                 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1320               p++;
1321               n++;
1322             }
1323           else
1324             {
1325               *p++ = *s++;
1326               if (*s)
1327                 *p++ = *s++;
1328               if (*s)
1329                 *p++ = *s++;
1330               if (*s)
1331                 *p = 0;
1332               return -1; /* Bad URI. */
1333             }
1334         }
1335       else
1336         {
1337           *p++ = *s;
1338           n++;
1339         }
1340     }
1341   *p = 0; /* Make sure to keep a string terminator. */
1342   return n;
1343 }
1344
1345
1346 /* If SPECIAL is NULL this function escapes in forms mode.  */
1347 static size_t
1348 escape_data (char *buffer, const void *data, size_t datalen,
1349              const char *special)
1350 {
1351   int forms = !special;
1352   const unsigned char *s;
1353   size_t n = 0;
1354
1355   if (forms)
1356     special = "%;?&=";
1357
1358   for (s = data; datalen; s++, datalen--)
1359     {
1360       if (forms && *s == ' ')
1361         {
1362           if (buffer)
1363             *buffer++ = '+';
1364           n++;
1365         }
1366       else if (forms && *s == '\n')
1367         {
1368           if (buffer)
1369             memcpy (buffer, "%0D%0A", 6);
1370           n += 6;
1371         }
1372       else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1373         {
1374           if (buffer)
1375             memcpy (buffer, "%0D%0A", 6);
1376           n += 6;
1377           s++;
1378           datalen--;
1379         }
1380       else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1381         {
1382           if (buffer)
1383             *(unsigned char*)buffer++ = *s;
1384           n++;
1385         }
1386       else
1387         {
1388           if (buffer)
1389             {
1390               snprintf (buffer, 4, "%%%02X", *s);
1391               buffer += 3;
1392             }
1393           n += 3;
1394         }
1395     }
1396   return n;
1397 }
1398
1399
1400 static int
1401 insert_escapes (char *buffer, const char *string,
1402                 const char *special)
1403 {
1404   return escape_data (buffer, string, strlen (string), special);
1405 }
1406
1407
1408 /* Allocate a new string from STRING using standard HTTP escaping as
1409    well as escaping of characters given in SPECIALS.  A common pattern
1410    for SPECIALS is "%;?&=". However it depends on the needs, for
1411    example "+" and "/: often needs to be escaped too.  Returns NULL on
1412    failure and sets ERRNO.  If SPECIAL is NULL a dedicated forms
1413    encoding mode is used. */
1414 char *
1415 http_escape_string (const char *string, const char *specials)
1416 {
1417   int n;
1418   char *buf;
1419
1420   n = insert_escapes (NULL, string, specials);
1421   buf = xtrymalloc (n+1);
1422   if (buf)
1423     {
1424       insert_escapes (buf, string, specials);
1425       buf[n] = 0;
1426     }
1427   return buf;
1428 }
1429
1430 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1431    escaping as well as escaping of characters given in SPECIALS.  A
1432    common pattern for SPECIALS is "%;?&=".  However it depends on the
1433    needs, for example "+" and "/: often needs to be escaped too.
1434    Returns NULL on failure and sets ERRNO.  If SPECIAL is NULL a
1435    dedicated forms encoding mode is used. */
1436 char *
1437 http_escape_data (const void *data, size_t datalen, const char *specials)
1438 {
1439   int n;
1440   char *buf;
1441
1442   n = escape_data (NULL, data, datalen, specials);
1443   buf = xtrymalloc (n+1);
1444   if (buf)
1445     {
1446       escape_data (buf, data, datalen, specials);
1447       buf[n] = 0;
1448     }
1449   return buf;
1450 }
1451
1452
1453 static uri_tuple_t
1454 parse_tuple (char *string)
1455 {
1456   char *p = string;
1457   char *p2;
1458   int n;
1459   uri_tuple_t tuple;
1460
1461   if ((p2 = strchr (p, '=')))
1462     *p2++ = 0;
1463   if ((n = remove_escapes (p)) < 0)
1464     return NULL; /* Bad URI. */
1465   if (n != strlen (p))
1466     return NULL; /* Name with a Nul in it. */
1467   tuple = xtrycalloc (1, sizeof *tuple);
1468   if (!tuple)
1469     return NULL; /* Out of core. */
1470   tuple->name = p;
1471   if (!p2) /* We have only the name, so we assume an empty value string. */
1472     {
1473       tuple->value = p + strlen (p);
1474       tuple->valuelen = 0;
1475       tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1476     }
1477   else /* Name and value. */
1478     {
1479       if ((n = remove_escapes (p2)) < 0)
1480         {
1481           xfree (tuple);
1482           return NULL; /* Bad URI. */
1483         }
1484       tuple->value = p2;
1485       tuple->valuelen = n;
1486     }
1487   return tuple;
1488 }
1489
1490
1491 /* Return true if STRING is likely "hostname:port" or only "hostname".  */
1492 static int
1493 is_hostname_port (const char *string)
1494 {
1495   int colons = 0;
1496
1497   if (!string || !*string)
1498     return 0;
1499   for (; *string; string++)
1500     {
1501       if (*string == ':')
1502         {
1503           if (colons)
1504             return 0;
1505           if (!string[1])
1506             return 0;
1507           colons++;
1508         }
1509       else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1510         return 0; /* Invalid characters in hostname. */
1511       else if (colons && !digitp (string))
1512         return 0; /* Not a digit in the port.  */
1513     }
1514   return 1;
1515 }
1516
1517
1518 /*
1519  * Send a HTTP request to the server
1520  * Returns 0 if the request was successful
1521  */
1522 static gpg_error_t
1523 send_request (http_t hd, const char *httphost, const char *auth,
1524               const char *proxy, const char *srvtag, strlist_t headers)
1525 {
1526   gpg_error_t err;
1527   const char *server;
1528   char *request, *p;
1529   unsigned short port;
1530   const char *http_proxy = NULL;
1531   char *proxy_authstr = NULL;
1532   char *authstr = NULL;
1533   int sock;
1534   int hnf;
1535
1536   if (hd->uri->use_tls && !hd->session)
1537     {
1538       log_error ("TLS requested but no session object provided\n");
1539       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1540     }
1541 #ifdef USE_TLS
1542   if (hd->uri->use_tls && !hd->session->tls_session)
1543     {
1544       log_error ("TLS requested but no GNUTLS context available\n");
1545       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1546     }
1547 #endif /*USE_TLS*/
1548
1549   if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1550     {
1551       int mode;
1552
1553       if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1554         {
1555           log_error ("Tor support is not available\n");
1556           return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1557         }
1558     }
1559
1560   server = *hd->uri->host ? hd->uri->host : "localhost";
1561   port = hd->uri->port ? hd->uri->port : 80;
1562
1563   /* Try to use SNI.  */
1564 #ifdef USE_TLS
1565   if (hd->uri->use_tls)
1566     {
1567 # if HTTP_USE_GNUTLS
1568       int rc;
1569 # endif
1570
1571       xfree (hd->session->servername);
1572       hd->session->servername = xtrystrdup (httphost? httphost : server);
1573       if (!hd->session->servername)
1574         {
1575           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1576           return err;
1577         }
1578
1579 # if HTTP_USE_NTBTLS
1580       err = ntbtls_set_hostname (hd->session->tls_session,
1581                                  hd->session->servername);
1582       if (err)
1583         {
1584           log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1585           return err;
1586         }
1587 # elif HTTP_USE_GNUTLS
1588       rc = gnutls_server_name_set (hd->session->tls_session,
1589                                    GNUTLS_NAME_DNS,
1590                                    hd->session->servername,
1591                                    strlen (hd->session->servername));
1592       if (rc < 0)
1593         log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1594 # endif /*HTTP_USE_GNUTLS*/
1595     }
1596 #endif /*USE_TLS*/
1597
1598   if ( (proxy && *proxy)
1599        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1600             && (http_proxy = getenv (HTTP_PROXY_ENV))
1601             && *http_proxy ))
1602     {
1603       parsed_uri_t uri;
1604       int save_errno;
1605
1606       if (proxy)
1607         http_proxy = proxy;
1608
1609       err = parse_uri (&uri, http_proxy, 0, 0);
1610       if (gpg_err_code (err) == GPG_ERR_INV_URI
1611           && is_hostname_port (http_proxy))
1612         {
1613           /* Retry assuming a "hostname:port" string.  */
1614           char *tmpname = strconcat ("http://", http_proxy, NULL);
1615           if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1616             err = 0;
1617           xfree (tmpname);
1618         }
1619
1620       if (err)
1621         ;
1622       else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1623         ;
1624       else if (!strcmp (uri->scheme, "socks5h"))
1625         err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1626       else
1627         err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1628
1629       if (err)
1630         {
1631           log_error ("invalid HTTP proxy (%s): %s\n",
1632                      http_proxy, gpg_strerror (err));
1633           return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1634         }
1635
1636       if (uri->auth)
1637         {
1638           remove_escapes (uri->auth);
1639           proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1640                                             "\r\n",
1641                                             uri->auth, strlen(uri->auth));
1642           if (!proxy_authstr)
1643             {
1644               err = gpg_err_make (default_errsource,
1645                                   gpg_err_code_from_syserror ());
1646               http_release_parsed_uri (uri);
1647               return err;
1648             }
1649         }
1650
1651       sock = connect_server (*uri->host ? uri->host : "localhost",
1652                              uri->port ? uri->port : 80,
1653                              hd->flags, srvtag, &hnf);
1654       save_errno = errno;
1655       http_release_parsed_uri (uri);
1656       if (sock == ASSUAN_INVALID_FD)
1657         gpg_err_set_errno (save_errno);
1658     }
1659   else
1660     {
1661       sock = connect_server (server, port, hd->flags, srvtag, &hnf);
1662     }
1663
1664   if (sock == ASSUAN_INVALID_FD)
1665     {
1666       xfree (proxy_authstr);
1667       return gpg_err_make (default_errsource,
1668                            (hnf? GPG_ERR_UNKNOWN_HOST
1669                                : gpg_err_code_from_syserror ()));
1670     }
1671   hd->sock = my_socket_new (sock);
1672   if (!hd->sock)
1673     {
1674       xfree (proxy_authstr);
1675       return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1676     }
1677
1678
1679
1680 #if HTTP_USE_NTBTLS
1681   if (hd->uri->use_tls)
1682     {
1683       my_socket_ref (hd->sock);
1684
1685       while ((err = ntbtls_handshake (hd->session->tls_session)))
1686         {
1687           switch (err)
1688             {
1689             default:
1690               log_info ("TLS handshake failed: %s <%s>\n",
1691                         gpg_strerror (err), gpg_strsource (err));
1692               xfree (proxy_authstr);
1693               return err;
1694             }
1695         }
1696
1697       hd->session->verify.done = 0;
1698       if (tls_callback)
1699         err = tls_callback (hd, hd->session, 0);
1700       else
1701         err = http_verify_server_credentials (hd->session);
1702       if (err)
1703         {
1704           log_info ("TLS connection authentication failed: %s <%s>\n",
1705                     gpg_strerror (err), gpg_strsource (err));
1706           xfree (proxy_authstr);
1707           return err;
1708         }
1709     }
1710 #elif HTTP_USE_GNUTLS
1711   if (hd->uri->use_tls)
1712     {
1713       int rc;
1714
1715       my_socket_ref (hd->sock);
1716       gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1717       gnutls_transport_set_pull_function (hd->session->tls_session,
1718                                           my_gnutls_read);
1719       gnutls_transport_set_push_function (hd->session->tls_session,
1720                                           my_gnutls_write);
1721
1722       do
1723         {
1724           rc = gnutls_handshake (hd->session->tls_session);
1725         }
1726       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1727       if (rc < 0)
1728         {
1729           if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1730               || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1731             {
1732               gnutls_alert_description_t alertno;
1733               const char *alertstr;
1734
1735               alertno = gnutls_alert_get (hd->session->tls_session);
1736               alertstr = gnutls_alert_get_name (alertno);
1737               log_info ("TLS handshake failed: %s (alert %d)\n",
1738                         alertstr, (int)alertno);
1739               if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1740                 log_info ("  (sent server name '%s')\n", server);
1741             }
1742           else
1743             log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1744           xfree (proxy_authstr);
1745           return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1746         }
1747
1748       hd->session->verify.done = 0;
1749       if (tls_callback)
1750         err = tls_callback (hd, hd->session, 0);
1751       else
1752         err = http_verify_server_credentials (hd->session);
1753       if (err)
1754         {
1755           log_info ("TLS connection authentication failed: %s\n",
1756                     gpg_strerror (err));
1757           xfree (proxy_authstr);
1758           return err;
1759         }
1760     }
1761 #endif /*HTTP_USE_GNUTLS*/
1762
1763   if (auth || hd->uri->auth)
1764     {
1765       char *myauth;
1766
1767       if (auth)
1768         {
1769           myauth = xtrystrdup (auth);
1770           if (!myauth)
1771             {
1772               xfree (proxy_authstr);
1773               return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1774             }
1775           remove_escapes (myauth);
1776         }
1777       else
1778         {
1779           remove_escapes (hd->uri->auth);
1780           myauth = hd->uri->auth;
1781         }
1782
1783       authstr = make_header_line ("Authorization: Basic ", "\r\n",
1784                                   myauth, strlen (myauth));
1785       if (auth)
1786         xfree (myauth);
1787
1788       if (!authstr)
1789         {
1790           xfree (proxy_authstr);
1791           return gpg_err_make (default_errsource,
1792                                gpg_err_code_from_syserror ());
1793         }
1794     }
1795
1796   p = build_rel_path (hd->uri);
1797   if (!p)
1798     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1799
1800   if (http_proxy && *http_proxy)
1801     {
1802       request = es_bsprintf
1803         ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1804          hd->req_type == HTTP_REQ_GET ? "GET" :
1805          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1806          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1807          hd->uri->use_tls? "https" : "http",
1808          httphost? httphost : server,
1809          port, *p == '/' ? "" : "/", p,
1810          authstr ? authstr : "",
1811          proxy_authstr ? proxy_authstr : "");
1812     }
1813   else
1814     {
1815       char portstr[35];
1816
1817       if (port == 80)
1818         *portstr = 0;
1819       else
1820         snprintf (portstr, sizeof portstr, ":%u", port);
1821
1822       request = es_bsprintf
1823         ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1824          hd->req_type == HTTP_REQ_GET ? "GET" :
1825          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1826          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1827          *p == '/' ? "" : "/", p,
1828          httphost? httphost : server,
1829          portstr,
1830          authstr? authstr:"");
1831     }
1832   xfree (p);
1833   if (!request)
1834     {
1835       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1836       xfree (authstr);
1837       xfree (proxy_authstr);
1838       return err;
1839     }
1840
1841   /* log_debug ("request:\n%s\nEND request\n", request); */
1842
1843   /* First setup estream so that we can write even the first line
1844      using estream.  This is also required for the sake of gnutls. */
1845   {
1846     cookie_t cookie;
1847
1848     cookie = xtrycalloc (1, sizeof *cookie);
1849     if (!cookie)
1850       {
1851         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1852         goto leave;
1853       }
1854     cookie->sock = my_socket_ref (hd->sock);
1855     hd->write_cookie = cookie;
1856     cookie->use_tls = hd->uri->use_tls;
1857     cookie->session = http_session_ref (hd->session);
1858
1859     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1860     if (!hd->fp_write)
1861       {
1862         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1863         my_socket_unref (cookie->sock, NULL, NULL);
1864         xfree (cookie);
1865         hd->write_cookie = NULL;
1866       }
1867     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1868       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1869     else
1870       err = 0;
1871
1872   if (!err)
1873     {
1874       for (;headers; headers=headers->next)
1875         {
1876           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
1877               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
1878             {
1879               err = gpg_err_make (default_errsource,
1880                                   gpg_err_code_from_syserror ());
1881               break;
1882             }
1883         }
1884     }
1885   }
1886
1887  leave:
1888   es_free (request);
1889   xfree (authstr);
1890   xfree (proxy_authstr);
1891
1892   return err;
1893 }
1894
1895
1896 /*
1897  * Build the relative path from the parsed URI.  Minimal
1898  * implementation.  May return NULL in case of memory failure; errno
1899  * is then set accordingly.
1900  */
1901 static char *
1902 build_rel_path (parsed_uri_t uri)
1903 {
1904   uri_tuple_t r;
1905   char *rel_path, *p;
1906   int n;
1907
1908   /* Count the needed space. */
1909   n = insert_escapes (NULL, uri->path, "%;?&");
1910   /* TODO: build params. */
1911   for (r = uri->query; r; r = r->next)
1912     {
1913       n++; /* '?'/'&' */
1914       n += insert_escapes (NULL, r->name, "%;?&=");
1915       if (!r->no_value)
1916         {
1917           n++; /* '=' */
1918           n += insert_escapes (NULL, r->value, "%;?&=");
1919         }
1920     }
1921   n++;
1922
1923   /* Now allocate and copy. */
1924   p = rel_path = xtrymalloc (n);
1925   if (!p)
1926     return NULL;
1927   n = insert_escapes (p, uri->path, "%;?&");
1928   p += n;
1929   /* TODO: add params. */
1930   for (r = uri->query; r; r = r->next)
1931     {
1932       *p++ = r == uri->query ? '?' : '&';
1933       n = insert_escapes (p, r->name, "%;?&=");
1934       p += n;
1935       if (!r->no_value)
1936         {
1937           *p++ = '=';
1938           /* TODO: Use valuelen. */
1939           n = insert_escapes (p, r->value, "%;?&=");
1940           p += n;
1941         }
1942     }
1943   *p = 0;
1944   return rel_path;
1945 }
1946
1947
1948 /* Transform a header name into a standard capitalized format; e.g.
1949    "Content-Type".  Conversion stops at the colon.  As usual we don't
1950    use the localized versions of ctype.h. */
1951 static void
1952 capitalize_header_name (char *name)
1953 {
1954   int first = 1;
1955
1956   for (; *name && *name != ':'; name++)
1957     {
1958       if (*name == '-')
1959         first = 1;
1960       else if (first)
1961         {
1962           if (*name >= 'a' && *name <= 'z')
1963             *name = *name - 'a' + 'A';
1964           first = 0;
1965         }
1966       else if (*name >= 'A' && *name <= 'Z')
1967         *name = *name - 'A' + 'a';
1968     }
1969 }
1970
1971
1972 /* Store an HTTP header line in LINE away.  Line continuation is
1973    supported as well as merging of headers with the same name. This
1974    function may modify LINE. */
1975 static gpg_err_code_t
1976 store_header (http_t hd, char *line)
1977 {
1978   size_t n;
1979   char *p, *value;
1980   header_t h;
1981
1982   n = strlen (line);
1983   if (n && line[n-1] == '\n')
1984     {
1985       line[--n] = 0;
1986       if (n && line[n-1] == '\r')
1987         line[--n] = 0;
1988     }
1989   if (!n)  /* we are never called to hit this. */
1990     return GPG_ERR_BUG;
1991   if (*line == ' ' || *line == '\t')
1992     {
1993       /* Continuation. This won't happen too often as it is not
1994          recommended.  We use a straightforward implementaion. */
1995       if (!hd->headers)
1996         return GPG_ERR_PROTOCOL_VIOLATION;
1997       n += strlen (hd->headers->value);
1998       p = xtrymalloc (n+1);
1999       if (!p)
2000         return gpg_err_code_from_syserror ();
2001       strcpy (stpcpy (p, hd->headers->value), line);
2002       xfree (hd->headers->value);
2003       hd->headers->value = p;
2004       return 0;
2005     }
2006
2007   capitalize_header_name (line);
2008   p = strchr (line, ':');
2009   if (!p)
2010     return GPG_ERR_PROTOCOL_VIOLATION;
2011   *p++ = 0;
2012   while (*p == ' ' || *p == '\t')
2013     p++;
2014   value = p;
2015
2016   for (h=hd->headers; h; h = h->next)
2017     if ( !strcmp (h->name, line) )
2018       break;
2019   if (h)
2020     {
2021       /* We have already seen a line with that name.  Thus we assume
2022          it is a comma separated list and merge them.  */
2023       p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
2024       if (!p)
2025         return gpg_err_code_from_syserror ();
2026       strcpy (stpcpy (stpcpy (p, h->value), ","), value);
2027       xfree (h->value);
2028       h->value = p;
2029       return 0;
2030     }
2031
2032   /* Append a new header. */
2033   h = xtrymalloc (sizeof *h + strlen (line));
2034   if (!h)
2035     return gpg_err_code_from_syserror ();
2036   strcpy (h->name, line);
2037   h->value = xtrymalloc (strlen (value)+1);
2038   if (!h->value)
2039     {
2040       xfree (h);
2041       return gpg_err_code_from_syserror ();
2042     }
2043   strcpy (h->value, value);
2044   h->next = hd->headers;
2045   hd->headers = h;
2046
2047   return 0;
2048 }
2049
2050
2051 /* Return the header NAME from the last response.  The returned value
2052    is valid as along as HD has not been closed and no other request
2053    has been send. If the header was not found, NULL is returned.  NAME
2054    must be canonicalized, that is the first letter of each dash
2055    delimited part must be uppercase and all other letters lowercase.  */
2056 const char *
2057 http_get_header (http_t hd, const char *name)
2058 {
2059   header_t h;
2060
2061   for (h=hd->headers; h; h = h->next)
2062     if ( !strcmp (h->name, name) )
2063       return h->value;
2064   return NULL;
2065 }
2066
2067
2068 /* Return a newly allocated and NULL terminated array with pointers to
2069    header names.  The array must be released with xfree() and its
2070    content is only values as long as no other request has been
2071    send.  */
2072 const char **
2073 http_get_header_names (http_t hd)
2074 {
2075   const char **array;
2076   size_t n;
2077   header_t h;
2078
2079   for (n=0, h = hd->headers; h; h = h->next)
2080     n++;
2081   array = xtrycalloc (n+1, sizeof *array);
2082   if (array)
2083     {
2084       for (n=0, h = hd->headers; h; h = h->next)
2085         array[n++] = h->name;
2086     }
2087
2088   return array;
2089 }
2090
2091
2092 /*
2093  * Parse the response from a server.
2094  * Returns: Errorcode and sets some files in the handle
2095  */
2096 static gpg_err_code_t
2097 parse_response (http_t hd)
2098 {
2099   char *line, *p, *p2;
2100   size_t maxlen, len;
2101   cookie_t cookie = hd->read_cookie;
2102   const char *s;
2103
2104   /* Delete old header lines.  */
2105   while (hd->headers)
2106     {
2107       header_t tmp = hd->headers->next;
2108       xfree (hd->headers->value);
2109       xfree (hd->headers);
2110       hd->headers = tmp;
2111     }
2112
2113   /* Wait for the status line. */
2114   do
2115     {
2116       maxlen = MAX_LINELEN;
2117       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2118       line = hd->buffer;
2119       if (!line)
2120         return gpg_err_code_from_syserror (); /* Out of core. */
2121       if (!maxlen)
2122         return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2123       if (!len)
2124         return GPG_ERR_EOF;
2125
2126       if ((hd->flags & HTTP_FLAG_LOG_RESP))
2127         log_info ("RESP: '%.*s'\n",
2128                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2129     }
2130   while (!*line);
2131
2132   if ((p = strchr (line, '/')))
2133     *p++ = 0;
2134   if (!p || strcmp (line, "HTTP"))
2135     return 0; /* Assume http 0.9. */
2136
2137   if ((p2 = strpbrk (p, " \t")))
2138     {
2139       *p2++ = 0;
2140       p2 += strspn (p2, " \t");
2141     }
2142   if (!p2)
2143     return 0; /* Also assume http 0.9. */
2144   p = p2;
2145   /* TODO: Add HTTP version number check. */
2146   if ((p2 = strpbrk (p, " \t")))
2147     *p2++ = 0;
2148   if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2149       || !isdigit ((unsigned int)p[2]) || p[3])
2150     {
2151       /* Malformed HTTP status code - assume http 0.9. */
2152       hd->is_http_0_9 = 1;
2153       hd->status_code = 200;
2154       return 0;
2155     }
2156   hd->status_code = atoi (p);
2157
2158   /* Skip all the header lines and wait for the empty line. */
2159   do
2160     {
2161       maxlen = MAX_LINELEN;
2162       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2163       line = hd->buffer;
2164       if (!line)
2165         return gpg_err_code_from_syserror (); /* Out of core. */
2166       /* Note, that we can silently ignore truncated lines. */
2167       if (!len)
2168         return GPG_ERR_EOF;
2169       /* Trim line endings of empty lines. */
2170       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2171         *line = 0;
2172       if ((hd->flags & HTTP_FLAG_LOG_RESP))
2173         log_info ("RESP: '%.*s'\n",
2174                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2175       if (*line)
2176         {
2177           gpg_err_code_t ec = store_header (hd, line);
2178           if (ec)
2179             return ec;
2180         }
2181     }
2182   while (len && *line);
2183
2184   cookie->content_length_valid = 0;
2185   if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2186     {
2187       s = http_get_header (hd, "Content-Length");
2188       if (s)
2189         {
2190           cookie->content_length_valid = 1;
2191           cookie->content_length = string_to_u64 (s);
2192         }
2193     }
2194
2195   return 0;
2196 }
2197
2198 #if 0
2199 static int
2200 start_server ()
2201 {
2202   struct sockaddr_in mya;
2203   struct sockaddr_in peer;
2204   int fd, client;
2205   fd_set rfds;
2206   int addrlen;
2207   int i;
2208
2209   if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2210     {
2211       log_error ("socket() failed: %s\n", strerror (errno));
2212       return -1;
2213     }
2214   i = 1;
2215   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2216     log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2217
2218   mya.sin_family = AF_INET;
2219   memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2220   mya.sin_port = htons (11371);
2221
2222   if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2223     {
2224       log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2225       sock_close (fd);
2226       return -1;
2227     }
2228
2229   if (listen (fd, 5))
2230     {
2231       log_error ("listen failed: %s\n", strerror (errno));
2232       sock_close (fd);
2233       return -1;
2234     }
2235
2236   for (;;)
2237     {
2238       FD_ZERO (&rfds);
2239       FD_SET (fd, &rfds);
2240
2241       if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2242         continue;               /* ignore any errors */
2243
2244       if (!FD_ISSET (fd, &rfds))
2245         continue;
2246
2247       addrlen = sizeof peer;
2248       client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2249       if (client == -1)
2250         continue;               /* oops */
2251
2252       log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2253
2254       fflush (stdout);
2255       fflush (stderr);
2256       if (!fork ())
2257         {
2258           int c;
2259           FILE *fp;
2260
2261           fp = fdopen (client, "r");
2262           while ((c = getc (fp)) != EOF)
2263             putchar (c);
2264           fclose (fp);
2265           exit (0);
2266         }
2267       sock_close (client);
2268     }
2269
2270
2271   return 0;
2272 }
2273 #endif
2274
2275 /* Actually connect to a server.  Returns the file descriptor or -1 on
2276    error.  ERRNO is set on error. */
2277 static assuan_fd_t
2278 connect_server (const char *server, unsigned short port,
2279                 unsigned int flags, const char *srvtag, int *r_host_not_found)
2280 {
2281   gpg_error_t err;
2282   assuan_fd_t sock = ASSUAN_INVALID_FD;
2283   int srvcount = 0;
2284   int hostfound = 0;
2285   int anyhostaddr = 0;
2286   int srv, connected;
2287   int last_errno = 0;
2288   struct srventry *serverlist = NULL;
2289   int ret;
2290
2291   *r_host_not_found = 0;
2292 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2293   init_sockets ();
2294 #endif /*Windows*/
2295
2296   /* Onion addresses require special treatment.  */
2297   if (is_onion_address (server))
2298     {
2299 #ifdef ASSUAN_SOCK_TOR
2300
2301       sock = assuan_sock_connect_byname (server, port, 0, NULL,
2302                                          ASSUAN_SOCK_TOR);
2303       if (sock == ASSUAN_INVALID_FD)
2304         {
2305           if (errno == EHOSTUNREACH)
2306             *r_host_not_found = 1;
2307           log_error ("can't connect to '%s': %s\n", server, strerror (errno));
2308         }
2309       else
2310         notify_netactivity ();
2311       return sock;
2312
2313 #else /*!ASSUAN_SOCK_TOR*/
2314
2315       gpg_err_set_errno (ENETUNREACH);
2316       return -1; /* Out of core.  */
2317
2318 #endif /*!HASSUAN_SOCK_TOR*/
2319     }
2320
2321 #ifdef USE_DNS_SRV
2322   /* Do the SRV thing */
2323   if (srvtag)
2324     {
2325       /* We're using SRV, so append the tags. */
2326       if (1 + strlen (srvtag) + 6 + strlen (server) + 1
2327           <= DIMof (struct srventry, target))
2328         {
2329           char *srvname = xtrymalloc (DIMof (struct srventry, target));
2330
2331           if (!srvname) /* Out of core */
2332             {
2333               serverlist = NULL;
2334               srvcount = 0;
2335             }
2336           else
2337             {
2338               stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
2339                               "._tcp."), server);
2340               srvcount = getsrv (srvname, &serverlist);
2341               xfree (srvname);
2342             }
2343         }
2344     }
2345 #else
2346   (void)flags;
2347   (void)srvtag;
2348 #endif /*USE_DNS_SRV*/
2349
2350   if (!serverlist)
2351     {
2352       /* Either we're not using SRV, or the SRV lookup failed.  Make
2353          up a fake SRV record. */
2354       serverlist = xtrycalloc (1, sizeof *serverlist);
2355       if (!serverlist)
2356         return -1; /* Out of core.  */
2357       serverlist->port = port;
2358       strncpy (serverlist->target, server, DIMof (struct srventry, target));
2359       serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2360       srvcount = 1;
2361     }
2362
2363   connected = 0;
2364   for (srv=0; srv < srvcount && !connected; srv++)
2365     {
2366       dns_addrinfo_t aibuf, ai;
2367
2368       err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2369                               &aibuf, NULL);
2370       if (err)
2371         {
2372           log_info ("resolving '%s' failed: %s\n",
2373                     serverlist[srv].target, gpg_strerror (err));
2374           continue; /* Not found - try next one. */
2375         }
2376       hostfound = 1;
2377
2378       for (ai = aibuf; ai && !connected; ai = ai->next)
2379         {
2380           if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2381             continue;
2382           if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2383             continue;
2384
2385           if (sock != ASSUAN_INVALID_FD)
2386             assuan_sock_close (sock);
2387           sock = assuan_sock_new (ai->family, ai->socktype, ai->protocol);
2388           if (sock == ASSUAN_INVALID_FD)
2389             {
2390               int save_errno = errno;
2391               log_error ("error creating socket: %s\n", strerror (errno));
2392               free_dns_addrinfo (aibuf);
2393               xfree (serverlist);
2394               errno = save_errno;
2395               return ASSUAN_INVALID_FD;
2396             }
2397
2398           anyhostaddr = 1;
2399           ret = assuan_sock_connect (sock, ai->addr, ai->addrlen);
2400           if (ret)
2401             last_errno = errno;
2402           else
2403             {
2404               connected = 1;
2405               notify_netactivity ();
2406             }
2407         }
2408       free_dns_addrinfo (aibuf);
2409     }
2410
2411   xfree (serverlist);
2412
2413   if (!connected)
2414     {
2415       if (!hostfound)
2416         log_error ("can't connect to '%s': %s\n",
2417                    server, "host not found");
2418       else if (!anyhostaddr)
2419         log_error ("can't connect to '%s': %s\n",
2420                    server, "no IP address for host");
2421       else
2422         {
2423 #ifdef HAVE_W32_SYSTEM
2424         log_error ("can't connect to '%s': ec=%d\n",
2425                    server, (int)WSAGetLastError());
2426 #else
2427         log_error ("can't connect to '%s': %s\n",
2428                    server, strerror (last_errno));
2429 #endif
2430         }
2431       if (!hostfound || (hostfound && !anyhostaddr))
2432         *r_host_not_found = 1;
2433       if (sock != ASSUAN_INVALID_FD)
2434         assuan_sock_close (sock);
2435       gpg_err_set_errno (last_errno);
2436       return ASSUAN_INVALID_FD;
2437     }
2438   return sock;
2439 }
2440
2441
2442 static gpg_error_t
2443 write_server (int sock, const char *data, size_t length)
2444 {
2445   int nleft;
2446   int nwritten;
2447
2448   nleft = length;
2449   while (nleft > 0)
2450     {
2451 #if defined(HAVE_W32_SYSTEM)
2452 # if defined(USE_NPTH)
2453       npth_unprotect ();
2454 # endif
2455       nwritten = send (sock, data, nleft, 0);
2456 # if defined(USE_NPTH)
2457       npth_protect ();
2458 # endif
2459       if ( nwritten == SOCKET_ERROR )
2460         {
2461           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2462           return gpg_error (GPG_ERR_NETWORK);
2463         }
2464 #else /*!HAVE_W32_SYSTEM*/
2465 # ifdef USE_NPTH
2466       nwritten = npth_write (sock, data, nleft);
2467 # else
2468       nwritten = write (sock, data, nleft);
2469 # endif
2470       if (nwritten == -1)
2471         {
2472           if (errno == EINTR)
2473             continue;
2474           if (errno == EAGAIN)
2475             {
2476               struct timeval tv;
2477
2478               tv.tv_sec = 0;
2479               tv.tv_usec = 50000;
2480               my_select (0, NULL, NULL, NULL, &tv);
2481               continue;
2482             }
2483           log_info ("network write failed: %s\n", strerror (errno));
2484           return gpg_error_from_syserror ();
2485         }
2486 #endif /*!HAVE_W32_SYSTEM*/
2487       nleft -= nwritten;
2488       data += nwritten;
2489     }
2490
2491   return 0;
2492 }
2493
2494
2495 \f
2496 /* Read handler for estream.  */
2497 static gpgrt_ssize_t
2498 cookie_read (void *cookie, void *buffer, size_t size)
2499 {
2500   cookie_t c = cookie;
2501   int nread;
2502
2503   if (c->content_length_valid)
2504     {
2505       if (!c->content_length)
2506         return 0; /* EOF */
2507       if (c->content_length < size)
2508         size = c->content_length;
2509     }
2510
2511 #ifdef HTTP_USE_GNUTLS
2512   if (c->use_tls && c->session && c->session->tls_session)
2513     {
2514     again:
2515       nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2516       if (nread < 0)
2517         {
2518           if (nread == GNUTLS_E_INTERRUPTED)
2519             goto again;
2520           if (nread == GNUTLS_E_AGAIN)
2521             {
2522               struct timeval tv;
2523
2524               tv.tv_sec = 0;
2525               tv.tv_usec = 50000;
2526               my_select (0, NULL, NULL, NULL, &tv);
2527               goto again;
2528             }
2529           if (nread == GNUTLS_E_REHANDSHAKE)
2530             goto again; /* A client is allowed to just ignore this request. */
2531           if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2532             {
2533               /* The server terminated the connection.  Close the TLS
2534                  session, and indicate EOF using a short read.  */
2535               close_tls_session (c->session);
2536               return 0;
2537             }
2538           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2539           gpg_err_set_errno (EIO);
2540           return -1;
2541         }
2542     }
2543   else
2544 #endif /*HTTP_USE_GNUTLS*/
2545     {
2546       do
2547         {
2548 #ifdef HAVE_W32_SYSTEM
2549           /* Under Windows we need to use recv for a socket.  */
2550 # if defined(USE_NPTH)
2551           npth_unprotect ();
2552 # endif
2553           nread = recv (c->sock->fd, buffer, size, 0);
2554 # if defined(USE_NPTH)
2555           npth_protect ();
2556 # endif
2557
2558 #else /*!HAVE_W32_SYSTEM*/
2559
2560 # ifdef USE_NPTH
2561           nread = npth_read (c->sock->fd, buffer, size);
2562 # else
2563           nread = read (c->sock->fd, buffer, size);
2564 # endif
2565
2566 #endif /*!HAVE_W32_SYSTEM*/
2567         }
2568       while (nread == -1 && errno == EINTR);
2569     }
2570
2571   if (c->content_length_valid && nread > 0)
2572     {
2573       if (nread < c->content_length)
2574         c->content_length -= nread;
2575       else
2576         c->content_length = 0;
2577     }
2578
2579   return (gpgrt_ssize_t)nread;
2580 }
2581
2582 /* Write handler for estream.  */
2583 static gpgrt_ssize_t
2584 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2585 {
2586   const char *buffer = buffer_arg;
2587   cookie_t c = cookie;
2588   int nwritten = 0;
2589
2590 #ifdef HTTP_USE_GNUTLS
2591   if (c->use_tls && c->session && c->session->tls_session)
2592     {
2593       int nleft = size;
2594       while (nleft > 0)
2595         {
2596           nwritten = gnutls_record_send (c->session->tls_session,
2597                                          buffer, nleft);
2598           if (nwritten <= 0)
2599             {
2600               if (nwritten == GNUTLS_E_INTERRUPTED)
2601                 continue;
2602               if (nwritten == GNUTLS_E_AGAIN)
2603                 {
2604                   struct timeval tv;
2605
2606                   tv.tv_sec = 0;
2607                   tv.tv_usec = 50000;
2608                   my_select (0, NULL, NULL, NULL, &tv);
2609                   continue;
2610                 }
2611               log_info ("TLS network write failed: %s\n",
2612                         gnutls_strerror (nwritten));
2613               gpg_err_set_errno (EIO);
2614               return -1;
2615             }
2616           nleft -= nwritten;
2617           buffer += nwritten;
2618         }
2619     }
2620   else
2621 #endif /*HTTP_USE_GNUTLS*/
2622     {
2623       if ( write_server (c->sock->fd, buffer, size) )
2624         {
2625           gpg_err_set_errno (EIO);
2626           nwritten = -1;
2627         }
2628       else
2629         nwritten = size;
2630     }
2631
2632   return (gpgrt_ssize_t)nwritten;
2633 }
2634
2635
2636 #ifdef HTTP_USE_GNUTLS
2637 /* Wrapper for gnutls_bye used by my_socket_unref.  */
2638 static void
2639 send_gnutls_bye (void *opaque)
2640 {
2641   tls_session_t tls_session = opaque;
2642   int ret;
2643
2644  again:
2645   do
2646     ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2647   while (ret == GNUTLS_E_INTERRUPTED);
2648   if (ret == GNUTLS_E_AGAIN)
2649     {
2650       struct timeval tv;
2651
2652       tv.tv_sec = 0;
2653       tv.tv_usec = 50000;
2654       my_select (0, NULL, NULL, NULL, &tv);
2655       goto again;
2656     }
2657 }
2658 #endif /*HTTP_USE_GNUTLS*/
2659
2660 /* Close handler for estream.  */
2661 static int
2662 cookie_close (void *cookie)
2663 {
2664   cookie_t c = cookie;
2665
2666   if (!c)
2667     return 0;
2668
2669 #ifdef HTTP_USE_GNUTLS
2670   if (c->use_tls && c->session && c->session->tls_session)
2671     my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2672   else
2673 #endif /*HTTP_USE_GNUTLS*/
2674     if (c->sock)
2675       my_socket_unref (c->sock, NULL, NULL);
2676
2677   if (c->session)
2678     http_session_unref (c->session);
2679   xfree (c);
2680   return 0;
2681 }
2682
2683
2684
2685 \f
2686 /* Verify the credentials of the server.  Returns 0 on success and
2687    store the result in the session object.  */
2688 gpg_error_t
2689 http_verify_server_credentials (http_session_t sess)
2690 {
2691 #if HTTP_USE_NTBTLS
2692   (void)sess;
2693   return 0;  /* FIXME!! */
2694 #elif HTTP_USE_GNUTLS
2695   static const char const errprefix[] = "TLS verification of peer failed";
2696   int rc;
2697   unsigned int status;
2698   const char *hostname;
2699   const gnutls_datum_t *certlist;
2700   unsigned int certlistlen;
2701   gnutls_x509_crt_t cert;
2702   gpg_error_t err = 0;
2703
2704   sess->verify.done = 1;
2705   sess->verify.status = 0;
2706   sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2707
2708   if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2709     {
2710       log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2711       sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2712       return gpg_error (GPG_ERR_GENERAL);
2713     }
2714
2715   rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2716   if (rc)
2717     {
2718       log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2719       if (!err)
2720         err = gpg_error (GPG_ERR_GENERAL);
2721     }
2722   else if (status)
2723     {
2724       log_error ("%s: status=0x%04x\n", errprefix, status);
2725 #if GNUTLS_VERSION_NUMBER >= 0x030104
2726       {
2727         gnutls_datum_t statusdat;
2728
2729         if (!gnutls_certificate_verification_status_print
2730             (status, GNUTLS_CRT_X509, &statusdat, 0))
2731           {
2732             log_info ("%s: %s\n", errprefix, statusdat.data);
2733             gnutls_free (statusdat.data);
2734           }
2735       }
2736 #endif /*gnutls >= 3.1.4*/
2737
2738       sess->verify.status = status;
2739       if (!err)
2740         err = gpg_error (GPG_ERR_GENERAL);
2741     }
2742
2743   hostname = sess->servername;
2744   if (!hostname || !strchr (hostname, '.'))
2745     {
2746       log_error ("%s: %s\n", errprefix, "hostname missing");
2747       if (!err)
2748         err = gpg_error (GPG_ERR_GENERAL);
2749     }
2750
2751   certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2752   if (!certlistlen)
2753     {
2754       log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2755       if (!err)
2756         err = gpg_error (GPG_ERR_GENERAL);
2757
2758       /* Need to stop here.  */
2759       if (err)
2760         return err;
2761     }
2762
2763   rc = gnutls_x509_crt_init (&cert);
2764   if (rc < 0)
2765     {
2766       if (!err)
2767         err = gpg_error (GPG_ERR_GENERAL);
2768       if (err)
2769         return err;
2770     }
2771
2772   rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2773   if (rc < 0)
2774     {
2775       log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
2776                  gnutls_strerror (rc));
2777       if (!err)
2778         err = gpg_error (GPG_ERR_GENERAL);
2779     }
2780
2781   if (!gnutls_x509_crt_check_hostname (cert, hostname))
2782     {
2783       log_error ("%s: %s\n", errprefix, "hostname does not match");
2784       if (!err)
2785         err = gpg_error (GPG_ERR_GENERAL);
2786     }
2787
2788   gnutls_x509_crt_deinit (cert);
2789
2790   if (!err)
2791     sess->verify.rc = 0;
2792
2793   if (sess->cert_log_cb)
2794     {
2795       const void *bufarr[10];
2796       size_t buflenarr[10];
2797       size_t n;
2798
2799       for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
2800         {
2801           bufarr[n] = certlist[n].data;
2802           buflenarr[n] = certlist[n].size;
2803         }
2804       bufarr[n] = NULL;
2805       buflenarr[n] = 0;
2806       sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
2807     }
2808
2809   return err;
2810 #else /*!HTTP_USE_GNUTLS*/
2811   (void)sess;
2812   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2813 #endif
2814 }
2815
2816 /* Return the first query variable with the specified key.  If there
2817    is no such variable, return NULL.  */
2818 struct uri_tuple_s *
2819 uri_query_lookup (parsed_uri_t uri, const char *key)
2820 {
2821   struct uri_tuple_s *t;
2822
2823   for (t = uri->query; t; t = t->next)
2824     if (strcmp (t->name, key) == 0)
2825       return t;
2826
2827   return NULL;
2828 }