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