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