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