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 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 /* The global callback for the verification function. */
259 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
261 /* The list of files with trusted CA certificates. */
262 static strlist_t tls_ca_certlist;
264 /* The global callback for net activity. */
265 static void (*netactivity_cb)(void);
269 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
271 #if GNUPG_MAJOR_VERSION == 1
272 #define REQ_WINSOCK_MAJOR 1
273 #define REQ_WINSOCK_MINOR 1
275 #define REQ_WINSOCK_MAJOR 2
276 #define REQ_WINSOCK_MINOR 2
281 deinit_sockets (void)
289 static int initialized;
290 static WSADATA wsdata;
295 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
297 log_error ("error initializing socket library: ec=%d\n",
298 (int)WSAGetLastError () );
301 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
302 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
304 log_error ("socket library version is %x.%x - but %d.%d needed\n",
305 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
306 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
310 atexit ( deinit_sockets );
313 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
316 /* Create a new socket object. Returns NULL and closes FD if not
317 enough memory is available. */
319 _my_socket_new (int lnr, assuan_fd_t fd)
323 so = xtrymalloc (sizeof *so);
326 int save_errno = errno;
327 assuan_sock_close (fd);
328 gpg_err_set_errno (save_errno);
333 /* log_debug ("http.c:socket_new(%d): object %p for fd %d created\n", */
334 /* lnr, so, so->fd); */
338 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
340 /* Bump up the reference counter for the socket object SO. */
342 _my_socket_ref (int lnr, my_socket_t so)
345 /* log_debug ("http.c:socket_ref(%d) object %p for fd %d refcount now %d\n", */
346 /* lnr, so, so->fd, so->refcount); */
350 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
353 /* Bump down the reference counter for the socket object SO. If SO
354 has no more references, close the socket and release the
357 _my_socket_unref (int lnr, my_socket_t so,
358 void (*preclose)(void*), void *preclosearg)
363 /* log_debug ("http.c:socket_unref(%d): object %p for fd %d ref now %d\n", */
364 /* lnr, so, so->fd, so->refcount); */
369 preclose (preclosearg);
370 assuan_sock_close (so->fd);
375 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
378 #ifdef HTTP_USE_GNUTLS
380 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
382 my_socket_t sock = ptr;
384 return npth_read (sock->fd, buffer, size);
386 return read (sock->fd, buffer, size);
390 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
392 my_socket_t sock = ptr;
394 return npth_write (sock->fd, buffer, size);
396 return write (sock->fd, buffer, size);
399 #endif /*HTTP_USE_GNUTLS*/
404 /* This notification function is called by estream whenever stream is
405 closed. Its purpose is to mark the closing in the handle so
406 that a http_close won't accidentally close the estream. The function
407 http_close removes this notification so that it won't be called if
408 http_close was used before an es_fclose. */
410 fp_onclose_notification (estream_t stream, void *opaque)
414 if (hd->fp_read && hd->fp_read == stream)
416 else if (hd->fp_write && hd->fp_write == stream)
422 * Helper function to create an HTTP header with hex encoded data. A
423 * new buffer is returned. This buffer is the concatenation of the
424 * string PREFIX, the hex-encoded DATA of length LEN and the string
425 * SUFFIX. On error NULL is returned and ERRNO set.
428 make_header_line (const char *prefix, const char *suffix,
429 const void *data, size_t len )
431 static unsigned char bintoasc[] =
432 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
433 "abcdefghijklmnopqrstuvwxyz"
435 const unsigned char *s = data;
438 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
441 p = stpcpy (buffer, prefix);
442 for ( ; len >= 3 ; len -= 3, s += 3 )
444 *p++ = bintoasc[(s[0] >> 2) & 077];
445 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
446 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
447 *p++ = bintoasc[s[2]&077];
452 *p++ = bintoasc[(s[0] >> 2) & 077];
453 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
454 *p++ = bintoasc[((s[1]<<2)&074)];
459 *p++ = bintoasc[(s[0] >> 2) & 077];
460 *p++ = bintoasc[(s[0] <<4)&060];
472 /* Register a non-standard global TLS callback function. If no
473 verification is desired a callback needs to be registered which
474 always returns NULL. */
476 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
482 /* Register a CA certificate for future use. The certificate is
483 expected to be in FNAME. PEM format is assume if FNAME has a
484 suffix of ".pem". If FNAME is NULL the list of CA files is
487 http_register_tls_ca (const char *fname)
493 free_strlist (tls_ca_certlist);
494 tls_ca_certlist = NULL;
498 /* Warn if we can't access right now, but register it anyway in
499 case it becomes accessible later */
500 if (access (fname, F_OK))
501 log_info (_("can't access '%s': %s\n"), fname,
502 gpg_strerror (gpg_error_from_syserror()));
503 sl = add_to_strlist (&tls_ca_certlist, fname);
504 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
510 /* Register a callback which is called every time the HTTP mode has
511 * made a successful connection to some server. */
513 http_register_netactivity_cb (void (*cb)(void))
519 /* Call the netactivity callback if any. */
521 notify_netactivity (void)
530 /* Free the TLS session associated with SESS, if any. */
532 close_tls_session (http_session_t sess)
534 if (sess->tls_session)
538 Possibly, ntbtls_get_transport and close those streams.
539 Somehow get SOCK to call my_socket_unref.
541 ntbtls_release (sess->tls_session);
542 # elif HTTP_USE_GNUTLS
543 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
544 my_socket_unref (sock, NULL, NULL);
545 gnutls_deinit (sess->tls_session);
547 gnutls_certificate_free_credentials (sess->certcred);
548 # endif /*HTTP_USE_GNUTLS*/
549 xfree (sess->servername);
550 sess->tls_session = NULL;
556 /* Release a session. Take care not to release it while it is being
557 used by a http context object. */
559 session_unref (int lnr, http_session_t sess)
565 /* log_debug ("http.c:session_unref(%d): sess %p ref now %d\n", */
566 /* lnr, sess, sess->refcount); */
572 close_tls_session (sess);
577 #define http_session_unref(a) session_unref (__LINE__, (a))
580 http_session_release (http_session_t sess)
582 http_session_unref (sess);
586 /* Create a new session object which is currently used to enable TLS
587 * support. It may eventually allow reusing existing connections.
588 * Valid values for FLAGS are:
589 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
590 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
593 http_session_new (http_session_t *r_session, const char *tls_priority,
594 const char *intended_hostname, unsigned int flags)
601 sess = xtrycalloc (1, sizeof *sess);
603 return gpg_error_from_syserror ();
610 /* ntbtls_set_debug (99, NULL, NULL); */
612 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
615 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
619 #elif HTTP_USE_GNUTLS
624 int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS);
627 rc = gnutls_certificate_allocate_credentials (&sess->certcred);
630 log_error ("gnutls_certificate_allocate_credentials failed: %s\n",
631 gnutls_strerror (rc));
632 err = gpg_error (GPG_ERR_GENERAL);
636 is_hkps_pool = (intended_hostname
637 && !ascii_strcasecmp (intended_hostname,
638 "hkps.pool.sks-keyservers.net"));
640 /* If the user has not specified a CA list, and they are looking
641 * for the hkps pool from sks-keyservers.net, then default to
642 * Kristian's certificate authority: */
643 if (!tls_ca_certlist && is_hkps_pool)
645 char *pemname = make_filename_try (gnupg_datadir (),
646 "sks-keyservers.netCA.pem", NULL);
649 err = gpg_error_from_syserror ();
650 log_error ("setting CA from file '%s' failed: %s\n",
651 pemname, gpg_strerror (err));
655 rc = gnutls_certificate_set_x509_trust_file
656 (sess->certcred, pemname, GNUTLS_X509_FMT_PEM);
658 log_info ("setting CA from file '%s' failed: %s\n",
659 pemname, gnutls_strerror (rc));
664 /* Add configured certificates to the session. */
665 if ((flags & HTTP_FLAG_TRUST_DEF))
667 for (sl = tls_ca_certlist; sl; sl = sl->next)
669 rc = gnutls_certificate_set_x509_trust_file
670 (sess->certcred, sl->d,
671 (sl->flags & 1)? GNUTLS_X509_FMT_PEM : GNUTLS_X509_FMT_DER);
673 log_info ("setting CA from file '%s' failed: %s\n",
674 sl->d, gnutls_strerror (rc));
676 if (!tls_ca_certlist && !is_hkps_pool)
680 /* Add system certificates to the session. */
683 #if GNUTLS_VERSION_NUMBER >= 0x030014
686 rc = gnutls_certificate_set_x509_system_trust (sess->certcred);
688 log_info ("setting system CAs failed: %s\n", gnutls_strerror (rc));
692 log_info ("number of system provided CAs: %d\n", rc);
694 #endif /* gnutls >= 3.0.20 */
697 rc = gnutls_init (&sess->tls_session, GNUTLS_CLIENT);
700 log_error ("gnutls_init failed: %s\n", gnutls_strerror (rc));
701 err = gpg_error (GPG_ERR_GENERAL);
704 /* A new session has the transport ptr set to (void*(-1), we need
706 gnutls_transport_set_ptr (sess->tls_session, NULL);
708 rc = gnutls_priority_set_direct (sess->tls_session,
709 tls_priority? tls_priority : "NORMAL",
713 log_error ("gnutls_priority_set_direct failed at '%s': %s\n",
714 errpos, gnutls_strerror (rc));
715 err = gpg_error (GPG_ERR_GENERAL);
719 rc = gnutls_credentials_set (sess->tls_session,
720 GNUTLS_CRD_CERTIFICATE, sess->certcred);
723 log_error ("gnutls_credentials_set failed: %s\n", gnutls_strerror (rc));
724 err = gpg_error (GPG_ERR_GENERAL);
728 #else /*!HTTP_USE_GNUTLS*/
732 #endif /*!HTTP_USE_GNUTLS*/
734 /* log_debug ("http.c:session_new: sess %p created\n", sess); */
741 http_session_unref (sess);
749 /* Increment the reference count for session SESS. Passing NULL for
752 http_session_ref (http_session_t sess)
757 /* log_debug ("http.c:session_ref: sess %p ref now %d\n", sess, */
758 /* sess->refcount); */
765 http_session_set_log_cb (http_session_t sess,
766 void (*cb)(http_session_t, gpg_error_t,
767 const char *hostname,
768 const void **certs, size_t *certlens))
770 sess->cert_log_cb = cb;
776 /* Start a HTTP retrieval and on success store at R_HD a context
777 pointer for completing the request and to wait for the response.
778 If HTTPHOST is not NULL it is used for the Host header instead of a
779 Host header derived from the URL. */
781 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
782 const char *httphost,
783 const char *auth, unsigned int flags, const char *proxy,
784 http_session_t session, const char *srvtag, strlist_t headers)
791 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
792 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
794 /* Create the handle. */
795 hd = xtrycalloc (1, sizeof *hd);
797 return gpg_error_from_syserror ();
798 hd->req_type = reqtype;
800 hd->session = http_session_ref (session);
802 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
804 err = send_request (hd, httphost, auth, proxy, srvtag, headers);
808 my_socket_unref (hd->sock, NULL, NULL);
810 es_fclose (hd->fp_read);
812 es_fclose (hd->fp_write);
813 http_session_unref (hd->session);
822 /* This function is useful to connect to a generic TCP service using
823 this http abstraction layer. This has the advantage of providing
824 service tags and an estream interface. */
826 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
827 unsigned int flags, const char *srvtag)
836 if ((flags & HTTP_FLAG_FORCE_TOR))
840 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
842 log_error ("Tor support is not available\n");
843 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
847 /* Create the handle. */
848 hd = xtrycalloc (1, sizeof *hd);
850 return gpg_error_from_syserror ();
851 hd->req_type = HTTP_REQ_OPAQUE;
858 sock = connect_server (server, port, hd->flags, srvtag, &hnf);
859 if (sock == ASSUAN_INVALID_FD)
861 err = gpg_err_make (default_errsource,
862 (hnf? GPG_ERR_UNKNOWN_HOST
863 : gpg_err_code_from_syserror ()));
867 hd->sock = my_socket_new (sock);
870 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
876 /* Setup estreams for reading and writing. */
877 cookie = xtrycalloc (1, sizeof *cookie);
880 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
883 cookie->sock = my_socket_ref (hd->sock);
884 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
887 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
888 my_socket_unref (cookie->sock, NULL, NULL);
892 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
894 cookie = xtrycalloc (1, sizeof *cookie);
897 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
900 cookie->sock = my_socket_ref (hd->sock);
901 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
904 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
905 my_socket_unref (cookie->sock, NULL, NULL);
909 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
911 /* Register close notification to interlock the use of es_fclose in
912 http_close and in user code. */
913 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
915 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
921 es_fclose (hd->fp_read);
923 es_fclose (hd->fp_write);
924 my_socket_unref (hd->sock, NULL, NULL);
936 http_start_data (http_t hd)
940 es_fputs ("\r\n", hd->fp_write);
941 es_fflush (hd->fp_write);
945 es_fflush (hd->fp_write);
950 http_wait_response (http_t hd)
955 /* Make sure that we are in the data. */
956 http_start_data (hd);
958 /* Close the write stream. Note that the reference counted socket
959 object keeps the actual system socket open. */
960 cookie = hd->write_cookie;
962 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
964 es_fclose (hd->fp_write);
966 /* The close has released the cookie and thus we better set it to NULL. */
967 hd->write_cookie = NULL;
969 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
970 is not required but some very old servers (e.g. the original pksd
971 keyserver didn't worked without it. */
972 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
973 shutdown (hd->sock->fd, 1);
976 /* Create a new cookie and a stream for reading. */
977 cookie = xtrycalloc (1, sizeof *cookie);
979 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
980 cookie->sock = my_socket_ref (hd->sock);
981 cookie->session = http_session_ref (hd->session);
982 cookie->use_tls = hd->uri->use_tls;
984 hd->read_cookie = cookie;
985 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
988 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
989 my_socket_unref (cookie->sock, NULL, NULL);
990 http_session_unref (cookie->session);
992 hd->read_cookie = NULL;
996 err = parse_response (hd);
999 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1005 /* Convenience function to send a request and wait for the response.
1006 Closes the handle on error. If PROXY is not NULL, this value will
1007 be used as an HTTP proxy and any enabled $http_proxy gets
1010 http_open_document (http_t *r_hd, const char *document,
1011 const char *auth, unsigned int flags, const char *proxy,
1012 http_session_t session,
1013 const char *srvtag, strlist_t headers)
1017 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1018 proxy, session, srvtag, headers);
1022 err = http_wait_response (*r_hd);
1024 http_close (*r_hd, 0);
1031 http_close (http_t hd, int keep_read_stream)
1036 /* First remove the close notifications for the streams. */
1038 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1040 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1042 /* Now we can close the streams. */
1043 my_socket_unref (hd->sock, NULL, NULL);
1044 if (hd->fp_read && !keep_read_stream)
1045 es_fclose (hd->fp_read);
1047 es_fclose (hd->fp_write);
1048 http_session_unref (hd->session);
1049 http_release_parsed_uri (hd->uri);
1052 header_t tmp = hd->headers->next;
1053 xfree (hd->headers->value);
1054 xfree (hd->headers);
1063 http_get_read_ptr (http_t hd)
1065 return hd?hd->fp_read:NULL;
1069 http_get_write_ptr (http_t hd)
1071 return hd?hd->fp_write:NULL;
1075 http_get_status_code (http_t hd)
1077 return hd?hd->status_code:0;
1080 /* Return information pertaining to TLS. If TLS is not in use for HD,
1081 NULL is returned. WHAT is used ask for specific information:
1083 (NULL) := Only check whether TLS is is use. Returns an
1084 unspecified string if TLS is in use. That string may
1085 even be the empty string.
1088 http_get_tls_info (http_t hd, const char *what)
1095 return hd->uri->use_tls? "":NULL;
1101 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1102 int no_scheme_check, int force_tls)
1106 *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1108 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1109 strcpy ((*ret_uri)->buffer, uri);
1110 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1116 return gpg_err_make (default_errsource, ec);
1121 * Parse an URI and put the result into the newly allocated RET_URI.
1122 * On success the caller must use http_release_parsed_uri() to
1123 * releases the resources. If NO_SCHEME_CHECK is set, the function
1124 * tries to parse the URL in the same way it would do for an HTTP
1128 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1129 int no_scheme_check)
1131 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1136 http_release_parsed_uri (parsed_uri_t uri)
1142 for (r = uri->query; r; r = r2)
1152 static gpg_err_code_t
1153 do_parse_uri (parsed_uri_t uri, int only_local_part,
1154 int no_scheme_check, int force_tls)
1157 char *p, *p2, *p3, *pp;
1161 n = strlen (uri->buffer);
1163 /* Initialize all fields to an empty string or an empty list. */
1164 uri->scheme = uri->host = uri->path = p + n;
1166 uri->params = uri->query = NULL;
1173 /* A quick validity check. */
1174 if (strspn (p, VALID_URI_CHARS) != n)
1175 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1177 if (!only_local_part)
1179 /* Find the scheme. */
1180 if (!(p2 = strchr (p, ':')) || p2 == p)
1181 return GPG_ERR_BAD_URI; /* No scheme. */
1183 for (pp=p; *pp; pp++)
1184 *pp = tolower (*(unsigned char*)pp);
1186 if (!strcmp (uri->scheme, "http") && !force_tls)
1191 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1197 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1198 || (force_tls && (!strcmp (uri->scheme, "http")
1199 || !strcmp (uri->scheme,"hkp"))))
1206 else if (!no_scheme_check)
1207 return GPG_ERR_INV_URI; /* Unsupported scheme */
1211 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1214 if ((p2 = strchr (p, '/')))
1217 /* Check for username/password encoding */
1218 if ((p3 = strchr (p, '@')))
1225 for (pp=p; *pp; pp++)
1226 *pp = tolower (*(unsigned char*)pp);
1228 /* Handle an IPv6 literal */
1229 if( *p == '[' && (p3=strchr( p, ']' )) )
1232 /* worst case, uri->host should have length 0, points to \0 */
1240 if ((p3 = strchr (p, ':')))
1243 uri->port = atoi (p3);
1246 if ((n = remove_escapes (uri->host)) < 0)
1247 return GPG_ERR_BAD_URI;
1248 if (n != strlen (uri->host))
1249 return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */
1252 else if (uri->is_http)
1253 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1258 if (is_onion_address (uri->path))
1263 } /* End global URI part. */
1265 /* Parse the pathname part if any. */
1268 /* TODO: Here we have to check params. */
1270 /* Do we have a query part? */
1271 if ((p2 = strchr (p, '?')))
1275 if ((n = remove_escapes (p)) < 0)
1276 return GPG_ERR_BAD_URI;
1277 if (n != strlen (p))
1278 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1281 /* Parse a query string if any. */
1289 if ((p2 = strchr (p, '&')))
1291 if (!(elem = parse_tuple (p)))
1292 return GPG_ERR_BAD_URI;
1303 if (is_onion_address (uri->host))
1311 * Remove all %xx escapes; this is done in-place. Returns: New length
1315 remove_escapes (char *string)
1318 unsigned char *p, *s;
1320 for (p = s = (unsigned char*)string; *s; s++)
1324 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1327 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1328 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1331 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1332 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1345 return -1; /* Bad URI. */
1354 *p = 0; /* Make sure to keep a string terminator. */
1359 /* If SPECIAL is NULL this function escapes in forms mode. */
1361 escape_data (char *buffer, const void *data, size_t datalen,
1362 const char *special)
1364 int forms = !special;
1365 const unsigned char *s;
1371 for (s = data; datalen; s++, datalen--)
1373 if (forms && *s == ' ')
1379 else if (forms && *s == '\n')
1382 memcpy (buffer, "%0D%0A", 6);
1385 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1388 memcpy (buffer, "%0D%0A", 6);
1393 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1396 *(unsigned char*)buffer++ = *s;
1403 snprintf (buffer, 4, "%%%02X", *s);
1414 insert_escapes (char *buffer, const char *string,
1415 const char *special)
1417 return escape_data (buffer, string, strlen (string), special);
1421 /* Allocate a new string from STRING using standard HTTP escaping as
1422 well as escaping of characters given in SPECIALS. A common pattern
1423 for SPECIALS is "%;?&=". However it depends on the needs, for
1424 example "+" and "/: often needs to be escaped too. Returns NULL on
1425 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1426 encoding mode is used. */
1428 http_escape_string (const char *string, const char *specials)
1433 n = insert_escapes (NULL, string, specials);
1434 buf = xtrymalloc (n+1);
1437 insert_escapes (buf, string, specials);
1443 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1444 escaping as well as escaping of characters given in SPECIALS. A
1445 common pattern for SPECIALS is "%;?&=". However it depends on the
1446 needs, for example "+" and "/: often needs to be escaped too.
1447 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1448 dedicated forms encoding mode is used. */
1450 http_escape_data (const void *data, size_t datalen, const char *specials)
1455 n = escape_data (NULL, data, datalen, specials);
1456 buf = xtrymalloc (n+1);
1459 escape_data (buf, data, datalen, specials);
1467 parse_tuple (char *string)
1474 if ((p2 = strchr (p, '=')))
1476 if ((n = remove_escapes (p)) < 0)
1477 return NULL; /* Bad URI. */
1478 if (n != strlen (p))
1479 return NULL; /* Name with a Nul in it. */
1480 tuple = xtrycalloc (1, sizeof *tuple);
1482 return NULL; /* Out of core. */
1484 if (!p2) /* We have only the name, so we assume an empty value string. */
1486 tuple->value = p + strlen (p);
1487 tuple->valuelen = 0;
1488 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1490 else /* Name and value. */
1492 if ((n = remove_escapes (p2)) < 0)
1495 return NULL; /* Bad URI. */
1498 tuple->valuelen = n;
1504 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1506 is_hostname_port (const char *string)
1510 if (!string || !*string)
1512 for (; *string; string++)
1522 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1523 return 0; /* Invalid characters in hostname. */
1524 else if (colons && !digitp (string))
1525 return 0; /* Not a digit in the port. */
1532 * Send a HTTP request to the server
1533 * Returns 0 if the request was successful
1536 send_request (http_t hd, const char *httphost, const char *auth,
1537 const char *proxy, const char *srvtag, strlist_t headers)
1542 unsigned short port;
1543 const char *http_proxy = NULL;
1544 char *proxy_authstr = NULL;
1545 char *authstr = NULL;
1549 if (hd->uri->use_tls && !hd->session)
1551 log_error ("TLS requested but no session object provided\n");
1552 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1555 if (hd->uri->use_tls && !hd->session->tls_session)
1557 log_error ("TLS requested but no GNUTLS context available\n");
1558 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1562 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1566 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1568 log_error ("Tor support is not available\n");
1569 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1573 server = *hd->uri->host ? hd->uri->host : "localhost";
1574 port = hd->uri->port ? hd->uri->port : 80;
1576 /* Try to use SNI. */
1578 if (hd->uri->use_tls)
1580 # if HTTP_USE_GNUTLS
1584 xfree (hd->session->servername);
1585 hd->session->servername = xtrystrdup (httphost? httphost : server);
1586 if (!hd->session->servername)
1588 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1592 # if HTTP_USE_NTBTLS
1593 err = ntbtls_set_hostname (hd->session->tls_session,
1594 hd->session->servername);
1597 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1600 # elif HTTP_USE_GNUTLS
1601 rc = gnutls_server_name_set (hd->session->tls_session,
1603 hd->session->servername,
1604 strlen (hd->session->servername));
1606 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1607 # endif /*HTTP_USE_GNUTLS*/
1611 if ( (proxy && *proxy)
1612 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1613 && (http_proxy = getenv (HTTP_PROXY_ENV))
1622 err = parse_uri (&uri, http_proxy, 0, 0);
1623 if (gpg_err_code (err) == GPG_ERR_INV_URI
1624 && is_hostname_port (http_proxy))
1626 /* Retry assuming a "hostname:port" string. */
1627 char *tmpname = strconcat ("http://", http_proxy, NULL);
1628 if (tmpname && !parse_uri (&uri, tmpname, 0, 0))
1635 else if (!strcmp (uri->scheme, "http") || !strcmp (uri->scheme, "socks4"))
1637 else if (!strcmp (uri->scheme, "socks5h"))
1638 err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1640 err = gpg_err_make (default_errsource, GPG_ERR_INV_URI);
1644 log_error ("invalid HTTP proxy (%s): %s\n",
1645 http_proxy, gpg_strerror (err));
1646 return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION);
1651 remove_escapes (uri->auth);
1652 proxy_authstr = make_header_line ("Proxy-Authorization: Basic ",
1654 uri->auth, strlen(uri->auth));
1657 err = gpg_err_make (default_errsource,
1658 gpg_err_code_from_syserror ());
1659 http_release_parsed_uri (uri);
1664 sock = connect_server (*uri->host ? uri->host : "localhost",
1665 uri->port ? uri->port : 80,
1666 hd->flags, srvtag, &hnf);
1668 http_release_parsed_uri (uri);
1669 if (sock == ASSUAN_INVALID_FD)
1670 gpg_err_set_errno (save_errno);
1674 sock = connect_server (server, port, hd->flags, srvtag, &hnf);
1677 if (sock == ASSUAN_INVALID_FD)
1679 xfree (proxy_authstr);
1680 return gpg_err_make (default_errsource,
1681 (hnf? GPG_ERR_UNKNOWN_HOST
1682 : gpg_err_code_from_syserror ()));
1684 hd->sock = my_socket_new (sock);
1687 xfree (proxy_authstr);
1688 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1694 if (hd->uri->use_tls)
1698 my_socket_ref (hd->sock);
1700 in = es_fdopen_nc (hd->sock->fd, "rb");
1703 err = gpg_error_from_syserror ();
1704 xfree (proxy_authstr);
1708 out = es_fdopen_nc (hd->sock->fd, "wb");
1711 err = gpg_error_from_syserror ();
1713 xfree (proxy_authstr);
1717 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1720 log_info ("TLS set_transport failed: %s <%s>\n",
1721 gpg_strerror (err), gpg_strsource (err));
1722 xfree (proxy_authstr);
1726 while ((err = ntbtls_handshake (hd->session->tls_session)))
1731 log_info ("TLS handshake failed: %s <%s>\n",
1732 gpg_strerror (err), gpg_strsource (err));
1733 xfree (proxy_authstr);
1738 hd->session->verify.done = 0;
1740 err = tls_callback (hd, hd->session, 0);
1742 err = http_verify_server_credentials (hd->session);
1745 log_info ("TLS connection authentication failed: %s <%s>\n",
1746 gpg_strerror (err), gpg_strsource (err));
1747 xfree (proxy_authstr);
1751 #elif HTTP_USE_GNUTLS
1752 if (hd->uri->use_tls)
1756 my_socket_ref (hd->sock);
1757 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1758 gnutls_transport_set_pull_function (hd->session->tls_session,
1760 gnutls_transport_set_push_function (hd->session->tls_session,
1765 rc = gnutls_handshake (hd->session->tls_session);
1767 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1770 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1771 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1773 gnutls_alert_description_t alertno;
1774 const char *alertstr;
1776 alertno = gnutls_alert_get (hd->session->tls_session);
1777 alertstr = gnutls_alert_get_name (alertno);
1778 log_info ("TLS handshake failed: %s (alert %d)\n",
1779 alertstr, (int)alertno);
1780 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1781 log_info (" (sent server name '%s')\n", server);
1784 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1785 xfree (proxy_authstr);
1786 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1789 hd->session->verify.done = 0;
1791 err = tls_callback (hd, hd->session, 0);
1793 err = http_verify_server_credentials (hd->session);
1796 log_info ("TLS connection authentication failed: %s\n",
1797 gpg_strerror (err));
1798 xfree (proxy_authstr);
1802 #endif /*HTTP_USE_GNUTLS*/
1804 if (auth || hd->uri->auth)
1810 myauth = xtrystrdup (auth);
1813 xfree (proxy_authstr);
1814 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1816 remove_escapes (myauth);
1820 remove_escapes (hd->uri->auth);
1821 myauth = hd->uri->auth;
1824 authstr = make_header_line ("Authorization: Basic ", "\r\n",
1825 myauth, strlen (myauth));
1831 xfree (proxy_authstr);
1832 return gpg_err_make (default_errsource,
1833 gpg_err_code_from_syserror ());
1837 p = build_rel_path (hd->uri);
1839 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1841 if (http_proxy && *http_proxy)
1843 request = es_bsprintf
1844 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1845 hd->req_type == HTTP_REQ_GET ? "GET" :
1846 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1847 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1848 hd->uri->use_tls? "https" : "http",
1849 httphost? httphost : server,
1850 port, *p == '/' ? "" : "/", p,
1851 authstr ? authstr : "",
1852 proxy_authstr ? proxy_authstr : "");
1861 snprintf (portstr, sizeof portstr, ":%u", port);
1863 request = es_bsprintf
1864 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
1865 hd->req_type == HTTP_REQ_GET ? "GET" :
1866 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1867 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1868 *p == '/' ? "" : "/", p,
1869 httphost? httphost : server,
1871 authstr? authstr:"");
1876 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1878 xfree (proxy_authstr);
1882 /* log_debug ("request:\n%s\nEND request\n", request); */
1884 /* First setup estream so that we can write even the first line
1885 using estream. This is also required for the sake of gnutls. */
1889 cookie = xtrycalloc (1, sizeof *cookie);
1892 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1895 cookie->sock = my_socket_ref (hd->sock);
1896 hd->write_cookie = cookie;
1897 cookie->use_tls = hd->uri->use_tls;
1898 cookie->session = http_session_ref (hd->session);
1900 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
1903 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1904 my_socket_unref (cookie->sock, NULL, NULL);
1906 hd->write_cookie = NULL;
1908 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
1909 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1915 for (;headers; headers=headers->next)
1917 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
1918 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
1920 err = gpg_err_make (default_errsource,
1921 gpg_err_code_from_syserror ());
1931 xfree (proxy_authstr);
1938 * Build the relative path from the parsed URI. Minimal
1939 * implementation. May return NULL in case of memory failure; errno
1940 * is then set accordingly.
1943 build_rel_path (parsed_uri_t uri)
1949 /* Count the needed space. */
1950 n = insert_escapes (NULL, uri->path, "%;?&");
1951 /* TODO: build params. */
1952 for (r = uri->query; r; r = r->next)
1955 n += insert_escapes (NULL, r->name, "%;?&=");
1959 n += insert_escapes (NULL, r->value, "%;?&=");
1964 /* Now allocate and copy. */
1965 p = rel_path = xtrymalloc (n);
1968 n = insert_escapes (p, uri->path, "%;?&");
1970 /* TODO: add params. */
1971 for (r = uri->query; r; r = r->next)
1973 *p++ = r == uri->query ? '?' : '&';
1974 n = insert_escapes (p, r->name, "%;?&=");
1979 /* TODO: Use valuelen. */
1980 n = insert_escapes (p, r->value, "%;?&=");
1989 /* Transform a header name into a standard capitalized format; e.g.
1990 "Content-Type". Conversion stops at the colon. As usual we don't
1991 use the localized versions of ctype.h. */
1993 capitalize_header_name (char *name)
1997 for (; *name && *name != ':'; name++)
2003 if (*name >= 'a' && *name <= 'z')
2004 *name = *name - 'a' + 'A';
2007 else if (*name >= 'A' && *name <= 'Z')
2008 *name = *name - 'A' + 'a';
2013 /* Store an HTTP header line in LINE away. Line continuation is
2014 supported as well as merging of headers with the same name. This
2015 function may modify LINE. */
2016 static gpg_err_code_t
2017 store_header (http_t hd, char *line)
2024 if (n && line[n-1] == '\n')
2027 if (n && line[n-1] == '\r')
2030 if (!n) /* we are never called to hit this. */
2032 if (*line == ' ' || *line == '\t')
2034 /* Continuation. This won't happen too often as it is not
2035 recommended. We use a straightforward implementaion. */
2037 return GPG_ERR_PROTOCOL_VIOLATION;
2038 n += strlen (hd->headers->value);
2039 p = xtrymalloc (n+1);
2041 return gpg_err_code_from_syserror ();
2042 strcpy (stpcpy (p, hd->headers->value), line);
2043 xfree (hd->headers->value);
2044 hd->headers->value = p;
2048 capitalize_header_name (line);
2049 p = strchr (line, ':');
2051 return GPG_ERR_PROTOCOL_VIOLATION;
2053 while (*p == ' ' || *p == '\t')
2057 for (h=hd->headers; h; h = h->next)
2058 if ( !strcmp (h->name, line) )
2062 /* We have already seen a line with that name. Thus we assume
2063 it is a comma separated list and merge them. */
2064 p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1);
2066 return gpg_err_code_from_syserror ();
2067 strcpy (stpcpy (stpcpy (p, h->value), ","), value);
2073 /* Append a new header. */
2074 h = xtrymalloc (sizeof *h + strlen (line));
2076 return gpg_err_code_from_syserror ();
2077 strcpy (h->name, line);
2078 h->value = xtrymalloc (strlen (value)+1);
2082 return gpg_err_code_from_syserror ();
2084 strcpy (h->value, value);
2085 h->next = hd->headers;
2092 /* Return the header NAME from the last response. The returned value
2093 is valid as along as HD has not been closed and no other request
2094 has been send. If the header was not found, NULL is returned. NAME
2095 must be canonicalized, that is the first letter of each dash
2096 delimited part must be uppercase and all other letters lowercase. */
2098 http_get_header (http_t hd, const char *name)
2102 for (h=hd->headers; h; h = h->next)
2103 if ( !strcmp (h->name, name) )
2109 /* Return a newly allocated and NULL terminated array with pointers to
2110 header names. The array must be released with xfree() and its
2111 content is only values as long as no other request has been
2114 http_get_header_names (http_t hd)
2120 for (n=0, h = hd->headers; h; h = h->next)
2122 array = xtrycalloc (n+1, sizeof *array);
2125 for (n=0, h = hd->headers; h; h = h->next)
2126 array[n++] = h->name;
2134 * Parse the response from a server.
2135 * Returns: Errorcode and sets some files in the handle
2137 static gpg_err_code_t
2138 parse_response (http_t hd)
2140 char *line, *p, *p2;
2142 cookie_t cookie = hd->read_cookie;
2145 /* Delete old header lines. */
2148 header_t tmp = hd->headers->next;
2149 xfree (hd->headers->value);
2150 xfree (hd->headers);
2154 /* Wait for the status line. */
2157 maxlen = MAX_LINELEN;
2158 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2161 return gpg_err_code_from_syserror (); /* Out of core. */
2163 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2167 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2168 log_info ("RESP: '%.*s'\n",
2169 (int)strlen(line)-(*line&&line[1]?2:0),line);
2173 if ((p = strchr (line, '/')))
2175 if (!p || strcmp (line, "HTTP"))
2176 return 0; /* Assume http 0.9. */
2178 if ((p2 = strpbrk (p, " \t")))
2181 p2 += strspn (p2, " \t");
2184 return 0; /* Also assume http 0.9. */
2186 /* TODO: Add HTTP version number check. */
2187 if ((p2 = strpbrk (p, " \t")))
2189 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2190 || !isdigit ((unsigned int)p[2]) || p[3])
2192 /* Malformed HTTP status code - assume http 0.9. */
2193 hd->is_http_0_9 = 1;
2194 hd->status_code = 200;
2197 hd->status_code = atoi (p);
2199 /* Skip all the header lines and wait for the empty line. */
2202 maxlen = MAX_LINELEN;
2203 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2206 return gpg_err_code_from_syserror (); /* Out of core. */
2207 /* Note, that we can silently ignore truncated lines. */
2210 /* Trim line endings of empty lines. */
2211 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2213 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2214 log_info ("RESP: '%.*s'\n",
2215 (int)strlen(line)-(*line&&line[1]?2:0),line);
2218 gpg_err_code_t ec = store_header (hd, line);
2223 while (len && *line);
2225 cookie->content_length_valid = 0;
2226 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2228 s = http_get_header (hd, "Content-Length");
2231 cookie->content_length_valid = 1;
2232 cookie->content_length = string_to_u64 (s);
2243 struct sockaddr_in mya;
2244 struct sockaddr_in peer;
2250 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2252 log_error ("socket() failed: %s\n", strerror (errno));
2256 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2257 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2259 mya.sin_family = AF_INET;
2260 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2261 mya.sin_port = htons (11371);
2263 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2265 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2272 log_error ("listen failed: %s\n", strerror (errno));
2282 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2283 continue; /* ignore any errors */
2285 if (!FD_ISSET (fd, &rfds))
2288 addrlen = sizeof peer;
2289 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2291 continue; /* oops */
2293 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2302 fp = fdopen (client, "r");
2303 while ((c = getc (fp)) != EOF)
2308 sock_close (client);
2316 /* Actually connect to a server. Returns the file descriptor or -1 on
2317 error. ERRNO is set on error. */
2319 connect_server (const char *server, unsigned short port,
2320 unsigned int flags, const char *srvtag, int *r_host_not_found)
2323 assuan_fd_t sock = ASSUAN_INVALID_FD;
2324 unsigned int srvcount = 0;
2326 int anyhostaddr = 0;
2329 struct srventry *serverlist = NULL;
2332 *r_host_not_found = 0;
2333 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2337 /* Onion addresses require special treatment. */
2338 if (is_onion_address (server))
2340 #ifdef ASSUAN_SOCK_TOR
2342 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2344 if (sock == ASSUAN_INVALID_FD)
2346 if (errno == EHOSTUNREACH)
2347 *r_host_not_found = 1;
2348 log_error ("can't connect to '%s': %s\n", server, strerror (errno));
2351 notify_netactivity ();
2354 #else /*!ASSUAN_SOCK_TOR*/
2356 gpg_err_set_errno (ENETUNREACH);
2357 return -1; /* Out of core. */
2359 #endif /*!HASSUAN_SOCK_TOR*/
2362 /* Do the SRV thing */
2365 /* We're using SRV, so append the tags. */
2366 if (1 + strlen (srvtag) + 6 + strlen (server) + 1
2367 <= DIMof (struct srventry, target))
2369 char *srvname = xtrymalloc (DIMof (struct srventry, target));
2371 if (!srvname) /* Out of core */
2378 stpcpy (stpcpy (stpcpy (stpcpy (srvname,"_"), srvtag),
2380 err = get_dns_srv (srvname, &serverlist, &srvcount);
2382 log_info ("getting SRV '%s' failed: %s\n",
2383 srvname, gpg_strerror (err));
2385 /* Note that on error SRVCOUNT is zero. */
2392 /* Either we're not using SRV, or the SRV lookup failed. Make
2393 up a fake SRV record. */
2394 serverlist = xtrycalloc (1, sizeof *serverlist);
2396 return -1; /* Out of core. */
2397 serverlist->port = port;
2398 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2399 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2404 for (srv=0; srv < srvcount && !connected; srv++)
2406 dns_addrinfo_t aibuf, ai;
2408 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2412 log_info ("resolving '%s' failed: %s\n",
2413 serverlist[srv].target, gpg_strerror (err));
2414 continue; /* Not found - try next one. */
2418 for (ai = aibuf; ai && !connected; ai = ai->next)
2420 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2422 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2425 if (sock != ASSUAN_INVALID_FD)
2426 assuan_sock_close (sock);
2427 sock = assuan_sock_new (ai->family, ai->socktype, ai->protocol);
2428 if (sock == ASSUAN_INVALID_FD)
2430 int save_errno = errno;
2431 log_error ("error creating socket: %s\n", strerror (errno));
2432 free_dns_addrinfo (aibuf);
2435 return ASSUAN_INVALID_FD;
2439 ret = assuan_sock_connect (sock, ai->addr, ai->addrlen);
2445 notify_netactivity ();
2448 free_dns_addrinfo (aibuf);
2456 log_error ("can't connect to '%s': %s\n",
2457 server, "host not found");
2458 else if (!anyhostaddr)
2459 log_error ("can't connect to '%s': %s\n",
2460 server, "no IP address for host");
2463 #ifdef HAVE_W32_SYSTEM
2464 log_error ("can't connect to '%s': ec=%d\n",
2465 server, (int)WSAGetLastError());
2467 log_error ("can't connect to '%s': %s\n",
2468 server, strerror (last_errno));
2471 if (!hostfound || (hostfound && !anyhostaddr))
2472 *r_host_not_found = 1;
2473 if (sock != ASSUAN_INVALID_FD)
2474 assuan_sock_close (sock);
2475 gpg_err_set_errno (last_errno);
2476 return ASSUAN_INVALID_FD;
2483 write_server (int sock, const char *data, size_t length)
2491 #if defined(HAVE_W32_SYSTEM)
2492 # if defined(USE_NPTH)
2495 nwritten = send (sock, data, nleft, 0);
2496 # if defined(USE_NPTH)
2499 if ( nwritten == SOCKET_ERROR )
2501 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2502 return gpg_error (GPG_ERR_NETWORK);
2504 #else /*!HAVE_W32_SYSTEM*/
2506 nwritten = npth_write (sock, data, nleft);
2508 nwritten = write (sock, data, nleft);
2514 if (errno == EAGAIN)
2520 my_select (0, NULL, NULL, NULL, &tv);
2523 log_info ("network write failed: %s\n", strerror (errno));
2524 return gpg_error_from_syserror ();
2526 #endif /*!HAVE_W32_SYSTEM*/
2536 /* Read handler for estream. */
2537 static gpgrt_ssize_t
2538 cookie_read (void *cookie, void *buffer, size_t size)
2540 cookie_t c = cookie;
2543 if (c->content_length_valid)
2545 if (!c->content_length)
2547 if (c->content_length < size)
2548 size = c->content_length;
2552 if (c->use_tls && c->session && c->session->tls_session)
2556 ntbtls_get_stream (c->session->tls_session, &in, &out);
2557 nread = es_fread (buffer, 1, size, in);
2558 log_debug ("TLS network read: %d/%u\n", nread, size);
2561 #elif HTTP_USE_GNUTLS
2562 if (c->use_tls && c->session && c->session->tls_session)
2565 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2568 if (nread == GNUTLS_E_INTERRUPTED)
2570 if (nread == GNUTLS_E_AGAIN)
2576 my_select (0, NULL, NULL, NULL, &tv);
2579 if (nread == GNUTLS_E_REHANDSHAKE)
2580 goto again; /* A client is allowed to just ignore this request. */
2581 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2583 /* The server terminated the connection. Close the TLS
2584 session, and indicate EOF using a short read. */
2585 close_tls_session (c->session);
2588 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2589 gpg_err_set_errno (EIO);
2594 #endif /*HTTP_USE_GNUTLS*/
2598 #ifdef HAVE_W32_SYSTEM
2599 /* Under Windows we need to use recv for a socket. */
2600 # if defined(USE_NPTH)
2603 nread = recv (c->sock->fd, buffer, size, 0);
2604 # if defined(USE_NPTH)
2608 #else /*!HAVE_W32_SYSTEM*/
2611 nread = npth_read (c->sock->fd, buffer, size);
2613 nread = read (c->sock->fd, buffer, size);
2616 #endif /*!HAVE_W32_SYSTEM*/
2618 while (nread == -1 && errno == EINTR);
2621 if (c->content_length_valid && nread > 0)
2623 if (nread < c->content_length)
2624 c->content_length -= nread;
2626 c->content_length = 0;
2629 return (gpgrt_ssize_t)nread;
2632 /* Write handler for estream. */
2633 static gpgrt_ssize_t
2634 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2636 const char *buffer = buffer_arg;
2637 cookie_t c = cookie;
2641 if (c->use_tls && c->session && c->session->tls_session)
2645 ntbtls_get_stream (c->session->tls_session, &in, &out);
2649 nwritten = es_fwrite (buffer, 1, size, out);
2650 log_debug ("TLS network write: %d/%u\n", nwritten, size);
2653 #elif HTTP_USE_GNUTLS
2654 if (c->use_tls && c->session && c->session->tls_session)
2659 nwritten = gnutls_record_send (c->session->tls_session,
2663 if (nwritten == GNUTLS_E_INTERRUPTED)
2665 if (nwritten == GNUTLS_E_AGAIN)
2671 my_select (0, NULL, NULL, NULL, &tv);
2674 log_info ("TLS network write failed: %s\n",
2675 gnutls_strerror (nwritten));
2676 gpg_err_set_errno (EIO);
2684 #endif /*HTTP_USE_GNUTLS*/
2686 if ( write_server (c->sock->fd, buffer, size) )
2688 gpg_err_set_errno (EIO);
2695 return (gpgrt_ssize_t)nwritten;
2699 #ifdef HTTP_USE_GNUTLS
2700 /* Wrapper for gnutls_bye used by my_socket_unref. */
2702 send_gnutls_bye (void *opaque)
2704 tls_session_t tls_session = opaque;
2709 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2710 while (ret == GNUTLS_E_INTERRUPTED);
2711 if (ret == GNUTLS_E_AGAIN)
2717 my_select (0, NULL, NULL, NULL, &tv);
2721 #endif /*HTTP_USE_GNUTLS*/
2723 /* Close handler for estream. */
2725 cookie_close (void *cookie)
2727 cookie_t c = cookie;
2733 if (c->use_tls && c->session && c->session->tls_session)
2735 /* FIXME!! Possibly call ntbtls_close_notify for close
2737 my_socket_unref (c->sock, NULL, NULL);
2740 #elif HTTP_USE_GNUTLS
2741 if (c->use_tls && c->session && c->session->tls_session)
2742 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
2744 #endif /*HTTP_USE_GNUTLS*/
2746 my_socket_unref (c->sock, NULL, NULL);
2749 http_session_unref (c->session);
2757 /* Verify the credentials of the server. Returns 0 on success and
2758 store the result in the session object. */
2760 http_verify_server_credentials (http_session_t sess)
2764 return 0; /* FIXME!! */
2765 #elif HTTP_USE_GNUTLS
2766 static const char const errprefix[] = "TLS verification of peer failed";
2768 unsigned int status;
2769 const char *hostname;
2770 const gnutls_datum_t *certlist;
2771 unsigned int certlistlen;
2772 gnutls_x509_crt_t cert;
2773 gpg_error_t err = 0;
2775 sess->verify.done = 1;
2776 sess->verify.status = 0;
2777 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
2779 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
2781 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
2782 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2783 return gpg_error (GPG_ERR_GENERAL);
2786 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
2789 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
2791 err = gpg_error (GPG_ERR_GENERAL);
2795 log_error ("%s: status=0x%04x\n", errprefix, status);
2796 #if GNUTLS_VERSION_NUMBER >= 0x030104
2798 gnutls_datum_t statusdat;
2800 if (!gnutls_certificate_verification_status_print
2801 (status, GNUTLS_CRT_X509, &statusdat, 0))
2803 log_info ("%s: %s\n", errprefix, statusdat.data);
2804 gnutls_free (statusdat.data);
2807 #endif /*gnutls >= 3.1.4*/
2809 sess->verify.status = status;
2811 err = gpg_error (GPG_ERR_GENERAL);
2814 hostname = sess->servername;
2815 if (!hostname || !strchr (hostname, '.'))
2817 log_error ("%s: %s\n", errprefix, "hostname missing");
2819 err = gpg_error (GPG_ERR_GENERAL);
2822 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
2825 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
2827 err = gpg_error (GPG_ERR_GENERAL);
2829 /* Need to stop here. */
2834 rc = gnutls_x509_crt_init (&cert);
2838 err = gpg_error (GPG_ERR_GENERAL);
2843 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
2846 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
2847 gnutls_strerror (rc));
2849 err = gpg_error (GPG_ERR_GENERAL);
2852 if (!gnutls_x509_crt_check_hostname (cert, hostname))
2854 log_error ("%s: %s\n", errprefix, "hostname does not match");
2856 err = gpg_error (GPG_ERR_GENERAL);
2859 gnutls_x509_crt_deinit (cert);
2862 sess->verify.rc = 0;
2864 if (sess->cert_log_cb)
2866 const void *bufarr[10];
2867 size_t buflenarr[10];
2870 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
2872 bufarr[n] = certlist[n].data;
2873 buflenarr[n] = certlist[n].size;
2877 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
2881 #else /*!HTTP_USE_GNUTLS*/
2883 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2887 /* Return the first query variable with the specified key. If there
2888 is no such variable, return NULL. */
2889 struct uri_tuple_s *
2890 uri_query_lookup (parsed_uri_t uri, const char *key)
2892 struct uri_tuple_s *t;
2894 for (t = uri->query; t; t = t->next)
2895 if (strcmp (t->name, key) == 0)