1 /* http.c - HTTP protocol handler
2 * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
3 * 2011 Free Software Foundation, Inc.
4 * Copyright (C) 2014 Werner Koch
5 * Copyright (C) 2015-2017 g10 Code GmbH
7 * This file is part of GnuPG.
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of either
12 * - the GNU Lesser General Public License as published by the Free
13 * Software Foundation; either version 3 of the License, or (at
14 * your option) any later version.
18 * - the GNU General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at
20 * your option) any later version.
22 * or both in parallel, as here.
24 * This file is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, see <https://www.gnu.org/licenses/>.
33 /* Simple HTTP client implementation. We try to keep the code as
34 self-contained as possible. There are some contraints however:
36 - estream is required. We now require estream because it provides a
37 very useful and portable asprintf implementation and the fopencookie
40 - fixme: list other requirements.
43 - With HTTP_USE_NTBTLS or HTTP_USE_GNUTLS support for https is
44 provided (this also requires estream).
46 - With HTTP_NO_WSASTARTUP the socket initialization is not done
47 under Windows. This is useful if the socket layer has already
48 been initialized elsewhere. This also avoids the installation of
49 an exit handler to cleanup the socket layer.
63 #ifdef HAVE_W32_SYSTEM
64 # ifdef HAVE_WINSOCK2_H
65 # include <winsock2.h>
68 #else /*!HAVE_W32_SYSTEM*/
69 # include <sys/types.h>
70 # include <sys/socket.h>
71 # include <sys/time.h>
73 # include <netinet/in.h>
74 # include <arpa/inet.h>
76 #endif /*!HAVE_W32_SYSTEM*/
78 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
86 #if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_NTBTLS)
87 # error Both, HTTP_USE_GNUTLS and HTTP_USE_NTBTLS, are defined.
90 #ifdef HTTP_USE_NTBTLS
93 # include <gnutls/gnutls.h>
94 # include <gnutls/x509.h>
95 #endif /*HTTP_USE_GNUTLS*/
97 #include <assuan.h> /* We need the socket wrapper. */
101 #include "dns-stuff.h"
106 # define my_select(a,b,c,d,e) npth_select ((a), (b), (c), (d), (e))
107 # define my_accept(a,b,c) npth_accept ((a), (b), (c))
109 # define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e))
110 # define my_accept(a,b,c) accept ((a), (b), (c))
113 #ifdef HAVE_W32_SYSTEM
114 #define sock_close(a) closesocket(a)
116 #define sock_close(a) close(a)
120 #define EAGAIN EWOULDBLOCK
122 #ifndef INADDR_NONE /* Slowaris is missing that. */
123 #define INADDR_NONE ((unsigned long)(-1))
124 #endif /*INADDR_NONE*/
126 #define HTTP_PROXY_ENV "http_proxy"
127 #define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
128 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
129 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
131 "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
134 typedef ntbtls_t tls_session_t;
136 #elif HTTP_USE_GNUTLS
137 typedef gnutls_session_t tls_session_t;
140 typedef void *tls_session_t;
144 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
145 int no_scheme_check, int force_tls);
146 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
147 int no_scheme_check, int force_tls);
148 static int remove_escapes (char *string);
149 static int insert_escapes (char *buffer, const char *string,
150 const char *special);
151 static uri_tuple_t parse_tuple (char *string);
152 static gpg_error_t send_request (http_t hd, const char *httphost,
153 const char *auth,const char *proxy,
154 const char *srvtag,strlist_t headers);
155 static char *build_rel_path (parsed_uri_t uri);
156 static gpg_error_t parse_response (http_t hd);
158 static gpg_error_t connect_server (const char *server, unsigned short port,
159 unsigned int flags, const char *srvtag,
160 assuan_fd_t *r_sock);
161 static gpg_error_t write_server (int sock, const char *data, size_t length);
163 static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
164 static gpgrt_ssize_t cookie_write (void *cookie,
165 const void *buffer, size_t size);
166 static int cookie_close (void *cookie);
169 /* A socket object used to a allow ref counting of sockets. */
172 assuan_fd_t fd; /* The actual socket - shall never be ASSUAN_INVALID_FD. */
173 int refcount; /* Number of references to this socket. */
175 typedef struct my_socket_s *my_socket_t;
178 /* Cookie function structure and cookie object. */
179 static es_cookie_io_functions_t cookie_functions =
189 /* Socket object or NULL if already closed. */
192 /* The session object or NULL if not used. */
193 http_session_t session;
195 /* True if TLS is to be used. */
198 /* The remaining content length and a flag telling whether to use
199 the content length. */
200 uint64_t content_length;
201 unsigned int content_length_valid:1;
203 typedef struct cookie_s *cookie_t;
205 /* The session object. */
206 struct http_session_s
208 int refcount; /* Number of references to this object. */
209 #ifdef HTTP_USE_GNUTLS
210 gnutls_certificate_credentials_t certcred;
211 #endif /*HTTP_USE_GNUTLS*/
213 tls_session_t tls_session;
215 int done; /* Verifciation has been done. */
216 int rc; /* TLS verification return code. */
217 unsigned int status; /* Verification status. */
219 char *servername; /* Malloced server name. */
221 /* A callback function to log details of TLS certifciates. */
222 void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
223 const void **, size_t *);
227 /* An object to save header lines. */
230 struct header_s *next;
231 char *value; /* The value of the header (malloced). */
232 char name[1]; /* The name of the header (canonicalized). */
234 typedef struct header_s *header_t;
237 /* Our handle context. */
238 struct http_context_s
240 unsigned int status_code;
242 unsigned int in_data:1;
243 unsigned int is_http_0_9:1;
248 http_session_t session;
251 char *buffer; /* Line buffer. */
254 header_t headers; /* Received headers. */
258 /* Two flags to enable verbose and debug mode. Although currently not
259 * set-able a value > 1 for OPT_DEBUG enables debugging of the session
260 * reference counting. */
261 static int opt_verbose;
262 static int opt_debug;
264 /* The global callback for the verification function. */
265 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
267 /* The list of files with trusted CA certificates. */
268 static strlist_t tls_ca_certlist;
270 /* The global callback for net activity. */
271 static void (*netactivity_cb)(void);
275 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
277 #if GNUPG_MAJOR_VERSION == 1
278 #define REQ_WINSOCK_MAJOR 1
279 #define REQ_WINSOCK_MINOR 1
281 #define REQ_WINSOCK_MAJOR 2
282 #define REQ_WINSOCK_MINOR 2
287 deinit_sockets (void)
295 static int initialized;
296 static WSADATA wsdata;
301 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
303 log_error ("error initializing socket library: ec=%d\n",
304 (int)WSAGetLastError () );
307 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
308 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
310 log_error ("socket library version is %x.%x - but %d.%d needed\n",
311 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
312 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
316 atexit ( deinit_sockets );
319 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
322 /* Create a new socket object. Returns NULL and closes FD if not
323 enough memory is available. */
325 _my_socket_new (int lnr, assuan_fd_t fd)
329 so = xtrymalloc (sizeof *so);
332 int save_errno = errno;
333 assuan_sock_close (fd);
334 gpg_err_set_errno (save_errno);
340 log_debug ("http.c:%d:socket_new: object %p for fd %d created\n",
344 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
346 /* Bump up the reference counter for the socket object SO. */
348 _my_socket_ref (int lnr, my_socket_t so)
352 log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n",
353 lnr, so, so->fd, so->refcount);
356 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
359 /* Bump down the reference counter for the socket object SO. If SO
360 has no more references, close the socket and release the
363 _my_socket_unref (int lnr, my_socket_t so,
364 void (*preclose)(void*), void *preclosearg)
370 log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n",
371 lnr, so, so->fd, so->refcount);
376 preclose (preclosearg);
377 assuan_sock_close (so->fd);
382 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
385 #ifdef HTTP_USE_GNUTLS
387 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
389 my_socket_t sock = ptr;
391 return npth_read (sock->fd, buffer, size);
393 return read (sock->fd, buffer, size);
397 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
399 my_socket_t sock = ptr;
401 return npth_write (sock->fd, buffer, size);
403 return write (sock->fd, buffer, size);
406 #endif /*HTTP_USE_GNUTLS*/
411 /* This notification function is called by estream whenever stream is
412 closed. Its purpose is to mark the closing in the handle so
413 that a http_close won't accidentally close the estream. The function
414 http_close removes this notification so that it won't be called if
415 http_close was used before an es_fclose. */
417 fp_onclose_notification (estream_t stream, void *opaque)
421 if (hd->fp_read && hd->fp_read == stream)
423 else if (hd->fp_write && hd->fp_write == stream)
429 * Helper function to create an HTTP header with hex encoded data. A
430 * new buffer is returned. This buffer is the concatenation of the
431 * string PREFIX, the hex-encoded DATA of length LEN and the string
432 * SUFFIX. On error NULL is returned and ERRNO set.
435 make_header_line (const char *prefix, const char *suffix,
436 const void *data, size_t len )
438 static unsigned char bintoasc[] =
439 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
440 "abcdefghijklmnopqrstuvwxyz"
442 const unsigned char *s = data;
445 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
448 p = stpcpy (buffer, prefix);
449 for ( ; len >= 3 ; len -= 3, s += 3 )
451 *p++ = bintoasc[(s[0] >> 2) & 077];
452 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
453 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
454 *p++ = bintoasc[s[2]&077];
459 *p++ = bintoasc[(s[0] >> 2) & 077];
460 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
461 *p++ = bintoasc[((s[1]<<2)&074)];
466 *p++ = bintoasc[(s[0] >> 2) & 077];
467 *p++ = bintoasc[(s[0] <<4)&060];
479 /* Set verbosity and debug mode for this module. */
481 http_set_verbose (int verbose, int debug)
483 opt_verbose = verbose;
488 /* Register a non-standard global TLS callback function. If no
489 verification is desired a callback needs to be registered which
490 always returns NULL. */
492 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
498 /* Register a CA certificate for future use. The certificate is
499 expected to be in FNAME. PEM format is assume if FNAME has a
500 suffix of ".pem". If FNAME is NULL the list of CA files is
503 http_register_tls_ca (const char *fname)
509 free_strlist (tls_ca_certlist);
510 tls_ca_certlist = NULL;
514 /* Warn if we can't access right now, but register it anyway in
515 case it becomes accessible later */
516 if (access (fname, F_OK))
517 log_info (_("can't access '%s': %s\n"), fname,
518 gpg_strerror (gpg_error_from_syserror()));
519 sl = add_to_strlist (&tls_ca_certlist, fname);
520 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
526 /* Register a callback which is called every time the HTTP mode has
527 * made a successful connection to some server. */
529 http_register_netactivity_cb (void (*cb)(void))
535 /* Call the netactivity callback if any. */
537 notify_netactivity (void)
546 /* Free the TLS session associated with SESS, if any. */
548 close_tls_session (http_session_t sess)
550 if (sess->tls_session)
554 Possibly, ntbtls_get_transport and close those streams.
555 Somehow get SOCK to call my_socket_unref.
557 ntbtls_release (sess->tls_session);
558 # elif HTTP_USE_GNUTLS
559 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
560 my_socket_unref (sock, NULL, NULL);
561 gnutls_deinit (sess->tls_session);
563 gnutls_certificate_free_credentials (sess->certcred);
564 # endif /*HTTP_USE_GNUTLS*/
565 xfree (sess->servername);
566 sess->tls_session = NULL;
572 /* Release a session. Take care not to release it while it is being
573 used by a http context object. */
575 session_unref (int lnr, http_session_t sess)
582 log_debug ("http.c:%d:session_unref: sess %p ref now %d\n",
583 lnr, sess, sess->refcount);
588 close_tls_session (sess);
593 #define http_session_unref(a) session_unref (__LINE__, (a))
596 http_session_release (http_session_t sess)
598 http_session_unref (sess);
602 /* Create a new session object which is currently used to enable TLS
603 * support. It may eventually allow reusing existing connections.
604 * Valid values for FLAGS are:
605 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
606 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
609 http_session_new (http_session_t *r_session, const char *tls_priority,
610 const char *intended_hostname, unsigned int flags)
617 sess = xtrycalloc (1, sizeof *sess);
619 return gpg_error_from_syserror ();
624 x509_cert_t ca_chain;
627 size_t nread, nbytes;
628 struct b64state state;
635 pemname = make_filename_try (gnupg_datadir (),
636 "sks-keyservers.netCA.pem", NULL);
639 err = gpg_error_from_syserror ();
640 log_error ("setting CA from file '%s' failed: %s\n",
641 pemname, gpg_strerror (err));
645 fp = es_fopen (pemname, "r");
648 err = gpg_error_from_syserror ();
649 log_error ("can't open '%s': %s\n", pemname, gpg_strerror (err));
655 mem_p = es_fopenmem (0, "r+b");
656 err = b64dec_start (&state, "CERTIFICATE");
659 log_error ("b64dec failure: %s\n", gpg_strerror (err));
663 while ( (nread = es_fread (line, 1, DIM (line), fp)) )
665 err = b64dec_proc (&state, line, nread, &nbytes);
668 if (gpg_err_code (err) == GPG_ERR_EOF)
671 log_error ("b64dec failure: %s\n", gpg_strerror (err));
677 es_fwrite (line, 1, nbytes, mem_p);
679 err = b64dec_finish (&state);
682 log_error ("b64dec failure: %s\n", gpg_strerror (err));
688 es_fclose_snatch (mem_p, &buf, &buflen);
691 err = ntbtls_x509_cert_new (&ca_chain);
694 log_error ("ntbtls_x509_new failed: %s\n", gpg_strerror (err));
699 err = ntbtls_x509_append_cert (ca_chain, buf, buflen);
702 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
705 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
706 ntbtls_x509_cert_release (ca_chain);
710 err = ntbtls_set_ca_chain (sess->tls_session, ca_chain, NULL);
712 #elif HTTP_USE_GNUTLS
717 int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS);
720 rc = gnutls_certificate_allocate_credentials (&sess->certcred);
723 log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
724 gnutls_strerror (rc));
725 err = gpg_error (GPG_ERR_GENERAL);
729 is_hkps_pool = (intended_hostname
730 && !ascii_strcasecmp (intended_hostname,
731 "hkps.pool.sks-keyservers.net"));
733 /* If the user has not specified a CA list, and they are looking
734 * for the hkps pool from sks-keyservers.net, then default to
735 * Kristian's certificate authority: */
736 if (!tls_ca_certlist && is_hkps_pool)
738 char *pemname = make_filename_try (gnupg_datadir (),
739 "sks-keyservers.netCA.pem", NULL);
742 err = gpg_error_from_syserror ();
743 log_error ("setting CA from file '%s' failed: %s\n",
744 pemname, gpg_strerror (err));
748 rc = gnutls_certificate_set_x509_trust_file
749 (sess->certcred, pemname, GNUTLS_X509_FMT_PEM);
751 log_info ("setting CA from file '%s' failed: %s\n",
752 pemname, gnutls_strerror (rc));
757 /* Add configured certificates to the session. */
758 if ((flags & HTTP_FLAG_TRUST_DEF))
760 for (sl = tls_ca_certlist; sl; sl = sl->next)
762 rc = gnutls_certificate_set_x509_trust_file
763 (sess->certcred, sl->d,
764 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
766 log_info ("setting CA from file '%s' failed: %s\n",
767 sl->d, gnutls_strerror (rc));
769 if (!tls_ca_certlist && !is_hkps_pool)
773 /* Add system certificates to the session. */
776 #if GNUTLS_VERSION_NUMBER >= 0x030014
779 rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
781 log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
785 log_info ("number of system provided CAs: %d\n", rc);
787 #endif /* gnutls >= 3.0.20 */
790 rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
793 log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
794 err = gpg_error (GPG_ERR_GENERAL);
797 /* A new session has the transport ptr set to (void*(-1), we need
799 gnutls_transport_set_ptr (sess->tls_session, NULL);
801 rc = gnutls_priority_set_direct (sess->tls_session,
802 tls_priority? tls_priority : "NORMAL",
806 log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
807 errpos, gnutls_strerror (rc));
808 err = gpg_error (GPG_ERR_GENERAL);
812 rc = gnutls_credentials_set (sess->tls_session,
813 GNUTLS_CRD_CERTIFICATE, sess->certcred);
816 log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
817 err = gpg_error (GPG_ERR_GENERAL);
821 #else /*!HTTP_USE_GNUTLS*/
825 #endif /*!HTTP_USE_GNUTLS*/
828 log_debug ("http.c:session_new: sess %p created\n", sess);
835 http_session_unref (sess);
843 /* Increment the reference count for session SESS. Passing NULL for
846 http_session_ref (http_session_t sess)
852 log_debug ("http.c:session_ref: sess %p ref now %d\n",
853 sess, sess->refcount);
860 http_session_set_log_cb (http_session_t sess,
861 void (*cb)(http_session_t, gpg_error_t,
862 const char *hostname,
863 const void **certs, size_t *certlens))
865 sess->cert_log_cb = cb;
871 /* Start a HTTP retrieval and on success store at R_HD a context
872 pointer for completing the request and to wait for the response.
873 If HTTPHOST is not NULL it is used for the Host header instead of a
874 Host header derived from the URL. */
876 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
877 const char *httphost,
878 const char *auth, unsigned int flags, const char *proxy,
879 http_session_t session, const char *srvtag, strlist_t headers)
886 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
887 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
889 /* Create the handle. */
890 hd = xtrycalloc (1, sizeof *hd);
892 return gpg_error_from_syserror ();
893 hd->req_type = reqtype;
895 hd->session = http_session_ref (session);
897 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
899 err = send_request (hd, httphost, auth, proxy, srvtag, headers);
903 my_socket_unref (hd->sock, NULL, NULL);
905 es_fclose (hd->fp_read);
907 es_fclose (hd->fp_write);
908 http_session_unref (hd->session);
917 /* This function is useful to connect to a generic TCP service using
918 this http abstraction layer. This has the advantage of providing
919 service tags and an estream interface. */
921 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
922 unsigned int flags, const char *srvtag)
930 if ((flags & HTTP_FLAG_FORCE_TOR))
934 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
936 log_error ("Tor support is not available\n");
937 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
941 /* Create the handle. */
942 hd = xtrycalloc (1, sizeof *hd);
944 return gpg_error_from_syserror ();
945 hd->req_type = HTTP_REQ_OPAQUE;
952 err = connect_server (server, port, hd->flags, srvtag, &sock);
958 hd->sock = my_socket_new (sock);
961 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
967 /* Setup estreams for reading and writing. */
968 cookie = xtrycalloc (1, sizeof *cookie);
971 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
974 cookie->sock = my_socket_ref (hd->sock);
975 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
978 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
979 my_socket_unref (cookie->sock, NULL, NULL);
983 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
985 cookie = xtrycalloc (1, sizeof *cookie);
988 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
991 cookie->sock = my_socket_ref (hd->sock);
992 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
995 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
996 my_socket_unref (cookie->sock, NULL, NULL);
1000 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1002 /* Register close notification to interlock the use of es_fclose in
1003 http_close and in user code. */
1004 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1006 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1012 es_fclose (hd->fp_read);
1014 es_fclose (hd->fp_write);
1015 my_socket_unref (hd->sock, NULL, NULL);
1027 http_start_data (http_t hd)
1031 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1032 log_debug_with_string ("\r\n", "http.c:request-header:");
1033 es_fputs ("\r\n", hd->fp_write);
1034 es_fflush (hd->fp_write);
1038 es_fflush (hd->fp_write);
1043 http_wait_response (http_t hd)
1048 /* Make sure that we are in the data. */
1049 http_start_data (hd);
1051 /* Close the write stream. Note that the reference counted socket
1052 object keeps the actual system socket open. */
1053 cookie = hd->write_cookie;
1055 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1057 es_fclose (hd->fp_write);
1058 hd->fp_write = NULL;
1059 /* The close has released the cookie and thus we better set it to NULL. */
1060 hd->write_cookie = NULL;
1062 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1063 is not required but some very old servers (e.g. the original pksd
1064 keyserver didn't worked without it. */
1065 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1066 shutdown (hd->sock->fd, 1);
1069 /* Create a new cookie and a stream for reading. */
1070 cookie = xtrycalloc (1, sizeof *cookie);
1072 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1073 cookie->sock = my_socket_ref (hd->sock);
1074 cookie->session = http_session_ref (hd->session);
1075 cookie->use_tls = hd->uri->use_tls;
1077 hd->read_cookie = cookie;
1078 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1081 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1082 my_socket_unref (cookie->sock, NULL, NULL);
1083 http_session_unref (cookie->session);
1085 hd->read_cookie = NULL;
1089 err = parse_response (hd);
1092 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1098 /* Convenience function to send a request and wait for the response.
1099 Closes the handle on error. If PROXY is not NULL, this value will
1100 be used as an HTTP proxy and any enabled $http_proxy gets
1103 http_open_document (http_t *r_hd, const char *document,
1104 const char *auth, unsigned int flags, const char *proxy,
1105 http_session_t session,
1106 const char *srvtag, strlist_t headers)
1110 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1111 proxy, session, srvtag, headers);
1115 err = http_wait_response (*r_hd);
1117 http_close (*r_hd, 0);
1124 http_close (http_t hd, int keep_read_stream)
1129 /* First remove the close notifications for the streams. */
1131 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1133 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1135 /* Now we can close the streams. */
1136 my_socket_unref (hd->sock, NULL, NULL);
1137 if (hd->fp_read && !keep_read_stream)
1138 es_fclose (hd->fp_read);
1140 es_fclose (hd->fp_write);
1141 http_session_unref (hd->session);
1142 http_release_parsed_uri (hd->uri);
1145 header_t tmp = hd->headers->next;
1146 xfree (hd->headers->value);
1147 xfree (hd->headers);
1156 http_get_read_ptr (http_t hd)
1158 return hd?hd->fp_read:NULL;
1162 http_get_write_ptr (http_t hd)
1164 return hd?hd->fp_write:NULL;
1168 http_get_status_code (http_t hd)
1170 return hd?hd->status_code:0;
1173 /* Return information pertaining to TLS. If TLS is not in use for HD,
1174 NULL is returned. WHAT is used ask for specific information:
1176 (NULL) := Only check whether TLS is is use. Returns an
1177 unspecified string if TLS is in use. That string may
1178 even be the empty string.
1181 http_get_tls_info (http_t hd, const char *what)
1188 return hd->uri->use_tls? "":NULL;
1194 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1195 int no_scheme_check, int force_tls)
1199 *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1201 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1202 strcpy ((*ret_uri)->buffer, uri);
1203 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1209 return gpg_err_make (default_errsource, ec);
1214 * Parse an URI and put the result into the newly allocated RET_URI.
1215 * On success the caller must use http_release_parsed_uri() to
1216 * releases the resources. If NO_SCHEME_CHECK is set, the function
1217 * tries to parse the URL in the same way it would do for an HTTP
1221 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1222 int no_scheme_check)
1224 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1229 http_release_parsed_uri (parsed_uri_t uri)
1235 for (r = uri->query; r; r = r2)
1245 static gpg_err_code_t
1246 do_parse_uri (parsed_uri_t uri, int only_local_part,
1247 int no_scheme_check, int force_tls)
1250 char *p, *p2, *p3, *pp;
1254 n = strlen (uri->buffer);
1256 /* Initialize all fields to an empty string or an empty list. */
1257 uri->scheme = uri->host = uri->path = p + n;
1259 uri->params = uri->query = NULL;
1265 uri->explicit_port = 0;
1267 /* A quick validity check. */
1268 if (strspn (p, VALID_URI_CHARS) != n)
1269 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1271 if (!only_local_part)
1273 /* Find the scheme. */
1274 if (!(p2 = strchr (p, ':')) || p2 == p)
1275 return GPG_ERR_BAD_URI; /* No scheme. */
1277 for (pp=p; *pp; pp++)
1278 *pp = tolower (*(unsigned char*)pp);
1280 if (!strcmp (uri->scheme, "http") && !force_tls)
1285 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1291 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1292 || (force_tls && (!strcmp (uri->scheme, "http")
1293 || !strcmp (uri->scheme,"hkp"))))
1300 else if (!no_scheme_check)
1301 return GPG_ERR_INV_URI; /* Unsupported scheme */
1305 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1308 if ((p2 = strchr (p, '/')))
1311 /* Check for username/password encoding */
1312 if ((p3 = strchr (p, '@')))
1319 for (pp=p; *pp; pp++)
1320 *pp = tolower (*(unsigned char*)pp);
1322 /* Handle an IPv6 literal */
1323 if( *p == '[' && (p3=strchr( p, ']' )) )
1326 /* worst case, uri->host should have length 0, points to \0 */
1334 if ((p3 = strchr (p, ':')))
1337 uri->port = atoi (p3);
1338 uri->explicit_port = 1;
1341 if ((n = remove_escapes (uri->host)) < 0)
1342 return GPG_ERR_BAD_URI;
1343 if (n != strlen (uri->host))
1344 return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */
1347 else if (uri->is_http)
1348 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1353 if (is_onion_address (uri->path))
1358 } /* End global URI part. */
1360 /* Parse the pathname part if any. */
1363 /* TODO: Here we have to check params. */
1365 /* Do we have a query part? */
1366 if ((p2 = strchr (p, '?')))
1370 if ((n = remove_escapes (p)) < 0)
1371 return GPG_ERR_BAD_URI;
1372 if (n != strlen (p))
1373 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1376 /* Parse a query string if any. */
1384 if ((p2 = strchr (p, '&')))
1386 if (!(elem = parse_tuple (p)))
1387 return GPG_ERR_BAD_URI;
1398 if (is_onion_address (uri->host))
1406 * Remove all %xx escapes; this is done in-place. Returns: New length
1410 remove_escapes (char *string)
1413 unsigned char *p, *s;
1415 for (p = s = (unsigned char*)string; *s; s++)
1419 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1422 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1423 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1426 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1427 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1440 return -1; /* Bad URI. */
1449 *p = 0; /* Make sure to keep a string terminator. */
1454 /* If SPECIAL is NULL this function escapes in forms mode. */
1456 escape_data (char *buffer, const void *data, size_t datalen,
1457 const char *special)
1459 int forms = !special;
1460 const unsigned char *s;
1466 for (s = data; datalen; s++, datalen--)
1468 if (forms && *s == ' ')
1474 else if (forms && *s == '\n')
1477 memcpy (buffer, "%0D%0A", 6);
1480 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1483 memcpy (buffer, "%0D%0A", 6);
1488 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1491 *(unsigned char*)buffer++ = *s;
1498 snprintf (buffer, 4, "%%%02X", *s);
1509 insert_escapes (char *buffer, const char *string,
1510 const char *special)
1512 return escape_data (buffer, string, strlen (string), special);
1516 /* Allocate a new string from STRING using standard HTTP escaping as
1517 well as escaping of characters given in SPECIALS. A common pattern
1518 for SPECIALS is "%;?&=". However it depends on the needs, for
1519 example "+" and "/: often needs to be escaped too. Returns NULL on
1520 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1521 encoding mode is used. */
1523 http_escape_string (const char *string, const char *specials)
1528 n = insert_escapes (NULL, string, specials);
1529 buf = xtrymalloc (n+1);
1532 insert_escapes (buf, string, specials);
1538 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1539 escaping as well as escaping of characters given in SPECIALS. A
1540 common pattern for SPECIALS is "%;?&=". However it depends on the
1541 needs, for example "+" and "/: often needs to be escaped too.
1542 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1543 dedicated forms encoding mode is used. */
1545 http_escape_data (const void *data, size_t datalen, const char *specials)
1550 n = escape_data (NULL, data, datalen, specials);
1551 buf = xtrymalloc (n+1);
1554 escape_data (buf, data, datalen, specials);
1562 parse_tuple (char *string)
1569 if ((p2 = strchr (p, '=')))
1571 if ((n = remove_escapes (p)) < 0)
1572 return NULL; /* Bad URI. */
1573 if (n != strlen (p))
1574 return NULL; /* Name with a Nul in it. */
1575 tuple = xtrycalloc (1, sizeof *tuple);
1577 return NULL; /* Out of core. */
1579 if (!p2) /* We have only the name, so we assume an empty value string. */
1581 tuple->value = p + strlen (p);
1582 tuple->valuelen = 0;
1583 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1585 else /* Name and value. */
1587 if ((n = remove_escapes (p2)) < 0)
1590 return NULL; /* Bad URI. */
1593 tuple->valuelen = n;
1599 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1601 is_hostname_port (const char *string)
1605 if (!string || !*string)
1607 for (; *string; string++)
1617 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1618 return 0; /* Invalid characters in hostname. */
1619 else if (colons && !digitp (string))
1620 return 0; /* Not a digit in the port. */
1627 * Send a HTTP request to the server
1628 * Returns 0 if the request was successful
1631 send_request (http_t hd, const char *httphost, const char *auth,
1632 const char *proxy, const char *srvtag, strlist_t headers)
1637 unsigned short port;
1638 const char *http_proxy = NULL;
1639 char *proxy_authstr = NULL;
1640 char *authstr = NULL;
1643 if (hd->uri->use_tls && !hd->session)
1645 log_error ("TLS requested but no session object provided\n");
1646 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1649 if (hd->uri->use_tls && !hd->session->tls_session)
1651 log_error ("TLS requested but no GNUTLS context available\n");
1652 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1656 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1660 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1662 log_error ("Tor support is not available\n");
1663 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1667 server = *hd->uri->host ? hd->uri->host : "localhost";
1668 port = hd->uri->port ? hd->uri->port : 80;
1670 /* Try to use SNI. */
1672 if (hd->uri->use_tls)
1674 # if HTTP_USE_GNUTLS
1678 xfree (hd->session->servername);
1679 hd->session->servername = xtrystrdup (httphost? httphost : server);
1680 if (!hd->session->servername)
1682 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1686 # if HTTP_USE_NTBTLS
1687 err = ntbtls_set_hostname (hd->session->tls_session,
1688 hd->session->servername);
1691 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1694 # elif HTTP_USE_GNUTLS
1695 rc = gnutls_server_name_set (hd->session->tls_session,
1697 hd->session->servername,
1698 strlen (hd->session->servername));
1700 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1701 # endif /*HTTP_USE_GNUTLS*/
1705 if ( (proxy && *proxy)
1706 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1707 && (http_proxy = getenv (HTTP_PROXY_ENV))
1715 err = parse_uri (&uri, http_proxy, 0, 0);
1716 if (gpg_err_code (err) == GPG_ERR_INV_URI
1717 && is_hostname_port (http_proxy))
1719 /* Retry assuming a "hostname:port" string. */
1720 char *tmpname = strconcat ("http://", http_proxy, NULL);
1721 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1728 else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1730 else if (!strcmp (uri->scheme, "socks5h"))
1731 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1733 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1737 log_error ("invalid HTTP proxy (%s): %s\n",
1738 http_proxy, gpg_strerror (err));
1739 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1744 remove_escapes (uri->auth);
1745 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1747 uri->auth, strlen(uri->auth));
1750 err = gpg_err_make (default_errsource,
1751 gpg_err_code_from_syserror ());
1752 http_release_parsed_uri (uri);
1757 err = connect_server (*uri->host ? uri->host : "localhost",
1758 uri->port ? uri->port : 80,
1759 hd->flags, srvtag, &sock);
1760 http_release_parsed_uri (uri);
1764 err = connect_server (server, port, hd->flags, srvtag, &sock);
1769 xfree (proxy_authstr);
1772 hd->sock = my_socket_new (sock);
1775 xfree (proxy_authstr);
1776 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1781 if (hd->uri->use_tls)
1785 my_socket_ref (hd->sock);
1787 in = es_fdopen_nc (hd->sock->fd, "rb");
1790 err = gpg_error_from_syserror ();
1791 xfree (proxy_authstr);
1795 out = es_fdopen_nc (hd->sock->fd, "wb");
1798 err = gpg_error_from_syserror ();
1800 xfree (proxy_authstr);
1804 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1807 log_info ("TLS set_transport failed: %s <%s>\n",
1808 gpg_strerror (err), gpg_strsource (err));
1809 xfree (proxy_authstr);
1813 while ((err = ntbtls_handshake (hd->session->tls_session)))
1818 log_info ("TLS handshake failed: %s <%s>\n",
1819 gpg_strerror (err), gpg_strsource (err));
1820 xfree (proxy_authstr);
1825 hd->session->verify.done = 0;
1827 err = tls_callback (hd, hd->session, 0);
1829 err = http_verify_server_credentials (hd->session);
1832 log_info ("TLS connection authentication failed: %s <%s>\n",
1833 gpg_strerror (err), gpg_strsource (err));
1834 xfree (proxy_authstr);
1838 #elif HTTP_USE_GNUTLS
1839 if (hd->uri->use_tls)
1843 my_socket_ref (hd->sock);
1844 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1845 gnutls_transport_set_pull_function (hd->session->tls_session,
1847 gnutls_transport_set_push_function (hd->session->tls_session,
1852 rc = gnutls_handshake (hd->session->tls_session);
1854 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1857 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1858 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1860 gnutls_alert_description_t alertno;
1861 const char *alertstr;
1863 alertno = gnutls_alert_get (hd->session->tls_session);
1864 alertstr = gnutls_alert_get_name (alertno);
1865 log_info ("TLS handshake failed: %s (alert %d)\n",
1866 alertstr, (int)alertno);
1867 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1868 log_info (" (sent server name '%s')\n", server);
1871 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1872 xfree (proxy_authstr);
1873 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1876 hd->session->verify.done = 0;
1878 err = tls_callback (hd, hd->session, 0);
1880 err = http_verify_server_credentials (hd->session);
1883 log_info ("TLS connection authentication failed: %s\n",
1884 gpg_strerror (err));
1885 xfree (proxy_authstr);
1889 #endif /*HTTP_USE_GNUTLS*/
1891 if (auth || hd->uri->auth)
1897 myauth = xtrystrdup (auth);
1900 xfree (proxy_authstr);
1901 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1903 remove_escapes (myauth);
1907 remove_escapes (hd->uri->auth);
1908 myauth = hd->uri->auth;
1911 authstr = make_header_line ("Authorization: Basic ", "\r\n",
1912 myauth, strlen (myauth));
1918 xfree (proxy_authstr);
1919 return gpg_err_make (default_errsource,
1920 gpg_err_code_from_syserror ());
1924 p = build_rel_path (hd->uri);
1926 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1928 if (http_proxy && *http_proxy)
1930 request = es_bsprintf
1931 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1932 hd->req_type == HTTP_REQ_GET ? "GET" :
1933 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1934 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1935 hd->uri->use_tls? "https" : "http",
1936 httphost? httphost : server,
1937 port, *p == '/' ? "" : "/", p,
1938 authstr ? authstr : "",
1939 proxy_authstr ? proxy_authstr : "");
1948 snprintf (portstr, sizeof portstr, ":%u", port);
1950 request = es_bsprintf
1951 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1952 hd->req_type == HTTP_REQ_GET ? "GET" :
1953 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1954 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1955 *p == '/' ? "" : "/", p,
1956 httphost? httphost : server,
1958 authstr? authstr:"");
1963 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1965 xfree (proxy_authstr);
1969 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1970 log_debug_with_string (request, "http.c:request:");
1972 /* First setup estream so that we can write even the first line
1973 using estream. This is also required for the sake of gnutls. */
1977 cookie = xtrycalloc (1, sizeof *cookie);
1980 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1983 cookie->sock = my_socket_ref (hd->sock);
1984 hd->write_cookie = cookie;
1985 cookie->use_tls = hd->uri->use_tls;
1986 cookie->session = http_session_ref (hd->session);
1988 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1991 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1992 my_socket_unref (cookie->sock, NULL, NULL);
1994 hd->write_cookie = NULL;
1996 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1997 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2003 for (;headers; headers=headers->next)
2005 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2006 log_debug_with_string (headers->d, "http.c:request-header:");
2007 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2008 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2010 err = gpg_err_make (default_errsource,
2011 gpg_err_code_from_syserror ());
2021 xfree (proxy_authstr);
2028 * Build the relative path from the parsed URI. Minimal
2029 * implementation. May return NULL in case of memory failure; errno
2030 * is then set accordingly.
2033 build_rel_path (parsed_uri_t uri)
2039 /* Count the needed space. */
2040 n = insert_escapes (NULL, uri->path, "%;?&");
2041 /* TODO: build params. */
2042 for (r = uri->query; r; r = r->next)
2045 n += insert_escapes (NULL, r->name, "%;?&=");
2049 n += insert_escapes (NULL, r->value, "%;?&=");
2054 /* Now allocate and copy. */
2055 p = rel_path = xtrymalloc (n);
2058 n = insert_escapes (p, uri->path, "%;?&");
2060 /* TODO: add params. */
2061 for (r = uri->query; r; r = r->next)
2063 *p++ = r == uri->query ? '?' : '&';
2064 n = insert_escapes (p, r->name, "%;?&=");
2069 /* TODO: Use valuelen. */
2070 n = insert_escapes (p, r->value, "%;?&=");
2079 /* Transform a header name into a standard capitalized format; e.g.
2080 "Content-Type". Conversion stops at the colon. As usual we don't
2081 use the localized versions of ctype.h. */
2083 capitalize_header_name (char *name)
2087 for (; *name && *name != ':'; name++)
2093 if (*name >= 'a' && *name <= 'z')
2094 *name = *name - 'a' + 'A';
2097 else if (*name >= 'A' && *name <= 'Z')
2098 *name = *name - 'A' + 'a';
2103 /* Store an HTTP header line in LINE away. Line continuation is
2104 supported as well as merging of headers with the same name. This
2105 function may modify LINE. */
2106 static gpg_err_code_t
2107 store_header (http_t hd, char *line)
2114 if (n && line[n-1] == '\n')
2117 if (n && line[n-1] == '\r')
2120 if (!n) /* we are never called to hit this. */
2122 if (*line == ' ' || *line == '\t')
2124 /* Continuation. This won't happen too often as it is not
2125 recommended. We use a straightforward implementaion. */
2127 return GPG_ERR_PROTOCOL_VIOLATION;
2128 n += strlen (hd->headers->value);
2129 p = xtrymalloc (n+1);
2131 return gpg_err_code_from_syserror ();
2132 strcpy (stpcpy (p, hd->headers->value), line);
2133 xfree (hd->headers->value);
2134 hd->headers->value = p;
2138 capitalize_header_name (line);
2139 p = strchr (line, ':');
2141 return GPG_ERR_PROTOCOL_VIOLATION;
2143 while (*p == ' ' || *p == '\t')
2147 for (h=hd->headers; h; h = h->next)
2148 if ( !strcmp (h->name, line) )
2152 /* We have already seen a line with that name. Thus we assume
2153 it is a comma separated list and merge them. */
2154 p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
2156 return gpg_err_code_from_syserror ();
2157 strcpy (stpcpy (stpcpy (p, h->value), ","), value);
2163 /* Append a new header. */
2164 h = xtrymalloc (sizeof *h + strlen (line));
2166 return gpg_err_code_from_syserror ();
2167 strcpy (h->name, line);
2168 h->value = xtrymalloc (strlen (value)+1);
2172 return gpg_err_code_from_syserror ();
2174 strcpy (h->value, value);
2175 h->next = hd->headers;
2182 /* Return the header NAME from the last response. The returned value
2183 is valid as along as HD has not been closed and no other request
2184 has been send. If the header was not found, NULL is returned. NAME
2185 must be canonicalized, that is the first letter of each dash
2186 delimited part must be uppercase and all other letters lowercase. */
2188 http_get_header (http_t hd, const char *name)
2192 for (h=hd->headers; h; h = h->next)
2193 if ( !strcmp (h->name, name) )
2199 /* Return a newly allocated and NULL terminated array with pointers to
2200 header names. The array must be released with xfree() and its
2201 content is only values as long as no other request has been
2204 http_get_header_names (http_t hd)
2210 for (n=0, h = hd->headers; h; h = h->next)
2212 array = xtrycalloc (n+1, sizeof *array);
2215 for (n=0, h = hd->headers; h; h = h->next)
2216 array[n++] = h->name;
2224 * Parse the response from a server.
2225 * Returns: Errorcode and sets some files in the handle
2227 static gpg_err_code_t
2228 parse_response (http_t hd)
2230 char *line, *p, *p2;
2232 cookie_t cookie = hd->read_cookie;
2235 /* Delete old header lines. */
2238 header_t tmp = hd->headers->next;
2239 xfree (hd->headers->value);
2240 xfree (hd->headers);
2244 /* Wait for the status line. */
2247 maxlen = MAX_LINELEN;
2248 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2251 return gpg_err_code_from_syserror (); /* Out of core. */
2253 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2257 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2258 log_debug_with_string (line, "http.c:response:\n");
2262 if ((p = strchr (line, '/')))
2264 if (!p || strcmp (line, "HTTP"))
2265 return 0; /* Assume http 0.9. */
2267 if ((p2 = strpbrk (p, " \t")))
2270 p2 += strspn (p2, " \t");
2273 return 0; /* Also assume http 0.9. */
2275 /* TODO: Add HTTP version number check. */
2276 if ((p2 = strpbrk (p, " \t")))
2278 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2279 || !isdigit ((unsigned int)p[2]) || p[3])
2281 /* Malformed HTTP status code - assume http 0.9. */
2282 hd->is_http_0_9 = 1;
2283 hd->status_code = 200;
2286 hd->status_code = atoi (p);
2288 /* Skip all the header lines and wait for the empty line. */
2291 maxlen = MAX_LINELEN;
2292 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2295 return gpg_err_code_from_syserror (); /* Out of core. */
2296 /* Note, that we can silently ignore truncated lines. */
2299 /* Trim line endings of empty lines. */
2300 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2302 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2303 log_info ("http.c:RESP: '%.*s'\n",
2304 (int)strlen(line)-(*line&&line[1]?2:0),line);
2307 gpg_err_code_t ec = store_header (hd, line);
2312 while (len && *line);
2314 cookie->content_length_valid = 0;
2315 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2317 s = http_get_header (hd, "Content-Length");
2320 cookie->content_length_valid = 1;
2321 cookie->content_length = string_to_u64 (s);
2332 struct sockaddr_in mya;
2333 struct sockaddr_in peer;
2339 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2341 log_error ("socket() failed: %s\n", strerror (errno));
2345 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2346 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2348 mya.sin_family = AF_INET;
2349 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2350 mya.sin_port = htons (11371);
2352 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2354 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2361 log_error ("listen failed: %s\n", strerror (errno));
2371 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2372 continue; /* ignore any errors */
2374 if (!FD_ISSET (fd, &rfds))
2377 addrlen = sizeof peer;
2378 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2380 continue; /* oops */
2382 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2391 fp = fdopen (client, "r");
2392 while ((c = getc (fp)) != EOF)
2397 sock_close (client);
2407 /* Return true if SOCKS shall be used. This is the case if tor_mode
2408 * is enabled and the desired address is not the loopback address.
2409 * This function is basically a copy of the same internal fucntion in
2412 use_socks (struct sockaddr *addr)
2416 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2417 return 0; /* Not in Tor mode. */
2418 else if (addr->sa_family == AF_INET6)
2420 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2421 const unsigned char *s;
2424 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2426 return 1; /* Last octet is not 1 - not the loopback address. */
2427 for (i=0; i < 15; i++, s++)
2429 return 1; /* Non-zero octet found - not the loopback address. */
2431 return 0; /* This is the loopback address. */
2433 else if (addr->sa_family == AF_INET)
2435 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2437 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2438 return 0; /* Loopback (127.0.0.0/8) */
2447 /* Wrapper around assuan_sock_new which takes the domain from an
2448 * address parameter. */
2450 my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
2454 if (use_socks (addr))
2456 /* Libassaun always uses 127.0.0.1 to connect to the socks
2457 * server (i.e. the Tor daemon). */
2461 domain = addr->sa_family;
2463 return assuan_sock_new (domain, type, proto);
2467 /* Actually connect to a server. On success 0 is returned and the
2468 * file descriptor for the socket is stored at R_SOCK; on error an
2469 * error code is returned and ASSUAN_INVALID_FD is stored at
2472 connect_server (const char *server, unsigned short port,
2473 unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
2476 assuan_fd_t sock = ASSUAN_INVALID_FD;
2477 unsigned int srvcount = 0;
2479 int anyhostaddr = 0;
2481 gpg_error_t last_err = 0;
2482 struct srventry *serverlist = NULL;
2484 *r_sock = ASSUAN_INVALID_FD;
2486 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2490 /* Onion addresses require special treatment. */
2491 if (is_onion_address (server))
2493 #ifdef ASSUAN_SOCK_TOR
2496 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2498 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2500 if (sock == ASSUAN_INVALID_FD)
2502 err = gpg_err_make (default_errsource,
2503 (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2504 : gpg_err_code_from_syserror ());
2505 log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2509 notify_netactivity ();
2513 #else /*!ASSUAN_SOCK_TOR*/
2515 err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2516 return ASSUAN_INVALID_FD;
2518 #endif /*!HASSUAN_SOCK_TOR*/
2521 /* Do the SRV thing */
2524 err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2526 log_info ("getting '%s' SRV for '%s' failed: %s\n",
2527 srvtag, server, gpg_strerror (err));
2528 /* Note that on error SRVCOUNT is zero. */
2534 /* Either we're not using SRV, or the SRV lookup failed. Make
2535 up a fake SRV record. */
2536 serverlist = xtrycalloc (1, sizeof *serverlist);
2538 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2540 serverlist->port = port;
2541 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2542 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2547 for (srv=0; srv < srvcount && !connected; srv++)
2549 dns_addrinfo_t aibuf, ai;
2552 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2553 serverlist[srv].target, port);
2554 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2558 log_info ("resolving '%s' failed: %s\n",
2559 serverlist[srv].target, gpg_strerror (err));
2561 continue; /* Not found - try next one. */
2565 for (ai = aibuf; ai && !connected; ai = ai->next)
2567 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2569 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2572 if (sock != ASSUAN_INVALID_FD)
2573 assuan_sock_close (sock);
2574 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2575 if (sock == ASSUAN_INVALID_FD)
2577 err = gpg_err_make (default_errsource,
2578 gpg_err_code_from_syserror ());
2579 log_error ("error creating socket: %s\n", gpg_strerror (err));
2580 free_dns_addrinfo (aibuf);
2586 if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
2588 last_err = gpg_err_make (default_errsource,
2589 gpg_err_code_from_syserror ());
2594 notify_netactivity ();
2597 free_dns_addrinfo (aibuf);
2605 log_error ("can't connect to '%s': %s\n",
2606 server, "host not found");
2607 else if (!anyhostaddr)
2608 log_error ("can't connect to '%s': %s\n",
2609 server, "no IP address for host");
2612 #ifdef HAVE_W32_SYSTEM
2613 log_error ("can't connect to '%s': ec=%d\n",
2614 server, (int)WSAGetLastError());
2616 log_error ("can't connect to '%s': %s\n",
2617 server, gpg_strerror (last_err));
2620 err = last_err? last_err : gpg_err_make (default_errsource,
2621 GPG_ERR_UNKNOWN_HOST);
2622 if (sock != ASSUAN_INVALID_FD)
2623 assuan_sock_close (sock);
2633 write_server (int sock, const char *data, size_t length)
2641 #if defined(HAVE_W32_SYSTEM)
2642 # if defined(USE_NPTH)
2645 nwritten = send (sock, data, nleft, 0);
2646 # if defined(USE_NPTH)
2649 if ( nwritten == SOCKET_ERROR )
2651 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2652 return gpg_error (GPG_ERR_NETWORK);
2654 #else /*!HAVE_W32_SYSTEM*/
2656 nwritten = npth_write (sock, data, nleft);
2658 nwritten = write (sock, data, nleft);
2664 if (errno == EAGAIN)
2670 my_select (0, NULL, NULL, NULL, &tv);
2673 log_info ("network write failed: %s\n", strerror (errno));
2674 return gpg_error_from_syserror ();
2676 #endif /*!HAVE_W32_SYSTEM*/
2686 /* Read handler for estream. */
2687 static gpgrt_ssize_t
2688 cookie_read (void *cookie, void *buffer, size_t size)
2690 cookie_t c = cookie;
2693 if (c->content_length_valid)
2695 if (!c->content_length)
2697 if (c->content_length < size)
2698 size = c->content_length;
2702 if (c->use_tls && c->session && c->session->tls_session)
2706 ntbtls_get_stream (c->session->tls_session, &in, &out);
2707 nread = es_fread (buffer, 1, size, in);
2709 log_debug ("TLS network read: %d/%zu\n", nread, size);
2712 #elif HTTP_USE_GNUTLS
2713 if (c->use_tls && c->session && c->session->tls_session)
2716 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2719 if (nread == GNUTLS_E_INTERRUPTED)
2721 if (nread == GNUTLS_E_AGAIN)
2727 my_select (0, NULL, NULL, NULL, &tv);
2730 if (nread == GNUTLS_E_REHANDSHAKE)
2731 goto again; /* A client is allowed to just ignore this request. */
2732 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2734 /* The server terminated the connection. Close the TLS
2735 session, and indicate EOF using a short read. */
2736 close_tls_session (c->session);
2739 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2740 gpg_err_set_errno (EIO);
2745 #endif /*HTTP_USE_GNUTLS*/
2749 #ifdef HAVE_W32_SYSTEM
2750 /* Under Windows we need to use recv for a socket. */
2751 # if defined(USE_NPTH)
2754 nread = recv (c->sock->fd, buffer, size, 0);
2755 # if defined(USE_NPTH)
2759 #else /*!HAVE_W32_SYSTEM*/
2762 nread = npth_read (c->sock->fd, buffer, size);
2764 nread = read (c->sock->fd, buffer, size);
2767 #endif /*!HAVE_W32_SYSTEM*/
2769 while (nread == -1 && errno == EINTR);
2772 if (c->content_length_valid && nread > 0)
2774 if (nread < c->content_length)
2775 c->content_length -= nread;
2777 c->content_length = 0;
2780 return (gpgrt_ssize_t)nread;
2783 /* Write handler for estream. */
2784 static gpgrt_ssize_t
2785 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2787 const char *buffer = buffer_arg;
2788 cookie_t c = cookie;
2792 if (c->use_tls && c->session && c->session->tls_session)
2796 ntbtls_get_stream (c->session->tls_session, &in, &out);
2800 nwritten = es_fwrite (buffer, 1, size, out);
2802 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
2805 #elif HTTP_USE_GNUTLS
2806 if (c->use_tls && c->session && c->session->tls_session)
2811 nwritten = gnutls_record_send (c->session->tls_session,
2815 if (nwritten == GNUTLS_E_INTERRUPTED)
2817 if (nwritten == GNUTLS_E_AGAIN)
2823 my_select (0, NULL, NULL, NULL, &tv);
2826 log_info ("TLS network write failed: %s\n",
2827 gnutls_strerror (nwritten));
2828 gpg_err_set_errno (EIO);
2836 #endif /*HTTP_USE_GNUTLS*/
2838 if ( write_server (c->sock->fd, buffer, size) )
2840 gpg_err_set_errno (EIO);
2847 return (gpgrt_ssize_t)nwritten;
2851 #ifdef HTTP_USE_GNUTLS
2852 /* Wrapper for gnutls_bye used by my_socket_unref. */
2854 send_gnutls_bye (void *opaque)
2856 tls_session_t tls_session = opaque;
2861 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2862 while (ret == GNUTLS_E_INTERRUPTED);
2863 if (ret == GNUTLS_E_AGAIN)
2869 my_select (0, NULL, NULL, NULL, &tv);
2873 #endif /*HTTP_USE_GNUTLS*/
2875 /* Close handler for estream. */
2877 cookie_close (void *cookie)
2879 cookie_t c = cookie;
2885 if (c->use_tls && c->session && c->session->tls_session)
2887 /* FIXME!! Possibly call ntbtls_close_notify for close
2889 my_socket_unref (c->sock, NULL, NULL);
2892 #elif HTTP_USE_GNUTLS
2893 if (c->use_tls && c->session && c->session->tls_session)
2894 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2896 #endif /*HTTP_USE_GNUTLS*/
2898 my_socket_unref (c->sock, NULL, NULL);
2901 http_session_unref (c->session);
2909 /* Verify the credentials of the server. Returns 0 on success and
2910 store the result in the session object. */
2912 http_verify_server_credentials (http_session_t sess)
2916 return 0; /* FIXME!! */
2917 #elif HTTP_USE_GNUTLS
2918 static const char const errprefix[] = "TLS verification of peer failed";
2920 unsigned int status;
2921 const char *hostname;
2922 const gnutls_datum_t *certlist;
2923 unsigned int certlistlen;
2924 gnutls_x509_crt_t cert;
2925 gpg_error_t err = 0;
2927 sess->verify.done = 1;
2928 sess->verify.status = 0;
2929 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2931 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2933 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2934 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2935 return gpg_error (GPG_ERR_GENERAL);
2938 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2941 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2943 err = gpg_error (GPG_ERR_GENERAL);
2947 log_error ("%s: status=0x%04x\n", errprefix, status);
2948 #if GNUTLS_VERSION_NUMBER >= 0x030104
2950 gnutls_datum_t statusdat;
2952 if (!gnutls_certificate_verification_status_print
2953 (status, GNUTLS_CRT_X509, &statusdat, 0))
2955 log_info ("%s: %s\n", errprefix, statusdat.data);
2956 gnutls_free (statusdat.data);
2959 #endif /*gnutls >= 3.1.4*/
2961 sess->verify.status = status;
2963 err = gpg_error (GPG_ERR_GENERAL);
2966 hostname = sess->servername;
2967 if (!hostname || !strchr (hostname, '.'))
2969 log_error ("%s: %s\n", errprefix, "hostname missing");
2971 err = gpg_error (GPG_ERR_GENERAL);
2974 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2977 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2979 err = gpg_error (GPG_ERR_GENERAL);
2981 /* Need to stop here. */
2986 rc = gnutls_x509_crt_init (&cert);
2990 err = gpg_error (GPG_ERR_GENERAL);
2995 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2998 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
2999 gnutls_strerror (rc));
3001 err = gpg_error (GPG_ERR_GENERAL);
3004 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3006 log_error ("%s: %s\n", errprefix, "hostname does not match");
3008 err = gpg_error (GPG_ERR_GENERAL);
3011 gnutls_x509_crt_deinit (cert);
3014 sess->verify.rc = 0;
3016 if (sess->cert_log_cb)
3018 const void *bufarr[10];
3019 size_t buflenarr[10];
3022 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3024 bufarr[n] = certlist[n].data;
3025 buflenarr[n] = certlist[n].size;
3029 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3033 #else /*!HTTP_USE_GNUTLS*/
3035 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3039 /* Return the first query variable with the specified key. If there
3040 is no such variable, return NULL. */
3041 struct uri_tuple_s *
3042 uri_query_lookup (parsed_uri_t uri, const char *key)
3044 struct uri_tuple_s *t;
3046 for (t = uri->query; t; t = t->next)
3047 if (strcmp (t->name, key) == 0)