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