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