common/iobuf.c: Combine iobuf_open, iobuf_create and iobuf_openrw.
[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 /* Return true if STRING is likely "hostname:port" or only "hostname".  */
1398 static int
1399 is_hostname_port (const char *string)
1400 {
1401   int colons = 0;
1402
1403   if (!string || !*string)
1404     return 0;
1405   for (; *string; string++)
1406     {
1407       if (*string == ':')
1408         {
1409           if (colons)
1410             return 0;
1411           if (!string[1])
1412             return 0;
1413           colons++;
1414         }
1415       else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1416         return 0; /* Invalid characters in hostname. */
1417       else if (colons && !digitp (string))
1418         return 0; /* Not a digit in the port.  */
1419     }
1420   return 1;
1421 }
1422
1423
1424 /*
1425  * Send a HTTP request to the server
1426  * Returns 0 if the request was successful
1427  */
1428 static gpg_error_t
1429 send_request (http_t hd, const char *httphost, const char *auth,
1430               const char *proxy, const char *srvtag, strlist_t headers)
1431 {
1432   gpg_error_t err;
1433   const char *server;
1434   char *request, *p;
1435   unsigned short port;
1436   const char *http_proxy = NULL;
1437   char *proxy_authstr = NULL;
1438   char *authstr = NULL;
1439   int sock;
1440   int hnf;
1441
1442   if (hd->uri->use_tls && !hd->session)
1443     {
1444       log_error ("TLS requested but no session object provided\n");
1445       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1446     }
1447 #ifdef USE_TLS
1448   if (hd->uri->use_tls && !hd->session->tls_session)
1449     {
1450       log_error ("TLS requested but no GNUTLS context available\n");
1451       return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1452     }
1453 #endif /*USE_TLS*/
1454
1455   server = *hd->uri->host ? hd->uri->host : "localhost";
1456   port = hd->uri->port ? hd->uri->port : 80;
1457
1458   /* Try to use SNI.  */
1459 #ifdef USE_TLS
1460   if (hd->uri->use_tls)
1461     {
1462 # if HTTP_USE_GNUTLS
1463       int rc;
1464 # endif
1465
1466       xfree (hd->session->servername);
1467       hd->session->servername = xtrystrdup (httphost? httphost : server);
1468       if (!hd->session->servername)
1469         {
1470           err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1471           return err;
1472         }
1473
1474 # if HTTP_USE_NTBTLS
1475       err = ntbtls_set_hostname (hd->session->tls_session,
1476                                  hd->session->servername);
1477       if (err)
1478         {
1479           log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1480           return err;
1481         }
1482 # elif HTTP_USE_GNUTLS
1483       rc = gnutls_server_name_set (hd->session->tls_session,
1484                                    GNUTLS_NAME_DNS,
1485                                    hd->session->servername,
1486                                    strlen (hd->session->servername));
1487       if (rc < 0)
1488         log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1489 # endif /*HTTP_USE_GNUTLS*/
1490     }
1491 #endif /*USE_TLS*/
1492
1493   if ( (proxy && *proxy)
1494        || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1495             && (http_proxy = getenv (HTTP_PROXY_ENV))
1496             && *http_proxy ))
1497     {
1498       parsed_uri_t uri;
1499       int save_errno;
1500
1501       if (proxy)
1502         http_proxy = proxy;
1503
1504       err = parse_uri (&uri, http_proxy, 1, 0);
1505       if (gpg_err_code (err) == GPG_ERR_INV_URI
1506           && is_hostname_port (http_proxy))
1507         {
1508           /* Retry assuming a "hostname:port" string.  */
1509           char *tmpname = strconcat ("http://", http_proxy, NULL);
1510           if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1511             err = 0;
1512           xfree (tmpname);
1513         }
1514
1515       if (err)
1516         ;
1517       else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1518         ;
1519       else if (!strcmp (uri->scheme, "socks5h"))
1520         err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1521       else
1522         err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1523
1524       if (err)
1525         {
1526           log_error ("invalid HTTP proxy (%s): %s\n",
1527                      http_proxy, gpg_strerror (err));
1528           return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1529         }
1530
1531       if (uri->auth)
1532         {
1533           remove_escapes (uri->auth);
1534           proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1535                                             "\r\n",
1536                                             uri->auth, strlen(uri->auth));
1537           if (!proxy_authstr)
1538             {
1539               err = gpg_err_make (default_errsource,
1540                                   gpg_err_code_from_syserror ());
1541               http_release_parsed_uri (uri);
1542               return err;
1543             }
1544         }
1545
1546       sock = connect_server (*uri->host ? uri->host : "localhost",
1547                              uri->port ? uri->port : 80,
1548                              hd->flags, srvtag, &hnf);
1549       save_errno = errno;
1550       http_release_parsed_uri (uri);
1551       if (sock == -1)
1552         gpg_err_set_errno (save_errno);
1553     }
1554   else
1555     {
1556       sock = connect_server (server, port, hd->flags, srvtag, &hnf);
1557     }
1558
1559   if (sock == -1)
1560     {
1561       xfree (proxy_authstr);
1562       return gpg_err_make (default_errsource,
1563                            (hnf? GPG_ERR_UNKNOWN_HOST
1564                                : gpg_err_code_from_syserror ()));
1565     }
1566   hd->sock = my_socket_new (sock);
1567   if (!hd->sock)
1568     {
1569       xfree (proxy_authstr);
1570       return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1571     }
1572
1573
1574
1575 #if HTTP_USE_NTBTLS
1576   if (hd->uri->use_tls)
1577     {
1578       my_socket_ref (hd->sock);
1579
1580       while ((err = ntbtls_handshake (hd->session->tls_session)))
1581         {
1582           switch (err)
1583             {
1584             default:
1585               log_info ("TLS handshake failed: %s <%s>\n",
1586                         gpg_strerror (err), gpg_strsource (err));
1587               xfree (proxy_authstr);
1588               return err;
1589             }
1590         }
1591
1592       hd->session->verify.done = 0;
1593       if (tls_callback)
1594         err = tls_callback (hd, hd->session, 0);
1595       else
1596         err = http_verify_server_credentials (hd->session);
1597       if (err)
1598         {
1599           log_info ("TLS connection authentication failed: %s <%s>\n",
1600                     gpg_strerror (err), gpg_strsource (err));
1601           xfree (proxy_authstr);
1602           return err;
1603         }
1604     }
1605 #elif HTTP_USE_GNUTLS
1606   if (hd->uri->use_tls)
1607     {
1608       int rc;
1609
1610       my_socket_ref (hd->sock);
1611       gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1612 #ifdef USE_NPTH
1613       gnutls_transport_set_pull_function (hd->session->tls_session,
1614                                           my_npth_read);
1615       gnutls_transport_set_push_function (hd->session->tls_session,
1616                                           my_npth_write);
1617 #endif
1618
1619       do
1620         {
1621           rc = gnutls_handshake (hd->session->tls_session);
1622         }
1623       while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1624       if (rc < 0)
1625         {
1626           if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1627               || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1628             {
1629               gnutls_alert_description_t alertno;
1630               const char *alertstr;
1631
1632               alertno = gnutls_alert_get (hd->session->tls_session);
1633               alertstr = gnutls_alert_get_name (alertno);
1634               log_info ("TLS handshake failed: %s (alert %d)\n",
1635                         alertstr, (int)alertno);
1636               if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1637                 log_info ("  (sent server name '%s')\n", server);
1638             }
1639           else
1640             log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1641           xfree (proxy_authstr);
1642           return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1643         }
1644
1645       hd->session->verify.done = 0;
1646       if (tls_callback)
1647         err = tls_callback (hd, hd->session, 0);
1648       else
1649         err = http_verify_server_credentials (hd->session);
1650       if (err)
1651         {
1652           log_info ("TLS connection authentication failed: %s\n",
1653                     gpg_strerror (err));
1654           xfree (proxy_authstr);
1655           return err;
1656         }
1657     }
1658 #endif /*HTTP_USE_GNUTLS*/
1659
1660   if (auth || hd->uri->auth)
1661     {
1662       char *myauth;
1663
1664       if (auth)
1665         {
1666           myauth = xtrystrdup (auth);
1667           if (!myauth)
1668             {
1669               xfree (proxy_authstr);
1670               return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1671             }
1672           remove_escapes (myauth);
1673         }
1674       else
1675         {
1676           remove_escapes (hd->uri->auth);
1677           myauth = hd->uri->auth;
1678         }
1679
1680       authstr = make_header_line ("Authorization: Basic ", "\r\n",
1681                                   myauth, strlen (myauth));
1682       if (auth)
1683         xfree (myauth);
1684
1685       if (!authstr)
1686         {
1687           xfree (proxy_authstr);
1688           return gpg_err_make (default_errsource,
1689                                gpg_err_code_from_syserror ());
1690         }
1691     }
1692
1693   p = build_rel_path (hd->uri);
1694   if (!p)
1695     return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1696
1697   if (http_proxy && *http_proxy)
1698     {
1699       request = es_bsprintf
1700         ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1701          hd->req_type == HTTP_REQ_GET ? "GET" :
1702          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1703          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1704          hd->uri->use_tls? "https" : "http",
1705          httphost? httphost : server,
1706          port, *p == '/' ? "" : "/", p,
1707          authstr ? authstr : "",
1708          proxy_authstr ? proxy_authstr : "");
1709     }
1710   else
1711     {
1712       char portstr[35];
1713
1714       if (port == 80)
1715         *portstr = 0;
1716       else
1717         snprintf (portstr, sizeof portstr, ":%u", port);
1718
1719       request = es_bsprintf
1720         ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1721          hd->req_type == HTTP_REQ_GET ? "GET" :
1722          hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1723          hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1724          *p == '/' ? "" : "/", p,
1725          httphost? httphost : server,
1726          portstr,
1727          authstr? authstr:"");
1728     }
1729   xfree (p);
1730   if (!request)
1731     {
1732       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1733       xfree (authstr);
1734       xfree (proxy_authstr);
1735       return err;
1736     }
1737
1738   /* log_debug ("request:\n%s\nEND request\n", request); */
1739
1740   /* First setup estream so that we can write even the first line
1741      using estream.  This is also required for the sake of gnutls. */
1742   {
1743     cookie_t cookie;
1744
1745     cookie = xtrycalloc (1, sizeof *cookie);
1746     if (!cookie)
1747       {
1748         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1749         goto leave;
1750       }
1751     cookie->sock = my_socket_ref (hd->sock);
1752     hd->write_cookie = cookie;
1753     cookie->use_tls = hd->uri->use_tls;
1754     cookie->session = http_session_ref (hd->session);
1755
1756     hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1757     if (!hd->fp_write)
1758       {
1759         err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1760         my_socket_unref (cookie->sock, NULL, NULL);
1761         xfree (cookie);
1762         hd->write_cookie = NULL;
1763       }
1764     else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1765       err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1766     else
1767       err = 0;
1768
1769   if (!err)
1770     {
1771       for (;headers; headers=headers->next)
1772         {
1773           if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
1774               || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
1775             {
1776               err = gpg_err_make (default_errsource,
1777                                   gpg_err_code_from_syserror ());
1778               break;
1779             }
1780         }
1781     }
1782   }
1783
1784  leave:
1785   es_free (request);
1786   xfree (authstr);
1787   xfree (proxy_authstr);
1788
1789   return err;
1790 }
1791
1792
1793 /*
1794  * Build the relative path from the parsed URI.  Minimal
1795  * implementation.  May return NULL in case of memory failure; errno
1796  * is then set accordingly.
1797  */
1798 static char *
1799 build_rel_path (parsed_uri_t uri)
1800 {
1801   uri_tuple_t r;
1802   char *rel_path, *p;
1803   int n;
1804
1805   /* Count the needed space. */
1806   n = insert_escapes (NULL, uri->path, "%;?&");
1807   /* TODO: build params. */
1808   for (r = uri->query; r; r = r->next)
1809     {
1810       n++; /* '?'/'&' */
1811       n += insert_escapes (NULL, r->name, "%;?&=");
1812       if (!r->no_value)
1813         {
1814           n++; /* '=' */
1815           n += insert_escapes (NULL, r->value, "%;?&=");
1816         }
1817     }
1818   n++;
1819
1820   /* Now allocate and copy. */
1821   p = rel_path = xtrymalloc (n);
1822   if (!p)
1823     return NULL;
1824   n = insert_escapes (p, uri->path, "%;?&");
1825   p += n;
1826   /* TODO: add params. */
1827   for (r = uri->query; r; r = r->next)
1828     {
1829       *p++ = r == uri->query ? '?' : '&';
1830       n = insert_escapes (p, r->name, "%;?&=");
1831       p += n;
1832       if (!r->no_value)
1833         {
1834           *p++ = '=';
1835           /* TODO: Use valuelen. */
1836           n = insert_escapes (p, r->value, "%;?&=");
1837           p += n;
1838         }
1839     }
1840   *p = 0;
1841   return rel_path;
1842 }
1843
1844
1845 /* Transform a header name into a standard capitalized format; e.g.
1846    "Content-Type".  Conversion stops at the colon.  As usual we don't
1847    use the localized versions of ctype.h. */
1848 static void
1849 capitalize_header_name (char *name)
1850 {
1851   int first = 1;
1852
1853   for (; *name && *name != ':'; name++)
1854     {
1855       if (*name == '-')
1856         first = 1;
1857       else if (first)
1858         {
1859           if (*name >= 'a' && *name <= 'z')
1860             *name = *name - 'a' + 'A';
1861           first = 0;
1862         }
1863       else if (*name >= 'A' && *name <= 'Z')
1864         *name = *name - 'A' + 'a';
1865     }
1866 }
1867
1868
1869 /* Store an HTTP header line in LINE away.  Line continuation is
1870    supported as well as merging of headers with the same name. This
1871    function may modify LINE. */
1872 static gpg_err_code_t
1873 store_header (http_t hd, char *line)
1874 {
1875   size_t n;
1876   char *p, *value;
1877   header_t h;
1878
1879   n = strlen (line);
1880   if (n && line[n-1] == '\n')
1881     {
1882       line[--n] = 0;
1883       if (n && line[n-1] == '\r')
1884         line[--n] = 0;
1885     }
1886   if (!n)  /* we are never called to hit this. */
1887     return GPG_ERR_BUG;
1888   if (*line == ' ' || *line == '\t')
1889     {
1890       /* Continuation. This won't happen too often as it is not
1891          recommended.  We use a straightforward implementaion. */
1892       if (!hd->headers)
1893         return GPG_ERR_PROTOCOL_VIOLATION;
1894       n += strlen (hd->headers->value);
1895       p = xtrymalloc (n+1);
1896       if (!p)
1897         return gpg_err_code_from_syserror ();
1898       strcpy (stpcpy (p, hd->headers->value), line);
1899       xfree (hd->headers->value);
1900       hd->headers->value = p;
1901       return 0;
1902     }
1903
1904   capitalize_header_name (line);
1905   p = strchr (line, ':');
1906   if (!p)
1907     return GPG_ERR_PROTOCOL_VIOLATION;
1908   *p++ = 0;
1909   while (*p == ' ' || *p == '\t')
1910     p++;
1911   value = p;
1912
1913   for (h=hd->headers; h; h = h->next)
1914     if ( !strcmp (h->name, line) )
1915       break;
1916   if (h)
1917     {
1918       /* We have already seen a line with that name.  Thus we assume
1919          it is a comma separated list and merge them.  */
1920       p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
1921       if (!p)
1922         return gpg_err_code_from_syserror ();
1923       strcpy (stpcpy (stpcpy (p, h->value), ","), value);
1924       xfree (h->value);
1925       h->value = p;
1926       return 0;
1927     }
1928
1929   /* Append a new header. */
1930   h = xtrymalloc (sizeof *h + strlen (line));
1931   if (!h)
1932     return gpg_err_code_from_syserror ();
1933   strcpy (h->name, line);
1934   h->value = xtrymalloc (strlen (value)+1);
1935   if (!h->value)
1936     {
1937       xfree (h);
1938       return gpg_err_code_from_syserror ();
1939     }
1940   strcpy (h->value, value);
1941   h->next = hd->headers;
1942   hd->headers = h;
1943
1944   return 0;
1945 }
1946
1947
1948 /* Return the header NAME from the last response.  The returned value
1949    is valid as along as HD has not been closed and no other request
1950    has been send. If the header was not found, NULL is returned.  NAME
1951    must be canonicalized, that is the first letter of each dash
1952    delimited part must be uppercase and all other letters lowercase.  */
1953 const char *
1954 http_get_header (http_t hd, const char *name)
1955 {
1956   header_t h;
1957
1958   for (h=hd->headers; h; h = h->next)
1959     if ( !strcmp (h->name, name) )
1960       return h->value;
1961   return NULL;
1962 }
1963
1964
1965 /* Return a newly allocated and NULL terminated array with pointers to
1966    header names.  The array must be released with xfree() and its
1967    content is only values as long as no other request has been
1968    send.  */
1969 const char **
1970 http_get_header_names (http_t hd)
1971 {
1972   const char **array;
1973   size_t n;
1974   header_t h;
1975
1976   for (n=0, h = hd->headers; h; h = h->next)
1977     n++;
1978   array = xtrycalloc (n+1, sizeof *array);
1979   if (array)
1980     {
1981       for (n=0, h = hd->headers; h; h = h->next)
1982         array[n++] = h->name;
1983     }
1984
1985   return array;
1986 }
1987
1988
1989 /*
1990  * Parse the response from a server.
1991  * Returns: Errorcode and sets some files in the handle
1992  */
1993 static gpg_err_code_t
1994 parse_response (http_t hd)
1995 {
1996   char *line, *p, *p2;
1997   size_t maxlen, len;
1998   cookie_t cookie = hd->read_cookie;
1999   const char *s;
2000
2001   /* Delete old header lines.  */
2002   while (hd->headers)
2003     {
2004       header_t tmp = hd->headers->next;
2005       xfree (hd->headers->value);
2006       xfree (hd->headers);
2007       hd->headers = tmp;
2008     }
2009
2010   /* Wait for the status 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       if (!maxlen)
2019         return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2020       if (!len)
2021         return GPG_ERR_EOF;
2022
2023       if ((hd->flags & HTTP_FLAG_LOG_RESP))
2024         log_info ("RESP: '%.*s'\n",
2025                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2026     }
2027   while (!*line);
2028
2029   if ((p = strchr (line, '/')))
2030     *p++ = 0;
2031   if (!p || strcmp (line, "HTTP"))
2032     return 0; /* Assume http 0.9. */
2033
2034   if ((p2 = strpbrk (p, " \t")))
2035     {
2036       *p2++ = 0;
2037       p2 += strspn (p2, " \t");
2038     }
2039   if (!p2)
2040     return 0; /* Also assume http 0.9. */
2041   p = p2;
2042   /* TODO: Add HTTP version number check. */
2043   if ((p2 = strpbrk (p, " \t")))
2044     *p2++ = 0;
2045   if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2046       || !isdigit ((unsigned int)p[2]) || p[3])
2047     {
2048       /* Malformed HTTP status code - assume http 0.9. */
2049       hd->is_http_0_9 = 1;
2050       hd->status_code = 200;
2051       return 0;
2052     }
2053   hd->status_code = atoi (p);
2054
2055   /* Skip all the header lines and wait for the empty line. */
2056   do
2057     {
2058       maxlen = MAX_LINELEN;
2059       len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2060       line = hd->buffer;
2061       if (!line)
2062         return gpg_err_code_from_syserror (); /* Out of core. */
2063       /* Note, that we can silently ignore truncated lines. */
2064       if (!len)
2065         return GPG_ERR_EOF;
2066       /* Trim line endings of empty lines. */
2067       if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2068         *line = 0;
2069       if ((hd->flags & HTTP_FLAG_LOG_RESP))
2070         log_info ("RESP: '%.*s'\n",
2071                   (int)strlen(line)-(*line&&line[1]?2:0),line);
2072       if (*line)
2073         {
2074           gpg_err_code_t ec = store_header (hd, line);
2075           if (ec)
2076             return ec;
2077         }
2078     }
2079   while (len && *line);
2080
2081   cookie->content_length_valid = 0;
2082   if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2083     {
2084       s = http_get_header (hd, "Content-Length");
2085       if (s)
2086         {
2087           cookie->content_length_valid = 1;
2088           cookie->content_length = counter_strtoul (s);
2089         }
2090     }
2091
2092   return 0;
2093 }
2094
2095 #if 0
2096 static int
2097 start_server ()
2098 {
2099   struct sockaddr_in mya;
2100   struct sockaddr_in peer;
2101   int fd, client;
2102   fd_set rfds;
2103   int addrlen;
2104   int i;
2105
2106   if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2107     {
2108       log_error ("socket() failed: %s\n", strerror (errno));
2109       return -1;
2110     }
2111   i = 1;
2112   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2113     log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2114
2115   mya.sin_family = AF_INET;
2116   memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2117   mya.sin_port = htons (11371);
2118
2119   if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2120     {
2121       log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2122       sock_close (fd);
2123       return -1;
2124     }
2125
2126   if (listen (fd, 5))
2127     {
2128       log_error ("listen failed: %s\n", strerror (errno));
2129       sock_close (fd);
2130       return -1;
2131     }
2132
2133   for (;;)
2134     {
2135       FD_ZERO (&rfds);
2136       FD_SET (fd, &rfds);
2137
2138       if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2139         continue;               /* ignore any errors */
2140
2141       if (!FD_ISSET (fd, &rfds))
2142         continue;
2143
2144       addrlen = sizeof peer;
2145       client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2146       if (client == -1)
2147         continue;               /* oops */
2148
2149       log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2150
2151       fflush (stdout);
2152       fflush (stderr);
2153       if (!fork ())
2154         {
2155           int c;
2156           FILE *fp;
2157
2158           fp = fdopen (client, "r");
2159           while ((c = getc (fp)) != EOF)
2160             putchar (c);
2161           fclose (fp);
2162           exit (0);
2163         }
2164       sock_close (client);
2165     }
2166
2167
2168   return 0;
2169 }
2170 #endif
2171
2172 /* Actually connect to a server.  Returns the file descriptor or -1 on
2173    error.  ERRNO is set on error. */
2174 static int
2175 connect_server (const char *server, unsigned short port,
2176                 unsigned int flags, const char *srvtag, int *r_host_not_found)
2177 {
2178   int sock = -1;
2179   int srvcount = 0;
2180   int hostfound = 0;
2181   int anyhostaddr = 0;
2182   int srv, connected;
2183   int last_errno = 0;
2184   struct srventry *serverlist = NULL;
2185 #ifdef HAVE_W32_SYSTEM
2186   unsigned long inaddr;
2187 #endif
2188
2189   *r_host_not_found = 0;
2190 #ifdef HAVE_W32_SYSTEM
2191
2192 #ifndef HTTP_NO_WSASTARTUP
2193   init_sockets ();
2194 #endif
2195   /* Win32 gethostbyname doesn't handle IP addresses internally, so we
2196      try inet_addr first on that platform only. */
2197   inaddr = inet_addr(server);
2198   if ( inaddr != INADDR_NONE )
2199     {
2200       struct sockaddr_in addr;
2201
2202       memset(&addr,0,sizeof(addr));
2203
2204       sock = socket(AF_INET,SOCK_STREAM,0);
2205       if ( sock==INVALID_SOCKET )
2206         {
2207           log_error("error creating socket: ec=%d\n",(int)WSAGetLastError());
2208           return -1;
2209         }
2210
2211       addr.sin_family = AF_INET;
2212       addr.sin_port = htons(port);
2213       memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr));
2214
2215       if (!my_connect (sock,(struct sockaddr *)&addr,sizeof(addr)) )
2216         return sock;
2217       sock_close(sock);
2218       return -1;
2219     }
2220 #endif /*HAVE_W32_SYSTEM*/
2221
2222 #ifdef USE_DNS_SRV
2223   /* Do the SRV thing */
2224   if (srvtag)
2225     {
2226       /* We're using SRV, so append the tags. */
2227       if (1+strlen (srvtag) + 6 + strlen (server) + 1 <= MAXDNAME)
2228         {
2229           char srvname[MAXDNAME];
2230
2231           stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
2232                            "._tcp."), server);
2233           srvcount = getsrv (srvname, &serverlist);
2234         }
2235     }
2236 #else
2237   (void)flags;
2238   (void)srvtag;
2239 #endif /*USE_DNS_SRV*/
2240
2241   if (!serverlist)
2242     {
2243       /* Either we're not using SRV, or the SRV lookup failed.  Make
2244          up a fake SRV record. */
2245       serverlist = xtrycalloc (1, sizeof *serverlist);
2246       if (!serverlist)
2247         return -1; /* Out of core.  */
2248       serverlist->port = port;
2249       strncpy (serverlist->target, server, MAXDNAME);
2250       serverlist->target[MAXDNAME-1] = '\0';
2251       srvcount = 1;
2252     }
2253
2254 #ifdef HAVE_GETADDRINFO
2255   connected = 0;
2256   for (srv=0; srv < srvcount && !connected; srv++)
2257     {
2258       struct addrinfo hints, *res, *ai;
2259       char portstr[35];
2260
2261       snprintf (portstr, sizeof portstr, "%hu", port);
2262       memset (&hints, 0, sizeof (hints));
2263       hints.ai_socktype = SOCK_STREAM;
2264       if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res))
2265         continue; /* Not found - try next one. */
2266       hostfound = 1;
2267
2268       for (ai = res; ai && !connected; ai = ai->ai_next)
2269         {
2270           if (ai->ai_family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2271             continue;
2272           if (ai->ai_family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2273             continue;
2274
2275           if (sock != -1)
2276             sock_close (sock);
2277           sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);
2278           if (sock == -1)
2279             {
2280               int save_errno = errno;
2281               log_error ("error creating socket: %s\n", strerror (errno));
2282               freeaddrinfo (res);
2283               xfree (serverlist);
2284               errno = save_errno;
2285               return -1;
2286             }
2287
2288           anyhostaddr = 1;
2289           if (my_connect (sock, ai->ai_addr, ai->ai_addrlen))
2290             last_errno = errno;
2291           else
2292             connected = 1;
2293         }
2294       freeaddrinfo (res);
2295     }
2296 #else /* !HAVE_GETADDRINFO */
2297   connected = 0;
2298   for (srv=0; srv < srvcount && !connected; srv++)
2299     {
2300       int i;
2301       struct hostent *host = NULL;
2302       struct sockaddr_in addr;
2303
2304       /* Note: This code is not thread-safe.  */
2305
2306       memset (&addr, 0, sizeof (addr));
2307       host = gethostbyname (serverlist[srv].target);
2308       if (!host)
2309         continue;
2310       hostfound = 1;
2311
2312       if (sock != -1)
2313         sock_close (sock);
2314       sock = socket (host->h_addrtype, SOCK_STREAM, 0);
2315       if (sock == -1)
2316         {
2317           log_error ("error creating socket: %s\n", strerror (errno));
2318           xfree (serverlist);
2319           return -1;
2320         }
2321
2322       addr.sin_family = host->h_addrtype;
2323       if (addr.sin_family != AF_INET)
2324         {
2325           log_error ("unknown address family for '%s'\n",
2326                      serverlist[srv].target);
2327           xfree (serverlist);
2328           return -1;
2329         }
2330       addr.sin_port = htons (serverlist[srv].port);
2331       if (host->h_length != 4)
2332         {
2333           log_error ("illegal address length for '%s'\n",
2334                      serverlist[srv].target);
2335           xfree (serverlist);
2336           return -1;
2337         }
2338
2339       /* Try all A records until one responds. */
2340       for (i = 0; host->h_addr_list[i] && !connected; i++)
2341         {
2342           anyhostaddr = 1;
2343           memcpy (&addr.sin_addr, host->h_addr_list[i], host->h_length);
2344           if (my_connect (sock, (struct sockaddr *) &addr, sizeof (addr)))
2345             last_errno = errno;
2346           else
2347             {
2348               connected = 1;
2349               break;
2350             }
2351         }
2352     }
2353 #endif /* !HAVE_GETADDRINFO */
2354
2355   xfree (serverlist);
2356
2357   if (!connected)
2358     {
2359       if (!hostfound)
2360         log_error ("can't connect to '%s': %s\n",
2361                    server, "host not found");
2362       else if (!anyhostaddr)
2363         log_error ("can't connect to '%s': %s\n",
2364                    server, "no IP address for host");
2365       else
2366         {
2367 #ifdef HAVE_W32_SYSTEM
2368         log_error ("can't connect to '%s': ec=%d\n",
2369                    server, (int)WSAGetLastError());
2370 #else
2371         log_error ("can't connect to '%s': %s\n",
2372                    server, strerror (last_errno));
2373 #endif
2374         }
2375       if (!hostfound || (hostfound && !anyhostaddr))
2376         *r_host_not_found = 1;
2377       if (sock != -1)
2378         sock_close (sock);
2379       gpg_err_set_errno (last_errno);
2380       return -1;
2381     }
2382   return sock;
2383 }
2384
2385
2386 static gpg_error_t
2387 write_server (int sock, const char *data, size_t length)
2388 {
2389   int nleft;
2390   int nwritten;
2391
2392   nleft = length;
2393   while (nleft > 0)
2394     {
2395 #if defined(HAVE_W32_SYSTEM)
2396 # if defined(USE_NPTH)
2397       npth_unprotect ();
2398 # endif
2399       nwritten = send (sock, data, nleft, 0);
2400 # if defined(USE_NPTH)
2401       npth_protect ();
2402 # endif
2403       if ( nwritten == SOCKET_ERROR )
2404         {
2405           log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2406           return gpg_error (GPG_ERR_NETWORK);
2407         }
2408 #else /*!HAVE_W32_SYSTEM*/
2409 # ifdef USE_NPTH
2410       nwritten = npth_write (sock, data, nleft);
2411 # else
2412       nwritten = write (sock, data, nleft);
2413 # endif
2414       if (nwritten == -1)
2415         {
2416           if (errno == EINTR)
2417             continue;
2418           if (errno == EAGAIN)
2419             {
2420               struct timeval tv;
2421
2422               tv.tv_sec = 0;
2423               tv.tv_usec = 50000;
2424               my_select (0, NULL, NULL, NULL, &tv);
2425               continue;
2426             }
2427           log_info ("network write failed: %s\n", strerror (errno));
2428           return gpg_error_from_syserror ();
2429         }
2430 #endif /*!HAVE_W32_SYSTEM*/
2431       nleft -= nwritten;
2432       data += nwritten;
2433     }
2434
2435   return 0;
2436 }
2437
2438
2439 \f
2440 /* Read handler for estream.  */
2441 static ssize_t
2442 cookie_read (void *cookie, void *buffer, size_t size)
2443 {
2444   cookie_t c = cookie;
2445   int nread;
2446
2447   if (c->content_length_valid)
2448     {
2449       if (!c->content_length)
2450         return 0; /* EOF */
2451       if (c->content_length < size)
2452         size = c->content_length;
2453     }
2454
2455 #ifdef HTTP_USE_GNUTLS
2456   if (c->use_tls && c->session && c->session->tls_session)
2457     {
2458     again:
2459       nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2460       if (nread < 0)
2461         {
2462           if (nread == GNUTLS_E_INTERRUPTED)
2463             goto again;
2464           if (nread == GNUTLS_E_AGAIN)
2465             {
2466               struct timeval tv;
2467
2468               tv.tv_sec = 0;
2469               tv.tv_usec = 50000;
2470               my_select (0, NULL, NULL, NULL, &tv);
2471               goto again;
2472             }
2473           if (nread == GNUTLS_E_REHANDSHAKE)
2474             goto again; /* A client is allowed to just ignore this request. */
2475           log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2476           gpg_err_set_errno (EIO);
2477           return -1;
2478         }
2479     }
2480   else
2481 #endif /*HTTP_USE_GNUTLS*/
2482     {
2483       do
2484         {
2485 #ifdef HAVE_W32_SYSTEM
2486           /* Under Windows we need to use recv for a socket.  */
2487 # if defined(USE_NPTH)
2488           npth_unprotect ();
2489 # endif
2490           nread = recv (c->sock->fd, buffer, size, 0);
2491 # if defined(USE_NPTH)
2492           npth_protect ();
2493 # endif
2494
2495 #else /*!HAVE_W32_SYSTEM*/
2496
2497 # ifdef USE_NPTH
2498           nread = npth_read (c->sock->fd, buffer, size);
2499 # else
2500           nread = read (c->sock->fd, buffer, size);
2501 # endif
2502
2503 #endif /*!HAVE_W32_SYSTEM*/
2504         }
2505       while (nread == -1 && errno == EINTR);
2506     }
2507
2508   if (c->content_length_valid && nread > 0)
2509     {
2510       if (nread < c->content_length)
2511         c->content_length -= nread;
2512       else
2513         c->content_length = 0;
2514     }
2515
2516   return nread;
2517 }
2518
2519 /* Write handler for estream.  */
2520 static ssize_t
2521 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2522 {
2523   const char *buffer = buffer_arg;
2524   cookie_t c = cookie;
2525   int nwritten = 0;
2526
2527 #ifdef HTTP_USE_GNUTLS
2528   if (c->use_tls && c->session && c->session->tls_session)
2529     {
2530       int nleft = size;
2531       while (nleft > 0)
2532         {
2533           nwritten = gnutls_record_send (c->session->tls_session,
2534                                          buffer, nleft);
2535           if (nwritten <= 0)
2536             {
2537               if (nwritten == GNUTLS_E_INTERRUPTED)
2538                 continue;
2539               if (nwritten == GNUTLS_E_AGAIN)
2540                 {
2541                   struct timeval tv;
2542
2543                   tv.tv_sec = 0;
2544                   tv.tv_usec = 50000;
2545                   my_select (0, NULL, NULL, NULL, &tv);
2546                   continue;
2547                 }
2548               log_info ("TLS network write failed: %s\n",
2549                         gnutls_strerror (nwritten));
2550               gpg_err_set_errno (EIO);
2551               return -1;
2552             }
2553           nleft -= nwritten;
2554           buffer += nwritten;
2555         }
2556     }
2557   else
2558 #endif /*HTTP_USE_GNUTLS*/
2559     {
2560       if ( write_server (c->sock->fd, buffer, size) )
2561         {
2562           gpg_err_set_errno (EIO);
2563           nwritten = -1;
2564         }
2565       else
2566         nwritten = size;
2567     }
2568
2569   return nwritten;
2570 }
2571
2572
2573 #ifdef HTTP_USE_GNUTLS
2574 /* Wrapper for gnutls_bye used by my_socket_unref.  */
2575 static void
2576 send_gnutls_bye (void *opaque)
2577 {
2578   tls_session_t tls_session = opaque;
2579   int ret;
2580
2581  again:
2582   do
2583     ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2584   while (ret == GNUTLS_E_INTERRUPTED);
2585   if (ret == GNUTLS_E_AGAIN)
2586     {
2587       struct timeval tv;
2588
2589       tv.tv_sec = 0;
2590       tv.tv_usec = 50000;
2591       my_select (0, NULL, NULL, NULL, &tv);
2592       goto again;
2593     }
2594 }
2595 #endif /*HTTP_USE_GNUTLS*/
2596
2597 /* Close handler for estream.  */
2598 static int
2599 cookie_close (void *cookie)
2600 {
2601   cookie_t c = cookie;
2602
2603   if (!c)
2604     return 0;
2605
2606 #ifdef HTTP_USE_GNUTLS
2607   if (c->use_tls && c->session && c->session->tls_session)
2608     my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2609   else
2610 #endif /*HTTP_USE_GNUTLS*/
2611     if (c->sock)
2612       my_socket_unref (c->sock, NULL, NULL);
2613
2614   if (c->session)
2615     http_session_unref (c->session);
2616   xfree (c);
2617   return 0;
2618 }
2619
2620
2621
2622 \f
2623 /* Verify the credentials of the server.  Returns 0 on success and
2624    store the result in the session object.  */
2625 gpg_error_t
2626 http_verify_server_credentials (http_session_t sess)
2627 {
2628 #if HTTP_USE_NTBTLS
2629   (void)sess;
2630   return 0;  /* FIXME!! */
2631 #elif HTTP_USE_GNUTLS
2632   static const char const errprefix[] = "TLS verification of peer failed";
2633   int rc;
2634   unsigned int status;
2635   const char *hostname;
2636   const gnutls_datum_t *certlist;
2637   unsigned int certlistlen;
2638   gnutls_x509_crt_t cert;
2639   gpg_error_t err = 0;
2640
2641   sess->verify.done = 1;
2642   sess->verify.status = 0;
2643   sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2644
2645   if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2646     {
2647       log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2648       sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2649       return gpg_error (GPG_ERR_GENERAL);
2650     }
2651
2652   rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2653   if (rc)
2654     {
2655       log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2656       if (!err)
2657         err = gpg_error (GPG_ERR_GENERAL);
2658     }
2659   else if (status)
2660     {
2661       log_error ("%s: status=0x%04x\n", errprefix, status);
2662 #if GNUTLS_VERSION_NUMBER >= 0x030104
2663       {
2664         gnutls_datum_t statusdat;
2665
2666         if (!gnutls_certificate_verification_status_print
2667             (status, GNUTLS_CRT_X509, &statusdat, 0))
2668           {
2669             log_info ("%s: %s\n", errprefix, statusdat.data);
2670             gnutls_free (statusdat.data);
2671           }
2672       }
2673 #endif /*gnutls >= 3.1.4*/
2674
2675       sess->verify.status = status;
2676       if (!err)
2677         err = gpg_error (GPG_ERR_GENERAL);
2678     }
2679
2680   hostname = sess->servername;
2681   if (!hostname || !strchr (hostname, '.'))
2682     {
2683       log_error ("%s: %s\n", errprefix, "hostname missing");
2684       if (!err)
2685         err = gpg_error (GPG_ERR_GENERAL);
2686     }
2687
2688   certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2689   if (!certlistlen)
2690     {
2691       log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2692       if (!err)
2693         err = gpg_error (GPG_ERR_GENERAL);
2694
2695       /* Need to stop here.  */
2696       if (err)
2697         return err;
2698     }
2699
2700   rc = gnutls_x509_crt_init (&cert);
2701   if (rc < 0)
2702     {
2703       if (!err)
2704         err = gpg_error (GPG_ERR_GENERAL);
2705       if (err)
2706         return err;
2707     }
2708
2709   rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2710   if (rc < 0)
2711     {
2712       log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
2713                  gnutls_strerror (rc));
2714       if (!err)
2715         err = gpg_error (GPG_ERR_GENERAL);
2716     }
2717
2718   if (!gnutls_x509_crt_check_hostname (cert, hostname))
2719     {
2720       log_error ("%s: %s\n", errprefix, "hostname does not match");
2721       if (!err)
2722         err = gpg_error (GPG_ERR_GENERAL);
2723     }
2724
2725   gnutls_x509_crt_deinit (cert);
2726
2727   if (!err)
2728     sess->verify.rc = 0;
2729
2730   if (sess->cert_log_cb)
2731     {
2732       const void *bufarr[10];
2733       size_t buflenarr[10];
2734       size_t n;
2735
2736       for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
2737         {
2738           bufarr[n] = certlist[n].data;
2739           buflenarr[n] = certlist[n].size;
2740         }
2741       bufarr[n] = NULL;
2742       buflenarr[n] = 0;
2743       sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
2744     }
2745
2746   return err;
2747 #else /*!HTTP_USE_GNUTLS*/
2748   (void)sess;
2749   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2750 #endif
2751 }
2752
2753 /* Return the first query variable with the specified key.  If there
2754    is no such variable, return NULL.  */
2755 struct uri_tuple_s *
2756 uri_query_lookup (parsed_uri_t uri, const char *key)
2757 {
2758   struct uri_tuple_s *t;
2759
2760   for (t = uri->query; t; t = t->next)
2761     if (strcmp (t->name, key) == 0)
2762       return t;
2763
2764   return NULL;
2765 }