1 /* http.c - HTTP protocol handler
2 * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
3 * 2011 Free Software Foundation, Inc.
4 * Copyright (C) 2014 Werner Koch
5 * Copyright (C) 2015-2017 g10 Code GmbH
7 * This file is part of GnuPG.
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of either
12 * - the GNU Lesser General Public License as published by the Free
13 * Software Foundation; either version 3 of the License, or (at
14 * your option) any later version.
18 * - the GNU General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at
20 * your option) any later version.
22 * or both in parallel, as here.
24 * This file is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, see <https://www.gnu.org/licenses/>.
33 /* Simple HTTP client implementation. We try to keep the code as
34 self-contained as possible. There are some contraints however:
36 - estream is required. We now require estream because it provides a
37 very useful and portable asprintf implementation and the fopencookie
40 - fixme: list other requirements.
43 - With HTTP_USE_NTBTLS or HTTP_USE_GNUTLS support for https is
44 provided (this also requires estream).
46 - With HTTP_NO_WSASTARTUP the socket initialization is not done
47 under Windows. This is useful if the socket layer has already
48 been initialized elsewhere. This also avoids the installation of
49 an exit handler to cleanup the socket layer.
63 #ifdef HAVE_W32_SYSTEM
64 # ifdef HAVE_WINSOCK2_H
65 # include <winsock2.h>
68 #else /*!HAVE_W32_SYSTEM*/
69 # include <sys/types.h>
70 # include <sys/socket.h>
71 # include <sys/time.h>
73 # include <netinet/in.h>
74 # include <arpa/inet.h>
76 #endif /*!HAVE_W32_SYSTEM*/
78 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
86 #if defined (HTTP_USE_GNUTLS) && defined (HTTP_USE_NTBTLS)
87 # error Both, HTTP_USE_GNUTLS and HTTP_USE_NTBTLS, are defined.
90 #ifdef HTTP_USE_NTBTLS
93 # include <gnutls/gnutls.h>
94 # include <gnutls/x509.h>
95 #endif /*HTTP_USE_GNUTLS*/
97 #include <assuan.h> /* We need the socket wrapper. */
101 #include "dns-stuff.h"
106 # define my_select(a,b,c,d,e) npth_select ((a), (b), (c), (d), (e))
107 # define my_accept(a,b,c) npth_accept ((a), (b), (c))
109 # define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e))
110 # define my_accept(a,b,c) accept ((a), (b), (c))
113 #ifdef HAVE_W32_SYSTEM
114 #define sock_close(a) closesocket(a)
116 #define sock_close(a) close(a)
120 #define EAGAIN EWOULDBLOCK
122 #ifndef INADDR_NONE /* Slowaris is missing that. */
123 #define INADDR_NONE ((unsigned long)(-1))
124 #endif /*INADDR_NONE*/
126 #define HTTP_PROXY_ENV "http_proxy"
127 #define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
128 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
129 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
131 "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
134 typedef ntbtls_t tls_session_t;
136 #elif HTTP_USE_GNUTLS
137 typedef gnutls_session_t tls_session_t;
140 typedef void *tls_session_t;
144 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
145 int no_scheme_check, int force_tls);
146 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
147 int no_scheme_check, int force_tls);
148 static int remove_escapes (char *string);
149 static int insert_escapes (char *buffer, const char *string,
150 const char *special);
151 static uri_tuple_t parse_tuple (char *string);
152 static gpg_error_t send_request (http_t hd, const char *httphost,
153 const char *auth,const char *proxy,
154 const char *srvtag,strlist_t headers);
155 static char *build_rel_path (parsed_uri_t uri);
156 static gpg_error_t parse_response (http_t hd);
158 static gpg_error_t connect_server (const char *server, unsigned short port,
159 unsigned int flags, const char *srvtag,
160 assuan_fd_t *r_sock);
161 static gpg_error_t write_server (int sock, const char *data, size_t length);
163 static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
164 static gpgrt_ssize_t cookie_write (void *cookie,
165 const void *buffer, size_t size);
166 static int cookie_close (void *cookie);
169 /* A socket object used to a allow ref counting of sockets. */
172 assuan_fd_t fd; /* The actual socket - shall never be ASSUAN_INVALID_FD. */
173 int refcount; /* Number of references to this socket. */
175 typedef struct my_socket_s *my_socket_t;
178 /* Cookie function structure and cookie object. */
179 static es_cookie_io_functions_t cookie_functions =
189 /* Socket object or NULL if already closed. */
192 /* The session object or NULL if not used. */
193 http_session_t session;
195 /* True if TLS is to be used. */
198 /* The remaining content length and a flag telling whether to use
199 the content length. */
200 uint64_t content_length;
201 unsigned int content_length_valid:1;
203 typedef struct cookie_s *cookie_t;
205 /* The session object. */
206 struct http_session_s
208 int refcount; /* Number of references to this object. */
209 #ifdef HTTP_USE_GNUTLS
210 gnutls_certificate_credentials_t certcred;
211 #endif /*HTTP_USE_GNUTLS*/
213 tls_session_t tls_session;
215 int done; /* Verifciation has been done. */
216 int rc; /* TLS verification return code. */
217 unsigned int status; /* Verification status. */
219 char *servername; /* Malloced server name. */
221 /* A callback function to log details of TLS certifciates. */
222 void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
223 const void **, size_t *);
227 /* An object to save header lines. */
230 struct header_s *next;
231 char *value; /* The value of the header (malloced). */
232 char name[1]; /* The name of the header (canonicalized). */
234 typedef struct header_s *header_t;
237 /* Our handle context. */
238 struct http_context_s
240 unsigned int status_code;
242 unsigned int in_data:1;
243 unsigned int is_http_0_9:1;
248 http_session_t session;
251 char *buffer; /* Line buffer. */
254 header_t headers; /* Received headers. */
258 /* Two flags to enable verbose and debug mode. Although currently not
259 * set-able a value > 1 for OPT_DEBUG enables debugging of the session
260 * reference counting. */
261 static int opt_verbose;
262 static int opt_debug;
264 /* The global callback for the verification function. */
265 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
267 /* The list of files with trusted CA certificates. */
268 static strlist_t tls_ca_certlist;
270 /* The global callback for net activity. */
271 static void (*netactivity_cb)(void);
275 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
277 #if GNUPG_MAJOR_VERSION == 1
278 #define REQ_WINSOCK_MAJOR 1
279 #define REQ_WINSOCK_MINOR 1
281 #define REQ_WINSOCK_MAJOR 2
282 #define REQ_WINSOCK_MINOR 2
287 deinit_sockets (void)
295 static int initialized;
296 static WSADATA wsdata;
301 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
303 log_error ("error initializing socket library: ec=%d\n",
304 (int)WSAGetLastError () );
307 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
308 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
310 log_error ("socket library version is %x.%x - but %d.%d needed\n",
311 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
312 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
316 atexit ( deinit_sockets );
319 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
322 /* Create a new socket object. Returns NULL and closes FD if not
323 enough memory is available. */
325 _my_socket_new (int lnr, assuan_fd_t fd)
329 so = xtrymalloc (sizeof *so);
332 int save_errno = errno;
333 assuan_sock_close (fd);
334 gpg_err_set_errno (save_errno);
340 log_debug ("http.c:%d:socket_new: object %p for fd %d created\n",
344 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
346 /* Bump up the reference counter for the socket object SO. */
348 _my_socket_ref (int lnr, my_socket_t so)
352 log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n",
353 lnr, so, so->fd, so->refcount);
356 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
359 /* Bump down the reference counter for the socket object SO. If SO
360 has no more references, close the socket and release the
363 _my_socket_unref (int lnr, my_socket_t so,
364 void (*preclose)(void*), void *preclosearg)
370 log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n",
371 lnr, so, so->fd, so->refcount);
376 preclose (preclosearg);
377 assuan_sock_close (so->fd);
382 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
385 #ifdef HTTP_USE_GNUTLS
387 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
389 my_socket_t sock = ptr;
391 return npth_read (sock->fd, buffer, size);
393 return read (sock->fd, buffer, size);
397 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
399 my_socket_t sock = ptr;
401 return npth_write (sock->fd, buffer, size);
403 return write (sock->fd, buffer, size);
406 #endif /*HTTP_USE_GNUTLS*/
411 /* This notification function is called by estream whenever stream is
412 closed. Its purpose is to mark the closing in the handle so
413 that a http_close won't accidentally close the estream. The function
414 http_close removes this notification so that it won't be called if
415 http_close was used before an es_fclose. */
417 fp_onclose_notification (estream_t stream, void *opaque)
421 if (hd->fp_read && hd->fp_read == stream)
423 else if (hd->fp_write && hd->fp_write == stream)
429 * Helper function to create an HTTP header with hex encoded data. A
430 * new buffer is returned. This buffer is the concatenation of the
431 * string PREFIX, the hex-encoded DATA of length LEN and the string
432 * SUFFIX. On error NULL is returned and ERRNO set.
435 make_header_line (const char *prefix, const char *suffix,
436 const void *data, size_t len )
438 static unsigned char bintoasc[] =
439 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
440 "abcdefghijklmnopqrstuvwxyz"
442 const unsigned char *s = data;
445 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
448 p = stpcpy (buffer, prefix);
449 for ( ; len >= 3 ; len -= 3, s += 3 )
451 *p++ = bintoasc[(s[0] >> 2) & 077];
452 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
453 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
454 *p++ = bintoasc[s[2]&077];
459 *p++ = bintoasc[(s[0] >> 2) & 077];
460 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
461 *p++ = bintoasc[((s[1]<<2)&074)];
466 *p++ = bintoasc[(s[0] >> 2) & 077];
467 *p++ = bintoasc[(s[0] <<4)&060];
479 /* Set verbosity and debug mode for this module. */
481 http_set_verbose (int verbose, int debug)
483 opt_verbose = verbose;
488 /* Register a non-standard global TLS callback function. If no
489 verification is desired a callback needs to be registered which
490 always returns NULL. */
492 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
498 /* Register a CA certificate for future use. The certificate is
499 expected to be in FNAME. PEM format is assume if FNAME has a
500 suffix of ".pem". If FNAME is NULL the list of CA files is
503 http_register_tls_ca (const char *fname)
509 free_strlist (tls_ca_certlist);
510 tls_ca_certlist = NULL;
514 /* Warn if we can't access right now, but register it anyway in
515 case it becomes accessible later */
516 if (access (fname, F_OK))
517 log_info (_("can't access '%s': %s\n"), fname,
518 gpg_strerror (gpg_error_from_syserror()));
519 sl = add_to_strlist (&tls_ca_certlist, fname);
520 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
526 /* Register a callback which is called every time the HTTP mode has
527 * made a successful connection to some server. */
529 http_register_netactivity_cb (void (*cb)(void))
535 /* Call the netactivity callback if any. */
537 notify_netactivity (void)
546 /* Free the TLS session associated with SESS, if any. */
548 close_tls_session (http_session_t sess)
550 if (sess->tls_session)
554 Possibly, ntbtls_get_transport and close those streams.
555 Somehow get SOCK to call my_socket_unref.
557 ntbtls_release (sess->tls_session);
558 # elif HTTP_USE_GNUTLS
559 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
560 my_socket_unref (sock, NULL, NULL);
561 gnutls_deinit (sess->tls_session);
563 gnutls_certificate_free_credentials (sess->certcred);
564 # endif /*HTTP_USE_GNUTLS*/
565 xfree (sess->servername);
566 sess->tls_session = NULL;
572 /* Release a session. Take care not to release it while it is being
573 used by a http context object. */
575 session_unref (int lnr, http_session_t sess)
582 log_debug ("http.c:%d:session_unref: sess %p ref now %d\n",
583 lnr, sess, sess->refcount);
588 close_tls_session (sess);
593 #define http_session_unref(a) session_unref (__LINE__, (a))
596 http_session_release (http_session_t sess)
598 http_session_unref (sess);
602 /* Create a new session object which is currently used to enable TLS
603 * support. It may eventually allow reusing existing connections.
604 * Valid values for FLAGS are:
605 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
606 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
609 http_session_new (http_session_t *r_session, const char *tls_priority,
610 const char *intended_hostname, unsigned int flags)
617 sess = xtrycalloc (1, sizeof *sess);
619 return gpg_error_from_syserror ();
624 x509_cert_t ca_chain;
627 size_t nread, nbytes;
628 struct b64state state;
635 pemname = make_filename_try (gnupg_datadir (),
636 "sks-keyservers.netCA.pem", NULL);
639 err = gpg_error_from_syserror ();
640 log_error ("setting CA from file '%s' failed: %s\n",
641 pemname, gpg_strerror (err));
645 fp = es_fopen (pemname, "r");
648 err = gpg_error_from_syserror ();
649 log_error ("can't open '%s': %s\n", pemname, gpg_strerror (err));
655 mem_p = es_fopenmem (0, "r+b");
656 err = b64dec_start (&state, "CERTIFICATE");
659 log_error ("b64dec failure: %s\n", gpg_strerror (err));
663 while ( (nread = es_fread (line, 1, DIM (line), fp)) )
665 err = b64dec_proc (&state, line, nread, &nbytes);
668 if (gpg_err_code (err) == GPG_ERR_EOF)
671 log_error ("b64dec failure: %s\n", gpg_strerror (err));
677 es_fwrite (line, 1, nbytes, mem_p);
679 err = b64dec_finish (&state);
682 log_error ("b64dec failure: %s\n", gpg_strerror (err));
688 es_fclose_snatch (mem_p, &buf, &buflen);
691 err = ntbtls_x509_cert_new (&ca_chain);
694 log_error ("ntbtls_x509_new failed: %s\n", gpg_strerror (err));
699 err = ntbtls_x509_append_cert (ca_chain, buf, buflen);
702 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
705 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
706 ntbtls_x509_cert_release (ca_chain);
710 err = ntbtls_set_ca_chain (sess->tls_session, ca_chain, NULL);
712 #elif HTTP_USE_GNUTLS
717 int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS);
720 rc = gnutls_certificate_allocate_credentials (&sess->certcred);
723 log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
724 gnutls_strerror (rc));
725 err = gpg_error (GPG_ERR_GENERAL);
729 is_hkps_pool = (intended_hostname
730 && !ascii_strcasecmp (intended_hostname,
731 "hkps.pool.sks-keyservers.net"));
733 /* If the user has not specified a CA list, and they are looking
734 * for the hkps pool from sks-keyservers.net, then default to
735 * Kristian's certificate authority: */
736 if (!tls_ca_certlist && is_hkps_pool)
738 char *pemname = make_filename_try (gnupg_datadir (),
739 "sks-keyservers.netCA.pem", NULL);
742 err = gpg_error_from_syserror ();
743 log_error ("setting CA from file '%s' failed: %s\n",
744 pemname, gpg_strerror (err));
748 rc = gnutls_certificate_set_x509_trust_file
749 (sess->certcred, pemname, GNUTLS_X509_FMT_PEM);
751 log_info ("setting CA from file '%s' failed: %s\n",
752 pemname, gnutls_strerror (rc));
757 /* Add configured certificates to the session. */
758 if ((flags & HTTP_FLAG_TRUST_DEF))
760 for (sl = tls_ca_certlist; sl; sl = sl->next)
762 rc = gnutls_certificate_set_x509_trust_file
763 (sess->certcred, sl->d,
764 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
766 log_info ("setting CA from file '%s' failed: %s\n",
767 sl->d, gnutls_strerror (rc));
769 if (!tls_ca_certlist && !is_hkps_pool)
773 /* Add system certificates to the session. */
776 #if GNUTLS_VERSION_NUMBER >= 0x030014
779 rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
781 log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
785 log_info ("number of system provided CAs: %d\n", rc);
787 #endif /* gnutls >= 3.0.20 */
790 rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
793 log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
794 err = gpg_error (GPG_ERR_GENERAL);
797 /* A new session has the transport ptr set to (void*(-1), we need
799 gnutls_transport_set_ptr (sess->tls_session, NULL);
801 rc = gnutls_priority_set_direct (sess->tls_session,
802 tls_priority? tls_priority : "NORMAL",
806 log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
807 errpos, gnutls_strerror (rc));
808 err = gpg_error (GPG_ERR_GENERAL);
812 rc = gnutls_credentials_set (sess->tls_session,
813 GNUTLS_CRD_CERTIFICATE, sess->certcred);
816 log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
817 err = gpg_error (GPG_ERR_GENERAL);
821 #else /*!HTTP_USE_GNUTLS*/
825 #endif /*!HTTP_USE_GNUTLS*/
828 log_debug ("http.c:session_new: sess %p created\n", sess);
835 http_session_unref (sess);
843 /* Increment the reference count for session SESS. Passing NULL for
846 http_session_ref (http_session_t sess)
852 log_debug ("http.c:session_ref: sess %p ref now %d\n",
853 sess, sess->refcount);
860 http_session_set_log_cb (http_session_t sess,
861 void (*cb)(http_session_t, gpg_error_t,
862 const char *hostname,
863 const void **certs, size_t *certlens))
865 sess->cert_log_cb = cb;
871 /* Start a HTTP retrieval and on success store at R_HD a context
872 pointer for completing the request and to wait for the response.
873 If HTTPHOST is not NULL it is used for the Host header instead of a
874 Host header derived from the URL. */
876 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
877 const char *httphost,
878 const char *auth, unsigned int flags, const char *proxy,
879 http_session_t session, const char *srvtag, strlist_t headers)
886 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
887 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
889 /* Create the handle. */
890 hd = xtrycalloc (1, sizeof *hd);
892 return gpg_error_from_syserror ();
893 hd->req_type = reqtype;
895 hd->session = http_session_ref (session);
897 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
899 err = send_request (hd, httphost, auth, proxy, srvtag, headers);
903 my_socket_unref (hd->sock, NULL, NULL);
905 es_fclose (hd->fp_read);
907 es_fclose (hd->fp_write);
908 http_session_unref (hd->session);
917 /* This function is useful to connect to a generic TCP service using
918 this http abstraction layer. This has the advantage of providing
919 service tags and an estream interface. */
921 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
922 unsigned int flags, const char *srvtag)
930 if ((flags & HTTP_FLAG_FORCE_TOR))
934 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
936 log_error ("Tor support is not available\n");
937 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
941 /* Create the handle. */
942 hd = xtrycalloc (1, sizeof *hd);
944 return gpg_error_from_syserror ();
945 hd->req_type = HTTP_REQ_OPAQUE;
952 err = connect_server (server, port, hd->flags, srvtag, &sock);
958 hd->sock = my_socket_new (sock);
961 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
967 /* Setup estreams for reading and writing. */
968 cookie = xtrycalloc (1, sizeof *cookie);
971 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
974 cookie->sock = my_socket_ref (hd->sock);
975 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
978 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
979 my_socket_unref (cookie->sock, NULL, NULL);
983 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
985 cookie = xtrycalloc (1, sizeof *cookie);
988 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
991 cookie->sock = my_socket_ref (hd->sock);
992 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
995 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
996 my_socket_unref (cookie->sock, NULL, NULL);
1000 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1002 /* Register close notification to interlock the use of es_fclose in
1003 http_close and in user code. */
1004 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1006 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1012 es_fclose (hd->fp_read);
1014 es_fclose (hd->fp_write);
1015 my_socket_unref (hd->sock, NULL, NULL);
1027 http_start_data (http_t hd)
1031 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1032 log_debug_with_string ("\r\n", "http.c:request-header:");
1033 es_fputs ("\r\n", hd->fp_write);
1034 es_fflush (hd->fp_write);
1038 es_fflush (hd->fp_write);
1043 http_wait_response (http_t hd)
1048 /* Make sure that we are in the data. */
1049 http_start_data (hd);
1051 /* Close the write stream. Note that the reference counted socket
1052 object keeps the actual system socket open. */
1053 cookie = hd->write_cookie;
1055 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1057 es_fclose (hd->fp_write);
1058 hd->fp_write = NULL;
1059 /* The close has released the cookie and thus we better set it to NULL. */
1060 hd->write_cookie = NULL;
1062 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1063 is not required but some very old servers (e.g. the original pksd
1064 keyserver didn't worked without it. */
1065 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1066 shutdown (hd->sock->fd, 1);
1069 /* Create a new cookie and a stream for reading. */
1070 cookie = xtrycalloc (1, sizeof *cookie);
1072 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1073 cookie->sock = my_socket_ref (hd->sock);
1074 cookie->session = http_session_ref (hd->session);
1075 cookie->use_tls = hd->uri->use_tls;
1077 hd->read_cookie = cookie;
1078 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1081 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1082 my_socket_unref (cookie->sock, NULL, NULL);
1083 http_session_unref (cookie->session);
1085 hd->read_cookie = NULL;
1089 err = parse_response (hd);
1092 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1098 /* Convenience function to send a request and wait for the response.
1099 Closes the handle on error. If PROXY is not NULL, this value will
1100 be used as an HTTP proxy and any enabled $http_proxy gets
1103 http_open_document (http_t *r_hd, const char *document,
1104 const char *auth, unsigned int flags, const char *proxy,
1105 http_session_t session,
1106 const char *srvtag, strlist_t headers)
1110 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1111 proxy, session, srvtag, headers);
1115 err = http_wait_response (*r_hd);
1117 http_close (*r_hd, 0);
1124 http_close (http_t hd, int keep_read_stream)
1129 /* First remove the close notifications for the streams. */
1131 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1133 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1135 /* Now we can close the streams. */
1136 my_socket_unref (hd->sock, NULL, NULL);
1137 if (hd->fp_read && !keep_read_stream)
1138 es_fclose (hd->fp_read);
1140 es_fclose (hd->fp_write);
1141 http_session_unref (hd->session);
1142 http_release_parsed_uri (hd->uri);
1145 header_t tmp = hd->headers->next;
1146 xfree (hd->headers->value);
1147 xfree (hd->headers);
1156 http_get_read_ptr (http_t hd)
1158 return hd?hd->fp_read:NULL;
1162 http_get_write_ptr (http_t hd)
1164 return hd?hd->fp_write:NULL;
1168 http_get_status_code (http_t hd)
1170 return hd?hd->status_code:0;
1173 /* Return information pertaining to TLS. If TLS is not in use for HD,
1174 NULL is returned. WHAT is used ask for specific information:
1176 (NULL) := Only check whether TLS is is use. Returns an
1177 unspecified string if TLS is in use. That string may
1178 even be the empty string.
1181 http_get_tls_info (http_t hd, const char *what)
1188 return hd->uri->use_tls? "":NULL;
1194 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1195 int no_scheme_check, int force_tls)
1199 *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1201 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1202 strcpy ((*ret_uri)->buffer, uri);
1203 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1209 return gpg_err_make (default_errsource, ec);
1214 * Parse an URI and put the result into the newly allocated RET_URI.
1215 * On success the caller must use http_release_parsed_uri() to
1216 * releases the resources. If NO_SCHEME_CHECK is set, the function
1217 * tries to parse the URL in the same way it would do for an HTTP
1221 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1222 int no_scheme_check)
1224 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1229 http_release_parsed_uri (parsed_uri_t uri)
1235 for (r = uri->query; r; r = r2)
1245 static gpg_err_code_t
1246 do_parse_uri (parsed_uri_t uri, int only_local_part,
1247 int no_scheme_check, int force_tls)
1250 char *p, *p2, *p3, *pp;
1254 n = strlen (uri->buffer);
1256 /* Initialize all fields to an empty string or an empty list. */
1257 uri->scheme = uri->host = uri->path = p + n;
1259 uri->params = uri->query = NULL;
1265 uri->explicit_port = 0;
1267 /* A quick validity check. */
1268 if (strspn (p, VALID_URI_CHARS) != n)
1269 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1271 if (!only_local_part)
1273 /* Find the scheme. */
1274 if (!(p2 = strchr (p, ':')) || p2 == p)
1275 return GPG_ERR_BAD_URI; /* No scheme. */
1277 for (pp=p; *pp; pp++)
1278 *pp = tolower (*(unsigned char*)pp);
1280 if (!strcmp (uri->scheme, "http") && !force_tls)
1285 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1291 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1292 || (force_tls && (!strcmp (uri->scheme, "http")
1293 || !strcmp (uri->scheme,"hkp"))))
1300 else if (!no_scheme_check)
1301 return GPG_ERR_INV_URI; /* Unsupported scheme */
1305 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1308 if ((p2 = strchr (p, '/')))
1311 /* Check for username/password encoding */
1312 if ((p3 = strchr (p, '@')))
1319 for (pp=p; *pp; pp++)
1320 *pp = tolower (*(unsigned char*)pp);
1322 /* Handle an IPv6 literal */
1323 if( *p == '[' && (p3=strchr( p, ']' )) )
1326 /* worst case, uri->host should have length 0, points to \0 */
1334 if ((p3 = strchr (p, ':')))
1337 uri->port = atoi (p3);
1338 uri->explicit_port = 1;
1341 if ((n = remove_escapes (uri->host)) < 0)
1342 return GPG_ERR_BAD_URI;
1343 if (n != strlen (uri->host))
1344 return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */
1347 else if (uri->is_http)
1348 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1353 if (is_onion_address (uri->path))
1358 } /* End global URI part. */
1360 /* Parse the pathname part if any. */
1363 /* TODO: Here we have to check params. */
1365 /* Do we have a query part? */
1366 if ((p2 = strchr (p, '?')))
1370 if ((n = remove_escapes (p)) < 0)
1371 return GPG_ERR_BAD_URI;
1372 if (n != strlen (p))
1373 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1376 /* Parse a query string if any. */
1384 if ((p2 = strchr (p, '&')))
1386 if (!(elem = parse_tuple (p)))
1387 return GPG_ERR_BAD_URI;
1398 if (is_onion_address (uri->host))
1406 * Remove all %xx escapes; this is done in-place. Returns: New length
1410 remove_escapes (char *string)
1413 unsigned char *p, *s;
1415 for (p = s = (unsigned char*)string; *s; s++)
1419 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1422 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1423 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1426 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1427 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1440 return -1; /* Bad URI. */
1449 *p = 0; /* Make sure to keep a string terminator. */
1454 /* If SPECIAL is NULL this function escapes in forms mode. */
1456 escape_data (char *buffer, const void *data, size_t datalen,
1457 const char *special)
1459 int forms = !special;
1460 const unsigned char *s;
1466 for (s = data; datalen; s++, datalen--)
1468 if (forms && *s == ' ')
1474 else if (forms && *s == '\n')
1477 memcpy (buffer, "%0D%0A", 6);
1480 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1483 memcpy (buffer, "%0D%0A", 6);
1488 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1491 *(unsigned char*)buffer++ = *s;
1498 snprintf (buffer, 4, "%%%02X", *s);
1509 insert_escapes (char *buffer, const char *string,
1510 const char *special)
1512 return escape_data (buffer, string, strlen (string), special);
1516 /* Allocate a new string from STRING using standard HTTP escaping as
1517 well as escaping of characters given in SPECIALS. A common pattern
1518 for SPECIALS is "%;?&=". However it depends on the needs, for
1519 example "+" and "/: often needs to be escaped too. Returns NULL on
1520 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1521 encoding mode is used. */
1523 http_escape_string (const char *string, const char *specials)
1528 n = insert_escapes (NULL, string, specials);
1529 buf = xtrymalloc (n+1);
1532 insert_escapes (buf, string, specials);
1538 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1539 escaping as well as escaping of characters given in SPECIALS. A
1540 common pattern for SPECIALS is "%;?&=". However it depends on the
1541 needs, for example "+" and "/: often needs to be escaped too.
1542 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1543 dedicated forms encoding mode is used. */
1545 http_escape_data (const void *data, size_t datalen, const char *specials)
1550 n = escape_data (NULL, data, datalen, specials);
1551 buf = xtrymalloc (n+1);
1554 escape_data (buf, data, datalen, specials);
1562 parse_tuple (char *string)
1569 if ((p2 = strchr (p, '=')))
1571 if ((n = remove_escapes (p)) < 0)
1572 return NULL; /* Bad URI. */
1573 if (n != strlen (p))
1574 return NULL; /* Name with a Nul in it. */
1575 tuple = xtrycalloc (1, sizeof *tuple);
1577 return NULL; /* Out of core. */
1579 if (!p2) /* We have only the name, so we assume an empty value string. */
1581 tuple->value = p + strlen (p);
1582 tuple->valuelen = 0;
1583 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1585 else /* Name and value. */
1587 if ((n = remove_escapes (p2)) < 0)
1590 return NULL; /* Bad URI. */
1593 tuple->valuelen = n;
1599 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1601 is_hostname_port (const char *string)
1605 if (!string || !*string)
1607 for (; *string; string++)
1617 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1618 return 0; /* Invalid characters in hostname. */
1619 else if (colons && !digitp (string))
1620 return 0; /* Not a digit in the port. */
1627 * Send a HTTP request to the server
1628 * Returns 0 if the request was successful
1631 send_request (http_t hd, const char *httphost, const char *auth,
1632 const char *proxy, const char *srvtag, strlist_t headers)
1637 unsigned short port;
1638 const char *http_proxy = NULL;
1639 char *proxy_authstr = NULL;
1640 char *authstr = NULL;
1643 if (hd->uri->use_tls && !hd->session)
1645 log_error ("TLS requested but no session object provided\n");
1646 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1649 if (hd->uri->use_tls && !hd->session->tls_session)
1651 log_error ("TLS requested but no GNUTLS context available\n");
1652 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1656 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1660 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1662 log_error ("Tor support is not available\n");
1663 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1667 server = *hd->uri->host ? hd->uri->host : "localhost";
1668 port = hd->uri->port ? hd->uri->port : 80;
1670 /* Try to use SNI. */
1672 if (hd->uri->use_tls)
1674 # if HTTP_USE_GNUTLS
1678 xfree (hd->session->servername);
1679 hd->session->servername = xtrystrdup (httphost? httphost : server);
1680 if (!hd->session->servername)
1682 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1686 # if HTTP_USE_NTBTLS
1687 err = ntbtls_set_hostname (hd->session->tls_session,
1688 hd->session->servername);
1691 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1694 # elif HTTP_USE_GNUTLS
1695 rc = gnutls_server_name_set (hd->session->tls_session,
1697 hd->session->servername,
1698 strlen (hd->session->servername));
1700 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1701 # endif /*HTTP_USE_GNUTLS*/
1705 if ( (proxy && *proxy)
1706 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1707 && (http_proxy = getenv (HTTP_PROXY_ENV))
1715 err = parse_uri (&uri, http_proxy, 0, 0);
1716 if (gpg_err_code (err) == GPG_ERR_INV_URI
1717 && is_hostname_port (http_proxy))
1719 /* Retry assuming a "hostname:port" string. */
1720 char *tmpname = strconcat ("http://", http_proxy, NULL);
1721 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1728 else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1730 else if (!strcmp (uri->scheme, "socks5h"))
1731 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1733 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1737 log_error ("invalid HTTP proxy (%s): %s\n",
1738 http_proxy, gpg_strerror (err));
1739 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1744 remove_escapes (uri->auth);
1745 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1747 uri->auth, strlen(uri->auth));
1750 err = gpg_err_make (default_errsource,
1751 gpg_err_code_from_syserror ());
1752 http_release_parsed_uri (uri);
1757 err = connect_server (*uri->host ? uri->host : "localhost",
1758 uri->port ? uri->port : 80,
1759 hd->flags, srvtag, &sock);
1760 http_release_parsed_uri (uri);
1764 err = connect_server (server, port, hd->flags, srvtag, &sock);
1769 xfree (proxy_authstr);
1772 hd->sock = my_socket_new (sock);
1775 xfree (proxy_authstr);
1776 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1781 if (hd->uri->use_tls)
1785 my_socket_ref (hd->sock);
1787 in = es_fdopen_nc (hd->sock->fd, "rb");
1790 err = gpg_error_from_syserror ();
1791 xfree (proxy_authstr);
1795 out = es_fdopen_nc (hd->sock->fd, "wb");
1798 err = gpg_error_from_syserror ();
1800 xfree (proxy_authstr);
1804 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1807 log_info ("TLS set_transport failed: %s <%s>\n",
1808 gpg_strerror (err), gpg_strsource (err));
1809 xfree (proxy_authstr);
1813 while ((err = ntbtls_handshake (hd->session->tls_session)))
1818 log_info ("TLS handshake failed: %s <%s>\n",
1819 gpg_strerror (err), gpg_strsource (err));
1820 xfree (proxy_authstr);
1825 hd->session->verify.done = 0;
1827 err = tls_callback (hd, hd->session, 0);
1829 err = http_verify_server_credentials (hd->session);
1832 log_info ("TLS connection authentication failed: %s <%s>\n",
1833 gpg_strerror (err), gpg_strsource (err));
1834 xfree (proxy_authstr);
1838 #elif HTTP_USE_GNUTLS
1839 if (hd->uri->use_tls)
1843 my_socket_ref (hd->sock);
1844 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1845 gnutls_transport_set_pull_function (hd->session->tls_session,
1847 gnutls_transport_set_push_function (hd->session->tls_session,
1853 rc = gnutls_handshake (hd->session->tls_session);
1855 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1858 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1859 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1861 gnutls_alert_description_t alertno;
1862 const char *alertstr;
1864 alertno = gnutls_alert_get (hd->session->tls_session);
1865 alertstr = gnutls_alert_get_name (alertno);
1866 log_info ("TLS handshake %s: %s (alert %d)\n",
1867 rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1868 ? "warning" : "failed",
1869 alertstr, (int)alertno);
1870 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1871 log_info (" (sent server name '%s')\n", server);
1873 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
1874 goto handshake_again;
1877 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1878 xfree (proxy_authstr);
1879 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1882 hd->session->verify.done = 0;
1884 err = tls_callback (hd, hd->session, 0);
1886 err = http_verify_server_credentials (hd->session);
1889 log_info ("TLS connection authentication failed: %s\n",
1890 gpg_strerror (err));
1891 xfree (proxy_authstr);
1895 #endif /*HTTP_USE_GNUTLS*/
1897 if (auth || hd->uri->auth)
1903 myauth = xtrystrdup (auth);
1906 xfree (proxy_authstr);
1907 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1909 remove_escapes (myauth);
1913 remove_escapes (hd->uri->auth);
1914 myauth = hd->uri->auth;
1917 authstr = make_header_line ("Authorization: Basic ", "\r\n",
1918 myauth, strlen (myauth));
1924 xfree (proxy_authstr);
1925 return gpg_err_make (default_errsource,
1926 gpg_err_code_from_syserror ());
1930 p = build_rel_path (hd->uri);
1932 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1934 if (http_proxy && *http_proxy)
1936 request = es_bsprintf
1937 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1938 hd->req_type == HTTP_REQ_GET ? "GET" :
1939 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1940 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1941 hd->uri->use_tls? "https" : "http",
1942 httphost? httphost : server,
1943 port, *p == '/' ? "" : "/", p,
1944 authstr ? authstr : "",
1945 proxy_authstr ? proxy_authstr : "");
1954 snprintf (portstr, sizeof portstr, ":%u", port);
1956 request = es_bsprintf
1957 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1958 hd->req_type == HTTP_REQ_GET ? "GET" :
1959 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1960 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1961 *p == '/' ? "" : "/", p,
1962 httphost? httphost : server,
1964 authstr? authstr:"");
1969 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1971 xfree (proxy_authstr);
1975 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1976 log_debug_with_string (request, "http.c:request:");
1978 /* First setup estream so that we can write even the first line
1979 using estream. This is also required for the sake of gnutls. */
1983 cookie = xtrycalloc (1, sizeof *cookie);
1986 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1989 cookie->sock = my_socket_ref (hd->sock);
1990 hd->write_cookie = cookie;
1991 cookie->use_tls = hd->uri->use_tls;
1992 cookie->session = http_session_ref (hd->session);
1994 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1997 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1998 my_socket_unref (cookie->sock, NULL, NULL);
2000 hd->write_cookie = NULL;
2002 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2003 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2009 for (;headers; headers=headers->next)
2011 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2012 log_debug_with_string (headers->d, "http.c:request-header:");
2013 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2014 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2016 err = gpg_err_make (default_errsource,
2017 gpg_err_code_from_syserror ());
2027 xfree (proxy_authstr);
2034 * Build the relative path from the parsed URI. Minimal
2035 * implementation. May return NULL in case of memory failure; errno
2036 * is then set accordingly.
2039 build_rel_path (parsed_uri_t uri)
2045 /* Count the needed space. */
2046 n = insert_escapes (NULL, uri->path, "%;?&");
2047 /* TODO: build params. */
2048 for (r = uri->query; r; r = r->next)
2051 n += insert_escapes (NULL, r->name, "%;?&=");
2055 n += insert_escapes (NULL, r->value, "%;?&=");
2060 /* Now allocate and copy. */
2061 p = rel_path = xtrymalloc (n);
2064 n = insert_escapes (p, uri->path, "%;?&");
2066 /* TODO: add params. */
2067 for (r = uri->query; r; r = r->next)
2069 *p++ = r == uri->query ? '?' : '&';
2070 n = insert_escapes (p, r->name, "%;?&=");
2075 /* TODO: Use valuelen. */
2076 n = insert_escapes (p, r->value, "%;?&=");
2085 /* Transform a header name into a standard capitalized format; e.g.
2086 "Content-Type". Conversion stops at the colon. As usual we don't
2087 use the localized versions of ctype.h. */
2089 capitalize_header_name (char *name)
2093 for (; *name && *name != ':'; name++)
2099 if (*name >= 'a' && *name <= 'z')
2100 *name = *name - 'a' + 'A';
2103 else if (*name >= 'A' && *name <= 'Z')
2104 *name = *name - 'A' + 'a';
2109 /* Store an HTTP header line in LINE away. Line continuation is
2110 supported as well as merging of headers with the same name. This
2111 function may modify LINE. */
2112 static gpg_err_code_t
2113 store_header (http_t hd, char *line)
2120 if (n && line[n-1] == '\n')
2123 if (n && line[n-1] == '\r')
2126 if (!n) /* we are never called to hit this. */
2128 if (*line == ' ' || *line == '\t')
2130 /* Continuation. This won't happen too often as it is not
2131 recommended. We use a straightforward implementaion. */
2133 return GPG_ERR_PROTOCOL_VIOLATION;
2134 n += strlen (hd->headers->value);
2135 p = xtrymalloc (n+1);
2137 return gpg_err_code_from_syserror ();
2138 strcpy (stpcpy (p, hd->headers->value), line);
2139 xfree (hd->headers->value);
2140 hd->headers->value = p;
2144 capitalize_header_name (line);
2145 p = strchr (line, ':');
2147 return GPG_ERR_PROTOCOL_VIOLATION;
2149 while (*p == ' ' || *p == '\t')
2153 for (h=hd->headers; h; h = h->next)
2154 if ( !strcmp (h->name, line) )
2158 /* We have already seen a line with that name. Thus we assume
2159 it is a comma separated list and merge them. */
2160 p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
2162 return gpg_err_code_from_syserror ();
2163 strcpy (stpcpy (stpcpy (p, h->value), ","), value);
2169 /* Append a new header. */
2170 h = xtrymalloc (sizeof *h + strlen (line));
2172 return gpg_err_code_from_syserror ();
2173 strcpy (h->name, line);
2174 h->value = xtrymalloc (strlen (value)+1);
2178 return gpg_err_code_from_syserror ();
2180 strcpy (h->value, value);
2181 h->next = hd->headers;
2188 /* Return the header NAME from the last response. The returned value
2189 is valid as along as HD has not been closed and no other request
2190 has been send. If the header was not found, NULL is returned. NAME
2191 must be canonicalized, that is the first letter of each dash
2192 delimited part must be uppercase and all other letters lowercase. */
2194 http_get_header (http_t hd, const char *name)
2198 for (h=hd->headers; h; h = h->next)
2199 if ( !strcmp (h->name, name) )
2205 /* Return a newly allocated and NULL terminated array with pointers to
2206 header names. The array must be released with xfree() and its
2207 content is only values as long as no other request has been
2210 http_get_header_names (http_t hd)
2216 for (n=0, h = hd->headers; h; h = h->next)
2218 array = xtrycalloc (n+1, sizeof *array);
2221 for (n=0, h = hd->headers; h; h = h->next)
2222 array[n++] = h->name;
2230 * Parse the response from a server.
2231 * Returns: Errorcode and sets some files in the handle
2233 static gpg_err_code_t
2234 parse_response (http_t hd)
2236 char *line, *p, *p2;
2238 cookie_t cookie = hd->read_cookie;
2241 /* Delete old header lines. */
2244 header_t tmp = hd->headers->next;
2245 xfree (hd->headers->value);
2246 xfree (hd->headers);
2250 /* Wait for the status line. */
2253 maxlen = MAX_LINELEN;
2254 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2257 return gpg_err_code_from_syserror (); /* Out of core. */
2259 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2263 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2264 log_debug_with_string (line, "http.c:response:\n");
2268 if ((p = strchr (line, '/')))
2270 if (!p || strcmp (line, "HTTP"))
2271 return 0; /* Assume http 0.9. */
2273 if ((p2 = strpbrk (p, " \t")))
2276 p2 += strspn (p2, " \t");
2279 return 0; /* Also assume http 0.9. */
2281 /* TODO: Add HTTP version number check. */
2282 if ((p2 = strpbrk (p, " \t")))
2284 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2285 || !isdigit ((unsigned int)p[2]) || p[3])
2287 /* Malformed HTTP status code - assume http 0.9. */
2288 hd->is_http_0_9 = 1;
2289 hd->status_code = 200;
2292 hd->status_code = atoi (p);
2294 /* Skip all the header lines and wait for the empty line. */
2297 maxlen = MAX_LINELEN;
2298 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2301 return gpg_err_code_from_syserror (); /* Out of core. */
2302 /* Note, that we can silently ignore truncated lines. */
2305 /* Trim line endings of empty lines. */
2306 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2308 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2309 log_info ("http.c:RESP: '%.*s'\n",
2310 (int)strlen(line)-(*line&&line[1]?2:0),line);
2313 gpg_err_code_t ec = store_header (hd, line);
2318 while (len && *line);
2320 cookie->content_length_valid = 0;
2321 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2323 s = http_get_header (hd, "Content-Length");
2326 cookie->content_length_valid = 1;
2327 cookie->content_length = string_to_u64 (s);
2338 struct sockaddr_in mya;
2339 struct sockaddr_in peer;
2345 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2347 log_error ("socket() failed: %s\n", strerror (errno));
2351 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2352 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2354 mya.sin_family = AF_INET;
2355 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2356 mya.sin_port = htons (11371);
2358 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2360 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2367 log_error ("listen failed: %s\n", strerror (errno));
2377 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2378 continue; /* ignore any errors */
2380 if (!FD_ISSET (fd, &rfds))
2383 addrlen = sizeof peer;
2384 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2386 continue; /* oops */
2388 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2397 fp = fdopen (client, "r");
2398 while ((c = getc (fp)) != EOF)
2403 sock_close (client);
2413 /* Return true if SOCKS shall be used. This is the case if tor_mode
2414 * is enabled and the desired address is not the loopback address.
2415 * This function is basically a copy of the same internal fucntion in
2418 use_socks (struct sockaddr *addr)
2422 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2423 return 0; /* Not in Tor mode. */
2424 else if (addr->sa_family == AF_INET6)
2426 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2427 const unsigned char *s;
2430 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2432 return 1; /* Last octet is not 1 - not the loopback address. */
2433 for (i=0; i < 15; i++, s++)
2435 return 1; /* Non-zero octet found - not the loopback address. */
2437 return 0; /* This is the loopback address. */
2439 else if (addr->sa_family == AF_INET)
2441 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2443 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2444 return 0; /* Loopback (127.0.0.0/8) */
2453 /* Wrapper around assuan_sock_new which takes the domain from an
2454 * address parameter. */
2456 my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
2460 if (use_socks (addr))
2462 /* Libassaun always uses 127.0.0.1 to connect to the socks
2463 * server (i.e. the Tor daemon). */
2467 domain = addr->sa_family;
2469 return assuan_sock_new (domain, type, proto);
2473 /* Actually connect to a server. On success 0 is returned and the
2474 * file descriptor for the socket is stored at R_SOCK; on error an
2475 * error code is returned and ASSUAN_INVALID_FD is stored at
2478 connect_server (const char *server, unsigned short port,
2479 unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
2482 assuan_fd_t sock = ASSUAN_INVALID_FD;
2483 unsigned int srvcount = 0;
2485 int anyhostaddr = 0;
2487 gpg_error_t last_err = 0;
2488 struct srventry *serverlist = NULL;
2490 *r_sock = ASSUAN_INVALID_FD;
2492 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2496 /* Onion addresses require special treatment. */
2497 if (is_onion_address (server))
2499 #ifdef ASSUAN_SOCK_TOR
2502 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2504 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2506 if (sock == ASSUAN_INVALID_FD)
2508 err = gpg_err_make (default_errsource,
2509 (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2510 : gpg_err_code_from_syserror ());
2511 log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2515 notify_netactivity ();
2519 #else /*!ASSUAN_SOCK_TOR*/
2521 err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2522 return ASSUAN_INVALID_FD;
2524 #endif /*!HASSUAN_SOCK_TOR*/
2527 /* Do the SRV thing */
2530 err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2532 log_info ("getting '%s' SRV for '%s' failed: %s\n",
2533 srvtag, server, gpg_strerror (err));
2534 /* Note that on error SRVCOUNT is zero. */
2540 /* Either we're not using SRV, or the SRV lookup failed. Make
2541 up a fake SRV record. */
2542 serverlist = xtrycalloc (1, sizeof *serverlist);
2544 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2546 serverlist->port = port;
2547 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2548 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2553 for (srv=0; srv < srvcount && !connected; srv++)
2555 dns_addrinfo_t aibuf, ai;
2558 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2559 serverlist[srv].target, port);
2560 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2564 log_info ("resolving '%s' failed: %s\n",
2565 serverlist[srv].target, gpg_strerror (err));
2567 continue; /* Not found - try next one. */
2571 for (ai = aibuf; ai && !connected; ai = ai->next)
2573 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2575 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2578 if (sock != ASSUAN_INVALID_FD)
2579 assuan_sock_close (sock);
2580 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2581 if (sock == ASSUAN_INVALID_FD)
2583 err = gpg_err_make (default_errsource,
2584 gpg_err_code_from_syserror ());
2585 log_error ("error creating socket: %s\n", gpg_strerror (err));
2586 free_dns_addrinfo (aibuf);
2592 if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
2594 last_err = gpg_err_make (default_errsource,
2595 gpg_err_code_from_syserror ());
2600 notify_netactivity ();
2603 free_dns_addrinfo (aibuf);
2611 log_error ("can't connect to '%s': %s\n",
2612 server, "host not found");
2613 else if (!anyhostaddr)
2614 log_error ("can't connect to '%s': %s\n",
2615 server, "no IP address for host");
2618 #ifdef HAVE_W32_SYSTEM
2619 log_error ("can't connect to '%s': ec=%d\n",
2620 server, (int)WSAGetLastError());
2622 log_error ("can't connect to '%s': %s\n",
2623 server, gpg_strerror (last_err));
2626 err = last_err? last_err : gpg_err_make (default_errsource,
2627 GPG_ERR_UNKNOWN_HOST);
2628 if (sock != ASSUAN_INVALID_FD)
2629 assuan_sock_close (sock);
2639 write_server (int sock, const char *data, size_t length)
2647 #if defined(HAVE_W32_SYSTEM)
2648 # if defined(USE_NPTH)
2651 nwritten = send (sock, data, nleft, 0);
2652 # if defined(USE_NPTH)
2655 if ( nwritten == SOCKET_ERROR )
2657 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2658 return gpg_error (GPG_ERR_NETWORK);
2660 #else /*!HAVE_W32_SYSTEM*/
2662 nwritten = npth_write (sock, data, nleft);
2664 nwritten = write (sock, data, nleft);
2670 if (errno == EAGAIN)
2676 my_select (0, NULL, NULL, NULL, &tv);
2679 log_info ("network write failed: %s\n", strerror (errno));
2680 return gpg_error_from_syserror ();
2682 #endif /*!HAVE_W32_SYSTEM*/
2692 /* Read handler for estream. */
2693 static gpgrt_ssize_t
2694 cookie_read (void *cookie, void *buffer, size_t size)
2696 cookie_t c = cookie;
2699 if (c->content_length_valid)
2701 if (!c->content_length)
2703 if (c->content_length < size)
2704 size = c->content_length;
2708 if (c->use_tls && c->session && c->session->tls_session)
2712 ntbtls_get_stream (c->session->tls_session, &in, &out);
2713 nread = es_fread (buffer, 1, size, in);
2715 log_debug ("TLS network read: %d/%zu\n", nread, size);
2718 #elif HTTP_USE_GNUTLS
2719 if (c->use_tls && c->session && c->session->tls_session)
2722 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2725 if (nread == GNUTLS_E_INTERRUPTED)
2727 if (nread == GNUTLS_E_AGAIN)
2733 my_select (0, NULL, NULL, NULL, &tv);
2736 if (nread == GNUTLS_E_REHANDSHAKE)
2737 goto again; /* A client is allowed to just ignore this request. */
2738 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2740 /* The server terminated the connection. Close the TLS
2741 session, and indicate EOF using a short read. */
2742 close_tls_session (c->session);
2745 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2746 gpg_err_set_errno (EIO);
2751 #endif /*HTTP_USE_GNUTLS*/
2755 #ifdef HAVE_W32_SYSTEM
2756 /* Under Windows we need to use recv for a socket. */
2757 # if defined(USE_NPTH)
2760 nread = recv (c->sock->fd, buffer, size, 0);
2761 # if defined(USE_NPTH)
2765 #else /*!HAVE_W32_SYSTEM*/
2768 nread = npth_read (c->sock->fd, buffer, size);
2770 nread = read (c->sock->fd, buffer, size);
2773 #endif /*!HAVE_W32_SYSTEM*/
2775 while (nread == -1 && errno == EINTR);
2778 if (c->content_length_valid && nread > 0)
2780 if (nread < c->content_length)
2781 c->content_length -= nread;
2783 c->content_length = 0;
2786 return (gpgrt_ssize_t)nread;
2789 /* Write handler for estream. */
2790 static gpgrt_ssize_t
2791 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2793 const char *buffer = buffer_arg;
2794 cookie_t c = cookie;
2798 if (c->use_tls && c->session && c->session->tls_session)
2802 ntbtls_get_stream (c->session->tls_session, &in, &out);
2806 nwritten = es_fwrite (buffer, 1, size, out);
2808 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
2811 #elif HTTP_USE_GNUTLS
2812 if (c->use_tls && c->session && c->session->tls_session)
2817 nwritten = gnutls_record_send (c->session->tls_session,
2821 if (nwritten == GNUTLS_E_INTERRUPTED)
2823 if (nwritten == GNUTLS_E_AGAIN)
2829 my_select (0, NULL, NULL, NULL, &tv);
2832 log_info ("TLS network write failed: %s\n",
2833 gnutls_strerror (nwritten));
2834 gpg_err_set_errno (EIO);
2842 #endif /*HTTP_USE_GNUTLS*/
2844 if ( write_server (c->sock->fd, buffer, size) )
2846 gpg_err_set_errno (EIO);
2853 return (gpgrt_ssize_t)nwritten;
2857 #ifdef HTTP_USE_GNUTLS
2858 /* Wrapper for gnutls_bye used by my_socket_unref. */
2860 send_gnutls_bye (void *opaque)
2862 tls_session_t tls_session = opaque;
2867 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2868 while (ret == GNUTLS_E_INTERRUPTED);
2869 if (ret == GNUTLS_E_AGAIN)
2875 my_select (0, NULL, NULL, NULL, &tv);
2879 #endif /*HTTP_USE_GNUTLS*/
2881 /* Close handler for estream. */
2883 cookie_close (void *cookie)
2885 cookie_t c = cookie;
2891 if (c->use_tls && c->session && c->session->tls_session)
2893 /* FIXME!! Possibly call ntbtls_close_notify for close
2895 my_socket_unref (c->sock, NULL, NULL);
2898 #elif HTTP_USE_GNUTLS
2899 if (c->use_tls && c->session && c->session->tls_session)
2900 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2902 #endif /*HTTP_USE_GNUTLS*/
2904 my_socket_unref (c->sock, NULL, NULL);
2907 http_session_unref (c->session);
2915 /* Verify the credentials of the server. Returns 0 on success and
2916 store the result in the session object. */
2918 http_verify_server_credentials (http_session_t sess)
2922 return 0; /* FIXME!! */
2923 #elif HTTP_USE_GNUTLS
2924 static const char const errprefix[] = "TLS verification of peer failed";
2926 unsigned int status;
2927 const char *hostname;
2928 const gnutls_datum_t *certlist;
2929 unsigned int certlistlen;
2930 gnutls_x509_crt_t cert;
2931 gpg_error_t err = 0;
2933 sess->verify.done = 1;
2934 sess->verify.status = 0;
2935 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2937 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2939 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2940 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2941 return gpg_error (GPG_ERR_GENERAL);
2944 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2947 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2949 err = gpg_error (GPG_ERR_GENERAL);
2953 log_error ("%s: status=0x%04x\n", errprefix, status);
2954 #if GNUTLS_VERSION_NUMBER >= 0x030104
2956 gnutls_datum_t statusdat;
2958 if (!gnutls_certificate_verification_status_print
2959 (status, GNUTLS_CRT_X509, &statusdat, 0))
2961 log_info ("%s: %s\n", errprefix, statusdat.data);
2962 gnutls_free (statusdat.data);
2965 #endif /*gnutls >= 3.1.4*/
2967 sess->verify.status = status;
2969 err = gpg_error (GPG_ERR_GENERAL);
2972 hostname = sess->servername;
2973 if (!hostname || !strchr (hostname, '.'))
2975 log_error ("%s: %s\n", errprefix, "hostname missing");
2977 err = gpg_error (GPG_ERR_GENERAL);
2980 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2983 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2985 err = gpg_error (GPG_ERR_GENERAL);
2987 /* Need to stop here. */
2992 rc = gnutls_x509_crt_init (&cert);
2996 err = gpg_error (GPG_ERR_GENERAL);
3001 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3004 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3005 gnutls_strerror (rc));
3007 err = gpg_error (GPG_ERR_GENERAL);
3010 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3012 log_error ("%s: %s\n", errprefix, "hostname does not match");
3014 err = gpg_error (GPG_ERR_GENERAL);
3017 gnutls_x509_crt_deinit (cert);
3020 sess->verify.rc = 0;
3022 if (sess->cert_log_cb)
3024 const void *bufarr[10];
3025 size_t buflenarr[10];
3028 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3030 bufarr[n] = certlist[n].data;
3031 buflenarr[n] = certlist[n].size;
3035 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3039 #else /*!HTTP_USE_GNUTLS*/
3041 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3045 /* Return the first query variable with the specified key. If there
3046 is no such variable, return NULL. */
3047 struct uri_tuple_s *
3048 uri_query_lookup (parsed_uri_t uri, const char *key)
3050 struct uri_tuple_s *t;
3052 for (t = uri->query; t; t = t->next)
3053 if (strcmp (t->name, key) == 0)