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