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 assuan_fd_t connect_server (const char *server, unsigned short port,
159 unsigned int flags, const char *srvtag,
160 int *r_host_not_found);
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)
931 if ((flags & HTTP_FLAG_FORCE_TOR))
935 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
937 log_error ("Tor support is not available\n");
938 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
942 /* Create the handle. */
943 hd = xtrycalloc (1, sizeof *hd);
945 return gpg_error_from_syserror ();
946 hd->req_type = HTTP_REQ_OPAQUE;
953 sock = connect_server (server, port, hd->flags, srvtag, &hnf);
954 if (sock == ASSUAN_INVALID_FD)
956 err = gpg_err_make (default_errsource,
957 (hnf? GPG_ERR_UNKNOWN_HOST
958 : gpg_err_code_from_syserror ()));
962 hd->sock = my_socket_new (sock);
965 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
971 /* Setup estreams for reading and writing. */
972 cookie = xtrycalloc (1, sizeof *cookie);
975 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
978 cookie->sock = my_socket_ref (hd->sock);
979 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
982 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
983 my_socket_unref (cookie->sock, NULL, NULL);
987 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
989 cookie = xtrycalloc (1, sizeof *cookie);
992 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
995 cookie->sock = my_socket_ref (hd->sock);
996 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
999 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1000 my_socket_unref (cookie->sock, NULL, NULL);
1004 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1006 /* Register close notification to interlock the use of es_fclose in
1007 http_close and in user code. */
1008 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1010 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1016 es_fclose (hd->fp_read);
1018 es_fclose (hd->fp_write);
1019 my_socket_unref (hd->sock, NULL, NULL);
1031 http_start_data (http_t hd)
1035 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1036 log_debug_with_string ("\r\n", "http.c:request-header:");
1037 es_fputs ("\r\n", hd->fp_write);
1038 es_fflush (hd->fp_write);
1042 es_fflush (hd->fp_write);
1047 http_wait_response (http_t hd)
1052 /* Make sure that we are in the data. */
1053 http_start_data (hd);
1055 /* Close the write stream. Note that the reference counted socket
1056 object keeps the actual system socket open. */
1057 cookie = hd->write_cookie;
1059 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1061 es_fclose (hd->fp_write);
1062 hd->fp_write = NULL;
1063 /* The close has released the cookie and thus we better set it to NULL. */
1064 hd->write_cookie = NULL;
1066 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1067 is not required but some very old servers (e.g. the original pksd
1068 keyserver didn't worked without it. */
1069 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1070 shutdown (hd->sock->fd, 1);
1073 /* Create a new cookie and a stream for reading. */
1074 cookie = xtrycalloc (1, sizeof *cookie);
1076 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1077 cookie->sock = my_socket_ref (hd->sock);
1078 cookie->session = http_session_ref (hd->session);
1079 cookie->use_tls = hd->uri->use_tls;
1081 hd->read_cookie = cookie;
1082 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1085 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1086 my_socket_unref (cookie->sock, NULL, NULL);
1087 http_session_unref (cookie->session);
1089 hd->read_cookie = NULL;
1093 err = parse_response (hd);
1096 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1102 /* Convenience function to send a request and wait for the response.
1103 Closes the handle on error. If PROXY is not NULL, this value will
1104 be used as an HTTP proxy and any enabled $http_proxy gets
1107 http_open_document (http_t *r_hd, const char *document,
1108 const char *auth, unsigned int flags, const char *proxy,
1109 http_session_t session,
1110 const char *srvtag, strlist_t headers)
1114 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1115 proxy, session, srvtag, headers);
1119 err = http_wait_response (*r_hd);
1121 http_close (*r_hd, 0);
1128 http_close (http_t hd, int keep_read_stream)
1133 /* First remove the close notifications for the streams. */
1135 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1137 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1139 /* Now we can close the streams. */
1140 my_socket_unref (hd->sock, NULL, NULL);
1141 if (hd->fp_read && !keep_read_stream)
1142 es_fclose (hd->fp_read);
1144 es_fclose (hd->fp_write);
1145 http_session_unref (hd->session);
1146 http_release_parsed_uri (hd->uri);
1149 header_t tmp = hd->headers->next;
1150 xfree (hd->headers->value);
1151 xfree (hd->headers);
1160 http_get_read_ptr (http_t hd)
1162 return hd?hd->fp_read:NULL;
1166 http_get_write_ptr (http_t hd)
1168 return hd?hd->fp_write:NULL;
1172 http_get_status_code (http_t hd)
1174 return hd?hd->status_code:0;
1177 /* Return information pertaining to TLS. If TLS is not in use for HD,
1178 NULL is returned. WHAT is used ask for specific information:
1180 (NULL) := Only check whether TLS is is use. Returns an
1181 unspecified string if TLS is in use. That string may
1182 even be the empty string.
1185 http_get_tls_info (http_t hd, const char *what)
1192 return hd->uri->use_tls? "":NULL;
1198 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1199 int no_scheme_check, int force_tls)
1203 *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1205 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1206 strcpy ((*ret_uri)->buffer, uri);
1207 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1213 return gpg_err_make (default_errsource, ec);
1218 * Parse an URI and put the result into the newly allocated RET_URI.
1219 * On success the caller must use http_release_parsed_uri() to
1220 * releases the resources. If NO_SCHEME_CHECK is set, the function
1221 * tries to parse the URL in the same way it would do for an HTTP
1225 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1226 int no_scheme_check)
1228 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1233 http_release_parsed_uri (parsed_uri_t uri)
1239 for (r = uri->query; r; r = r2)
1249 static gpg_err_code_t
1250 do_parse_uri (parsed_uri_t uri, int only_local_part,
1251 int no_scheme_check, int force_tls)
1254 char *p, *p2, *p3, *pp;
1258 n = strlen (uri->buffer);
1260 /* Initialize all fields to an empty string or an empty list. */
1261 uri->scheme = uri->host = uri->path = p + n;
1263 uri->params = uri->query = NULL;
1269 uri->explicit_port = 0;
1271 /* A quick validity check. */
1272 if (strspn (p, VALID_URI_CHARS) != n)
1273 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1275 if (!only_local_part)
1277 /* Find the scheme. */
1278 if (!(p2 = strchr (p, ':')) || p2 == p)
1279 return GPG_ERR_BAD_URI; /* No scheme. */
1281 for (pp=p; *pp; pp++)
1282 *pp = tolower (*(unsigned char*)pp);
1284 if (!strcmp (uri->scheme, "http") && !force_tls)
1289 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1295 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1296 || (force_tls && (!strcmp (uri->scheme, "http")
1297 || !strcmp (uri->scheme,"hkp"))))
1304 else if (!no_scheme_check)
1305 return GPG_ERR_INV_URI; /* Unsupported scheme */
1309 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1312 if ((p2 = strchr (p, '/')))
1315 /* Check for username/password encoding */
1316 if ((p3 = strchr (p, '@')))
1323 for (pp=p; *pp; pp++)
1324 *pp = tolower (*(unsigned char*)pp);
1326 /* Handle an IPv6 literal */
1327 if( *p == '[' && (p3=strchr( p, ']' )) )
1330 /* worst case, uri->host should have length 0, points to \0 */
1338 if ((p3 = strchr (p, ':')))
1341 uri->port = atoi (p3);
1342 uri->explicit_port = 1;
1345 if ((n = remove_escapes (uri->host)) < 0)
1346 return GPG_ERR_BAD_URI;
1347 if (n != strlen (uri->host))
1348 return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */
1351 else if (uri->is_http)
1352 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1357 if (is_onion_address (uri->path))
1362 } /* End global URI part. */
1364 /* Parse the pathname part if any. */
1367 /* TODO: Here we have to check params. */
1369 /* Do we have a query part? */
1370 if ((p2 = strchr (p, '?')))
1374 if ((n = remove_escapes (p)) < 0)
1375 return GPG_ERR_BAD_URI;
1376 if (n != strlen (p))
1377 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1380 /* Parse a query string if any. */
1388 if ((p2 = strchr (p, '&')))
1390 if (!(elem = parse_tuple (p)))
1391 return GPG_ERR_BAD_URI;
1402 if (is_onion_address (uri->host))
1410 * Remove all %xx escapes; this is done in-place. Returns: New length
1414 remove_escapes (char *string)
1417 unsigned char *p, *s;
1419 for (p = s = (unsigned char*)string; *s; s++)
1423 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1426 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1427 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1430 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1431 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1444 return -1; /* Bad URI. */
1453 *p = 0; /* Make sure to keep a string terminator. */
1458 /* If SPECIAL is NULL this function escapes in forms mode. */
1460 escape_data (char *buffer, const void *data, size_t datalen,
1461 const char *special)
1463 int forms = !special;
1464 const unsigned char *s;
1470 for (s = data; datalen; s++, datalen--)
1472 if (forms && *s == ' ')
1478 else if (forms && *s == '\n')
1481 memcpy (buffer, "%0D%0A", 6);
1484 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1487 memcpy (buffer, "%0D%0A", 6);
1492 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1495 *(unsigned char*)buffer++ = *s;
1502 snprintf (buffer, 4, "%%%02X", *s);
1513 insert_escapes (char *buffer, const char *string,
1514 const char *special)
1516 return escape_data (buffer, string, strlen (string), special);
1520 /* Allocate a new string from STRING using standard HTTP escaping as
1521 well as escaping of characters given in SPECIALS. A common pattern
1522 for SPECIALS is "%;?&=". However it depends on the needs, for
1523 example "+" and "/: often needs to be escaped too. Returns NULL on
1524 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1525 encoding mode is used. */
1527 http_escape_string (const char *string, const char *specials)
1532 n = insert_escapes (NULL, string, specials);
1533 buf = xtrymalloc (n+1);
1536 insert_escapes (buf, string, specials);
1542 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1543 escaping as well as escaping of characters given in SPECIALS. A
1544 common pattern for SPECIALS is "%;?&=". However it depends on the
1545 needs, for example "+" and "/: often needs to be escaped too.
1546 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1547 dedicated forms encoding mode is used. */
1549 http_escape_data (const void *data, size_t datalen, const char *specials)
1554 n = escape_data (NULL, data, datalen, specials);
1555 buf = xtrymalloc (n+1);
1558 escape_data (buf, data, datalen, specials);
1566 parse_tuple (char *string)
1573 if ((p2 = strchr (p, '=')))
1575 if ((n = remove_escapes (p)) < 0)
1576 return NULL; /* Bad URI. */
1577 if (n != strlen (p))
1578 return NULL; /* Name with a Nul in it. */
1579 tuple = xtrycalloc (1, sizeof *tuple);
1581 return NULL; /* Out of core. */
1583 if (!p2) /* We have only the name, so we assume an empty value string. */
1585 tuple->value = p + strlen (p);
1586 tuple->valuelen = 0;
1587 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1589 else /* Name and value. */
1591 if ((n = remove_escapes (p2)) < 0)
1594 return NULL; /* Bad URI. */
1597 tuple->valuelen = n;
1603 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1605 is_hostname_port (const char *string)
1609 if (!string || !*string)
1611 for (; *string; string++)
1621 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1622 return 0; /* Invalid characters in hostname. */
1623 else if (colons && !digitp (string))
1624 return 0; /* Not a digit in the port. */
1631 * Send a HTTP request to the server
1632 * Returns 0 if the request was successful
1635 send_request (http_t hd, const char *httphost, const char *auth,
1636 const char *proxy, const char *srvtag, strlist_t headers)
1641 unsigned short port;
1642 const char *http_proxy = NULL;
1643 char *proxy_authstr = NULL;
1644 char *authstr = NULL;
1648 if (hd->uri->use_tls && !hd->session)
1650 log_error ("TLS requested but no session object provided\n");
1651 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1654 if (hd->uri->use_tls && !hd->session->tls_session)
1656 log_error ("TLS requested but no GNUTLS context available\n");
1657 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1661 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1665 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1667 log_error ("Tor support is not available\n");
1668 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1672 server = *hd->uri->host ? hd->uri->host : "localhost";
1673 port = hd->uri->port ? hd->uri->port : 80;
1675 /* Try to use SNI. */
1677 if (hd->uri->use_tls)
1679 # if HTTP_USE_GNUTLS
1683 xfree (hd->session->servername);
1684 hd->session->servername = xtrystrdup (httphost? httphost : server);
1685 if (!hd->session->servername)
1687 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1691 # if HTTP_USE_NTBTLS
1692 err = ntbtls_set_hostname (hd->session->tls_session,
1693 hd->session->servername);
1696 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1699 # elif HTTP_USE_GNUTLS
1700 rc = gnutls_server_name_set (hd->session->tls_session,
1702 hd->session->servername,
1703 strlen (hd->session->servername));
1705 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1706 # endif /*HTTP_USE_GNUTLS*/
1710 if ( (proxy && *proxy)
1711 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1712 && (http_proxy = getenv (HTTP_PROXY_ENV))
1721 err = parse_uri (&uri, http_proxy, 0, 0);
1722 if (gpg_err_code (err) == GPG_ERR_INV_URI
1723 && is_hostname_port (http_proxy))
1725 /* Retry assuming a "hostname:port" string. */
1726 char *tmpname = strconcat ("http://", http_proxy, NULL);
1727 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1734 else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1736 else if (!strcmp (uri->scheme, "socks5h"))
1737 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1739 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1743 log_error ("invalid HTTP proxy (%s): %s\n",
1744 http_proxy, gpg_strerror (err));
1745 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1750 remove_escapes (uri->auth);
1751 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1753 uri->auth, strlen(uri->auth));
1756 err = gpg_err_make (default_errsource,
1757 gpg_err_code_from_syserror ());
1758 http_release_parsed_uri (uri);
1763 sock = connect_server (*uri->host ? uri->host : "localhost",
1764 uri->port ? uri->port : 80,
1765 hd->flags, srvtag, &hnf);
1767 http_release_parsed_uri (uri);
1768 if (sock == ASSUAN_INVALID_FD)
1769 gpg_err_set_errno (save_errno);
1773 sock = connect_server (server, port, hd->flags, srvtag, &hnf);
1776 if (sock == ASSUAN_INVALID_FD)
1778 xfree (proxy_authstr);
1779 return gpg_err_make (default_errsource,
1780 (hnf? GPG_ERR_UNKNOWN_HOST
1781 : gpg_err_code_from_syserror ()));
1783 hd->sock = my_socket_new (sock);
1786 xfree (proxy_authstr);
1787 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1793 if (hd->uri->use_tls)
1797 my_socket_ref (hd->sock);
1799 in = es_fdopen_nc (hd->sock->fd, "rb");
1802 err = gpg_error_from_syserror ();
1803 xfree (proxy_authstr);
1807 out = es_fdopen_nc (hd->sock->fd, "wb");
1810 err = gpg_error_from_syserror ();
1812 xfree (proxy_authstr);
1816 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1819 log_info ("TLS set_transport failed: %s <%s>\n",
1820 gpg_strerror (err), gpg_strsource (err));
1821 xfree (proxy_authstr);
1825 while ((err = ntbtls_handshake (hd->session->tls_session)))
1830 log_info ("TLS handshake failed: %s <%s>\n",
1831 gpg_strerror (err), gpg_strsource (err));
1832 xfree (proxy_authstr);
1837 hd->session->verify.done = 0;
1839 err = tls_callback (hd, hd->session, 0);
1841 err = http_verify_server_credentials (hd->session);
1844 log_info ("TLS connection authentication failed: %s <%s>\n",
1845 gpg_strerror (err), gpg_strsource (err));
1846 xfree (proxy_authstr);
1850 #elif HTTP_USE_GNUTLS
1851 if (hd->uri->use_tls)
1855 my_socket_ref (hd->sock);
1856 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1857 gnutls_transport_set_pull_function (hd->session->tls_session,
1859 gnutls_transport_set_push_function (hd->session->tls_session,
1864 rc = gnutls_handshake (hd->session->tls_session);
1866 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1869 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1870 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1872 gnutls_alert_description_t alertno;
1873 const char *alertstr;
1875 alertno = gnutls_alert_get (hd->session->tls_session);
1876 alertstr = gnutls_alert_get_name (alertno);
1877 log_info ("TLS handshake failed: %s (alert %d)\n",
1878 alertstr, (int)alertno);
1879 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1880 log_info (" (sent server name '%s')\n", server);
1883 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1884 xfree (proxy_authstr);
1885 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1888 hd->session->verify.done = 0;
1890 err = tls_callback (hd, hd->session, 0);
1892 err = http_verify_server_credentials (hd->session);
1895 log_info ("TLS connection authentication failed: %s\n",
1896 gpg_strerror (err));
1897 xfree (proxy_authstr);
1901 #endif /*HTTP_USE_GNUTLS*/
1903 if (auth || hd->uri->auth)
1909 myauth = xtrystrdup (auth);
1912 xfree (proxy_authstr);
1913 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1915 remove_escapes (myauth);
1919 remove_escapes (hd->uri->auth);
1920 myauth = hd->uri->auth;
1923 authstr = make_header_line ("Authorization: Basic ", "\r\n",
1924 myauth, strlen (myauth));
1930 xfree (proxy_authstr);
1931 return gpg_err_make (default_errsource,
1932 gpg_err_code_from_syserror ());
1936 p = build_rel_path (hd->uri);
1938 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1940 if (http_proxy && *http_proxy)
1942 request = es_bsprintf
1943 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1944 hd->req_type == HTTP_REQ_GET ? "GET" :
1945 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1946 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1947 hd->uri->use_tls? "https" : "http",
1948 httphost? httphost : server,
1949 port, *p == '/' ? "" : "/", p,
1950 authstr ? authstr : "",
1951 proxy_authstr ? proxy_authstr : "");
1960 snprintf (portstr, sizeof portstr, ":%u", port);
1962 request = es_bsprintf
1963 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1964 hd->req_type == HTTP_REQ_GET ? "GET" :
1965 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1966 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1967 *p == '/' ? "" : "/", p,
1968 httphost? httphost : server,
1970 authstr? authstr:"");
1975 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1977 xfree (proxy_authstr);
1981 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1982 log_debug_with_string (request, "http.c:request:");
1984 /* First setup estream so that we can write even the first line
1985 using estream. This is also required for the sake of gnutls. */
1989 cookie = xtrycalloc (1, sizeof *cookie);
1992 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1995 cookie->sock = my_socket_ref (hd->sock);
1996 hd->write_cookie = cookie;
1997 cookie->use_tls = hd->uri->use_tls;
1998 cookie->session = http_session_ref (hd->session);
2000 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2003 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2004 my_socket_unref (cookie->sock, NULL, NULL);
2006 hd->write_cookie = NULL;
2008 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2009 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2015 for (;headers; headers=headers->next)
2017 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2018 log_debug_with_string (headers->d, "http.c:request-header:");
2019 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2020 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2022 err = gpg_err_make (default_errsource,
2023 gpg_err_code_from_syserror ());
2033 xfree (proxy_authstr);
2040 * Build the relative path from the parsed URI. Minimal
2041 * implementation. May return NULL in case of memory failure; errno
2042 * is then set accordingly.
2045 build_rel_path (parsed_uri_t uri)
2051 /* Count the needed space. */
2052 n = insert_escapes (NULL, uri->path, "%;?&");
2053 /* TODO: build params. */
2054 for (r = uri->query; r; r = r->next)
2057 n += insert_escapes (NULL, r->name, "%;?&=");
2061 n += insert_escapes (NULL, r->value, "%;?&=");
2066 /* Now allocate and copy. */
2067 p = rel_path = xtrymalloc (n);
2070 n = insert_escapes (p, uri->path, "%;?&");
2072 /* TODO: add params. */
2073 for (r = uri->query; r; r = r->next)
2075 *p++ = r == uri->query ? '?' : '&';
2076 n = insert_escapes (p, r->name, "%;?&=");
2081 /* TODO: Use valuelen. */
2082 n = insert_escapes (p, r->value, "%;?&=");
2091 /* Transform a header name into a standard capitalized format; e.g.
2092 "Content-Type". Conversion stops at the colon. As usual we don't
2093 use the localized versions of ctype.h. */
2095 capitalize_header_name (char *name)
2099 for (; *name && *name != ':'; name++)
2105 if (*name >= 'a' && *name <= 'z')
2106 *name = *name - 'a' + 'A';
2109 else if (*name >= 'A' && *name <= 'Z')
2110 *name = *name - 'A' + 'a';
2115 /* Store an HTTP header line in LINE away. Line continuation is
2116 supported as well as merging of headers with the same name. This
2117 function may modify LINE. */
2118 static gpg_err_code_t
2119 store_header (http_t hd, char *line)
2126 if (n && line[n-1] == '\n')
2129 if (n && line[n-1] == '\r')
2132 if (!n) /* we are never called to hit this. */
2134 if (*line == ' ' || *line == '\t')
2136 /* Continuation. This won't happen too often as it is not
2137 recommended. We use a straightforward implementaion. */
2139 return GPG_ERR_PROTOCOL_VIOLATION;
2140 n += strlen (hd->headers->value);
2141 p = xtrymalloc (n+1);
2143 return gpg_err_code_from_syserror ();
2144 strcpy (stpcpy (p, hd->headers->value), line);
2145 xfree (hd->headers->value);
2146 hd->headers->value = p;
2150 capitalize_header_name (line);
2151 p = strchr (line, ':');
2153 return GPG_ERR_PROTOCOL_VIOLATION;
2155 while (*p == ' ' || *p == '\t')
2159 for (h=hd->headers; h; h = h->next)
2160 if ( !strcmp (h->name, line) )
2164 /* We have already seen a line with that name. Thus we assume
2165 it is a comma separated list and merge them. */
2166 p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
2168 return gpg_err_code_from_syserror ();
2169 strcpy (stpcpy (stpcpy (p, h->value), ","), value);
2175 /* Append a new header. */
2176 h = xtrymalloc (sizeof *h + strlen (line));
2178 return gpg_err_code_from_syserror ();
2179 strcpy (h->name, line);
2180 h->value = xtrymalloc (strlen (value)+1);
2184 return gpg_err_code_from_syserror ();
2186 strcpy (h->value, value);
2187 h->next = hd->headers;
2194 /* Return the header NAME from the last response. The returned value
2195 is valid as along as HD has not been closed and no other request
2196 has been send. If the header was not found, NULL is returned. NAME
2197 must be canonicalized, that is the first letter of each dash
2198 delimited part must be uppercase and all other letters lowercase. */
2200 http_get_header (http_t hd, const char *name)
2204 for (h=hd->headers; h; h = h->next)
2205 if ( !strcmp (h->name, name) )
2211 /* Return a newly allocated and NULL terminated array with pointers to
2212 header names. The array must be released with xfree() and its
2213 content is only values as long as no other request has been
2216 http_get_header_names (http_t hd)
2222 for (n=0, h = hd->headers; h; h = h->next)
2224 array = xtrycalloc (n+1, sizeof *array);
2227 for (n=0, h = hd->headers; h; h = h->next)
2228 array[n++] = h->name;
2236 * Parse the response from a server.
2237 * Returns: Errorcode and sets some files in the handle
2239 static gpg_err_code_t
2240 parse_response (http_t hd)
2242 char *line, *p, *p2;
2244 cookie_t cookie = hd->read_cookie;
2247 /* Delete old header lines. */
2250 header_t tmp = hd->headers->next;
2251 xfree (hd->headers->value);
2252 xfree (hd->headers);
2256 /* Wait for the status line. */
2259 maxlen = MAX_LINELEN;
2260 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2263 return gpg_err_code_from_syserror (); /* Out of core. */
2265 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2269 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2270 log_debug_with_string (line, "http.c:response:\n");
2274 if ((p = strchr (line, '/')))
2276 if (!p || strcmp (line, "HTTP"))
2277 return 0; /* Assume http 0.9. */
2279 if ((p2 = strpbrk (p, " \t")))
2282 p2 += strspn (p2, " \t");
2285 return 0; /* Also assume http 0.9. */
2287 /* TODO: Add HTTP version number check. */
2288 if ((p2 = strpbrk (p, " \t")))
2290 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2291 || !isdigit ((unsigned int)p[2]) || p[3])
2293 /* Malformed HTTP status code - assume http 0.9. */
2294 hd->is_http_0_9 = 1;
2295 hd->status_code = 200;
2298 hd->status_code = atoi (p);
2300 /* Skip all the header lines and wait for the empty line. */
2303 maxlen = MAX_LINELEN;
2304 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2307 return gpg_err_code_from_syserror (); /* Out of core. */
2308 /* Note, that we can silently ignore truncated lines. */
2311 /* Trim line endings of empty lines. */
2312 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2314 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2315 log_info ("http.c:RESP: '%.*s'\n",
2316 (int)strlen(line)-(*line&&line[1]?2:0),line);
2319 gpg_err_code_t ec = store_header (hd, line);
2324 while (len && *line);
2326 cookie->content_length_valid = 0;
2327 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2329 s = http_get_header (hd, "Content-Length");
2332 cookie->content_length_valid = 1;
2333 cookie->content_length = string_to_u64 (s);
2344 struct sockaddr_in mya;
2345 struct sockaddr_in peer;
2351 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2353 log_error ("socket() failed: %s\n", strerror (errno));
2357 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2358 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2360 mya.sin_family = AF_INET;
2361 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2362 mya.sin_port = htons (11371);
2364 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2366 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2373 log_error ("listen failed: %s\n", strerror (errno));
2383 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2384 continue; /* ignore any errors */
2386 if (!FD_ISSET (fd, &rfds))
2389 addrlen = sizeof peer;
2390 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2392 continue; /* oops */
2394 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2403 fp = fdopen (client, "r");
2404 while ((c = getc (fp)) != EOF)
2409 sock_close (client);
2419 /* Return true if SOCKS shall be used. This is the case if tor_mode
2420 * is enabled and the desired address is not the loopback address.
2421 * This function is basically a copy of the same internal fucntion in
2424 use_socks (struct sockaddr *addr)
2428 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2429 return 0; /* Not in Tor mode. */
2430 else if (addr->sa_family == AF_INET6)
2432 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2433 const unsigned char *s;
2436 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2438 return 1; /* Last octet is not 1 - not the loopback address. */
2439 for (i=0; i < 15; i++, s++)
2441 return 1; /* Non-zero octet found - not the loopback address. */
2443 return 0; /* This is the loopback address. */
2445 else if (addr->sa_family == AF_INET)
2447 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2449 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2450 return 0; /* Loopback (127.0.0.0/8) */
2459 /* Wrapper around assuan_sock_new which takes the domain from an
2460 * address parameter. */
2462 my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
2466 if (use_socks (addr))
2468 /* Libassaun always uses 127.0.0.1 to connect to the socks
2469 * server (i.e. the Tor daemon). */
2473 domain = addr->sa_family;
2475 return assuan_sock_new (domain, type, proto);
2479 /* Actually connect to a server. Returns the file descriptor or -1 on
2480 error. ERRNO is set on error. */
2482 connect_server (const char *server, unsigned short port,
2483 unsigned int flags, const char *srvtag, int *r_host_not_found)
2486 assuan_fd_t sock = ASSUAN_INVALID_FD;
2487 unsigned int srvcount = 0;
2489 int anyhostaddr = 0;
2492 struct srventry *serverlist = NULL;
2495 *r_host_not_found = 0;
2496 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2500 /* Onion addresses require special treatment. */
2501 if (is_onion_address (server))
2503 #ifdef ASSUAN_SOCK_TOR
2506 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2508 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2510 if (sock == ASSUAN_INVALID_FD)
2512 if (errno == EHOSTUNREACH)
2513 *r_host_not_found = 1;
2514 log_error ("can't connect to '%s': %s\n", server, strerror (errno));
2517 notify_netactivity ();
2520 #else /*!ASSUAN_SOCK_TOR*/
2522 gpg_err_set_errno (ENETUNREACH);
2523 return -1; /* Out of core. */
2525 #endif /*!HASSUAN_SOCK_TOR*/
2528 /* Do the SRV thing */
2531 err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2533 log_info ("getting '%s' SRV for '%s' failed: %s\n",
2534 srvtag, server, gpg_strerror (err));
2535 /* 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 -1; /* Out of core. */
2545 serverlist->port = port;
2546 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2547 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2552 for (srv=0; srv < srvcount && !connected; srv++)
2554 dns_addrinfo_t aibuf, ai;
2557 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2558 serverlist[srv].target, port);
2559 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2563 log_info ("resolving '%s' failed: %s\n",
2564 serverlist[srv].target, gpg_strerror (err));
2565 continue; /* Not found - try next one. */
2569 for (ai = aibuf; ai && !connected; ai = ai->next)
2571 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2573 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2576 if (sock != ASSUAN_INVALID_FD)
2577 assuan_sock_close (sock);
2578 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2579 if (sock == ASSUAN_INVALID_FD)
2581 int save_errno = errno;
2582 log_error ("error creating socket: %s\n", strerror (errno));
2583 free_dns_addrinfo (aibuf);
2586 return ASSUAN_INVALID_FD;
2590 ret = assuan_sock_connect (sock, ai->addr, ai->addrlen);
2596 notify_netactivity ();
2599 free_dns_addrinfo (aibuf);
2607 log_error ("can't connect to '%s': %s\n",
2608 server, "host not found");
2609 else if (!anyhostaddr)
2610 log_error ("can't connect to '%s': %s\n",
2611 server, "no IP address for host");
2614 #ifdef HAVE_W32_SYSTEM
2615 log_error ("can't connect to '%s': ec=%d\n",
2616 server, (int)WSAGetLastError());
2618 log_error ("can't connect to '%s': %s\n",
2619 server, strerror (last_errno));
2622 if (!hostfound || (hostfound && !anyhostaddr))
2623 *r_host_not_found = 1;
2624 if (sock != ASSUAN_INVALID_FD)
2625 assuan_sock_close (sock);
2626 gpg_err_set_errno (last_errno);
2627 return ASSUAN_INVALID_FD;
2634 write_server (int sock, const char *data, size_t length)
2642 #if defined(HAVE_W32_SYSTEM)
2643 # if defined(USE_NPTH)
2646 nwritten = send (sock, data, nleft, 0);
2647 # if defined(USE_NPTH)
2650 if ( nwritten == SOCKET_ERROR )
2652 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2653 return gpg_error (GPG_ERR_NETWORK);
2655 #else /*!HAVE_W32_SYSTEM*/
2657 nwritten = npth_write (sock, data, nleft);
2659 nwritten = write (sock, data, nleft);
2665 if (errno == EAGAIN)
2671 my_select (0, NULL, NULL, NULL, &tv);
2674 log_info ("network write failed: %s\n", strerror (errno));
2675 return gpg_error_from_syserror ();
2677 #endif /*!HAVE_W32_SYSTEM*/
2687 /* Read handler for estream. */
2688 static gpgrt_ssize_t
2689 cookie_read (void *cookie, void *buffer, size_t size)
2691 cookie_t c = cookie;
2694 if (c->content_length_valid)
2696 if (!c->content_length)
2698 if (c->content_length < size)
2699 size = c->content_length;
2703 if (c->use_tls && c->session && c->session->tls_session)
2707 ntbtls_get_stream (c->session->tls_session, &in, &out);
2708 nread = es_fread (buffer, 1, size, in);
2710 log_debug ("TLS network read: %d/%zu\n", nread, size);
2713 #elif HTTP_USE_GNUTLS
2714 if (c->use_tls && c->session && c->session->tls_session)
2717 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2720 if (nread == GNUTLS_E_INTERRUPTED)
2722 if (nread == GNUTLS_E_AGAIN)
2728 my_select (0, NULL, NULL, NULL, &tv);
2731 if (nread == GNUTLS_E_REHANDSHAKE)
2732 goto again; /* A client is allowed to just ignore this request. */
2733 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2735 /* The server terminated the connection. Close the TLS
2736 session, and indicate EOF using a short read. */
2737 close_tls_session (c->session);
2740 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2741 gpg_err_set_errno (EIO);
2746 #endif /*HTTP_USE_GNUTLS*/
2750 #ifdef HAVE_W32_SYSTEM
2751 /* Under Windows we need to use recv for a socket. */
2752 # if defined(USE_NPTH)
2755 nread = recv (c->sock->fd, buffer, size, 0);
2756 # if defined(USE_NPTH)
2760 #else /*!HAVE_W32_SYSTEM*/
2763 nread = npth_read (c->sock->fd, buffer, size);
2765 nread = read (c->sock->fd, buffer, size);
2768 #endif /*!HAVE_W32_SYSTEM*/
2770 while (nread == -1 && errno == EINTR);
2773 if (c->content_length_valid && nread > 0)
2775 if (nread < c->content_length)
2776 c->content_length -= nread;
2778 c->content_length = 0;
2781 return (gpgrt_ssize_t)nread;
2784 /* Write handler for estream. */
2785 static gpgrt_ssize_t
2786 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2788 const char *buffer = buffer_arg;
2789 cookie_t c = cookie;
2793 if (c->use_tls && c->session && c->session->tls_session)
2797 ntbtls_get_stream (c->session->tls_session, &in, &out);
2801 nwritten = es_fwrite (buffer, 1, size, out);
2803 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
2806 #elif HTTP_USE_GNUTLS
2807 if (c->use_tls && c->session && c->session->tls_session)
2812 nwritten = gnutls_record_send (c->session->tls_session,
2816 if (nwritten == GNUTLS_E_INTERRUPTED)
2818 if (nwritten == GNUTLS_E_AGAIN)
2824 my_select (0, NULL, NULL, NULL, &tv);
2827 log_info ("TLS network write failed: %s\n",
2828 gnutls_strerror (nwritten));
2829 gpg_err_set_errno (EIO);
2837 #endif /*HTTP_USE_GNUTLS*/
2839 if ( write_server (c->sock->fd, buffer, size) )
2841 gpg_err_set_errno (EIO);
2848 return (gpgrt_ssize_t)nwritten;
2852 #ifdef HTTP_USE_GNUTLS
2853 /* Wrapper for gnutls_bye used by my_socket_unref. */
2855 send_gnutls_bye (void *opaque)
2857 tls_session_t tls_session = opaque;
2862 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2863 while (ret == GNUTLS_E_INTERRUPTED);
2864 if (ret == GNUTLS_E_AGAIN)
2870 my_select (0, NULL, NULL, NULL, &tv);
2874 #endif /*HTTP_USE_GNUTLS*/
2876 /* Close handler for estream. */
2878 cookie_close (void *cookie)
2880 cookie_t c = cookie;
2886 if (c->use_tls && c->session && c->session->tls_session)
2888 /* FIXME!! Possibly call ntbtls_close_notify for close
2890 my_socket_unref (c->sock, NULL, NULL);
2893 #elif HTTP_USE_GNUTLS
2894 if (c->use_tls && c->session && c->session->tls_session)
2895 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2897 #endif /*HTTP_USE_GNUTLS*/
2899 my_socket_unref (c->sock, NULL, NULL);
2902 http_session_unref (c->session);
2910 /* Verify the credentials of the server. Returns 0 on success and
2911 store the result in the session object. */
2913 http_verify_server_credentials (http_session_t sess)
2917 return 0; /* FIXME!! */
2918 #elif HTTP_USE_GNUTLS
2919 static const char const errprefix[] = "TLS verification of peer failed";
2921 unsigned int status;
2922 const char *hostname;
2923 const gnutls_datum_t *certlist;
2924 unsigned int certlistlen;
2925 gnutls_x509_crt_t cert;
2926 gpg_error_t err = 0;
2928 sess->verify.done = 1;
2929 sess->verify.status = 0;
2930 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2932 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2934 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2935 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2936 return gpg_error (GPG_ERR_GENERAL);
2939 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2942 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2944 err = gpg_error (GPG_ERR_GENERAL);
2948 log_error ("%s: status=0x%04x\n", errprefix, status);
2949 #if GNUTLS_VERSION_NUMBER >= 0x030104
2951 gnutls_datum_t statusdat;
2953 if (!gnutls_certificate_verification_status_print
2954 (status, GNUTLS_CRT_X509, &statusdat, 0))
2956 log_info ("%s: %s\n", errprefix, statusdat.data);
2957 gnutls_free (statusdat.data);
2960 #endif /*gnutls >= 3.1.4*/
2962 sess->verify.status = status;
2964 err = gpg_error (GPG_ERR_GENERAL);
2967 hostname = sess->servername;
2968 if (!hostname || !strchr (hostname, '.'))
2970 log_error ("%s: %s\n", errprefix, "hostname missing");
2972 err = gpg_error (GPG_ERR_GENERAL);
2975 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2978 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2980 err = gpg_error (GPG_ERR_GENERAL);
2982 /* Need to stop here. */
2987 rc = gnutls_x509_crt_init (&cert);
2991 err = gpg_error (GPG_ERR_GENERAL);
2996 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2999 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3000 gnutls_strerror (rc));
3002 err = gpg_error (GPG_ERR_GENERAL);
3005 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3007 log_error ("%s: %s\n", errprefix, "hostname does not match");
3009 err = gpg_error (GPG_ERR_GENERAL);
3012 gnutls_x509_crt_deinit (cert);
3015 sess->verify.rc = 0;
3017 if (sess->cert_log_cb)
3019 const void *bufarr[10];
3020 size_t buflenarr[10];
3023 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3025 bufarr[n] = certlist[n].data;
3026 buflenarr[n] = certlist[n].size;
3030 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3034 #else /*!HTTP_USE_GNUTLS*/
3036 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3040 /* Return the first query variable with the specified key. If there
3041 is no such variable, return NULL. */
3042 struct uri_tuple_s *
3043 uri_query_lookup (parsed_uri_t uri, const char *key)
3045 struct uri_tuple_s *t;
3047 for (t = uri->query; t; t = t->next)
3048 if (strcmp (t->name, key) == 0)