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