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