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