1 /* http.c - HTTP protocol handler
2 * Copyright (C) 1999, 2001-2004, 2006, 2009, 2010,
3 * 2011 Free Software Foundation, Inc.
4 * Copyright (C) 1999, 2001-2004, 2006, 2009, 2010, 2011, 2014 Werner Koch
5 * Copyright (C) 2015-2017, 2021 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 constraints 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.
42 - Either HTTP_USE_NTBTLS or HTTP_USE_GNUTLS must be defined to select
43 which TLS library to use.
45 - With HTTP_NO_WSASTARTUP the socket initialization is not done
46 under Windows. This is useful if the socket layer has already
47 been initialized elsewhere. This also avoids the installation of
48 an exit handler to cleanup the socket layer.
62 #ifdef HAVE_W32_SYSTEM
63 # ifdef HAVE_WINSOCK2_H
64 # include <winsock2.h>
68 # define EHOSTUNREACH WSAEHOSTUNREACH
71 # define EAFNOSUPPORT WSAEAFNOSUPPORT
73 #else /*!HAVE_W32_SYSTEM*/
74 # include <sys/types.h>
75 # include <sys/socket.h>
76 # include <sys/time.h>
79 # include <netinet/in.h>
80 # include <arpa/inet.h>
82 #endif /*!HAVE_W32_SYSTEM*/
84 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
92 #if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_NTBTLS)
93 # error Both, HTTP_USE_GNUTLS and HTTP_USE_NTBTLS, are defined.
96 #ifdef HTTP_USE_NTBTLS
99 # include <gnutls/gnutls.h>
100 # include <gnutls/x509.h>
101 #endif /*HTTP_USE_GNUTLS*/
103 #include <assuan.h> /* We need the socket wrapper. */
105 #include "../common/util.h"
106 #include "../common/i18n.h"
107 #include "../common/sysutils.h" /* (gnupg_fd_t) */
108 #include "dns-stuff.h"
109 #include "dirmngr-status.h" /* (dirmngr_status_printf) */
111 #include "http-common.h"
115 # define my_select(a,b,c,d,e) npth_select ((a), (b), (c), (d), (e))
116 # define my_accept(a,b,c) npth_accept ((a), (b), (c))
118 # define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e))
119 # define my_accept(a,b,c) accept ((a), (b), (c))
122 #ifdef HAVE_W32_SYSTEM
123 #define sock_close(a) closesocket(a)
125 #define sock_close(a) close(a)
129 #define EAGAIN EWOULDBLOCK
131 #ifndef INADDR_NONE /* Slowaris is missing that. */
132 #define INADDR_NONE ((unsigned long)(-1))
133 #endif /*INADDR_NONE*/
135 #define HTTP_PROXY_ENV "http_proxy"
136 #define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
137 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
138 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
140 "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
143 typedef ntbtls_t tls_session_t;
144 #elif HTTP_USE_GNUTLS
145 typedef gnutls_session_t tls_session_t;
147 # error building without TLS is not supported
150 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
151 int no_scheme_check, int force_tls);
152 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
153 int no_scheme_check, int force_tls);
154 static int remove_escapes (char *string);
155 static int insert_escapes (char *buffer, const char *string,
156 const char *special);
157 static uri_tuple_t parse_tuple (char *string);
158 static gpg_error_t send_request (ctrl_t ctrl, http_t hd, const char *httphost,
159 const char *auth,const char *proxy,
160 const char *srvtag, unsigned int timeout,
162 static char *build_rel_path (parsed_uri_t uri);
163 static gpg_error_t parse_response (http_t hd);
165 static gpg_error_t connect_server (ctrl_t ctrl,
166 const char *server, unsigned short port,
167 unsigned int flags, const char *srvtag,
168 unsigned int timeout, assuan_fd_t *r_sock);
169 static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
170 static gpg_error_t write_server (assuan_fd_t sock, const char *data, size_t length);
172 static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
173 static gpgrt_ssize_t cookie_write (void *cookie,
174 const void *buffer, size_t size);
175 static int cookie_close (void *cookie);
176 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
177 static gpgrt_ssize_t simple_cookie_read (void *cookie,
178 void *buffer, size_t size);
179 static gpgrt_ssize_t simple_cookie_write (void *cookie,
180 const void *buffer, size_t size);
183 /* A socket object used to a allow ref counting of sockets. */
186 assuan_fd_t fd; /* The actual socket - shall never be ASSUAN_INVALID_FD. */
187 int refcount; /* Number of references to this socket. */
189 typedef struct my_socket_s *my_socket_t;
192 /* Cookie function structure and cookie object. */
193 static es_cookie_io_functions_t cookie_functions =
204 /* Socket object or NULL if already closed. */
207 /* The session object or NULL if not used. */
208 http_session_t session;
210 /* True if TLS is to be used. */
213 /* The remaining content length and a flag telling whether to use
214 the content length. */
215 uint64_t content_length;
216 unsigned int content_length_valid:1;
218 typedef struct cookie_s *cookie_t;
221 /* Simple cookie functions. Here the cookie is an int with the
223 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
224 static es_cookie_io_functions_t simple_cookie_functions =
234 #if SIZEOF_UNSIGNED_LONG == 8
235 # define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */
237 # define HTTP_SESSION_MAGIC 0x68547365 /* "hTse" */
240 /* The session object. */
241 struct http_session_s
245 int refcount; /* Number of references to this object. */
247 tls_session_t tls_session;
249 int done; /* Verifciation has been done. */
250 int rc; /* TLS verification return code. */
251 unsigned int status; /* Verification status. */
253 char *servername; /* Malloced server name. */
255 /* A callback function to log details of TLS certifciates. */
256 void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
257 const void **, size_t *);
259 /* The flags passed to the session object. */
262 /* A per-session TLS verification callback. */
263 http_verify_cb_t verify_cb;
264 void *verify_cb_value;
266 /* The connect timeout */
267 unsigned int connect_timeout;
269 #ifdef HTTP_USE_GNUTLS
270 gnutls_certificate_credentials_t certcred;
271 #endif /*HTTP_USE_GNUTLS*/
275 /* An object to save header lines. */
278 struct header_s *next;
279 char *value; /* The value of the header (malloced). */
280 char name[1]; /* The name of the header (canonicalized). */
282 typedef struct header_s *header_t;
285 #if SIZEOF_UNSIGNED_LONG == 8
286 # define HTTP_CONTEXT_MAGIC 0x0068545470435458 /* "hTTpCTX" */
288 # define HTTP_CONTEXT_MAGIC 0x68546378 /* "hTcx" */
292 /* Our handle context. */
293 struct http_context_s
296 unsigned int status_code;
298 unsigned int in_data:1;
299 unsigned int is_http_0_9:1;
304 http_session_t session;
307 char *buffer; /* Line buffer. */
310 header_t headers; /* Received headers. */
314 /* Two flags to enable verbose and debug mode. Although currently not
315 * set-able a value > 1 for OPT_DEBUG enables debugging of the session
316 * reference counting. */
317 static int opt_verbose;
318 static int opt_debug;
320 /* The global callback for the verification function. */
321 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
323 /* The list of files with trusted CA certificates. */
324 static strlist_t tls_ca_certlist;
326 /* The list of files with extra trusted CA certificates. */
327 static strlist_t cfg_ca_certlist;
329 /* The global callback for net activity. */
330 static void (*netactivity_cb)(void);
334 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
336 #if GNUPG_MAJOR_VERSION == 1
337 #define REQ_WINSOCK_MAJOR 1
338 #define REQ_WINSOCK_MINOR 1
340 #define REQ_WINSOCK_MAJOR 2
341 #define REQ_WINSOCK_MINOR 2
346 deinit_sockets (void)
354 static int initialized;
355 static WSADATA wsdata;
360 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
362 log_error ("error initializing socket library: ec=%d\n",
363 (int)WSAGetLastError () );
366 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
367 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
369 log_error ("socket library version is %x.%x - but %d.%d needed\n",
370 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
371 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
375 atexit ( deinit_sockets );
378 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
381 /* Create a new socket object. Returns NULL and closes FD if not
382 enough memory is available. */
384 _my_socket_new (int lnr, assuan_fd_t fd)
388 so = xtrymalloc (sizeof *so);
391 int save_errno = errno;
392 assuan_sock_close (fd);
393 gpg_err_set_errno (save_errno);
399 log_debug ("http.c:%d:socket_new: object %p for fd %d created\n",
400 lnr, so, (int)so->fd);
403 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
405 /* Bump up the reference counter for the socket object SO. */
407 _my_socket_ref (int lnr, my_socket_t so)
411 log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n",
412 lnr, so, (int)so->fd, so->refcount);
415 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
418 /* Bump down the reference counter for the socket object SO. If SO
419 has no more references, close the socket and release the
422 _my_socket_unref (int lnr, my_socket_t so,
423 void (*preclose)(void*), void *preclosearg)
429 log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n",
430 lnr, so, (int)so->fd, so->refcount);
435 preclose (preclosearg);
436 assuan_sock_close (so->fd);
441 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
444 #ifdef HTTP_USE_GNUTLS
446 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
448 my_socket_t sock = ptr;
449 #ifdef HAVE_W32_SYSTEM
450 /* Under Windows we need to use recv for a socket. */
455 nread = recv (FD2INT (sock->fd), buffer, size, 0);
461 #else /* !HAVE_W32_SYSTEM */
463 return npth_read (sock->fd, buffer, size);
465 return read (sock->fd, buffer, size);
470 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
472 my_socket_t sock = ptr;
473 #ifdef HAVE_W32_SYSTEM
478 nwritten = send (FD2INT (sock->fd), buffer, size, 0);
484 #else /*!HAVE_W32_SYSTEM*/
487 return npth_write (sock->fd, buffer, size);
489 return write (sock->fd, buffer, size);
493 #endif /*HTTP_USE_GNUTLS*/
496 #ifdef HTTP_USE_NTBTLS
497 /* Connect the ntbls callback to our generic callback. */
499 my_ntbtls_verify_cb (void *opaque, ntbtls_t tls, unsigned int verify_flags)
505 log_assert (hd && hd->session && hd->session->verify_cb);
506 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
507 log_assert (hd->session->magic == HTTP_SESSION_MAGIC);
509 return hd->session->verify_cb (hd->session->verify_cb_value,
511 (hd->flags | hd->session->flags),
514 #endif /*HTTP_USE_NTBTLS*/
519 /* This notification function is called by estream whenever stream is
520 closed. Its purpose is to mark the closing in the handle so
521 that a http_close won't accidentally close the estream. The function
522 http_close removes this notification so that it won't be called if
523 http_close was used before an es_fclose. */
525 fp_onclose_notification (estream_t stream, void *opaque)
529 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
530 if (hd->fp_read && hd->fp_read == stream)
532 else if (hd->fp_write && hd->fp_write == stream)
538 * Helper function to create an HTTP header with hex encoded data. A
539 * new buffer is returned. This buffer is the concatenation of the
540 * string PREFIX, the hex-encoded DATA of length LEN and the string
541 * SUFFIX. On error NULL is returned and ERRNO set.
544 make_header_line (const char *prefix, const char *suffix,
545 const void *data, size_t len )
547 static unsigned char bintoasc[] =
548 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
549 "abcdefghijklmnopqrstuvwxyz"
551 const unsigned char *s = data;
554 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
557 p = stpcpy (buffer, prefix);
558 for ( ; len >= 3 ; len -= 3, s += 3 )
560 *p++ = bintoasc[(s[0] >> 2) & 077];
561 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
562 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
563 *p++ = bintoasc[s[2]&077];
568 *p++ = bintoasc[(s[0] >> 2) & 077];
569 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
570 *p++ = bintoasc[((s[1]<<2)&074)];
575 *p++ = bintoasc[(s[0] >> 2) & 077];
576 *p++ = bintoasc[(s[0] <<4)&060];
588 /* Set verbosity and debug mode for this module. */
590 http_set_verbose (int verbose, int debug)
592 opt_verbose = verbose;
597 /* Register a non-standard global TLS callback function. If no
598 verification is desired a callback needs to be registered which
599 always returns NULL. */
601 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
607 /* Register a CA certificate for future use. The certificate is
608 expected to be in FNAME. PEM format is assume if FNAME has a
609 suffix of ".pem". If FNAME is NULL the list of CA files is
612 http_register_tls_ca (const char *fname)
619 free_strlist (tls_ca_certlist);
620 tls_ca_certlist = NULL;
624 /* Warn if we can't access right now, but register it anyway in
625 case it becomes accessible later */
626 if ((ec = gnupg_access (fname, F_OK)))
627 log_info (_("can't access '%s': %s\n"), fname, gpg_strerror (ec));
628 sl = add_to_strlist (&tls_ca_certlist, fname);
629 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
635 /* Register a CA certificate for future use. The certificate is
636 * expected to be in FNAME. PEM format is assume if FNAME has a
637 * suffix of ".pem". If FNAME is NULL the list of CA files is
638 * removed. This is a variant of http_register_tls_ca which puts the
639 * certificate into a separate list enabled using HTTP_FLAG_TRUST_CFG. */
641 http_register_cfg_ca (const char *fname)
648 free_strlist (cfg_ca_certlist);
649 cfg_ca_certlist = NULL;
653 /* Warn if we can't access right now, but register it anyway in
654 case it becomes accessible later */
655 if ((ec = gnupg_access (fname, F_OK)))
656 log_info (_("can't access '%s': %s\n"), fname, gpg_strerror (ec));
657 sl = add_to_strlist (&cfg_ca_certlist, fname);
658 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
664 /* Register a callback which is called every time the HTTP mode has
665 * made a successful connection to some server. */
667 http_register_netactivity_cb (void (*cb)(void))
673 /* Call the netactivity callback if any. */
675 notify_netactivity (void)
683 /* Free the TLS session associated with SESS, if any. */
685 close_tls_session (http_session_t sess)
687 if (sess->tls_session)
691 Possibly, ntbtls_get_transport and close those streams.
692 Somehow get SOCK to call my_socket_unref.
694 ntbtls_release (sess->tls_session);
695 #elif HTTP_USE_GNUTLS
696 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
697 my_socket_unref (sock, NULL, NULL);
698 gnutls_deinit (sess->tls_session);
700 gnutls_certificate_free_credentials (sess->certcred);
701 #endif /*HTTP_USE_GNUTLS*/
702 xfree (sess->servername);
703 sess->tls_session = NULL;
708 /* Release a session. Take care not to release it while it is being
709 used by a http context object. */
711 session_unref (int lnr, http_session_t sess)
716 log_assert (sess->magic == HTTP_SESSION_MAGIC);
720 log_debug ("http.c:%d:session_unref: sess %p ref now %d\n",
721 lnr, sess, sess->refcount);
725 close_tls_session (sess);
727 sess->magic = 0xdeadbeef;
730 #define http_session_unref(a) session_unref (__LINE__, (a))
734 http_session_release (http_session_t sess)
736 http_session_unref (sess);
740 /* Create a new session object which is currently used to enable TLS
741 * support. It may eventually allow reusing existing connections.
742 * Valid values for FLAGS are:
743 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
744 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
745 * HTTP_FLAG_TRUST_CFG - Also use CAs set with http_register_cfg_ca
746 * HTTP_FLAG_NO_CRL - Do not consult CRLs for https.
749 http_session_new (http_session_t *r_session,
750 const char *intended_hostname, unsigned int flags,
751 http_verify_cb_t verify_cb, void *verify_cb_value)
758 sess = xtrycalloc (1, sizeof *sess);
760 return gpg_error_from_syserror ();
761 sess->magic = HTTP_SESSION_MAGIC;
764 sess->verify_cb = verify_cb;
765 sess->verify_cb_value = verify_cb_value;
766 sess->connect_timeout = 0;
770 (void)intended_hostname; /* Not needed because we do not preload
773 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
776 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
781 #elif HTTP_USE_GNUTLS
786 int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS);
789 rc = gnutls_certificate_allocate_credentials (&sess->certcred);
792 log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
793 gnutls_strerror (rc));
794 err = gpg_error (GPG_ERR_GENERAL);
798 /* Disabled for 2.3.2 to due problems with the standard hkps pool. */
799 /* is_hkps_pool = (intended_hostname */
800 /* && !ascii_strcasecmp (intended_hostname, */
801 /* get_default_keyserver (1))); */
804 /* If we are looking for the hkps pool from sks-keyservers.net,
805 * then forcefully use its dedicated certificate authority. */
806 /* Disabled for 2.3.2 because the service had to be shutdown. */
807 /* if (is_hkps_pool) */
809 /* char *pemname = make_filename_try (gnupg_datadir (), */
810 /* "sks-keyservers.netCA.pem", NULL); */
813 /* err = gpg_error_from_syserror (); */
814 /* log_error ("setting CA from file '%s' failed: %s\n", */
815 /* pemname, gpg_strerror (err)); */
819 /* rc = gnutls_certificate_set_x509_trust_file */
820 /* (sess->certcred, pemname, GNUTLS_X509_FMT_PEM); */
822 /* log_info ("setting CA from file '%s' failed: %s\n", */
823 /* pemname, gnutls_strerror (rc)); */
824 /* xfree (pemname); */
827 /* if (is_hkps_pool) */
828 /* add_system_cas = 0; */
831 /* Add configured certificates to the session. */
832 if ((flags & HTTP_FLAG_TRUST_DEF) && !is_hkps_pool)
834 for (sl = tls_ca_certlist; sl; sl = sl->next)
836 rc = gnutls_certificate_set_x509_trust_file
837 (sess->certcred, sl->d,
838 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
840 log_info ("setting CA from file '%s' failed: %s\n",
841 sl->d, gnutls_strerror (rc));
844 /* If HKP trust is requested and there are no HKP certificates
845 * configured, also try the standard system certificates. */
846 if (!tls_ca_certlist)
850 /* Add system certificates to the session. */
853 #if GNUTLS_VERSION_NUMBER >= 0x030014
856 rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
858 log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
862 log_info ("number of system provided CAs: %d\n", rc);
864 #endif /* gnutls >= 3.0.20 */
867 /* Add other configured certificates to the session. */
868 if ((flags & HTTP_FLAG_TRUST_CFG) && !is_hkps_pool)
870 for (sl = cfg_ca_certlist; sl; sl = sl->next)
872 rc = gnutls_certificate_set_x509_trust_file
873 (sess->certcred, sl->d,
874 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
876 log_info ("setting extra CA from file '%s' failed: %s\n",
877 sl->d, gnutls_strerror (rc));
882 rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
885 log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
886 err = gpg_error (GPG_ERR_GENERAL);
889 /* A new session has the transport ptr set to (void*(-1), we need
891 gnutls_transport_set_ptr (sess->tls_session, NULL);
893 rc = gnutls_priority_set_direct (sess->tls_session,
898 log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
899 errpos, gnutls_strerror (rc));
900 err = gpg_error (GPG_ERR_GENERAL);
904 rc = gnutls_credentials_set (sess->tls_session,
905 GNUTLS_CRD_CERTIFICATE, sess->certcred);
908 log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
909 err = gpg_error (GPG_ERR_GENERAL);
913 #else /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/
915 (void)intended_hostname;
918 #endif /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/
921 log_debug ("http.c:session_new: sess %p created\n", sess);
926 http_session_unref (sess);
934 /* Increment the reference count for session SESS. Passing NULL for
937 http_session_ref (http_session_t sess)
943 log_debug ("http.c:session_ref: sess %p ref now %d\n",
944 sess, sess->refcount);
951 http_session_set_log_cb (http_session_t sess,
952 void (*cb)(http_session_t, gpg_error_t,
953 const char *hostname,
954 const void **certs, size_t *certlens))
956 sess->cert_log_cb = cb;
960 /* Set the TIMEOUT in milliseconds for the connection's connect
961 * calls. Using 0 disables the timeout. */
963 http_session_set_timeout (http_session_t sess, unsigned int timeout)
965 sess->connect_timeout = timeout;
971 /* Start a HTTP retrieval and on success store at R_HD a context
972 pointer for completing the request and to wait for the response.
973 If HTTPHOST is not NULL it is used for the Host header instead of a
974 Host header derived from the URL. */
976 http_open (ctrl_t ctrl, http_t *r_hd, http_req_t reqtype, const char *url,
977 const char *httphost,
978 const char *auth, unsigned int flags, const char *proxy,
979 http_session_t session, const char *srvtag, strlist_t headers)
986 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
987 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
989 /* Create the handle. */
990 hd = xtrycalloc (1, sizeof *hd);
992 return gpg_error_from_syserror ();
993 hd->magic = HTTP_CONTEXT_MAGIC;
994 hd->req_type = reqtype;
996 hd->session = http_session_ref (session);
998 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
1000 err = send_request (ctrl, hd, httphost, auth, proxy, srvtag,
1001 hd->session? hd->session->connect_timeout : 0,
1006 my_socket_unref (hd->sock, NULL, NULL);
1008 es_fclose (hd->fp_read);
1010 es_fclose (hd->fp_write);
1011 http_session_unref (hd->session);
1020 /* This function is useful to connect to a generic TCP service using
1021 this http abstraction layer. This has the advantage of providing
1022 service tags and an estream interface. TIMEOUT is in milliseconds. */
1024 http_raw_connect (ctrl_t ctrl, http_t *r_hd,
1025 const char *server, unsigned short port,
1026 unsigned int flags, const char *srvtag, unsigned int timeout)
1028 gpg_error_t err = 0;
1034 if ((flags & HTTP_FLAG_FORCE_TOR))
1038 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1040 log_error ("Tor support is not available\n");
1041 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1043 /* Non-blocking connects do not work with our Tor proxy because
1044 * we can't continue the Socks protocol after the EINPROGRESS.
1045 * Disable the timeout to use a blocking connect. */
1049 /* Create the handle. */
1050 hd = xtrycalloc (1, sizeof *hd);
1052 return gpg_error_from_syserror ();
1053 hd->magic = HTTP_CONTEXT_MAGIC;
1054 hd->req_type = HTTP_REQ_OPAQUE;
1061 err = connect_server (ctrl, server, port,
1062 hd->flags, srvtag, timeout, &sock);
1068 hd->sock = my_socket_new (sock);
1071 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1077 /* Setup estreams for reading and writing. */
1078 cookie = xtrycalloc (1, sizeof *cookie);
1081 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1084 cookie->sock = my_socket_ref (hd->sock);
1085 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1088 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1089 my_socket_unref (cookie->sock, NULL, NULL);
1093 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
1095 cookie = xtrycalloc (1, sizeof *cookie);
1098 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1101 cookie->sock = my_socket_ref (hd->sock);
1102 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1105 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1106 my_socket_unref (cookie->sock, NULL, NULL);
1110 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1112 /* Register close notification to interlock the use of es_fclose in
1113 http_close and in user code. */
1114 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1116 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1122 es_fclose (hd->fp_read);
1124 es_fclose (hd->fp_write);
1125 my_socket_unref (hd->sock, NULL, NULL);
1137 http_start_data (http_t hd)
1141 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1142 log_debug_string ("\r\n", "http.c:request-header:");
1143 es_fputs ("\r\n", hd->fp_write);
1144 es_fflush (hd->fp_write);
1148 es_fflush (hd->fp_write);
1153 http_wait_response (http_t hd)
1159 /* Make sure that we are in the data. */
1160 http_start_data (hd);
1162 /* Close the write stream. Note that the reference counted socket
1163 object keeps the actual system socket open. */
1164 cookie = hd->write_cookie;
1166 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1168 use_tls = cookie->use_tls;
1169 es_fclose (hd->fp_write);
1170 hd->fp_write = NULL;
1171 /* The close has released the cookie and thus we better set it to NULL. */
1172 hd->write_cookie = NULL;
1174 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1175 is not required but some very old servers (e.g. the original pksd
1176 keyserver didn't worked without it. */
1177 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1178 shutdown (FD2INT (hd->sock->fd), 1);
1181 /* Create a new cookie and a stream for reading. */
1182 cookie = xtrycalloc (1, sizeof *cookie);
1184 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1185 cookie->sock = my_socket_ref (hd->sock);
1186 cookie->session = http_session_ref (hd->session);
1187 cookie->use_tls = use_tls;
1189 hd->read_cookie = cookie;
1190 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1193 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1194 my_socket_unref (cookie->sock, NULL, NULL);
1195 http_session_unref (cookie->session);
1197 hd->read_cookie = NULL;
1201 err = parse_response (hd);
1204 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1210 /* Convenience function to send a request and wait for the response.
1211 Closes the handle on error. If PROXY is not NULL, this value will
1212 be used as an HTTP proxy and any enabled $http_proxy gets
1215 http_open_document (ctrl_t ctrl, http_t *r_hd, const char *document,
1216 const char *auth, unsigned int flags, const char *proxy,
1217 http_session_t session,
1218 const char *srvtag, strlist_t headers)
1222 err = http_open (ctrl, r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1223 proxy, session, srvtag, headers);
1227 err = http_wait_response (*r_hd);
1229 http_close (*r_hd, 0);
1236 http_close (http_t hd, int keep_read_stream)
1241 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
1243 /* First remove the close notifications for the streams. */
1245 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1247 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1249 /* Now we can close the streams. */
1250 my_socket_unref (hd->sock, NULL, NULL);
1251 if (hd->fp_read && !keep_read_stream)
1252 es_fclose (hd->fp_read);
1254 es_fclose (hd->fp_write);
1255 http_session_unref (hd->session);
1256 hd->magic = 0xdeadbeef;
1257 http_release_parsed_uri (hd->uri);
1260 header_t tmp = hd->headers->next;
1261 xfree (hd->headers->value);
1262 xfree (hd->headers);
1271 http_get_read_ptr (http_t hd)
1273 return hd?hd->fp_read:NULL;
1277 http_get_write_ptr (http_t hd)
1279 return hd?hd->fp_write:NULL;
1283 http_get_status_code (http_t hd)
1285 return hd?hd->status_code:0;
1288 /* Return information pertaining to TLS. If TLS is not in use for HD,
1289 NULL is returned. WHAT is used ask for specific information:
1291 (NULL) := Only check whether TLS is in use. Returns an
1292 unspecified string if TLS is in use. That string may
1293 even be the empty string.
1296 http_get_tls_info (http_t hd, const char *what)
1303 return hd->uri->use_tls? "":NULL;
1309 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1310 int no_scheme_check, int force_tls)
1314 *ret_uri = xtrycalloc (1, sizeof **ret_uri + 2 * strlen (uri) + 1);
1316 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1317 strcpy ((*ret_uri)->buffer, uri);
1318 strcpy ((*ret_uri)->buffer + strlen (uri) + 1, uri);
1319 (*ret_uri)->original = (*ret_uri)->buffer + strlen (uri) + 1;
1320 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1323 http_release_parsed_uri (*ret_uri);
1326 return gpg_err_make (default_errsource, ec);
1331 * Parse an URI and put the result into the newly allocated RET_URI.
1332 * On success the caller must use http_release_parsed_uri() to
1333 * releases the resources. If the HTTP_PARSE_NO_SCHEME_CHECK flag is
1334 * set, the function tries to parse the URL in the same way it would
1335 * do for an HTTP style URI. */
1337 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1340 return parse_uri (ret_uri, uri, !!(flags & HTTP_PARSE_NO_SCHEME_CHECK), 0);
1345 http_release_parsed_uri (parsed_uri_t uri)
1351 for (r = uri->params; r; r = r2)
1356 for (r = uri->query; r; r = r2)
1366 static gpg_err_code_t
1367 do_parse_uri (parsed_uri_t uri, int only_local_part,
1368 int no_scheme_check, int force_tls)
1371 char *p, *p2, *p3, *pp;
1375 n = strlen (uri->buffer);
1377 /* Initialize all fields to an empty string or an empty list. */
1378 uri->scheme = uri->host = uri->path = p + n;
1380 uri->params = uri->query = NULL;
1387 uri->explicit_port = 0;
1391 /* A quick validity check unless we have the opaque scheme. */
1392 if (strspn (p, VALID_URI_CHARS) != n
1393 && strncmp (p, "opaque:", 7))
1394 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1396 if (!only_local_part)
1398 /* Find the scheme. */
1399 if (!(p2 = strchr (p, ':')) || p2 == p)
1400 return GPG_ERR_BAD_URI; /* No scheme. */
1402 for (pp=p; *pp; pp++)
1403 *pp = tolower (*(unsigned char*)pp);
1405 if (!strcmp (uri->scheme, "http") && !force_tls)
1410 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1415 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1416 || (force_tls && (!strcmp (uri->scheme, "http")
1417 || !strcmp (uri->scheme,"hkp"))))
1423 else if (!strcmp (uri->scheme, "opaque"))
1429 else if (!no_scheme_check)
1430 return GPG_ERR_INV_URI; /* Not an http style scheme. */
1431 else if (!strcmp (uri->scheme, "ldap") && !force_tls)
1436 else if (!strcmp (uri->scheme, "ldaps")
1437 || (force_tls && (!strcmp (uri->scheme, "ldap"))))
1443 else if (!strcmp (uri->scheme, "ldapi")) /* LDAP via IPC. */
1451 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1454 if ((p2 = strchr (p, '/')))
1456 if (p2 - uri->buffer > 10000)
1457 return GPG_ERR_BAD_URI;
1458 uri->off_path = p2 - uri->buffer;
1463 n = (p - uri->buffer) + strlen (p);
1465 return GPG_ERR_BAD_URI;
1469 /* Check for username/password encoding */
1470 if ((p3 = strchr (p, '@')))
1477 for (pp=p; *pp; pp++)
1478 *pp = tolower (*(unsigned char*)pp);
1480 /* Handle an IPv6 literal */
1481 if( *p == '[' && (p3=strchr( p, ']' )) )
1484 /* worst case, uri->host should have length 0, points to \0 */
1486 if (p - uri->buffer > 10000)
1487 return GPG_ERR_BAD_URI;
1488 uri->off_host = (p + 1) - uri->buffer;
1495 if (p - uri->buffer > 10000)
1496 return GPG_ERR_BAD_URI;
1497 uri->off_host = p - uri->buffer;
1500 if ((p3 = strchr (p, ':')))
1503 uri->port = atoi (p3);
1504 uri->explicit_port = 1;
1507 if ((n = remove_escapes (uri->host)) < 0)
1508 return GPG_ERR_BAD_URI;
1509 if (n != strlen (uri->host))
1510 return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */
1513 else if (!no_scheme_check && (uri->is_http || uri->is_ldap))
1514 return GPG_ERR_INV_URI; /* HTTP or LDAP w/o leading double slash. */
1519 if (is_onion_address (uri->path))
1524 } /* End global URI part. */
1526 /* Parse the pathname part if any. */
1529 /* TODO: Here we have to check params. */
1531 /* Do we have a query part? */
1532 if ((p2 = strchr (p, '?')))
1536 if ((n = remove_escapes (p)) < 0)
1537 return GPG_ERR_BAD_URI;
1538 if (n != strlen (p))
1539 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1542 /* Parse a query string if any. */
1550 if ((p2 = strchr (p, '&')))
1552 if (!(elem = parse_tuple (p)))
1553 return GPG_ERR_BAD_URI;
1564 if (is_onion_address (uri->host))
1572 * Remove all %xx escapes; this is done in-place. Returns: New length
1576 remove_escapes (char *string)
1579 unsigned char *p, *s;
1581 for (p = s = (unsigned char*)string; *s; s++)
1585 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1588 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1589 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1592 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1593 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1606 return -1; /* Bad URI. */
1615 *p = 0; /* Make sure to keep a string terminator. */
1620 /* If SPECIAL is NULL this function escapes in forms mode. */
1622 escape_data (char *buffer, const void *data, size_t datalen,
1623 const char *special)
1625 int forms = !special;
1626 const unsigned char *s;
1632 for (s = data; datalen; s++, datalen--)
1634 if (forms && *s == ' ')
1640 else if (forms && *s == '\n')
1643 memcpy (buffer, "%0D%0A", 6);
1646 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1649 memcpy (buffer, "%0D%0A", 6);
1654 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1657 *(unsigned char*)buffer++ = *s;
1664 snprintf (buffer, 4, "%%%02X", *s);
1675 insert_escapes (char *buffer, const char *string,
1676 const char *special)
1678 return escape_data (buffer, string, strlen (string), special);
1682 /* Allocate a new string from STRING using standard HTTP escaping as
1683 well as escaping of characters given in SPECIALS. A common pattern
1684 for SPECIALS is "%;?&=". However it depends on the needs, for
1685 example "+" and "/: often needs to be escaped too. Returns NULL on
1686 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1687 encoding mode is used. */
1689 http_escape_string (const char *string, const char *specials)
1694 n = insert_escapes (NULL, string, specials);
1695 buf = xtrymalloc (n+1);
1698 insert_escapes (buf, string, specials);
1704 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1705 escaping as well as escaping of characters given in SPECIALS. A
1706 common pattern for SPECIALS is "%;?&=". However it depends on the
1707 needs, for example "+" and "/: often needs to be escaped too.
1708 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1709 dedicated forms encoding mode is used. */
1711 http_escape_data (const void *data, size_t datalen, const char *specials)
1716 n = escape_data (NULL, data, datalen, specials);
1717 buf = xtrymalloc (n+1);
1720 escape_data (buf, data, datalen, specials);
1728 parse_tuple (char *string)
1735 if ((p2 = strchr (p, '=')))
1737 if ((n = remove_escapes (p)) < 0)
1738 return NULL; /* Bad URI. */
1739 if (n != strlen (p))
1740 return NULL; /* Name with a Nul in it. */
1741 tuple = xtrycalloc (1, sizeof *tuple);
1743 return NULL; /* Out of core. */
1745 if (!p2) /* We have only the name, so we assume an empty value string. */
1747 tuple->value = p + strlen (p);
1748 tuple->valuelen = 0;
1749 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1751 else /* Name and value. */
1753 if ((n = remove_escapes (p2)) < 0)
1756 return NULL; /* Bad URI. */
1759 tuple->valuelen = n;
1765 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1767 is_hostname_port (const char *string)
1771 if (!string || !*string)
1773 for (; *string; string++)
1783 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1784 return 0; /* Invalid characters in hostname. */
1785 else if (colons && !digitp (string))
1786 return 0; /* Not a digit in the port. */
1793 * Send a HTTP request to the server
1794 * Returns 0 if the request was successful
1797 send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth,
1798 const char *proxy, const char *srvtag, unsigned int timeout,
1804 unsigned short port;
1805 const char *http_proxy = NULL;
1806 char *proxy_authstr = NULL;
1807 char *authstr = NULL;
1809 int have_http_proxy = 0;
1811 if (hd->uri->use_tls && !hd->session)
1813 log_error ("TLS requested but no session object provided\n");
1814 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1816 if (hd->uri->use_tls && !hd->session->tls_session)
1818 log_error ("TLS requested but no TLS context available\n");
1819 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1822 log_debug ("Using TLS library: %s %s\n",
1824 "NTBTLS", ntbtls_check_version (NULL)
1825 #elif HTTP_USE_GNUTLS
1826 "GNUTLS", gnutls_check_version (NULL)
1827 #endif /*HTTP_USE_GNUTLS*/
1830 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1834 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1836 log_error ("Tor support is not available\n");
1837 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1839 /* Non-blocking connects do not work with our Tor proxy because
1840 * we can't continue the Socks protocol after the EINPROGRESS.
1841 * Disable the timeout to use a blocking connect. */
1845 server = *hd->uri->host ? hd->uri->host : "localhost";
1846 port = hd->uri->port ? hd->uri->port : 80;
1848 /* Try to use SNI. */
1849 if (hd->uri->use_tls)
1855 xfree (hd->session->servername);
1856 hd->session->servername = xtrystrdup (httphost? httphost : server);
1857 if (!hd->session->servername)
1859 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1864 err = ntbtls_set_hostname (hd->session->tls_session,
1865 hd->session->servername);
1868 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1871 #elif HTTP_USE_GNUTLS
1872 rc = gnutls_server_name_set (hd->session->tls_session,
1874 hd->session->servername,
1875 strlen (hd->session->servername));
1877 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1878 #endif /*HTTP_USE_GNUTLS*/
1881 if ( (proxy && *proxy)
1882 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1883 && (http_proxy = getenv (HTTP_PROXY_ENV))
1891 err = parse_uri (&uri, http_proxy, 0, 0);
1892 if (gpg_err_code (err) == GPG_ERR_INV_URI
1893 && is_hostname_port (http_proxy))
1895 /* Retry assuming a "hostname:port" string. */
1896 char *tmpname = strconcat ("http://", http_proxy, NULL);
1897 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1904 else if (!strcmp (uri->scheme, "http"))
1905 have_http_proxy = 1;
1906 else if (!strcmp (uri->scheme, "socks4")
1907 || !strcmp (uri->scheme, "socks5h"))
1908 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1910 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1914 log_error ("invalid HTTP proxy (%s): %s\n",
1915 http_proxy, gpg_strerror (err));
1916 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1921 remove_escapes (uri->auth);
1922 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1924 uri->auth, strlen(uri->auth));
1927 err = gpg_err_make (default_errsource,
1928 gpg_err_code_from_syserror ());
1929 http_release_parsed_uri (uri);
1934 err = connect_server (ctrl,
1935 *uri->host ? uri->host : "localhost",
1936 uri->port ? uri->port : 80,
1937 hd->flags, NULL, timeout, &sock);
1938 http_release_parsed_uri (uri);
1942 err = connect_server (ctrl,
1943 server, port, hd->flags, srvtag, timeout, &sock);
1948 xfree (proxy_authstr);
1951 hd->sock = my_socket_new (sock);
1954 xfree (proxy_authstr);
1955 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1958 if (have_http_proxy && hd->uri->use_tls)
1963 /* Try to use the CONNECT method to proxy our TLS stream. */
1964 request = es_bsprintf
1965 ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s",
1966 httphost ? httphost : server,
1968 httphost ? httphost : server,
1970 proxy_authstr ? proxy_authstr : "");
1971 xfree (proxy_authstr);
1972 proxy_authstr = NULL;
1975 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1977 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1978 log_debug_string (request, "http.c:request:");
1980 cookie = xtrycalloc (1, sizeof *cookie);
1983 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1987 cookie->sock = my_socket_ref (hd->sock);
1988 hd->write_cookie = cookie;
1990 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1993 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1994 my_socket_unref (cookie->sock, NULL, NULL);
1997 hd->write_cookie = NULL;
2000 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2001 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2006 /* Make sure http_wait_response doesn't close the stream. */
2007 saved_flags = hd->flags;
2008 hd->flags &= ~HTTP_FLAG_SHUTDOWN;
2010 /* Get the response. */
2011 err = http_wait_response (hd);
2013 /* Restore flags, destroy stream. */
2014 hd->flags = saved_flags;
2015 es_fclose (hd->fp_read);
2017 hd->read_cookie = NULL;
2025 if (hd->status_code != 200)
2027 request = es_bsprintf
2029 httphost ? httphost : server,
2032 log_error (_("error accessing '%s': http status %u\n"),
2033 request ? request : "out of core",
2034 http_get_status_code (hd));
2037 return gpg_error (GPG_ERR_NO_DATA);
2040 /* We are done with the proxy, the code below will establish a
2041 * TLS session and talk directly to the target server. */
2046 if (hd->uri->use_tls)
2050 my_socket_ref (hd->sock);
2052 /* Until we support send/recv in estream under Windows we need
2053 * to use es_fopencookie. */
2054 # ifdef HAVE_W32_SYSTEM
2055 in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb",
2056 simple_cookie_functions);
2058 in = es_fdopen_nc (hd->sock->fd, "rb");
2062 err = gpg_error_from_syserror ();
2063 xfree (proxy_authstr);
2067 # ifdef HAVE_W32_SYSTEM
2068 out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb",
2069 simple_cookie_functions);
2071 out = es_fdopen_nc (hd->sock->fd, "wb");
2075 err = gpg_error_from_syserror ();
2077 xfree (proxy_authstr);
2081 err = ntbtls_set_transport (hd->session->tls_session, in, out);
2084 log_info ("TLS set_transport failed: %s <%s>\n",
2085 gpg_strerror (err), gpg_strsource (err));
2086 xfree (proxy_authstr);
2090 if (hd->session->verify_cb)
2092 err = ntbtls_set_verify_cb (hd->session->tls_session,
2093 my_ntbtls_verify_cb, hd);
2096 log_error ("ntbtls_set_verify_cb failed: %s\n",
2097 gpg_strerror (err));
2098 xfree (proxy_authstr);
2103 while ((err = ntbtls_handshake (hd->session->tls_session)))
2105 #if NTBTLS_VERSION_NUMBER >= 0x000200
2106 unsigned int tlevel, ttype;
2107 const char *s = ntbtls_get_last_alert (hd->session->tls_session,
2110 log_info ("TLS alert: %s (%u.%u)\n", s, tlevel, ttype);
2116 log_info ("TLS handshake failed: %s <%s>\n",
2117 gpg_strerror (err), gpg_strsource (err));
2118 xfree (proxy_authstr);
2123 hd->session->verify.done = 0;
2125 /* Try the available verify callbacks until one returns success
2126 * or a real error. Note that NTBTLS does the verification
2127 * during the handshake via */
2128 err = 0; /* Fixme check that the CB has been called. */
2130 if (hd->session->verify_cb
2131 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2132 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2133 err = hd->session->verify_cb (hd->session->verify_cb_value,
2135 (hd->flags | hd->session->flags),
2136 hd->session->tls_session);
2139 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2140 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2141 err = tls_callback (hd, hd->session, 0);
2143 if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2144 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2145 err = http_verify_server_credentials (hd->session);
2149 log_info ("TLS connection authentication failed: %s <%s>\n",
2150 gpg_strerror (err), gpg_strsource (err));
2151 xfree (proxy_authstr);
2157 #elif HTTP_USE_GNUTLS
2159 if (hd->uri->use_tls)
2163 my_socket_ref (hd->sock);
2164 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
2165 gnutls_transport_set_pull_function (hd->session->tls_session,
2167 gnutls_transport_set_push_function (hd->session->tls_session,
2173 rc = gnutls_handshake (hd->session->tls_session);
2175 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
2178 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2179 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
2181 gnutls_alert_description_t alertno;
2182 const char *alertstr;
2184 alertno = gnutls_alert_get (hd->session->tls_session);
2185 alertstr = gnutls_alert_get_name (alertno);
2186 log_info ("TLS handshake %s: %s (alert %d)\n",
2187 rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2188 ? "warning" : "failed",
2189 alertstr, (int)alertno);
2190 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
2191 log_info (" (sent server name '%s')\n", server);
2193 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
2194 goto handshake_again;
2197 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
2198 xfree (proxy_authstr);
2199 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
2202 hd->session->verify.done = 0;
2204 err = tls_callback (hd, hd->session, 0);
2206 err = http_verify_server_credentials (hd->session);
2209 log_info ("TLS connection authentication failed: %s\n",
2210 gpg_strerror (err));
2211 xfree (proxy_authstr);
2216 #endif /*HTTP_USE_GNUTLS*/
2218 if (auth || hd->uri->auth)
2224 myauth = xtrystrdup (auth);
2227 xfree (proxy_authstr);
2228 return gpg_err_make (default_errsource,
2229 gpg_err_code_from_syserror ());
2231 remove_escapes (myauth);
2235 remove_escapes (hd->uri->auth);
2236 myauth = hd->uri->auth;
2239 authstr = make_header_line ("Authorization: Basic ", "\r\n",
2240 myauth, strlen (myauth));
2246 xfree (proxy_authstr);
2247 return gpg_err_make (default_errsource,
2248 gpg_err_code_from_syserror ());
2252 p = build_rel_path (hd->uri);
2256 xfree (proxy_authstr);
2257 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2260 if (http_proxy && *http_proxy)
2262 request = es_bsprintf
2263 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
2264 hd->req_type == HTTP_REQ_GET ? "GET" :
2265 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2266 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2267 hd->uri->use_tls? "https" : "http",
2268 httphost? httphost : server,
2269 port, *p == '/' ? "" : "/", p,
2270 authstr ? authstr : "",
2271 proxy_authstr ? proxy_authstr : "");
2277 if (port == (hd->uri->use_tls? 443 : 80))
2280 snprintf (portstr, sizeof portstr, ":%u", port);
2282 request = es_bsprintf
2283 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
2284 hd->req_type == HTTP_REQ_GET ? "GET" :
2285 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2286 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2287 *p == '/' ? "" : "/", p,
2288 httphost? httphost : server,
2290 authstr? authstr:"");
2295 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2297 xfree (proxy_authstr);
2301 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2302 log_debug_string (request, "http.c:request:");
2304 /* First setup estream so that we can write even the first line
2305 using estream. This is also required for the sake of gnutls. */
2309 cookie = xtrycalloc (1, sizeof *cookie);
2312 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2315 cookie->sock = my_socket_ref (hd->sock);
2316 hd->write_cookie = cookie;
2317 cookie->use_tls = hd->uri->use_tls;
2318 cookie->session = http_session_ref (hd->session);
2320 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2323 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2324 my_socket_unref (cookie->sock, NULL, NULL);
2326 hd->write_cookie = NULL;
2328 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2329 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2335 for (;headers; headers=headers->next)
2337 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2338 log_debug_string (headers->d, "http.c:request-header:");
2339 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2340 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2342 err = gpg_err_make (default_errsource,
2343 gpg_err_code_from_syserror ());
2353 xfree (proxy_authstr);
2360 * Build the relative path from the parsed URI. Minimal
2361 * implementation. May return NULL in case of memory failure; errno
2362 * is then set accordingly.
2365 build_rel_path (parsed_uri_t uri)
2371 /* Count the needed space. */
2372 n = insert_escapes (NULL, uri->path, "%;?&");
2373 /* TODO: build params. */
2374 for (r = uri->query; r; r = r->next)
2377 n += insert_escapes (NULL, r->name, "%;?&=");
2381 n += insert_escapes (NULL, r->value, "%;?&=");
2386 /* Now allocate and copy. */
2387 p = rel_path = xtrymalloc (n);
2390 n = insert_escapes (p, uri->path, "%;?&");
2392 /* TODO: add params. */
2393 for (r = uri->query; r; r = r->next)
2395 *p++ = r == uri->query ? '?' : '&';
2396 n = insert_escapes (p, r->name, "%;?&=");
2401 /* TODO: Use valuelen. */
2402 n = insert_escapes (p, r->value, "%;?&=");
2411 /* Transform a header name into a standard capitalized format; e.g.
2412 "Content-Type". Conversion stops at the colon. As usual we don't
2413 use the localized versions of ctype.h. */
2415 capitalize_header_name (char *name)
2419 for (; *name && *name != ':'; name++)
2425 if (*name >= 'a' && *name <= 'z')
2426 *name = *name - 'a' + 'A';
2429 else if (*name >= 'A' && *name <= 'Z')
2430 *name = *name - 'A' + 'a';
2435 /* Store an HTTP header line in LINE away. Line continuation is
2436 supported as well as merging of headers with the same name. This
2437 function may modify LINE. */
2438 static gpg_err_code_t
2439 store_header (http_t hd, char *line)
2446 if (n && line[n-1] == '\n')
2449 if (n && line[n-1] == '\r')
2452 if (!n) /* we are never called to hit this. */
2454 if (*line == ' ' || *line == '\t')
2456 /* Continuation. This won't happen too often as it is not
2457 recommended. We use a straightforward implementation. */
2459 return GPG_ERR_PROTOCOL_VIOLATION;
2460 n += strlen (hd->headers->value);
2461 p = xtrymalloc (n+1);
2463 return gpg_err_code_from_syserror ();
2464 strcpy (stpcpy (p, hd->headers->value), line);
2465 xfree (hd->headers->value);
2466 hd->headers->value = p;
2470 capitalize_header_name (line);
2471 p = strchr (line, ':');
2473 return GPG_ERR_PROTOCOL_VIOLATION;
2475 while (*p == ' ' || *p == '\t')
2479 for (h=hd->headers; h; h = h->next)
2480 if ( !strcmp (h->name, line) )
2484 /* We have already seen a line with that name. Thus we assume
2485 * it is a comma separated list and merge them. */
2486 p = strconcat (h->value, ",", value, NULL);
2488 return gpg_err_code_from_syserror ();
2494 /* Append a new header. */
2495 h = xtrymalloc (sizeof *h + strlen (line));
2497 return gpg_err_code_from_syserror ();
2498 strcpy (h->name, line);
2499 h->value = xtrymalloc (strlen (value)+1);
2503 return gpg_err_code_from_syserror ();
2505 strcpy (h->value, value);
2506 h->next = hd->headers;
2513 /* Return the header NAME from the last response. The returned value
2514 is valid as along as HD has not been closed and no other request
2515 has been send. If the header was not found, NULL is returned. NAME
2516 must be canonicalized, that is the first letter of each dash
2517 delimited part must be uppercase and all other letters lowercase. */
2519 http_get_header (http_t hd, const char *name)
2523 for (h=hd->headers; h; h = h->next)
2524 if ( !strcmp (h->name, name) )
2530 /* Return a newly allocated and NULL terminated array with pointers to
2531 header names. The array must be released with xfree() and its
2532 content is only values as long as no other request has been
2535 http_get_header_names (http_t hd)
2541 for (n=0, h = hd->headers; h; h = h->next)
2543 array = xtrycalloc (n+1, sizeof *array);
2546 for (n=0, h = hd->headers; h; h = h->next)
2547 array[n++] = h->name;
2555 * Parse the response from a server.
2556 * Returns: Errorcode and sets some files in the handle
2559 parse_response (http_t hd)
2561 char *line, *p, *p2;
2563 cookie_t cookie = hd->read_cookie;
2566 /* Delete old header lines. */
2569 header_t tmp = hd->headers->next;
2570 xfree (hd->headers->value);
2571 xfree (hd->headers);
2575 /* Wait for the status line. */
2578 maxlen = MAX_LINELEN;
2579 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2582 return gpg_error_from_syserror (); /* Out of core. */
2584 return gpg_error (GPG_ERR_TRUNCATED); /* Line has been truncated. */
2586 return gpg_error (GPG_ERR_EOF);
2588 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2589 log_debug_string (line, "http.c:response:\n");
2593 if ((p = strchr (line, '/')))
2595 if (!p || strcmp (line, "HTTP"))
2596 return 0; /* Assume http 0.9. */
2598 if ((p2 = strpbrk (p, " \t")))
2601 p2 += strspn (p2, " \t");
2604 return 0; /* Also assume http 0.9. */
2606 /* TODO: Add HTTP version number check. */
2607 if ((p2 = strpbrk (p, " \t")))
2609 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2610 || !isdigit ((unsigned int)p[2]) || p[3])
2612 /* Malformed HTTP status code - assume http 0.9. */
2613 hd->is_http_0_9 = 1;
2614 hd->status_code = 200;
2617 hd->status_code = atoi (p);
2619 /* Skip all the header lines and wait for the empty line. */
2622 maxlen = MAX_LINELEN;
2623 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2626 return gpg_error_from_syserror (); /* Out of core. */
2627 /* Note, that we can silently ignore truncated lines. */
2629 return gpg_error (GPG_ERR_EOF);
2630 /* Trim line endings of empty lines. */
2631 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2633 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2634 log_info ("http.c:RESP: '%.*s'\n",
2635 (int)strlen(line)-(*line&&line[1]?2:0),line);
2638 gpg_err_code_t ec = store_header (hd, line);
2640 return gpg_error (ec);
2643 while (len && *line);
2645 cookie->content_length_valid = 0;
2646 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2648 s = http_get_header (hd, "Content-Length");
2651 cookie->content_length_valid = 1;
2652 cookie->content_length = string_to_u64 (s);
2663 struct sockaddr_in mya;
2664 struct sockaddr_in peer;
2670 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2672 log_error ("socket() failed: %s\n", strerror (errno));
2676 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2677 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2679 mya.sin_family = AF_INET;
2680 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2681 mya.sin_port = htons (11371);
2683 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2685 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2692 log_error ("listen failed: %s\n", strerror (errno));
2702 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2703 continue; /* ignore any errors */
2705 if (!FD_ISSET (fd, &rfds))
2708 addrlen = sizeof peer;
2709 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2711 continue; /* oops */
2713 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2722 fp = fdopen (client, "r");
2723 while ((c = getc (fp)) != EOF)
2728 sock_close (client);
2738 /* Return true if SOCKS shall be used. This is the case if tor_mode
2739 * is enabled and the desired address is not the loopback address.
2740 * This function is basically a copy of the same internal function in
2743 use_socks (struct sockaddr_storage *addr)
2747 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2748 return 0; /* Not in Tor mode. */
2749 else if (addr->ss_family == AF_INET6)
2751 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2752 const unsigned char *s;
2755 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2757 return 1; /* Last octet is not 1 - not the loopback address. */
2758 for (i=0; i < 15; i++, s++)
2760 return 1; /* Non-zero octet found - not the loopback address. */
2762 return 0; /* This is the loopback address. */
2764 else if (addr->ss_family == AF_INET)
2766 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2768 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2769 return 0; /* Loopback (127.0.0.0/8) */
2778 /* Wrapper around assuan_sock_new which takes the domain from an
2779 * address parameter. */
2781 my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
2785 if (use_socks (addr))
2787 /* Libassaun always uses 127.0.0.1 to connect to the socks
2788 * server (i.e. the Tor daemon). */
2792 domain = addr->ss_family;
2794 return assuan_sock_new (domain, type, proto);
2798 /* Call WSAGetLastError and map it to a libgpg-error. */
2799 #ifdef HAVE_W32_SYSTEM
2801 my_wsagetlasterror (void)
2806 wsaerr = WSAGetLastError ();
2809 case WSAENOTSOCK: ec = GPG_ERR_EINVAL; break;
2810 case WSAEWOULDBLOCK: ec = GPG_ERR_EAGAIN; break;
2811 case ERROR_BROKEN_PIPE: ec = GPG_ERR_EPIPE; break;
2812 case WSANOTINITIALISED: ec = GPG_ERR_ENOSYS; break;
2813 case WSAENOBUFS: ec = GPG_ERR_ENOBUFS; break;
2814 case WSAEMSGSIZE: ec = GPG_ERR_EMSGSIZE; break;
2815 case WSAECONNREFUSED: ec = GPG_ERR_ECONNREFUSED; break;
2816 case WSAEISCONN: ec = GPG_ERR_EISCONN; break;
2817 case WSAEALREADY: ec = GPG_ERR_EALREADY; break;
2818 case WSAETIMEDOUT: ec = GPG_ERR_ETIMEDOUT; break;
2819 default: ec = GPG_ERR_EIO; break;
2822 return gpg_err_make (default_errsource, ec);
2824 #endif /*HAVE_W32_SYSTEM*/
2827 /* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
2828 * be established within TIMEOUT milliseconds. 0 indicates the
2829 * system's default timeout. The other args are the usual connect
2830 * args. On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
2831 * another error code for other errors. On timeout the caller needs
2832 * to close the socket as soon as possible to stop an ongoing
2835 * This implementation is for well-behaving systems; see Stevens,
2836 * Network Programming, 2nd edition, Vol 1, 15.4. */
2838 connect_with_timeout (assuan_fd_t sock,
2839 struct sockaddr *addr, int addrlen,
2840 unsigned int timeout)
2846 struct timeval tval;
2849 #ifndef HAVE_W32_SYSTEM
2851 # define RESTORE_BLOCKING() do { \
2852 fcntl (sock, F_SETFL, oflags); \
2854 #else /*HAVE_W32_SYSTEM*/
2855 # define RESTORE_BLOCKING() do { \
2856 unsigned long along = 0; \
2857 ioctlsocket (FD2INT (sock), FIONBIO, &along); \
2859 #endif /*HAVE_W32_SYSTEM*/
2865 if (assuan_sock_connect (sock, addr, addrlen))
2866 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2872 /* Switch the socket into non-blocking mode. */
2873 #ifdef HAVE_W32_SYSTEM
2875 unsigned long along = 1;
2876 if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
2877 return my_wsagetlasterror ();
2880 oflags = fcntl (sock, F_GETFL, 0);
2881 if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
2882 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2885 /* Do the connect. */
2886 if (!assuan_sock_connect (sock, addr, addrlen))
2888 /* Immediate connect. Restore flags. */
2889 RESTORE_BLOCKING ();
2890 return 0; /* Success. */
2892 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2893 if (gpg_err_code (err) != GPG_ERR_EINPROGRESS
2894 #ifdef HAVE_W32_SYSTEM
2895 && gpg_err_code (err) != GPG_ERR_EAGAIN
2899 RESTORE_BLOCKING ();
2904 FD_SET (FD2INT (sock), &rset);
2906 tval.tv_sec = timeout / 1000;
2907 tval.tv_usec = (timeout % 1000) * 1000;
2909 n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
2912 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2913 RESTORE_BLOCKING ();
2918 /* Timeout: We do not restore the socket flags on timeout
2919 * because the caller is expected to close the socket. */
2920 return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
2922 if (!FD_ISSET (FD2INT (sock), &rset) && !FD_ISSET (FD2INT (sock), &wset))
2924 /* select misbehaved. */
2925 return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
2928 slen = sizeof (syserr);
2929 if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
2930 (void*)&syserr, &slen) < 0)
2932 /* Assume that this is Solaris which returns the error in ERRNO. */
2933 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2936 err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
2938 err = 0; /* Connected. */
2940 RESTORE_BLOCKING ();
2944 #undef RESTORE_BLOCKING
2948 /* Actually connect to a server. On success 0 is returned and the
2949 * file descriptor for the socket is stored at R_SOCK; on error an
2950 * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
2951 * TIMEOUT is the connect timeout in milliseconds. Note that the
2952 * function tries to connect to all known addresses and the timeout is
2955 connect_server (ctrl_t ctrl, const char *server, unsigned short port,
2956 unsigned int flags, const char *srvtag, unsigned int timeout,
2957 assuan_fd_t *r_sock)
2960 assuan_fd_t sock = ASSUAN_INVALID_FD;
2961 unsigned int srvcount = 0;
2963 int anyhostaddr = 0;
2964 int srv, connected, v4_valid, v6_valid;
2965 gpg_error_t last_err = 0;
2966 struct srventry *serverlist = NULL;
2968 *r_sock = ASSUAN_INVALID_FD;
2970 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2974 check_inet_support (&v4_valid, &v6_valid);
2976 /* Onion addresses require special treatment. */
2977 if (is_onion_address (server))
2979 #ifdef ASSUAN_SOCK_TOR
2982 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2984 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2986 if (sock == ASSUAN_INVALID_FD)
2988 err = gpg_err_make (default_errsource,
2989 (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2990 : gpg_err_code_from_syserror ());
2991 log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2995 notify_netactivity ();
2999 #else /*!ASSUAN_SOCK_TOR*/
3001 err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
3002 return ASSUAN_INVALID_FD;
3004 #endif /*!HASSUAN_SOCK_TOR*/
3007 /* Do the SRV thing */
3010 err = get_dns_srv (ctrl, server, srvtag, NULL, &serverlist, &srvcount);
3012 log_info ("getting '%s' SRV for '%s' failed: %s\n",
3013 srvtag, server, gpg_strerror (err));
3014 /* Note that on error SRVCOUNT is zero. */
3020 /* Either we're not using SRV, or the SRV lookup failed. Make
3021 up a fake SRV record. */
3022 serverlist = xtrycalloc (1, sizeof *serverlist);
3024 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
3026 serverlist->port = port;
3027 strncpy (serverlist->target, server, DIMof (struct srventry, target));
3028 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
3033 for (srv=0; srv < srvcount && !connected; srv++)
3035 dns_addrinfo_t aibuf, ai;
3038 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
3039 serverlist[srv].target, port);
3040 err = resolve_dns_name (ctrl,
3041 serverlist[srv].target, port, 0, SOCK_STREAM,
3045 log_info ("resolving '%s' failed: %s\n",
3046 serverlist[srv].target, gpg_strerror (err));
3048 continue; /* Not found - try next one. */
3052 for (ai = aibuf; ai && !connected; ai = ai->next)
3054 if (ai->family == AF_INET
3055 && ((flags & HTTP_FLAG_IGNORE_IPv4) || !v4_valid))
3057 if (ai->family == AF_INET6
3058 && ((flags & HTTP_FLAG_IGNORE_IPv6) || !v6_valid))
3061 if (sock != ASSUAN_INVALID_FD)
3062 assuan_sock_close (sock);
3063 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
3064 if (sock == ASSUAN_INVALID_FD)
3066 if (errno == EAFNOSUPPORT)
3068 if (ai->family == AF_INET)
3070 if (ai->family == AF_INET6)
3075 err = gpg_err_make (default_errsource,
3076 gpg_err_code_from_syserror ());
3077 log_error ("error creating socket: %s\n", gpg_strerror (err));
3078 free_dns_addrinfo (aibuf);
3084 err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
3085 ai->addrlen, timeout);
3093 notify_netactivity ();
3096 free_dns_addrinfo (aibuf);
3104 log_error ("can't connect to '%s': %s\n",
3105 server, "host not found");
3106 else if (!anyhostaddr)
3107 log_error ("can't connect to '%s': %s\n",
3108 server, "no IP address for host");
3111 #ifdef HAVE_W32_SYSTEM
3112 log_error ("can't connect to '%s': ec=%d\n",
3113 server, (int)WSAGetLastError());
3115 log_error ("can't connect to '%s': %s\n",
3116 server, gpg_strerror (last_err));
3119 err = last_err? last_err : gpg_err_make (default_errsource,
3120 GPG_ERR_UNKNOWN_HOST);
3121 if (sock != ASSUAN_INVALID_FD)
3122 assuan_sock_close (sock);
3131 /* Helper to read from a socket. This handles npth things and
3133 static gpgrt_ssize_t
3134 read_server (assuan_fd_t sock, void *buffer, size_t size)
3140 #ifdef HAVE_W32_SYSTEM
3141 /* Under Windows we need to use recv for a socket. */
3142 # if defined(USE_NPTH)
3145 nread = recv (FD2INT (sock), buffer, size, 0);
3146 # if defined(USE_NPTH)
3150 #else /*!HAVE_W32_SYSTEM*/
3153 nread = npth_read (sock, buffer, size);
3155 nread = read (sock, buffer, size);
3158 #endif /*!HAVE_W32_SYSTEM*/
3160 while (nread == -1 && errno == EINTR);
3167 write_server (assuan_fd_t sock, const char *data, size_t length)
3175 #if defined(HAVE_W32_SYSTEM)
3176 # if defined(USE_NPTH)
3179 nwritten = send (FD2INT (sock), data, nleft, 0);
3180 # if defined(USE_NPTH)
3183 if ( nwritten == SOCKET_ERROR )
3185 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
3186 return gpg_error (GPG_ERR_NETWORK);
3188 #else /*!HAVE_W32_SYSTEM*/
3190 nwritten = npth_write (sock, data, nleft);
3192 nwritten = write (sock, data, nleft);
3198 if (errno == EAGAIN)
3204 my_select (0, NULL, NULL, NULL, &tv);
3207 log_info ("network write failed: %s\n", strerror (errno));
3208 return gpg_error_from_syserror ();
3210 #endif /*!HAVE_W32_SYSTEM*/
3220 /* Read handler for estream. */
3221 static gpgrt_ssize_t
3222 cookie_read (void *cookie, void *buffer, size_t size)
3224 cookie_t c = cookie;
3227 if (c->content_length_valid)
3229 if (!c->content_length)
3231 if (c->content_length < size)
3232 size = c->content_length;
3236 if (c->use_tls && c->session && c->session->tls_session)
3240 ntbtls_get_stream (c->session->tls_session, &in, &out);
3241 nread = es_fread (buffer, 1, size, in);
3243 log_debug ("TLS network read: %d/%zu\n", nread, size);
3246 #elif HTTP_USE_GNUTLS
3247 if (c->use_tls && c->session && c->session->tls_session)
3250 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
3253 if (nread == GNUTLS_E_INTERRUPTED)
3255 if (nread == GNUTLS_E_AGAIN)
3261 my_select (0, NULL, NULL, NULL, &tv);
3264 if (nread == GNUTLS_E_REHANDSHAKE)
3265 goto again; /* A client is allowed to just ignore this request. */
3266 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
3268 /* The server terminated the connection. Close the TLS
3269 session, and indicate EOF using a short read. */
3270 close_tls_session (c->session);
3273 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
3274 gpg_err_set_errno (EIO);
3279 #endif /*HTTP_USE_GNUTLS*/
3281 nread = read_server (c->sock->fd, buffer, size);
3284 if (c->content_length_valid && nread > 0)
3286 if (nread < c->content_length)
3287 c->content_length -= nread;
3289 c->content_length = 0;
3292 return (gpgrt_ssize_t)nread;
3295 /* Write handler for estream. */
3296 static gpgrt_ssize_t
3297 cookie_write (void *cookie, const void *buffer_arg, size_t size)
3299 const char *buffer = buffer_arg;
3300 cookie_t c = cookie;
3304 if (c->use_tls && c->session && c->session->tls_session)
3308 ntbtls_get_stream (c->session->tls_session, &in, &out);
3312 nwritten = es_fwrite (buffer, 1, size, out);
3314 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
3317 #elif HTTP_USE_GNUTLS
3318 if (c->use_tls && c->session && c->session->tls_session)
3323 nwritten = gnutls_record_send (c->session->tls_session,
3327 if (nwritten == GNUTLS_E_INTERRUPTED)
3329 if (nwritten == GNUTLS_E_AGAIN)
3335 my_select (0, NULL, NULL, NULL, &tv);
3338 log_info ("TLS network write failed: %s\n",
3339 gnutls_strerror (nwritten));
3340 gpg_err_set_errno (EIO);
3348 #endif /*HTTP_USE_GNUTLS*/
3350 if ( write_server (c->sock->fd, buffer, size) )
3352 gpg_err_set_errno (EIO);
3359 return (gpgrt_ssize_t)nwritten;
3363 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
3364 static gpgrt_ssize_t
3365 simple_cookie_read (void *cookie, void *buffer, size_t size)
3367 assuan_fd_t sock = (assuan_fd_t)cookie;
3368 return read_server (sock, buffer, size);
3371 static gpgrt_ssize_t
3372 simple_cookie_write (void *cookie, const void *buffer_arg, size_t size)
3374 assuan_fd_t sock = (assuan_fd_t)cookie;
3375 const char *buffer = buffer_arg;
3378 if (write_server (sock, buffer, size))
3380 gpg_err_set_errno (EIO);
3386 return (gpgrt_ssize_t)nwritten;
3388 #endif /*HAVE_W32_SYSTEM*/
3391 #ifdef HTTP_USE_GNUTLS
3392 /* Wrapper for gnutls_bye used by my_socket_unref. */
3394 send_gnutls_bye (void *opaque)
3396 tls_session_t tls_session = opaque;
3401 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
3402 while (ret == GNUTLS_E_INTERRUPTED);
3403 if (ret == GNUTLS_E_AGAIN)
3409 my_select (0, NULL, NULL, NULL, &tv);
3413 #endif /*HTTP_USE_GNUTLS*/
3415 /* Close handler for estream. */
3417 cookie_close (void *cookie)
3419 cookie_t c = cookie;
3425 if (c->use_tls && c->session && c->session->tls_session)
3427 /* FIXME!! Possibly call ntbtls_close_notify for close
3429 my_socket_unref (c->sock, NULL, NULL);
3432 #elif HTTP_USE_GNUTLS
3433 if (c->use_tls && c->session && c->session->tls_session)
3434 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
3436 #endif /*HTTP_USE_GNUTLS*/
3438 my_socket_unref (c->sock, NULL, NULL);
3441 http_session_unref (c->session);
3449 /* Verify the credentials of the server. Returns 0 on success and
3450 store the result in the session object. */
3452 http_verify_server_credentials (http_session_t sess)
3455 static const char errprefix[] = "TLS verification of peer failed";
3457 unsigned int status;
3458 const char *hostname;
3459 const gnutls_datum_t *certlist;
3460 unsigned int certlistlen;
3461 gnutls_x509_crt_t cert;
3462 gpg_error_t err = 0;
3464 sess->verify.done = 1;
3465 sess->verify.status = 0;
3466 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
3468 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
3470 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
3471 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
3472 return gpg_error (GPG_ERR_GENERAL);
3475 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
3478 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
3480 err = gpg_error (GPG_ERR_GENERAL);
3484 log_error ("%s: status=0x%04x\n", errprefix, status);
3485 #if GNUTLS_VERSION_NUMBER >= 0x030104
3487 gnutls_datum_t statusdat;
3489 if (!gnutls_certificate_verification_status_print
3490 (status, GNUTLS_CRT_X509, &statusdat, 0))
3492 log_info ("%s: %s\n", errprefix, statusdat.data);
3493 gnutls_free (statusdat.data);
3496 #endif /*gnutls >= 3.1.4*/
3498 sess->verify.status = status;
3500 err = gpg_error (GPG_ERR_GENERAL);
3503 hostname = sess->servername;
3504 if (!hostname || !strchr (hostname, '.'))
3506 log_error ("%s: %s\n", errprefix, "hostname missing");
3508 err = gpg_error (GPG_ERR_GENERAL);
3511 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
3514 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
3516 err = gpg_error (GPG_ERR_GENERAL);
3518 /* Need to stop here. */
3523 rc = gnutls_x509_crt_init (&cert);
3527 err = gpg_error (GPG_ERR_GENERAL);
3532 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3535 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3536 gnutls_strerror (rc));
3538 err = gpg_error (GPG_ERR_GENERAL);
3541 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3543 log_error ("%s: %s\n", errprefix, "hostname does not match");
3545 err = gpg_error (GPG_ERR_GENERAL);
3548 gnutls_x509_crt_deinit (cert);
3551 sess->verify.rc = 0;
3553 if (sess->cert_log_cb)
3555 const void *bufarr[10];
3556 size_t buflenarr[10];
3559 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3561 bufarr[n] = certlist[n].data;
3562 buflenarr[n] = certlist[n].size;
3566 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3570 #else /*!HTTP_USE_GNUTLS*/
3572 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3577 /* Return the first query variable with the specified key. If there
3578 is no such variable, return NULL. */
3579 struct uri_tuple_s *
3580 uri_query_lookup (parsed_uri_t uri, const char *key)
3582 struct uri_tuple_s *t;
3584 for (t = uri->query; t; t = t->next)
3585 if (strcmp (t->name, key) == 0)
3592 uri_query_value (parsed_uri_t url, const char *key)
3594 struct uri_tuple_s *t;
3595 t = uri_query_lookup (url, key);
3596 return t? t->value : NULL;
3601 /* Return true if both URI point to the same host for the purpose of
3602 * redirection check. A is the original host and B the host given in
3603 * the Location header. As a temporary workaround a fixed list of
3604 * exceptions is also consulted. */
3606 same_host_p (parsed_uri_t a, parsed_uri_t b)
3610 const char *from; /* NULL uses the last entry from the table. */
3614 { "protonmail.com", "api.protonmail.com" },
3615 { NULL, "api.protonmail.ch" },
3616 { "protonmail.ch", "api.protonmail.com" },
3617 { NULL, "api.protonmail.ch" },
3618 { "pm.me", "api.protonmail.ch" }
3620 static const char *subdomains[] =
3627 if (!a->host || !b->host)
3630 if (!ascii_strcasecmp (a->host, b->host))
3634 for (i=0; i < DIM (allow); i++)
3637 from = allow[i].from;
3640 if (!ascii_strcasecmp (from, a->host)
3641 && !ascii_strcasecmp (allow[i].to, b->host))
3645 /* Also consider hosts the same if they differ only in a subdomain;
3646 * in both direction. This allows to have redirection between the
3647 * WKD advanced and direct lookup methods. */
3648 for (i=0; i < DIM (subdomains); i++)
3650 const char *subdom = subdomains[i];
3651 size_t subdomlen = strlen (subdom);
3653 if (!ascii_strncasecmp (a->host, subdom, subdomlen)
3654 && !ascii_strcasecmp (a->host + subdomlen, b->host))
3656 if (!ascii_strncasecmp (b->host, subdom, subdomlen)
3657 && !ascii_strcasecmp (b->host + subdomlen, a->host))
3665 /* Prepare a new URL for a HTTP redirect. INFO has flags controlling
3666 * the operation, STATUS_CODE is used for diagnostics, LOCATION is the
3667 * value of the "Location" header, and R_URL reveives the new URL on
3668 * success or NULL or error. Note that INFO->ORIG_URL is
3671 http_prepare_redirect (http_redir_info_t *info, unsigned int status_code,
3672 const char *location, char **r_url)
3675 parsed_uri_t locuri;
3676 parsed_uri_t origuri;
3682 if (!info || !info->orig_url)
3683 return gpg_error (GPG_ERR_INV_ARG);
3686 log_info (_("URL '%s' redirected to '%s' (%u)\n"),
3687 info->orig_url, location? location:"[none]", status_code);
3689 if (!info->redirects_left)
3692 log_error (_("too many redirections\n"));
3693 return gpg_error (GPG_ERR_NO_DATA);
3695 info->redirects_left--;
3697 if (!location || !*location)
3698 return gpg_error (GPG_ERR_NO_DATA);
3700 err = http_parse_uri (&locuri, location, 0);
3704 /* Make sure that an onion address only redirects to another
3705 * onion address, or that a https address only redirects to a
3707 if (info->orig_onion && !locuri->onion)
3709 dirmngr_status_printf (info->ctrl, "WARNING",
3711 " redirect from onion to non-onion address"
3714 http_release_parsed_uri (locuri);
3715 return gpg_error (GPG_ERR_FORBIDDEN);
3717 if (!info->allow_downgrade && info->orig_https && !locuri->use_tls)
3719 err = gpg_error (GPG_ERR_FORBIDDEN);
3720 dirmngr_status_printf (info->ctrl, "WARNING",
3722 " redirect '%s' to '%s' rejected",
3723 err, info->orig_url, location);
3724 http_release_parsed_uri (locuri);
3728 if (info->trust_location)
3730 /* We trust the Location - return it verbatim. */
3731 http_release_parsed_uri (locuri);
3732 newurl = xtrystrdup (location);
3735 err = gpg_error_from_syserror ();
3739 else if ((err = http_parse_uri (&origuri, info->orig_url, 0)))
3741 http_release_parsed_uri (locuri);
3744 else if (!info->restrict_redir || same_host_p (origuri, locuri))
3746 /* Take the syntactically correct location or if restrict_redir
3747 * is set the host is the same or on an exception list and thus
3748 * we can take the location verbatim. */
3749 http_release_parsed_uri (origuri);
3750 http_release_parsed_uri (locuri);
3751 newurl = xtrystrdup (location);
3754 err = gpg_error_from_syserror ();
3758 else /* Strictly rectricted redirection which we used in the past. */
3760 /* We take only the host and port from the URL given in the
3761 * Location. This limits the effects of redirection attacks by
3762 * rogue hosts returning an URL to servers in the client's own
3763 * network. We don't even include the userinfo because they
3764 * should be considered similar to the path and query parts.
3766 if (!(locuri->off_path - locuri->off_host))
3768 http_release_parsed_uri (origuri);
3769 http_release_parsed_uri (locuri);
3770 return gpg_error (GPG_ERR_BAD_URI);
3772 if (!(origuri->off_path - origuri->off_host))
3774 http_release_parsed_uri (origuri);
3775 http_release_parsed_uri (locuri);
3776 return gpg_error (GPG_ERR_BAD_URI);
3779 newurl = xtrymalloc (strlen (origuri->original)
3780 + (locuri->off_path - locuri->off_host) + 1);
3783 err = gpg_error_from_syserror ();
3784 http_release_parsed_uri (origuri);
3785 http_release_parsed_uri (locuri);
3788 /* Build new URL from
3789 * uriguri: scheme userinfo ---- ---- path rest
3790 * locuri: ------ -------- host port ---- ----
3793 memcpy (p, origuri->original, origuri->off_host);
3794 p += origuri->off_host;
3795 memcpy (p, locuri->original + locuri->off_host,
3796 (locuri->off_path - locuri->off_host));
3797 p += locuri->off_path - locuri->off_host;
3798 strcpy (p, origuri->original + origuri->off_path);
3800 http_release_parsed_uri (origuri);
3801 http_release_parsed_uri (locuri);
3803 log_info (_("redirection changed to '%s'\n"), newurl);
3804 dirmngr_status_printf (info->ctrl, "WARNING",
3805 "http_redirect_cleanup %u"
3806 " changed from '%s' to '%s'",
3807 0, info->orig_url, newurl);
3815 /* Return string describing the http STATUS. Returns an empty string
3816 * for an unknown status. */
3818 http_status2string (unsigned int status)
3822 case 500: return "Internal Server Error";
3823 case 501: return "Not Implemented";
3824 case 502: return "Bad Gateway";
3825 case 503: return "Service Unavailable";
3826 case 504: return "Gateway Timeout";
3827 case 505: return "HTTP version Not Supported";
3828 case 506: return "Variant Also Negation";
3829 case 507: return "Insufficient Storage";
3830 case 508: return "Loop Detected";
3831 case 510: return "Not Extended";
3832 case 511: return "Network Authentication Required";