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 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.
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>
74 # include <netinet/in.h>
75 # include <arpa/inet.h>
77 #endif /*!HAVE_W32_SYSTEM*/
79 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
87 #if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_NTBTLS)
88 # error Both, HTTP_USE_GNUTLS and HTTP_USE_NTBTLS, are defined.
91 #ifdef HTTP_USE_NTBTLS
94 # include <gnutls/gnutls.h>
95 # include <gnutls/x509.h>
96 #endif /*HTTP_USE_GNUTLS*/
98 #include <assuan.h> /* We need the socket wrapper. */
100 #include "../common/util.h"
101 #include "../common/i18n.h"
102 #include "../common/sysutils.h" /* (gnupg_fd_t) */
103 #include "dns-stuff.h"
105 #include "http-common.h"
109 # define my_select(a,b,c,d,e) npth_select ((a), (b), (c), (d), (e))
110 # define my_accept(a,b,c) npth_accept ((a), (b), (c))
112 # define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e))
113 # define my_accept(a,b,c) accept ((a), (b), (c))
116 #ifdef HAVE_W32_SYSTEM
117 #define sock_close(a) closesocket(a)
119 #define sock_close(a) close(a)
123 #define EAGAIN EWOULDBLOCK
125 #ifndef INADDR_NONE /* Slowaris is missing that. */
126 #define INADDR_NONE ((unsigned long)(-1))
127 #endif /*INADDR_NONE*/
129 #define HTTP_PROXY_ENV "http_proxy"
130 #define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
131 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
132 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
134 "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
137 typedef ntbtls_t tls_session_t;
139 #elif HTTP_USE_GNUTLS
140 typedef gnutls_session_t tls_session_t;
143 typedef void *tls_session_t;
147 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
148 int no_scheme_check, int force_tls);
149 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
150 int no_scheme_check, int force_tls);
151 static int remove_escapes (char *string);
152 static int insert_escapes (char *buffer, const char *string,
153 const char *special);
154 static uri_tuple_t parse_tuple (char *string);
155 static gpg_error_t send_request (http_t hd, const char *httphost,
156 const char *auth,const char *proxy,
157 const char *srvtag, unsigned int timeout,
159 static char *build_rel_path (parsed_uri_t uri);
160 static gpg_error_t parse_response (http_t hd);
162 static gpg_error_t connect_server (const char *server, unsigned short port,
163 unsigned int flags, const char *srvtag,
164 unsigned int timeout, assuan_fd_t *r_sock);
165 static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
166 static gpg_error_t write_server (assuan_fd_t sock, const char *data, size_t length);
168 static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
169 static gpgrt_ssize_t cookie_write (void *cookie,
170 const void *buffer, size_t size);
171 static int cookie_close (void *cookie);
172 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
173 static gpgrt_ssize_t simple_cookie_read (void *cookie,
174 void *buffer, size_t size);
175 static gpgrt_ssize_t simple_cookie_write (void *cookie,
176 const void *buffer, size_t size);
179 /* A socket object used to a allow ref counting of sockets. */
182 assuan_fd_t fd; /* The actual socket - shall never be ASSUAN_INVALID_FD. */
183 int refcount; /* Number of references to this socket. */
185 typedef struct my_socket_s *my_socket_t;
188 /* Cookie function structure and cookie object. */
189 static es_cookie_io_functions_t cookie_functions =
200 /* Socket object or NULL if already closed. */
203 /* The session object or NULL if not used. */
204 http_session_t session;
206 /* True if TLS is to be used. */
209 /* The remaining content length and a flag telling whether to use
210 the content length. */
211 uint64_t content_length;
212 unsigned int content_length_valid:1;
214 typedef struct cookie_s *cookie_t;
217 /* Simple cookie functions. Here the cookie is an int with the
219 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
220 static es_cookie_io_functions_t simple_cookie_functions =
230 #if SIZEOF_UNSIGNED_LONG == 8
231 # define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */
233 # define HTTP_SESSION_MAGIC 0x68547365 /* "hTse" */
236 /* The session object. */
237 struct http_session_s
241 int refcount; /* Number of references to this object. */
242 #ifdef HTTP_USE_GNUTLS
243 gnutls_certificate_credentials_t certcred;
244 #endif /*HTTP_USE_GNUTLS*/
246 tls_session_t tls_session;
248 int done; /* Verifciation has been done. */
249 int rc; /* TLS verification return code. */
250 unsigned int status; /* Verification status. */
252 char *servername; /* Malloced server name. */
254 /* A callback function to log details of TLS certifciates. */
255 void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
256 const void **, size_t *);
258 /* The flags passed to the session object. */
261 /* A per-session TLS verification callback. */
262 http_verify_cb_t verify_cb;
263 void *verify_cb_value;
265 /* The connect timeout */
266 unsigned int connect_timeout;
270 /* An object to save header lines. */
273 struct header_s *next;
274 char *value; /* The value of the header (malloced). */
275 char name[1]; /* The name of the header (canonicalized). */
277 typedef struct header_s *header_t;
280 #if SIZEOF_UNSIGNED_LONG == 8
281 # define HTTP_CONTEXT_MAGIC 0x0068545470435458 /* "hTTpCTX" */
283 # define HTTP_CONTEXT_MAGIC 0x68546378 /* "hTcx" */
287 /* Our handle context. */
288 struct http_context_s
291 unsigned int status_code;
293 unsigned int in_data:1;
294 unsigned int is_http_0_9:1;
299 http_session_t session;
302 char *buffer; /* Line buffer. */
305 header_t headers; /* Received headers. */
309 /* Two flags to enable verbose and debug mode. Although currently not
310 * set-able a value > 1 for OPT_DEBUG enables debugging of the session
311 * reference counting. */
312 static int opt_verbose;
313 static int opt_debug;
315 /* The global callback for the verification function. */
316 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
318 /* The list of files with trusted CA certificates. */
319 static strlist_t tls_ca_certlist;
321 /* The global callback for net activity. */
322 static void (*netactivity_cb)(void);
326 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
328 #if GNUPG_MAJOR_VERSION == 1
329 #define REQ_WINSOCK_MAJOR 1
330 #define REQ_WINSOCK_MINOR 1
332 #define REQ_WINSOCK_MAJOR 2
333 #define REQ_WINSOCK_MINOR 2
338 deinit_sockets (void)
346 static int initialized;
347 static WSADATA wsdata;
352 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
354 log_error ("error initializing socket library: ec=%d\n",
355 (int)WSAGetLastError () );
358 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
359 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
361 log_error ("socket library version is %x.%x - but %d.%d needed\n",
362 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
363 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
367 atexit ( deinit_sockets );
370 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
373 /* Create a new socket object. Returns NULL and closes FD if not
374 enough memory is available. */
376 _my_socket_new (int lnr, assuan_fd_t fd)
380 so = xtrymalloc (sizeof *so);
383 int save_errno = errno;
384 assuan_sock_close (fd);
385 gpg_err_set_errno (save_errno);
391 log_debug ("http.c:%d:socket_new: object %p for fd %d created\n",
392 lnr, so, (int)so->fd);
395 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
397 /* Bump up the reference counter for the socket object SO. */
399 _my_socket_ref (int lnr, my_socket_t so)
403 log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n",
404 lnr, so, (int)so->fd, so->refcount);
407 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
410 /* Bump down the reference counter for the socket object SO. If SO
411 has no more references, close the socket and release the
414 _my_socket_unref (int lnr, my_socket_t so,
415 void (*preclose)(void*), void *preclosearg)
421 log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n",
422 lnr, so, (int)so->fd, so->refcount);
427 preclose (preclosearg);
428 assuan_sock_close (so->fd);
433 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
436 #ifdef HTTP_USE_GNUTLS
438 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
440 my_socket_t sock = ptr;
442 return npth_read (sock->fd, buffer, size);
444 return read (sock->fd, buffer, size);
448 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
450 my_socket_t sock = ptr;
452 return npth_write (sock->fd, buffer, size);
454 return write (sock->fd, buffer, size);
457 #endif /*HTTP_USE_GNUTLS*/
460 #ifdef HTTP_USE_NTBTLS
461 /* Connect the ntbls callback to our generic callback. */
463 my_ntbtls_verify_cb (void *opaque, ntbtls_t tls, unsigned int verify_flags)
469 log_assert (hd && hd->session && hd->session->verify_cb);
470 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
471 log_assert (hd->session->magic == HTTP_SESSION_MAGIC);
473 return hd->session->verify_cb (hd->session->verify_cb_value,
475 (hd->flags | hd->session->flags),
478 #endif /*HTTP_USE_NTBTLS*/
483 /* This notification function is called by estream whenever stream is
484 closed. Its purpose is to mark the closing in the handle so
485 that a http_close won't accidentally close the estream. The function
486 http_close removes this notification so that it won't be called if
487 http_close was used before an es_fclose. */
489 fp_onclose_notification (estream_t stream, void *opaque)
493 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
494 if (hd->fp_read && hd->fp_read == stream)
496 else if (hd->fp_write && hd->fp_write == stream)
502 * Helper function to create an HTTP header with hex encoded data. A
503 * new buffer is returned. This buffer is the concatenation of the
504 * string PREFIX, the hex-encoded DATA of length LEN and the string
505 * SUFFIX. On error NULL is returned and ERRNO set.
508 make_header_line (const char *prefix, const char *suffix,
509 const void *data, size_t len )
511 static unsigned char bintoasc[] =
512 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
513 "abcdefghijklmnopqrstuvwxyz"
515 const unsigned char *s = data;
518 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
521 p = stpcpy (buffer, prefix);
522 for ( ; len >= 3 ; len -= 3, s += 3 )
524 *p++ = bintoasc[(s[0] >> 2) & 077];
525 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
526 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
527 *p++ = bintoasc[s[2]&077];
532 *p++ = bintoasc[(s[0] >> 2) & 077];
533 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
534 *p++ = bintoasc[((s[1]<<2)&074)];
539 *p++ = bintoasc[(s[0] >> 2) & 077];
540 *p++ = bintoasc[(s[0] <<4)&060];
552 /* Set verbosity and debug mode for this module. */
554 http_set_verbose (int verbose, int debug)
556 opt_verbose = verbose;
561 /* Register a non-standard global TLS callback function. If no
562 verification is desired a callback needs to be registered which
563 always returns NULL. */
565 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
571 /* Register a CA certificate for future use. The certificate is
572 expected to be in FNAME. PEM format is assume if FNAME has a
573 suffix of ".pem". If FNAME is NULL the list of CA files is
576 http_register_tls_ca (const char *fname)
582 free_strlist (tls_ca_certlist);
583 tls_ca_certlist = NULL;
587 /* Warn if we can't access right now, but register it anyway in
588 case it becomes accessible later */
589 if (access (fname, F_OK))
590 log_info (_("can't access '%s': %s\n"), fname,
591 gpg_strerror (gpg_error_from_syserror()));
592 sl = add_to_strlist (&tls_ca_certlist, fname);
593 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
599 /* Register a callback which is called every time the HTTP mode has
600 * made a successful connection to some server. */
602 http_register_netactivity_cb (void (*cb)(void))
608 /* Call the netactivity callback if any. */
610 notify_netactivity (void)
619 /* Free the TLS session associated with SESS, if any. */
621 close_tls_session (http_session_t sess)
623 if (sess->tls_session)
627 Possibly, ntbtls_get_transport and close those streams.
628 Somehow get SOCK to call my_socket_unref.
630 ntbtls_release (sess->tls_session);
631 # elif HTTP_USE_GNUTLS
632 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
633 my_socket_unref (sock, NULL, NULL);
634 gnutls_deinit (sess->tls_session);
636 gnutls_certificate_free_credentials (sess->certcred);
637 # endif /*HTTP_USE_GNUTLS*/
638 xfree (sess->servername);
639 sess->tls_session = NULL;
645 /* Release a session. Take care not to release it while it is being
646 used by a http context object. */
648 session_unref (int lnr, http_session_t sess)
653 log_assert (sess->magic == HTTP_SESSION_MAGIC);
657 log_debug ("http.c:%d:session_unref: sess %p ref now %d\n",
658 lnr, sess, sess->refcount);
663 close_tls_session (sess);
666 sess->magic = 0xdeadbeef;
669 #define http_session_unref(a) session_unref (__LINE__, (a))
672 http_session_release (http_session_t sess)
674 http_session_unref (sess);
678 /* Create a new session object which is currently used to enable TLS
679 * support. It may eventually allow reusing existing connections.
680 * Valid values for FLAGS are:
681 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
682 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
683 * HTTP_FLAG_NO_CRL - Do not consult CRLs for https.
686 http_session_new (http_session_t *r_session,
687 const char *intended_hostname, unsigned int flags,
688 http_verify_cb_t verify_cb, void *verify_cb_value)
695 sess = xtrycalloc (1, sizeof *sess);
697 return gpg_error_from_syserror ();
698 sess->magic = HTTP_SESSION_MAGIC;
701 sess->verify_cb = verify_cb;
702 sess->verify_cb_value = verify_cb_value;
703 sess->connect_timeout = 0;
707 (void)intended_hostname; /* Not needed because we do not preload
710 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
713 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
718 #elif HTTP_USE_GNUTLS
723 int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS);
726 rc = gnutls_certificate_allocate_credentials (&sess->certcred);
729 log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
730 gnutls_strerror (rc));
731 err = gpg_error (GPG_ERR_GENERAL);
735 is_hkps_pool = (intended_hostname
736 && !ascii_strcasecmp (intended_hostname,
737 get_default_keyserver (1)));
739 /* If the user has not specified a CA list, and they are looking
740 * for the hkps pool from sks-keyservers.net, then default to
741 * Kristian's certificate authority: */
742 if (!tls_ca_certlist && is_hkps_pool)
744 char *pemname = make_filename_try (gnupg_datadir (),
745 "sks-keyservers.netCA.pem", NULL);
748 err = gpg_error_from_syserror ();
749 log_error ("setting CA from file '%s' failed: %s\n",
750 pemname, gpg_strerror (err));
754 rc = gnutls_certificate_set_x509_trust_file
755 (sess->certcred, pemname, GNUTLS_X509_FMT_PEM);
757 log_info ("setting CA from file '%s' failed: %s\n",
758 pemname, gnutls_strerror (rc));
763 /* Add configured certificates to the session. */
764 if ((flags & HTTP_FLAG_TRUST_DEF))
766 for (sl = tls_ca_certlist; sl; sl = sl->next)
768 rc = gnutls_certificate_set_x509_trust_file
769 (sess->certcred, sl->d,
770 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
772 log_info ("setting CA from file '%s' failed: %s\n",
773 sl->d, gnutls_strerror (rc));
775 if (!tls_ca_certlist && !is_hkps_pool)
779 /* Add system certificates to the session. */
782 #if GNUTLS_VERSION_NUMBER >= 0x030014
785 rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
787 log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
791 log_info ("number of system provided CAs: %d\n", rc);
793 #endif /* gnutls >= 3.0.20 */
796 rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
799 log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
800 err = gpg_error (GPG_ERR_GENERAL);
803 /* A new session has the transport ptr set to (void*(-1), we need
805 gnutls_transport_set_ptr (sess->tls_session, NULL);
807 rc = gnutls_priority_set_direct (sess->tls_session,
812 log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
813 errpos, gnutls_strerror (rc));
814 err = gpg_error (GPG_ERR_GENERAL);
818 rc = gnutls_credentials_set (sess->tls_session,
819 GNUTLS_CRD_CERTIFICATE, sess->certcred);
822 log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
823 err = gpg_error (GPG_ERR_GENERAL);
827 #else /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/
829 (void)intended_hostname;
832 #endif /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/
835 log_debug ("http.c:session_new: sess %p created\n", sess);
842 http_session_unref (sess);
850 /* Increment the reference count for session SESS. Passing NULL for
853 http_session_ref (http_session_t sess)
859 log_debug ("http.c:session_ref: sess %p ref now %d\n",
860 sess, sess->refcount);
867 http_session_set_log_cb (http_session_t sess,
868 void (*cb)(http_session_t, gpg_error_t,
869 const char *hostname,
870 const void **certs, size_t *certlens))
872 sess->cert_log_cb = cb;
876 /* Set the TIMEOUT in milliseconds for the connection's connect
877 * calls. Using 0 disables the timeout. */
879 http_session_set_timeout (http_session_t sess, unsigned int timeout)
881 sess->connect_timeout = timeout;
887 /* Start a HTTP retrieval and on success store at R_HD a context
888 pointer for completing the request and to wait for the response.
889 If HTTPHOST is not NULL it is used for the Host header instead of a
890 Host header derived from the URL. */
892 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
893 const char *httphost,
894 const char *auth, unsigned int flags, const char *proxy,
895 http_session_t session, const char *srvtag, strlist_t headers)
902 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
903 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
905 /* Create the handle. */
906 hd = xtrycalloc (1, sizeof *hd);
908 return gpg_error_from_syserror ();
909 hd->magic = HTTP_CONTEXT_MAGIC;
910 hd->req_type = reqtype;
912 hd->session = http_session_ref (session);
914 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
916 err = send_request (hd, httphost, auth, proxy, srvtag,
917 hd->session? hd->session->connect_timeout : 0,
922 my_socket_unref (hd->sock, NULL, NULL);
924 es_fclose (hd->fp_read);
926 es_fclose (hd->fp_write);
927 http_session_unref (hd->session);
936 /* This function is useful to connect to a generic TCP service using
937 this http abstraction layer. This has the advantage of providing
938 service tags and an estream interface. TIMEOUT is in milliseconds. */
940 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
941 unsigned int flags, const char *srvtag, unsigned int timeout)
949 if ((flags & HTTP_FLAG_FORCE_TOR))
953 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
955 log_error ("Tor support is not available\n");
956 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
958 /* Non-blocking connects do not work with our Tor proxy because
959 * we can't continue the Socks protocol after the EINPROGRESS.
960 * Disable the timeout to use a blocking connect. */
964 /* Create the handle. */
965 hd = xtrycalloc (1, sizeof *hd);
967 return gpg_error_from_syserror ();
968 hd->magic = HTTP_CONTEXT_MAGIC;
969 hd->req_type = HTTP_REQ_OPAQUE;
976 err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
982 hd->sock = my_socket_new (sock);
985 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
991 /* Setup estreams for reading and writing. */
992 cookie = xtrycalloc (1, sizeof *cookie);
995 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
998 cookie->sock = my_socket_ref (hd->sock);
999 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1002 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1003 my_socket_unref (cookie->sock, NULL, NULL);
1007 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
1009 cookie = xtrycalloc (1, sizeof *cookie);
1012 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1015 cookie->sock = my_socket_ref (hd->sock);
1016 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1019 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1020 my_socket_unref (cookie->sock, NULL, NULL);
1024 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1026 /* Register close notification to interlock the use of es_fclose in
1027 http_close and in user code. */
1028 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1030 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1036 es_fclose (hd->fp_read);
1038 es_fclose (hd->fp_write);
1039 my_socket_unref (hd->sock, NULL, NULL);
1051 http_start_data (http_t hd)
1055 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1056 log_debug_with_string ("\r\n", "http.c:request-header:");
1057 es_fputs ("\r\n", hd->fp_write);
1058 es_fflush (hd->fp_write);
1062 es_fflush (hd->fp_write);
1067 http_wait_response (http_t hd)
1073 /* Make sure that we are in the data. */
1074 http_start_data (hd);
1076 /* Close the write stream. Note that the reference counted socket
1077 object keeps the actual system socket open. */
1078 cookie = hd->write_cookie;
1080 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1082 use_tls = cookie->use_tls;
1083 es_fclose (hd->fp_write);
1084 hd->fp_write = NULL;
1085 /* The close has released the cookie and thus we better set it to NULL. */
1086 hd->write_cookie = NULL;
1088 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1089 is not required but some very old servers (e.g. the original pksd
1090 keyserver didn't worked without it. */
1091 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1092 shutdown (FD2INT (hd->sock->fd), 1);
1095 /* Create a new cookie and a stream for reading. */
1096 cookie = xtrycalloc (1, sizeof *cookie);
1098 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1099 cookie->sock = my_socket_ref (hd->sock);
1100 cookie->session = http_session_ref (hd->session);
1101 cookie->use_tls = use_tls;
1103 hd->read_cookie = cookie;
1104 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1107 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1108 my_socket_unref (cookie->sock, NULL, NULL);
1109 http_session_unref (cookie->session);
1111 hd->read_cookie = NULL;
1115 err = parse_response (hd);
1118 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1124 /* Convenience function to send a request and wait for the response.
1125 Closes the handle on error. If PROXY is not NULL, this value will
1126 be used as an HTTP proxy and any enabled $http_proxy gets
1129 http_open_document (http_t *r_hd, const char *document,
1130 const char *auth, unsigned int flags, const char *proxy,
1131 http_session_t session,
1132 const char *srvtag, strlist_t headers)
1136 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1137 proxy, session, srvtag, headers);
1141 err = http_wait_response (*r_hd);
1143 http_close (*r_hd, 0);
1150 http_close (http_t hd, int keep_read_stream)
1155 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
1157 /* First remove the close notifications for the streams. */
1159 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1161 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1163 /* Now we can close the streams. */
1164 my_socket_unref (hd->sock, NULL, NULL);
1165 if (hd->fp_read && !keep_read_stream)
1166 es_fclose (hd->fp_read);
1168 es_fclose (hd->fp_write);
1169 http_session_unref (hd->session);
1170 hd->magic = 0xdeadbeef;
1171 http_release_parsed_uri (hd->uri);
1174 header_t tmp = hd->headers->next;
1175 xfree (hd->headers->value);
1176 xfree (hd->headers);
1185 http_get_read_ptr (http_t hd)
1187 return hd?hd->fp_read:NULL;
1191 http_get_write_ptr (http_t hd)
1193 return hd?hd->fp_write:NULL;
1197 http_get_status_code (http_t hd)
1199 return hd?hd->status_code:0;
1202 /* Return information pertaining to TLS. If TLS is not in use for HD,
1203 NULL is returned. WHAT is used ask for specific information:
1205 (NULL) := Only check whether TLS is in use. Returns an
1206 unspecified string if TLS is in use. That string may
1207 even be the empty string.
1210 http_get_tls_info (http_t hd, const char *what)
1217 return hd->uri->use_tls? "":NULL;
1223 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1224 int no_scheme_check, int force_tls)
1228 *ret_uri = xtrycalloc (1, sizeof **ret_uri + 2 * strlen (uri) + 1);
1230 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1231 strcpy ((*ret_uri)->buffer, uri);
1232 strcpy ((*ret_uri)->buffer + strlen (uri) + 1, uri);
1233 (*ret_uri)->original = (*ret_uri)->buffer + strlen (uri) + 1;
1234 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1237 http_release_parsed_uri (*ret_uri);
1240 return gpg_err_make (default_errsource, ec);
1245 * Parse an URI and put the result into the newly allocated RET_URI.
1246 * On success the caller must use http_release_parsed_uri() to
1247 * releases the resources. If NO_SCHEME_CHECK is set, the function
1248 * tries to parse the URL in the same way it would do for an HTTP
1252 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1253 int no_scheme_check)
1255 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1260 http_release_parsed_uri (parsed_uri_t uri)
1266 for (r = uri->params; r; r = r2)
1271 for (r = uri->query; r; r = r2)
1281 static gpg_err_code_t
1282 do_parse_uri (parsed_uri_t uri, int only_local_part,
1283 int no_scheme_check, int force_tls)
1286 char *p, *p2, *p3, *pp;
1290 n = strlen (uri->buffer);
1292 /* Initialize all fields to an empty string or an empty list. */
1293 uri->scheme = uri->host = uri->path = p + n;
1295 uri->params = uri->query = NULL;
1301 uri->explicit_port = 0;
1303 /* A quick validity check. */
1304 if (strspn (p, VALID_URI_CHARS) != n)
1305 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1307 if (!only_local_part)
1309 /* Find the scheme. */
1310 if (!(p2 = strchr (p, ':')) || p2 == p)
1311 return GPG_ERR_BAD_URI; /* No scheme. */
1313 for (pp=p; *pp; pp++)
1314 *pp = tolower (*(unsigned char*)pp);
1316 if (!strcmp (uri->scheme, "http") && !force_tls)
1321 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1327 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1328 || (force_tls && (!strcmp (uri->scheme, "http")
1329 || !strcmp (uri->scheme,"hkp"))))
1336 else if (!no_scheme_check)
1337 return GPG_ERR_INV_URI; /* Unsupported scheme */
1341 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1344 if ((p2 = strchr (p, '/')))
1347 /* Check for username/password encoding */
1348 if ((p3 = strchr (p, '@')))
1355 for (pp=p; *pp; pp++)
1356 *pp = tolower (*(unsigned char*)pp);
1358 /* Handle an IPv6 literal */
1359 if( *p == '[' && (p3=strchr( p, ']' )) )
1362 /* worst case, uri->host should have length 0, points to \0 */
1370 if ((p3 = strchr (p, ':')))
1373 uri->port = atoi (p3);
1374 uri->explicit_port = 1;
1377 if ((n = remove_escapes (uri->host)) < 0)
1378 return GPG_ERR_BAD_URI;
1379 if (n != strlen (uri->host))
1380 return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */
1383 else if (uri->is_http)
1384 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1389 if (is_onion_address (uri->path))
1394 } /* End global URI part. */
1396 /* Parse the pathname part if any. */
1399 /* TODO: Here we have to check params. */
1401 /* Do we have a query part? */
1402 if ((p2 = strchr (p, '?')))
1406 if ((n = remove_escapes (p)) < 0)
1407 return GPG_ERR_BAD_URI;
1408 if (n != strlen (p))
1409 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1412 /* Parse a query string if any. */
1420 if ((p2 = strchr (p, '&')))
1422 if (!(elem = parse_tuple (p)))
1423 return GPG_ERR_BAD_URI;
1434 if (is_onion_address (uri->host))
1442 * Remove all %xx escapes; this is done in-place. Returns: New length
1446 remove_escapes (char *string)
1449 unsigned char *p, *s;
1451 for (p = s = (unsigned char*)string; *s; s++)
1455 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1458 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1459 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1462 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1463 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1476 return -1; /* Bad URI. */
1485 *p = 0; /* Make sure to keep a string terminator. */
1490 /* If SPECIAL is NULL this function escapes in forms mode. */
1492 escape_data (char *buffer, const void *data, size_t datalen,
1493 const char *special)
1495 int forms = !special;
1496 const unsigned char *s;
1502 for (s = data; datalen; s++, datalen--)
1504 if (forms && *s == ' ')
1510 else if (forms && *s == '\n')
1513 memcpy (buffer, "%0D%0A", 6);
1516 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1519 memcpy (buffer, "%0D%0A", 6);
1524 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1527 *(unsigned char*)buffer++ = *s;
1534 snprintf (buffer, 4, "%%%02X", *s);
1545 insert_escapes (char *buffer, const char *string,
1546 const char *special)
1548 return escape_data (buffer, string, strlen (string), special);
1552 /* Allocate a new string from STRING using standard HTTP escaping as
1553 well as escaping of characters given in SPECIALS. A common pattern
1554 for SPECIALS is "%;?&=". However it depends on the needs, for
1555 example "+" and "/: often needs to be escaped too. Returns NULL on
1556 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1557 encoding mode is used. */
1559 http_escape_string (const char *string, const char *specials)
1564 n = insert_escapes (NULL, string, specials);
1565 buf = xtrymalloc (n+1);
1568 insert_escapes (buf, string, specials);
1574 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1575 escaping as well as escaping of characters given in SPECIALS. A
1576 common pattern for SPECIALS is "%;?&=". However it depends on the
1577 needs, for example "+" and "/: often needs to be escaped too.
1578 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1579 dedicated forms encoding mode is used. */
1581 http_escape_data (const void *data, size_t datalen, const char *specials)
1586 n = escape_data (NULL, data, datalen, specials);
1587 buf = xtrymalloc (n+1);
1590 escape_data (buf, data, datalen, specials);
1598 parse_tuple (char *string)
1605 if ((p2 = strchr (p, '=')))
1607 if ((n = remove_escapes (p)) < 0)
1608 return NULL; /* Bad URI. */
1609 if (n != strlen (p))
1610 return NULL; /* Name with a Nul in it. */
1611 tuple = xtrycalloc (1, sizeof *tuple);
1613 return NULL; /* Out of core. */
1615 if (!p2) /* We have only the name, so we assume an empty value string. */
1617 tuple->value = p + strlen (p);
1618 tuple->valuelen = 0;
1619 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1621 else /* Name and value. */
1623 if ((n = remove_escapes (p2)) < 0)
1626 return NULL; /* Bad URI. */
1629 tuple->valuelen = n;
1635 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1637 is_hostname_port (const char *string)
1641 if (!string || !*string)
1643 for (; *string; string++)
1653 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1654 return 0; /* Invalid characters in hostname. */
1655 else if (colons && !digitp (string))
1656 return 0; /* Not a digit in the port. */
1663 * Send a HTTP request to the server
1664 * Returns 0 if the request was successful
1667 send_request (http_t hd, const char *httphost, const char *auth,
1668 const char *proxy, const char *srvtag, unsigned int timeout,
1674 unsigned short port;
1675 const char *http_proxy = NULL;
1676 char *proxy_authstr = NULL;
1677 char *authstr = NULL;
1680 int have_http_proxy = 0;
1683 if (hd->uri->use_tls && !hd->session)
1685 log_error ("TLS requested but no session object provided\n");
1686 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1689 if (hd->uri->use_tls && !hd->session->tls_session)
1691 log_error ("TLS requested but no GNUTLS context available\n");
1692 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1696 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1700 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1702 log_error ("Tor support is not available\n");
1703 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1705 /* Non-blocking connects do not work with our Tor proxy because
1706 * we can't continue the Socks protocol after the EINPROGRESS.
1707 * Disable the timeout to use a blocking connect. */
1711 server = *hd->uri->host ? hd->uri->host : "localhost";
1712 port = hd->uri->port ? hd->uri->port : 80;
1714 /* Try to use SNI. */
1716 if (hd->uri->use_tls)
1718 # if HTTP_USE_GNUTLS
1722 xfree (hd->session->servername);
1723 hd->session->servername = xtrystrdup (httphost? httphost : server);
1724 if (!hd->session->servername)
1726 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1730 # if HTTP_USE_NTBTLS
1731 err = ntbtls_set_hostname (hd->session->tls_session,
1732 hd->session->servername);
1735 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1738 # elif HTTP_USE_GNUTLS
1739 rc = gnutls_server_name_set (hd->session->tls_session,
1741 hd->session->servername,
1742 strlen (hd->session->servername));
1744 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1745 # endif /*HTTP_USE_GNUTLS*/
1749 if ( (proxy && *proxy)
1750 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1751 && (http_proxy = getenv (HTTP_PROXY_ENV))
1759 err = parse_uri (&uri, http_proxy, 0, 0);
1760 if (gpg_err_code (err) == GPG_ERR_INV_URI
1761 && is_hostname_port (http_proxy))
1763 /* Retry assuming a "hostname:port" string. */
1764 char *tmpname = strconcat ("http://", http_proxy, NULL);
1765 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1773 else if (!strcmp (uri->scheme, "http"))
1774 have_http_proxy = 1;
1776 else if (!strcmp (uri->scheme, "socks4")
1777 || !strcmp (uri->scheme, "socks5h"))
1778 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1780 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1784 log_error ("invalid HTTP proxy (%s): %s\n",
1785 http_proxy, gpg_strerror (err));
1786 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1791 remove_escapes (uri->auth);
1792 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1794 uri->auth, strlen(uri->auth));
1797 err = gpg_err_make (default_errsource,
1798 gpg_err_code_from_syserror ());
1799 http_release_parsed_uri (uri);
1804 err = connect_server (*uri->host ? uri->host : "localhost",
1805 uri->port ? uri->port : 80,
1806 hd->flags, NULL, timeout, &sock);
1807 http_release_parsed_uri (uri);
1811 err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
1816 xfree (proxy_authstr);
1819 hd->sock = my_socket_new (sock);
1822 xfree (proxy_authstr);
1823 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1827 if (have_http_proxy && hd->uri->use_tls)
1832 /* Try to use the CONNECT method to proxy our TLS stream. */
1833 request = es_bsprintf
1834 ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s",
1835 httphost ? httphost : server,
1837 httphost ? httphost : server,
1839 proxy_authstr ? proxy_authstr : "");
1840 xfree (proxy_authstr);
1841 proxy_authstr = NULL;
1844 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1846 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1847 log_debug_with_string (request, "http.c:request:");
1849 cookie = xtrycalloc (1, sizeof *cookie);
1852 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1856 cookie->sock = my_socket_ref (hd->sock);
1857 hd->write_cookie = cookie;
1859 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1862 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1863 my_socket_unref (cookie->sock, NULL, NULL);
1866 hd->write_cookie = NULL;
1869 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1870 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1875 /* Make sure http_wait_response doesn't close the stream. */
1876 saved_flags = hd->flags;
1877 hd->flags &= ~HTTP_FLAG_SHUTDOWN;
1879 /* Get the response. */
1880 err = http_wait_response (hd);
1882 /* Restore flags, destroy stream. */
1883 hd->flags = saved_flags;
1884 es_fclose (hd->fp_read);
1886 hd->read_cookie = NULL;
1894 if (hd->status_code != 200)
1896 request = es_bsprintf
1898 httphost ? httphost : server,
1901 log_error (_("error accessing '%s': http status %u\n"),
1902 request ? request : "out of core",
1903 http_get_status_code (hd));
1906 return gpg_error (GPG_ERR_NO_DATA);
1909 /* We are done with the proxy, the code below will establish a
1910 * TLS session and talk directly to the target server. */
1913 #endif /* USE_TLS */
1916 if (hd->uri->use_tls)
1920 my_socket_ref (hd->sock);
1922 /* Until we support send/recv in estream under Windows we need
1923 * to use es_fopencookie. */
1924 #ifdef HAVE_W32_SYSTEM
1925 in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb",
1926 simple_cookie_functions);
1928 in = es_fdopen_nc (hd->sock->fd, "rb");
1932 err = gpg_error_from_syserror ();
1933 xfree (proxy_authstr);
1937 #ifdef HAVE_W32_SYSTEM
1938 out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb",
1939 simple_cookie_functions);
1941 out = es_fdopen_nc (hd->sock->fd, "wb");
1945 err = gpg_error_from_syserror ();
1947 xfree (proxy_authstr);
1951 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1954 log_info ("TLS set_transport failed: %s <%s>\n",
1955 gpg_strerror (err), gpg_strsource (err));
1956 xfree (proxy_authstr);
1960 #ifdef HTTP_USE_NTBTLS
1961 if (hd->session->verify_cb)
1963 err = ntbtls_set_verify_cb (hd->session->tls_session,
1964 my_ntbtls_verify_cb, hd);
1967 log_error ("ntbtls_set_verify_cb failed: %s\n",
1968 gpg_strerror (err));
1969 xfree (proxy_authstr);
1973 #endif /*HTTP_USE_NTBTLS*/
1975 while ((err = ntbtls_handshake (hd->session->tls_session)))
1980 log_info ("TLS handshake failed: %s <%s>\n",
1981 gpg_strerror (err), gpg_strsource (err));
1982 xfree (proxy_authstr);
1987 hd->session->verify.done = 0;
1989 /* Try the available verify callbacks until one returns success
1990 * or a real error. Note that NTBTLS does the verification
1991 * during the handshake via */
1992 #ifdef HTTP_USE_NTBTLS
1993 err = 0; /* Fixme check that the CB has been called. */
1995 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1998 if (hd->session->verify_cb
1999 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2000 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2001 err = hd->session->verify_cb (hd->session->verify_cb_value,
2003 (hd->flags | hd->session->flags),
2004 hd->session->tls_session);
2007 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2008 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2009 err = tls_callback (hd, hd->session, 0);
2011 if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
2012 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
2013 err = http_verify_server_credentials (hd->session);
2017 log_info ("TLS connection authentication failed: %s <%s>\n",
2018 gpg_strerror (err), gpg_strsource (err));
2019 xfree (proxy_authstr);
2024 #elif HTTP_USE_GNUTLS
2025 if (hd->uri->use_tls)
2029 my_socket_ref (hd->sock);
2030 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
2031 gnutls_transport_set_pull_function (hd->session->tls_session,
2033 gnutls_transport_set_push_function (hd->session->tls_session,
2039 rc = gnutls_handshake (hd->session->tls_session);
2041 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
2044 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2045 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
2047 gnutls_alert_description_t alertno;
2048 const char *alertstr;
2050 alertno = gnutls_alert_get (hd->session->tls_session);
2051 alertstr = gnutls_alert_get_name (alertno);
2052 log_info ("TLS handshake %s: %s (alert %d)\n",
2053 rc == GNUTLS_E_WARNING_ALERT_RECEIVED
2054 ? "warning" : "failed",
2055 alertstr, (int)alertno);
2056 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
2057 log_info (" (sent server name '%s')\n", server);
2059 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
2060 goto handshake_again;
2063 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
2064 xfree (proxy_authstr);
2065 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
2068 hd->session->verify.done = 0;
2070 err = tls_callback (hd, hd->session, 0);
2072 err = http_verify_server_credentials (hd->session);
2075 log_info ("TLS connection authentication failed: %s\n",
2076 gpg_strerror (err));
2077 xfree (proxy_authstr);
2081 #endif /*HTTP_USE_GNUTLS*/
2083 if (auth || hd->uri->auth)
2089 myauth = xtrystrdup (auth);
2092 xfree (proxy_authstr);
2093 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2095 remove_escapes (myauth);
2099 remove_escapes (hd->uri->auth);
2100 myauth = hd->uri->auth;
2103 authstr = make_header_line ("Authorization: Basic ", "\r\n",
2104 myauth, strlen (myauth));
2110 xfree (proxy_authstr);
2111 return gpg_err_make (default_errsource,
2112 gpg_err_code_from_syserror ());
2116 p = build_rel_path (hd->uri);
2118 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2120 if (http_proxy && *http_proxy)
2122 request = es_bsprintf
2123 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
2124 hd->req_type == HTTP_REQ_GET ? "GET" :
2125 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2126 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2127 hd->uri->use_tls? "https" : "http",
2128 httphost? httphost : server,
2129 port, *p == '/' ? "" : "/", p,
2130 authstr ? authstr : "",
2131 proxy_authstr ? proxy_authstr : "");
2137 if (port == (hd->uri->use_tls? 443 : 80))
2140 snprintf (portstr, sizeof portstr, ":%u", port);
2142 request = es_bsprintf
2143 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
2144 hd->req_type == HTTP_REQ_GET ? "GET" :
2145 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2146 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2147 *p == '/' ? "" : "/", p,
2148 httphost? httphost : server,
2150 authstr? authstr:"");
2155 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2157 xfree (proxy_authstr);
2161 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2162 log_debug_with_string (request, "http.c:request:");
2164 /* First setup estream so that we can write even the first line
2165 using estream. This is also required for the sake of gnutls. */
2169 cookie = xtrycalloc (1, sizeof *cookie);
2172 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2175 cookie->sock = my_socket_ref (hd->sock);
2176 hd->write_cookie = cookie;
2177 cookie->use_tls = hd->uri->use_tls;
2178 cookie->session = http_session_ref (hd->session);
2180 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2183 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2184 my_socket_unref (cookie->sock, NULL, NULL);
2186 hd->write_cookie = NULL;
2188 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2189 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2195 for (;headers; headers=headers->next)
2197 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2198 log_debug_with_string (headers->d, "http.c:request-header:");
2199 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2200 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2202 err = gpg_err_make (default_errsource,
2203 gpg_err_code_from_syserror ());
2213 xfree (proxy_authstr);
2220 * Build the relative path from the parsed URI. Minimal
2221 * implementation. May return NULL in case of memory failure; errno
2222 * is then set accordingly.
2225 build_rel_path (parsed_uri_t uri)
2231 /* Count the needed space. */
2232 n = insert_escapes (NULL, uri->path, "%;?&");
2233 /* TODO: build params. */
2234 for (r = uri->query; r; r = r->next)
2237 n += insert_escapes (NULL, r->name, "%;?&=");
2241 n += insert_escapes (NULL, r->value, "%;?&=");
2246 /* Now allocate and copy. */
2247 p = rel_path = xtrymalloc (n);
2250 n = insert_escapes (p, uri->path, "%;?&");
2252 /* TODO: add params. */
2253 for (r = uri->query; r; r = r->next)
2255 *p++ = r == uri->query ? '?' : '&';
2256 n = insert_escapes (p, r->name, "%;?&=");
2261 /* TODO: Use valuelen. */
2262 n = insert_escapes (p, r->value, "%;?&=");
2271 /* Transform a header name into a standard capitalized format; e.g.
2272 "Content-Type". Conversion stops at the colon. As usual we don't
2273 use the localized versions of ctype.h. */
2275 capitalize_header_name (char *name)
2279 for (; *name && *name != ':'; name++)
2285 if (*name >= 'a' && *name <= 'z')
2286 *name = *name - 'a' + 'A';
2289 else if (*name >= 'A' && *name <= 'Z')
2290 *name = *name - 'A' + 'a';
2295 /* Store an HTTP header line in LINE away. Line continuation is
2296 supported as well as merging of headers with the same name. This
2297 function may modify LINE. */
2298 static gpg_err_code_t
2299 store_header (http_t hd, char *line)
2306 if (n && line[n-1] == '\n')
2309 if (n && line[n-1] == '\r')
2312 if (!n) /* we are never called to hit this. */
2314 if (*line == ' ' || *line == '\t')
2316 /* Continuation. This won't happen too often as it is not
2317 recommended. We use a straightforward implementation. */
2319 return GPG_ERR_PROTOCOL_VIOLATION;
2320 n += strlen (hd->headers->value);
2321 p = xtrymalloc (n+1);
2323 return gpg_err_code_from_syserror ();
2324 strcpy (stpcpy (p, hd->headers->value), line);
2325 xfree (hd->headers->value);
2326 hd->headers->value = p;
2330 capitalize_header_name (line);
2331 p = strchr (line, ':');
2333 return GPG_ERR_PROTOCOL_VIOLATION;
2335 while (*p == ' ' || *p == '\t')
2339 for (h=hd->headers; h; h = h->next)
2340 if ( !strcmp (h->name, line) )
2344 /* We have already seen a line with that name. Thus we assume
2345 * it is a comma separated list and merge them. */
2346 p = strconcat (h->value, ",", value, NULL);
2348 return gpg_err_code_from_syserror ();
2354 /* Append a new header. */
2355 h = xtrymalloc (sizeof *h + strlen (line));
2357 return gpg_err_code_from_syserror ();
2358 strcpy (h->name, line);
2359 h->value = xtrymalloc (strlen (value)+1);
2363 return gpg_err_code_from_syserror ();
2365 strcpy (h->value, value);
2366 h->next = hd->headers;
2373 /* Return the header NAME from the last response. The returned value
2374 is valid as along as HD has not been closed and no other request
2375 has been send. If the header was not found, NULL is returned. NAME
2376 must be canonicalized, that is the first letter of each dash
2377 delimited part must be uppercase and all other letters lowercase. */
2379 http_get_header (http_t hd, const char *name)
2383 for (h=hd->headers; h; h = h->next)
2384 if ( !strcmp (h->name, name) )
2390 /* Return a newly allocated and NULL terminated array with pointers to
2391 header names. The array must be released with xfree() and its
2392 content is only values as long as no other request has been
2395 http_get_header_names (http_t hd)
2401 for (n=0, h = hd->headers; h; h = h->next)
2403 array = xtrycalloc (n+1, sizeof *array);
2406 for (n=0, h = hd->headers; h; h = h->next)
2407 array[n++] = h->name;
2415 * Parse the response from a server.
2416 * Returns: Errorcode and sets some files in the handle
2418 static gpg_err_code_t
2419 parse_response (http_t hd)
2421 char *line, *p, *p2;
2423 cookie_t cookie = hd->read_cookie;
2426 /* Delete old header lines. */
2429 header_t tmp = hd->headers->next;
2430 xfree (hd->headers->value);
2431 xfree (hd->headers);
2435 /* Wait for the status line. */
2438 maxlen = MAX_LINELEN;
2439 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2442 return gpg_err_code_from_syserror (); /* Out of core. */
2444 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2448 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2449 log_debug_with_string (line, "http.c:response:\n");
2453 if ((p = strchr (line, '/')))
2455 if (!p || strcmp (line, "HTTP"))
2456 return 0; /* Assume http 0.9. */
2458 if ((p2 = strpbrk (p, " \t")))
2461 p2 += strspn (p2, " \t");
2464 return 0; /* Also assume http 0.9. */
2466 /* TODO: Add HTTP version number check. */
2467 if ((p2 = strpbrk (p, " \t")))
2469 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2470 || !isdigit ((unsigned int)p[2]) || p[3])
2472 /* Malformed HTTP status code - assume http 0.9. */
2473 hd->is_http_0_9 = 1;
2474 hd->status_code = 200;
2477 hd->status_code = atoi (p);
2479 /* Skip all the header lines and wait for the empty line. */
2482 maxlen = MAX_LINELEN;
2483 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2486 return gpg_err_code_from_syserror (); /* Out of core. */
2487 /* Note, that we can silently ignore truncated lines. */
2490 /* Trim line endings of empty lines. */
2491 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2493 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2494 log_info ("http.c:RESP: '%.*s'\n",
2495 (int)strlen(line)-(*line&&line[1]?2:0),line);
2498 gpg_err_code_t ec = store_header (hd, line);
2503 while (len && *line);
2505 cookie->content_length_valid = 0;
2506 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2508 s = http_get_header (hd, "Content-Length");
2511 cookie->content_length_valid = 1;
2512 cookie->content_length = string_to_u64 (s);
2523 struct sockaddr_in mya;
2524 struct sockaddr_in peer;
2530 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2532 log_error ("socket() failed: %s\n", strerror (errno));
2536 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2537 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2539 mya.sin_family = AF_INET;
2540 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2541 mya.sin_port = htons (11371);
2543 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2545 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2552 log_error ("listen failed: %s\n", strerror (errno));
2562 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2563 continue; /* ignore any errors */
2565 if (!FD_ISSET (fd, &rfds))
2568 addrlen = sizeof peer;
2569 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2571 continue; /* oops */
2573 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2582 fp = fdopen (client, "r");
2583 while ((c = getc (fp)) != EOF)
2588 sock_close (client);
2598 /* Return true if SOCKS shall be used. This is the case if tor_mode
2599 * is enabled and the desired address is not the loopback address.
2600 * This function is basically a copy of the same internal function in
2603 use_socks (struct sockaddr_storage *addr)
2607 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2608 return 0; /* Not in Tor mode. */
2609 else if (addr->ss_family == AF_INET6)
2611 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2612 const unsigned char *s;
2615 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2617 return 1; /* Last octet is not 1 - not the loopback address. */
2618 for (i=0; i < 15; i++, s++)
2620 return 1; /* Non-zero octet found - not the loopback address. */
2622 return 0; /* This is the loopback address. */
2624 else if (addr->ss_family == AF_INET)
2626 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2628 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2629 return 0; /* Loopback (127.0.0.0/8) */
2638 /* Wrapper around assuan_sock_new which takes the domain from an
2639 * address parameter. */
2641 my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
2645 if (use_socks (addr))
2647 /* Libassaun always uses 127.0.0.1 to connect to the socks
2648 * server (i.e. the Tor daemon). */
2652 domain = addr->ss_family;
2654 return assuan_sock_new (domain, type, proto);
2658 /* Call WSAGetLastError and map it to a libgpg-error. */
2659 #ifdef HAVE_W32_SYSTEM
2661 my_wsagetlasterror (void)
2666 wsaerr = WSAGetLastError ();
2669 case WSAENOTSOCK: ec = GPG_ERR_EINVAL; break;
2670 case WSAEWOULDBLOCK: ec = GPG_ERR_EAGAIN; break;
2671 case ERROR_BROKEN_PIPE: ec = GPG_ERR_EPIPE; break;
2672 case WSANOTINITIALISED: ec = GPG_ERR_ENOSYS; break;
2673 case WSAENOBUFS: ec = GPG_ERR_ENOBUFS; break;
2674 case WSAEMSGSIZE: ec = GPG_ERR_EMSGSIZE; break;
2675 case WSAECONNREFUSED: ec = GPG_ERR_ECONNREFUSED; break;
2676 case WSAEISCONN: ec = GPG_ERR_EISCONN; break;
2677 case WSAEALREADY: ec = GPG_ERR_EALREADY; break;
2678 case WSAETIMEDOUT: ec = GPG_ERR_ETIMEDOUT; break;
2679 default: ec = GPG_ERR_EIO; break;
2682 return gpg_err_make (default_errsource, ec);
2684 #endif /*HAVE_W32_SYSTEM*/
2687 /* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
2688 * be established within TIMEOUT milliseconds. 0 indicates the
2689 * system's default timeout. The other args are the usual connect
2690 * args. On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
2691 * another error code for other errors. On timeout the caller needs
2692 * to close the socket as soon as possible to stop an ongoing
2695 * This implementation is for well-behaving systems; see Stevens,
2696 * Network Programming, 2nd edition, Vol 1, 15.4. */
2698 connect_with_timeout (assuan_fd_t sock,
2699 struct sockaddr *addr, int addrlen,
2700 unsigned int timeout)
2706 struct timeval tval;
2709 #ifndef HAVE_W32_SYSTEM
2711 # define RESTORE_BLOCKING() do { \
2712 fcntl (sock, F_SETFL, oflags); \
2714 #else /*HAVE_W32_SYSTEM*/
2715 # define RESTORE_BLOCKING() do { \
2716 unsigned long along = 0; \
2717 ioctlsocket (FD2INT (sock), FIONBIO, &along); \
2719 #endif /*HAVE_W32_SYSTEM*/
2725 if (assuan_sock_connect (sock, addr, addrlen))
2726 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2732 /* Switch the socket into non-blocking mode. */
2733 #ifdef HAVE_W32_SYSTEM
2735 unsigned long along = 1;
2736 if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
2737 return my_wsagetlasterror ();
2740 oflags = fcntl (sock, F_GETFL, 0);
2741 if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
2742 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2745 /* Do the connect. */
2746 if (!assuan_sock_connect (sock, addr, addrlen))
2748 /* Immediate connect. Restore flags. */
2749 RESTORE_BLOCKING ();
2750 return 0; /* Success. */
2752 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2753 if (gpg_err_code (err) != GPG_ERR_EINPROGRESS
2754 #ifdef HAVE_W32_SYSTEM
2755 && gpg_err_code (err) != GPG_ERR_EAGAIN
2759 RESTORE_BLOCKING ();
2764 FD_SET (FD2INT (sock), &rset);
2766 tval.tv_sec = timeout / 1000;
2767 tval.tv_usec = (timeout % 1000) * 1000;
2769 n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
2772 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2773 RESTORE_BLOCKING ();
2778 /* Timeout: We do not restore the socket flags on timeout
2779 * because the caller is expected to close the socket. */
2780 return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
2782 if (!FD_ISSET (sock, &rset) && !FD_ISSET (sock, &wset))
2784 /* select misbehaved. */
2785 return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
2788 slen = sizeof (syserr);
2789 if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
2790 (void*)&syserr, &slen) < 0)
2792 /* Assume that this is Solaris which returns the error in ERRNO. */
2793 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2796 err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
2798 err = 0; /* Connected. */
2800 RESTORE_BLOCKING ();
2804 #undef RESTORE_BLOCKING
2808 /* Actually connect to a server. On success 0 is returned and the
2809 * file descriptor for the socket is stored at R_SOCK; on error an
2810 * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
2811 * TIMEOUT is the connect timeout in milliseconds. Note that the
2812 * function tries to connect to all known addresses and the timeout is
2815 connect_server (const char *server, unsigned short port,
2816 unsigned int flags, const char *srvtag, unsigned int timeout,
2817 assuan_fd_t *r_sock)
2820 assuan_fd_t sock = ASSUAN_INVALID_FD;
2821 unsigned int srvcount = 0;
2823 int anyhostaddr = 0;
2825 gpg_error_t last_err = 0;
2826 struct srventry *serverlist = NULL;
2828 *r_sock = ASSUAN_INVALID_FD;
2830 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2834 /* Onion addresses require special treatment. */
2835 if (is_onion_address (server))
2837 #ifdef ASSUAN_SOCK_TOR
2840 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2842 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2844 if (sock == ASSUAN_INVALID_FD)
2846 err = gpg_err_make (default_errsource,
2847 (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2848 : gpg_err_code_from_syserror ());
2849 log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2853 notify_netactivity ();
2857 #else /*!ASSUAN_SOCK_TOR*/
2859 err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2860 return ASSUAN_INVALID_FD;
2862 #endif /*!HASSUAN_SOCK_TOR*/
2865 /* Do the SRV thing */
2868 err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2870 log_info ("getting '%s' SRV for '%s' failed: %s\n",
2871 srvtag, server, gpg_strerror (err));
2872 /* Note that on error SRVCOUNT is zero. */
2878 /* Either we're not using SRV, or the SRV lookup failed. Make
2879 up a fake SRV record. */
2880 serverlist = xtrycalloc (1, sizeof *serverlist);
2882 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2884 serverlist->port = port;
2885 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2886 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2891 for (srv=0; srv < srvcount && !connected; srv++)
2893 dns_addrinfo_t aibuf, ai;
2896 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2897 serverlist[srv].target, port);
2898 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2902 log_info ("resolving '%s' failed: %s\n",
2903 serverlist[srv].target, gpg_strerror (err));
2905 continue; /* Not found - try next one. */
2909 for (ai = aibuf; ai && !connected; ai = ai->next)
2911 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2913 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2916 if (sock != ASSUAN_INVALID_FD)
2917 assuan_sock_close (sock);
2918 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2919 if (sock == ASSUAN_INVALID_FD)
2921 err = gpg_err_make (default_errsource,
2922 gpg_err_code_from_syserror ());
2923 log_error ("error creating socket: %s\n", gpg_strerror (err));
2924 free_dns_addrinfo (aibuf);
2930 err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
2931 ai->addrlen, timeout);
2939 notify_netactivity ();
2942 free_dns_addrinfo (aibuf);
2950 log_error ("can't connect to '%s': %s\n",
2951 server, "host not found");
2952 else if (!anyhostaddr)
2953 log_error ("can't connect to '%s': %s\n",
2954 server, "no IP address for host");
2957 #ifdef HAVE_W32_SYSTEM
2958 log_error ("can't connect to '%s': ec=%d\n",
2959 server, (int)WSAGetLastError());
2961 log_error ("can't connect to '%s': %s\n",
2962 server, gpg_strerror (last_err));
2965 err = last_err? last_err : gpg_err_make (default_errsource,
2966 GPG_ERR_UNKNOWN_HOST);
2967 if (sock != ASSUAN_INVALID_FD)
2968 assuan_sock_close (sock);
2977 /* Helper to read from a socket. This handles npth things and
2979 static gpgrt_ssize_t
2980 read_server (assuan_fd_t sock, void *buffer, size_t size)
2986 #ifdef HAVE_W32_SYSTEM
2987 /* Under Windows we need to use recv for a socket. */
2988 # if defined(USE_NPTH)
2991 nread = recv (FD2INT (sock), buffer, size, 0);
2992 # if defined(USE_NPTH)
2996 #else /*!HAVE_W32_SYSTEM*/
2999 nread = npth_read (sock, buffer, size);
3001 nread = read (sock, buffer, size);
3004 #endif /*!HAVE_W32_SYSTEM*/
3006 while (nread == -1 && errno == EINTR);
3013 write_server (assuan_fd_t sock, const char *data, size_t length)
3021 #if defined(HAVE_W32_SYSTEM)
3022 # if defined(USE_NPTH)
3025 nwritten = send (FD2INT (sock), data, nleft, 0);
3026 # if defined(USE_NPTH)
3029 if ( nwritten == SOCKET_ERROR )
3031 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
3032 return gpg_error (GPG_ERR_NETWORK);
3034 #else /*!HAVE_W32_SYSTEM*/
3036 nwritten = npth_write (sock, data, nleft);
3038 nwritten = write (sock, data, nleft);
3044 if (errno == EAGAIN)
3050 my_select (0, NULL, NULL, NULL, &tv);
3053 log_info ("network write failed: %s\n", strerror (errno));
3054 return gpg_error_from_syserror ();
3056 #endif /*!HAVE_W32_SYSTEM*/
3066 /* Read handler for estream. */
3067 static gpgrt_ssize_t
3068 cookie_read (void *cookie, void *buffer, size_t size)
3070 cookie_t c = cookie;
3073 if (c->content_length_valid)
3075 if (!c->content_length)
3077 if (c->content_length < size)
3078 size = c->content_length;
3082 if (c->use_tls && c->session && c->session->tls_session)
3086 ntbtls_get_stream (c->session->tls_session, &in, &out);
3087 nread = es_fread (buffer, 1, size, in);
3089 log_debug ("TLS network read: %d/%zu\n", nread, size);
3092 #elif HTTP_USE_GNUTLS
3093 if (c->use_tls && c->session && c->session->tls_session)
3096 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
3099 if (nread == GNUTLS_E_INTERRUPTED)
3101 if (nread == GNUTLS_E_AGAIN)
3107 my_select (0, NULL, NULL, NULL, &tv);
3110 if (nread == GNUTLS_E_REHANDSHAKE)
3111 goto again; /* A client is allowed to just ignore this request. */
3112 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
3114 /* The server terminated the connection. Close the TLS
3115 session, and indicate EOF using a short read. */
3116 close_tls_session (c->session);
3119 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
3120 gpg_err_set_errno (EIO);
3125 #endif /*HTTP_USE_GNUTLS*/
3127 nread = read_server (c->sock->fd, buffer, size);
3130 if (c->content_length_valid && nread > 0)
3132 if (nread < c->content_length)
3133 c->content_length -= nread;
3135 c->content_length = 0;
3138 return (gpgrt_ssize_t)nread;
3141 /* Write handler for estream. */
3142 static gpgrt_ssize_t
3143 cookie_write (void *cookie, const void *buffer_arg, size_t size)
3145 const char *buffer = buffer_arg;
3146 cookie_t c = cookie;
3150 if (c->use_tls && c->session && c->session->tls_session)
3154 ntbtls_get_stream (c->session->tls_session, &in, &out);
3158 nwritten = es_fwrite (buffer, 1, size, out);
3160 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
3163 #elif HTTP_USE_GNUTLS
3164 if (c->use_tls && c->session && c->session->tls_session)
3169 nwritten = gnutls_record_send (c->session->tls_session,
3173 if (nwritten == GNUTLS_E_INTERRUPTED)
3175 if (nwritten == GNUTLS_E_AGAIN)
3181 my_select (0, NULL, NULL, NULL, &tv);
3184 log_info ("TLS network write failed: %s\n",
3185 gnutls_strerror (nwritten));
3186 gpg_err_set_errno (EIO);
3194 #endif /*HTTP_USE_GNUTLS*/
3196 if ( write_server (c->sock->fd, buffer, size) )
3198 gpg_err_set_errno (EIO);
3205 return (gpgrt_ssize_t)nwritten;
3209 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
3210 static gpgrt_ssize_t
3211 simple_cookie_read (void *cookie, void *buffer, size_t size)
3213 assuan_fd_t sock = (assuan_fd_t)cookie;
3214 return read_server (sock, buffer, size);
3217 static gpgrt_ssize_t
3218 simple_cookie_write (void *cookie, const void *buffer_arg, size_t size)
3220 assuan_fd_t sock = (assuan_fd_t)cookie;
3221 const char *buffer = buffer_arg;
3224 if (write_server (sock, buffer, size))
3226 gpg_err_set_errno (EIO);
3232 return (gpgrt_ssize_t)nwritten;
3234 #endif /*HAVE_W32_SYSTEM*/
3237 #ifdef HTTP_USE_GNUTLS
3238 /* Wrapper for gnutls_bye used by my_socket_unref. */
3240 send_gnutls_bye (void *opaque)
3242 tls_session_t tls_session = opaque;
3247 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
3248 while (ret == GNUTLS_E_INTERRUPTED);
3249 if (ret == GNUTLS_E_AGAIN)
3255 my_select (0, NULL, NULL, NULL, &tv);
3259 #endif /*HTTP_USE_GNUTLS*/
3261 /* Close handler for estream. */
3263 cookie_close (void *cookie)
3265 cookie_t c = cookie;
3271 if (c->use_tls && c->session && c->session->tls_session)
3273 /* FIXME!! Possibly call ntbtls_close_notify for close
3275 my_socket_unref (c->sock, NULL, NULL);
3278 #elif HTTP_USE_GNUTLS
3279 if (c->use_tls && c->session && c->session->tls_session)
3280 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
3282 #endif /*HTTP_USE_GNUTLS*/
3284 my_socket_unref (c->sock, NULL, NULL);
3287 http_session_unref (c->session);
3295 /* Verify the credentials of the server. Returns 0 on success and
3296 store the result in the session object. */
3298 http_verify_server_credentials (http_session_t sess)
3301 static const char errprefix[] = "TLS verification of peer failed";
3303 unsigned int status;
3304 const char *hostname;
3305 const gnutls_datum_t *certlist;
3306 unsigned int certlistlen;
3307 gnutls_x509_crt_t cert;
3308 gpg_error_t err = 0;
3310 sess->verify.done = 1;
3311 sess->verify.status = 0;
3312 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
3314 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
3316 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
3317 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
3318 return gpg_error (GPG_ERR_GENERAL);
3321 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
3324 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
3326 err = gpg_error (GPG_ERR_GENERAL);
3330 log_error ("%s: status=0x%04x\n", errprefix, status);
3331 #if GNUTLS_VERSION_NUMBER >= 0x030104
3333 gnutls_datum_t statusdat;
3335 if (!gnutls_certificate_verification_status_print
3336 (status, GNUTLS_CRT_X509, &statusdat, 0))
3338 log_info ("%s: %s\n", errprefix, statusdat.data);
3339 gnutls_free (statusdat.data);
3342 #endif /*gnutls >= 3.1.4*/
3344 sess->verify.status = status;
3346 err = gpg_error (GPG_ERR_GENERAL);
3349 hostname = sess->servername;
3350 if (!hostname || !strchr (hostname, '.'))
3352 log_error ("%s: %s\n", errprefix, "hostname missing");
3354 err = gpg_error (GPG_ERR_GENERAL);
3357 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
3360 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
3362 err = gpg_error (GPG_ERR_GENERAL);
3364 /* Need to stop here. */
3369 rc = gnutls_x509_crt_init (&cert);
3373 err = gpg_error (GPG_ERR_GENERAL);
3378 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3381 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3382 gnutls_strerror (rc));
3384 err = gpg_error (GPG_ERR_GENERAL);
3387 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3389 log_error ("%s: %s\n", errprefix, "hostname does not match");
3391 err = gpg_error (GPG_ERR_GENERAL);
3394 gnutls_x509_crt_deinit (cert);
3397 sess->verify.rc = 0;
3399 if (sess->cert_log_cb)
3401 const void *bufarr[10];
3402 size_t buflenarr[10];
3405 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3407 bufarr[n] = certlist[n].data;
3408 buflenarr[n] = certlist[n].size;
3412 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3416 #else /*!HTTP_USE_GNUTLS*/
3418 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3422 /* Return the first query variable with the specified key. If there
3423 is no such variable, return NULL. */
3424 struct uri_tuple_s *
3425 uri_query_lookup (parsed_uri_t uri, const char *key)
3427 struct uri_tuple_s *t;
3429 for (t = uri->query; t; t = t->next)
3430 if (strcmp (t->name, key) == 0)