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