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