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