1 /* http.c - HTTP protocol handler
2 * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
3 * 2011 Free Software Foundation, Inc.
4 * Copyright (C) 2014 Werner Koch
5 * Copyright (C) 2015-2017 g10 Code GmbH
7 * This file is part of GnuPG.
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of either
12 * - the GNU Lesser General Public License as published by the Free
13 * Software Foundation; either version 3 of the License, or (at
14 * your option) any later version.
18 * - the GNU General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at
20 * your option) any later version.
22 * or both in parallel, as here.
24 * This file is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, see <https://www.gnu.org/licenses/>.
33 /* Simple HTTP client implementation. We try to keep the code as
34 self-contained as possible. There are some constraints however:
36 - estream is required. We now require estream because it provides a
37 very useful and portable asprintf implementation and the fopencookie
40 - fixme: list other requirements.
43 - With HTTP_USE_NTBTLS or HTTP_USE_GNUTLS support for https is
44 provided (this also requires estream).
46 - With HTTP_NO_WSASTARTUP the socket initialization is not done
47 under Windows. This is useful if the socket layer has already
48 been initialized elsewhere. This also avoids the installation of
49 an exit handler to cleanup the socket layer.
63 #ifdef HAVE_W32_SYSTEM
64 # ifdef HAVE_WINSOCK2_H
65 # include <winsock2.h>
68 #else /*!HAVE_W32_SYSTEM*/
69 # include <sys/types.h>
70 # include <sys/socket.h>
71 # include <sys/time.h>
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. */
99 #include "../common/util.h"
100 #include "../common/i18n.h"
101 #include "../common/sysutils.h" /* (gnupg_fd_t) */
102 #include "dns-stuff.h"
104 #include "http-common.h"
108 # define my_select(a,b,c,d,e) npth_select ((a), (b), (c), (d), (e))
109 # define my_accept(a,b,c) npth_accept ((a), (b), (c))
111 # define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e))
112 # define my_accept(a,b,c) accept ((a), (b), (c))
115 #ifdef HAVE_W32_SYSTEM
116 #define sock_close(a) closesocket(a)
118 #define sock_close(a) close(a)
122 #define EAGAIN EWOULDBLOCK
124 #ifndef INADDR_NONE /* Slowaris is missing that. */
125 #define INADDR_NONE ((unsigned long)(-1))
126 #endif /*INADDR_NONE*/
128 #define HTTP_PROXY_ENV "http_proxy"
129 #define MAX_LINELEN 20000 /* Max. length of a HTTP header line. */
130 #define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
131 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
133 "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
136 typedef ntbtls_t tls_session_t;
138 #elif HTTP_USE_GNUTLS
139 typedef gnutls_session_t tls_session_t;
142 typedef void *tls_session_t;
146 static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part,
147 int no_scheme_check, int force_tls);
148 static gpg_error_t parse_uri (parsed_uri_t *ret_uri, const char *uri,
149 int no_scheme_check, int force_tls);
150 static int remove_escapes (char *string);
151 static int insert_escapes (char *buffer, const char *string,
152 const char *special);
153 static uri_tuple_t parse_tuple (char *string);
154 static gpg_error_t send_request (http_t hd, const char *httphost,
155 const char *auth,const char *proxy,
156 const char *srvtag,strlist_t headers);
157 static char *build_rel_path (parsed_uri_t uri);
158 static gpg_error_t parse_response (http_t hd);
160 static gpg_error_t connect_server (const char *server, unsigned short port,
161 unsigned int flags, const char *srvtag,
162 assuan_fd_t *r_sock);
163 static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
164 static gpg_error_t write_server (assuan_fd_t sock, const char *data, size_t length);
166 static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
167 static gpgrt_ssize_t cookie_write (void *cookie,
168 const void *buffer, size_t size);
169 static int cookie_close (void *cookie);
170 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
171 static gpgrt_ssize_t simple_cookie_read (void *cookie,
172 void *buffer, size_t size);
173 static gpgrt_ssize_t simple_cookie_write (void *cookie,
174 const void *buffer, size_t size);
177 /* A socket object used to a allow ref counting of sockets. */
180 assuan_fd_t fd; /* The actual socket - shall never be ASSUAN_INVALID_FD. */
181 int refcount; /* Number of references to this socket. */
183 typedef struct my_socket_s *my_socket_t;
186 /* Cookie function structure and cookie object. */
187 static es_cookie_io_functions_t cookie_functions =
198 /* Socket object or NULL if already closed. */
201 /* The session object or NULL if not used. */
202 http_session_t session;
204 /* True if TLS is to be used. */
207 /* The remaining content length and a flag telling whether to use
208 the content length. */
209 uint64_t content_length;
210 unsigned int content_length_valid:1;
212 typedef struct cookie_s *cookie_t;
215 /* Simple cookie functions. Here the cookie is an int with the
217 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
218 static es_cookie_io_functions_t simple_cookie_functions =
228 #if SIZEOF_UNSIGNED_LONG == 8
229 # define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */
231 # define HTTP_SESSION_MAGIC 0x68547365 /* "hTse" */
234 /* The session object. */
235 struct http_session_s
239 int refcount; /* Number of references to this object. */
240 #ifdef HTTP_USE_GNUTLS
241 gnutls_certificate_credentials_t certcred;
242 #endif /*HTTP_USE_GNUTLS*/
244 tls_session_t tls_session;
246 int done; /* Verifciation has been done. */
247 int rc; /* TLS verification return code. */
248 unsigned int status; /* Verification status. */
250 char *servername; /* Malloced server name. */
252 /* A callback function to log details of TLS certifciates. */
253 void (*cert_log_cb) (http_session_t, gpg_error_t, const char *,
254 const void **, size_t *);
256 /* The flags passed to the session object. */
259 /* A per-session TLS verification callback. */
260 http_verify_cb_t verify_cb;
261 void *verify_cb_value;
265 /* An object to save header lines. */
268 struct header_s *next;
269 char *value; /* The value of the header (malloced). */
270 char name[1]; /* The name of the header (canonicalized). */
272 typedef struct header_s *header_t;
275 #if SIZEOF_UNSIGNED_LONG == 8
276 # define HTTP_CONTEXT_MAGIC 0x0068545470435458 /* "hTTpCTX" */
278 # define HTTP_CONTEXT_MAGIC 0x68546378 /* "hTcx" */
282 /* Our handle context. */
283 struct http_context_s
286 unsigned int status_code;
288 unsigned int in_data:1;
289 unsigned int is_http_0_9:1;
294 http_session_t session;
297 char *buffer; /* Line buffer. */
300 header_t headers; /* Received headers. */
304 /* Two flags to enable verbose and debug mode. Although currently not
305 * set-able a value > 1 for OPT_DEBUG enables debugging of the session
306 * reference counting. */
307 static int opt_verbose;
308 static int opt_debug;
310 /* The global callback for the verification function. */
311 static gpg_error_t (*tls_callback) (http_t, http_session_t, int);
313 /* The list of files with trusted CA certificates. */
314 static strlist_t tls_ca_certlist;
316 /* The global callback for net activity. */
317 static void (*netactivity_cb)(void);
321 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
323 #if GNUPG_MAJOR_VERSION == 1
324 #define REQ_WINSOCK_MAJOR 1
325 #define REQ_WINSOCK_MINOR 1
327 #define REQ_WINSOCK_MAJOR 2
328 #define REQ_WINSOCK_MINOR 2
333 deinit_sockets (void)
341 static int initialized;
342 static WSADATA wsdata;
347 if ( WSAStartup( MAKEWORD (REQ_WINSOCK_MINOR, REQ_WINSOCK_MAJOR), &wsdata ) )
349 log_error ("error initializing socket library: ec=%d\n",
350 (int)WSAGetLastError () );
353 if ( LOBYTE(wsdata.wVersion) != REQ_WINSOCK_MAJOR
354 || HIBYTE(wsdata.wVersion) != REQ_WINSOCK_MINOR )
356 log_error ("socket library version is %x.%x - but %d.%d needed\n",
357 LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion),
358 REQ_WINSOCK_MAJOR, REQ_WINSOCK_MINOR);
362 atexit ( deinit_sockets );
365 #endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
368 /* Create a new socket object. Returns NULL and closes FD if not
369 enough memory is available. */
371 _my_socket_new (int lnr, assuan_fd_t fd)
375 so = xtrymalloc (sizeof *so);
378 int save_errno = errno;
379 assuan_sock_close (fd);
380 gpg_err_set_errno (save_errno);
386 log_debug ("http.c:%d:socket_new: object %p for fd %d created\n",
387 lnr, so, (int)so->fd);
390 #define my_socket_new(a) _my_socket_new (__LINE__, (a))
392 /* Bump up the reference counter for the socket object SO. */
394 _my_socket_ref (int lnr, my_socket_t so)
398 log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n",
399 lnr, so, (int)so->fd, so->refcount);
402 #define my_socket_ref(a) _my_socket_ref (__LINE__,(a))
405 /* Bump down the reference counter for the socket object SO. If SO
406 has no more references, close the socket and release the
409 _my_socket_unref (int lnr, my_socket_t so,
410 void (*preclose)(void*), void *preclosearg)
416 log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n",
417 lnr, so, (int)so->fd, so->refcount);
422 preclose (preclosearg);
423 assuan_sock_close (so->fd);
428 #define my_socket_unref(a,b,c) _my_socket_unref (__LINE__,(a),(b),(c))
431 #ifdef HTTP_USE_GNUTLS
433 my_gnutls_read (gnutls_transport_ptr_t ptr, void *buffer, size_t size)
435 my_socket_t sock = ptr;
437 return npth_read (sock->fd, buffer, size);
439 return read (sock->fd, buffer, size);
443 my_gnutls_write (gnutls_transport_ptr_t ptr, const void *buffer, size_t size)
445 my_socket_t sock = ptr;
447 return npth_write (sock->fd, buffer, size);
449 return write (sock->fd, buffer, size);
452 #endif /*HTTP_USE_GNUTLS*/
455 #ifdef HTTP_USE_NTBTLS
456 /* Connect the ntbls callback to our generic callback. */
458 my_ntbtls_verify_cb (void *opaque, ntbtls_t tls, unsigned int verify_flags)
464 log_assert (hd && hd->session && hd->session->verify_cb);
465 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
466 log_assert (hd->session->magic == HTTP_SESSION_MAGIC);
468 return hd->session->verify_cb (hd->session->verify_cb_value,
470 (hd->flags | hd->session->flags),
473 #endif /*HTTP_USE_NTBTLS*/
478 /* This notification function is called by estream whenever stream is
479 closed. Its purpose is to mark the closing in the handle so
480 that a http_close won't accidentally close the estream. The function
481 http_close removes this notification so that it won't be called if
482 http_close was used before an es_fclose. */
484 fp_onclose_notification (estream_t stream, void *opaque)
488 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
489 if (hd->fp_read && hd->fp_read == stream)
491 else if (hd->fp_write && hd->fp_write == stream)
497 * Helper function to create an HTTP header with hex encoded data. A
498 * new buffer is returned. This buffer is the concatenation of the
499 * string PREFIX, the hex-encoded DATA of length LEN and the string
500 * SUFFIX. On error NULL is returned and ERRNO set.
503 make_header_line (const char *prefix, const char *suffix,
504 const void *data, size_t len )
506 static unsigned char bintoasc[] =
507 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
508 "abcdefghijklmnopqrstuvwxyz"
510 const unsigned char *s = data;
513 buffer = xtrymalloc (strlen (prefix) + (len+2)/3*4 + strlen (suffix) + 1);
516 p = stpcpy (buffer, prefix);
517 for ( ; len >= 3 ; len -= 3, s += 3 )
519 *p++ = bintoasc[(s[0] >> 2) & 077];
520 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
521 *p++ = bintoasc[(((s[1]<<2)&074)|((s[2]>>6)&03))&077];
522 *p++ = bintoasc[s[2]&077];
527 *p++ = bintoasc[(s[0] >> 2) & 077];
528 *p++ = bintoasc[(((s[0] <<4)&060)|((s[1] >> 4)&017))&077];
529 *p++ = bintoasc[((s[1]<<2)&074)];
534 *p++ = bintoasc[(s[0] >> 2) & 077];
535 *p++ = bintoasc[(s[0] <<4)&060];
547 /* Set verbosity and debug mode for this module. */
549 http_set_verbose (int verbose, int debug)
551 opt_verbose = verbose;
556 /* Register a non-standard global TLS callback function. If no
557 verification is desired a callback needs to be registered which
558 always returns NULL. */
560 http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int))
566 /* Register a CA certificate for future use. The certificate is
567 expected to be in FNAME. PEM format is assume if FNAME has a
568 suffix of ".pem". If FNAME is NULL the list of CA files is
571 http_register_tls_ca (const char *fname)
577 free_strlist (tls_ca_certlist);
578 tls_ca_certlist = NULL;
582 /* Warn if we can't access right now, but register it anyway in
583 case it becomes accessible later */
584 if (access (fname, F_OK))
585 log_info (_("can't access '%s': %s\n"), fname,
586 gpg_strerror (gpg_error_from_syserror()));
587 sl = add_to_strlist (&tls_ca_certlist, fname);
588 if (*sl->d && !strcmp (sl->d + strlen (sl->d) - 4, ".pem"))
594 /* Register a callback which is called every time the HTTP mode has
595 * made a successful connection to some server. */
597 http_register_netactivity_cb (void (*cb)(void))
603 /* Call the netactivity callback if any. */
605 notify_netactivity (void)
614 /* Free the TLS session associated with SESS, if any. */
616 close_tls_session (http_session_t sess)
618 if (sess->tls_session)
622 Possibly, ntbtls_get_transport and close those streams.
623 Somehow get SOCK to call my_socket_unref.
625 ntbtls_release (sess->tls_session);
626 # elif HTTP_USE_GNUTLS
627 my_socket_t sock = gnutls_transport_get_ptr (sess->tls_session);
628 my_socket_unref (sock, NULL, NULL);
629 gnutls_deinit (sess->tls_session);
631 gnutls_certificate_free_credentials (sess->certcred);
632 # endif /*HTTP_USE_GNUTLS*/
633 xfree (sess->servername);
634 sess->tls_session = NULL;
640 /* Release a session. Take care not to release it while it is being
641 used by a http context object. */
643 session_unref (int lnr, http_session_t sess)
648 log_assert (sess->magic == HTTP_SESSION_MAGIC);
652 log_debug ("http.c:%d:session_unref: sess %p ref now %d\n",
653 lnr, sess, sess->refcount);
658 close_tls_session (sess);
661 sess->magic = 0xdeadbeef;
664 #define http_session_unref(a) session_unref (__LINE__, (a))
667 http_session_release (http_session_t sess)
669 http_session_unref (sess);
673 /* Create a new session object which is currently used to enable TLS
674 * support. It may eventually allow reusing existing connections.
675 * Valid values for FLAGS are:
676 * HTTP_FLAG_TRUST_DEF - Use the CAs set with http_register_tls_ca
677 * HTTP_FLAG_TRUST_SYS - Also use the CAs defined by the system
678 * HTTP_FLAG_NO_CRL - Do not consult CRLs for https.
681 http_session_new (http_session_t *r_session,
682 const char *intended_hostname, unsigned int flags,
683 http_verify_cb_t verify_cb, void *verify_cb_value)
690 sess = xtrycalloc (1, sizeof *sess);
692 return gpg_error_from_syserror ();
693 sess->magic = HTTP_SESSION_MAGIC;
696 sess->verify_cb = verify_cb;
697 sess->verify_cb_value = verify_cb_value;
701 (void)intended_hostname; /* Not needed because we do not preload
704 err = ntbtls_new (&sess->tls_session, NTBTLS_CLIENT);
707 log_error ("ntbtls_new failed: %s\n", gpg_strerror (err));
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 get_default_keyserver (1)));
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,
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 && !HTTP_USE_NTBTLS*/
823 (void)intended_hostname;
826 #endif /*!HTTP_USE_GNUTLS && !HTTP_USE_NTBTLS*/
829 log_debug ("http.c:session_new: sess %p created\n", sess);
836 http_session_unref (sess);
844 /* Increment the reference count for session SESS. Passing NULL for
847 http_session_ref (http_session_t sess)
853 log_debug ("http.c:session_ref: sess %p ref now %d\n",
854 sess, sess->refcount);
861 http_session_set_log_cb (http_session_t sess,
862 void (*cb)(http_session_t, gpg_error_t,
863 const char *hostname,
864 const void **certs, size_t *certlens))
866 sess->cert_log_cb = cb;
872 /* Start a HTTP retrieval and on success store at R_HD a context
873 pointer for completing the request and to wait for the response.
874 If HTTPHOST is not NULL it is used for the Host header instead of a
875 Host header derived from the URL. */
877 http_open (http_t *r_hd, http_req_t reqtype, const char *url,
878 const char *httphost,
879 const char *auth, unsigned int flags, const char *proxy,
880 http_session_t session, const char *srvtag, strlist_t headers)
887 if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST))
888 return gpg_err_make (default_errsource, GPG_ERR_INV_ARG);
890 /* Create the handle. */
891 hd = xtrycalloc (1, sizeof *hd);
893 return gpg_error_from_syserror ();
894 hd->magic = HTTP_CONTEXT_MAGIC;
895 hd->req_type = reqtype;
897 hd->session = http_session_ref (session);
899 err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
901 err = send_request (hd, httphost, auth, proxy, srvtag, headers);
905 my_socket_unref (hd->sock, NULL, NULL);
907 es_fclose (hd->fp_read);
909 es_fclose (hd->fp_write);
910 http_session_unref (hd->session);
919 /* This function is useful to connect to a generic TCP service using
920 this http abstraction layer. This has the advantage of providing
921 service tags and an estream interface. */
923 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
924 unsigned int flags, const char *srvtag)
932 if ((flags & HTTP_FLAG_FORCE_TOR))
936 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
938 log_error ("Tor support is not available\n");
939 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
943 /* Create the handle. */
944 hd = xtrycalloc (1, sizeof *hd);
946 return gpg_error_from_syserror ();
947 hd->magic = HTTP_CONTEXT_MAGIC;
948 hd->req_type = HTTP_REQ_OPAQUE;
955 err = connect_server (server, port, hd->flags, srvtag, &sock);
961 hd->sock = my_socket_new (sock);
964 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
970 /* Setup estreams for reading and writing. */
971 cookie = xtrycalloc (1, sizeof *cookie);
974 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
977 cookie->sock = my_socket_ref (hd->sock);
978 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
981 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
982 my_socket_unref (cookie->sock, NULL, NULL);
986 hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */
988 cookie = xtrycalloc (1, sizeof *cookie);
991 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
994 cookie->sock = my_socket_ref (hd->sock);
995 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
998 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
999 my_socket_unref (cookie->sock, NULL, NULL);
1003 hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */
1005 /* Register close notification to interlock the use of es_fclose in
1006 http_close and in user code. */
1007 err = es_onclose (hd->fp_write, 1, fp_onclose_notification, hd);
1009 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1015 es_fclose (hd->fp_read);
1017 es_fclose (hd->fp_write);
1018 my_socket_unref (hd->sock, NULL, NULL);
1030 http_start_data (http_t hd)
1034 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
1035 log_debug_with_string ("\r\n", "http.c:request-header:");
1036 es_fputs ("\r\n", hd->fp_write);
1037 es_fflush (hd->fp_write);
1041 es_fflush (hd->fp_write);
1046 http_wait_response (http_t hd)
1051 /* Make sure that we are in the data. */
1052 http_start_data (hd);
1054 /* Close the write stream. Note that the reference counted socket
1055 object keeps the actual system socket open. */
1056 cookie = hd->write_cookie;
1058 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1060 es_fclose (hd->fp_write);
1061 hd->fp_write = NULL;
1062 /* The close has released the cookie and thus we better set it to NULL. */
1063 hd->write_cookie = NULL;
1065 /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
1066 is not required but some very old servers (e.g. the original pksd
1067 keyserver didn't worked without it. */
1068 if ((hd->flags & HTTP_FLAG_SHUTDOWN))
1069 shutdown (FD2INT (hd->sock->fd), 1);
1072 /* Create a new cookie and a stream for reading. */
1073 cookie = xtrycalloc (1, sizeof *cookie);
1075 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1076 cookie->sock = my_socket_ref (hd->sock);
1077 cookie->session = http_session_ref (hd->session);
1078 cookie->use_tls = hd->uri->use_tls;
1080 hd->read_cookie = cookie;
1081 hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
1084 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1085 my_socket_unref (cookie->sock, NULL, NULL);
1086 http_session_unref (cookie->session);
1088 hd->read_cookie = NULL;
1092 err = parse_response (hd);
1095 err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd);
1101 /* Convenience function to send a request and wait for the response.
1102 Closes the handle on error. If PROXY is not NULL, this value will
1103 be used as an HTTP proxy and any enabled $http_proxy gets
1106 http_open_document (http_t *r_hd, const char *document,
1107 const char *auth, unsigned int flags, const char *proxy,
1108 http_session_t session,
1109 const char *srvtag, strlist_t headers)
1113 err = http_open (r_hd, HTTP_REQ_GET, document, NULL, auth, flags,
1114 proxy, session, srvtag, headers);
1118 err = http_wait_response (*r_hd);
1120 http_close (*r_hd, 0);
1127 http_close (http_t hd, int keep_read_stream)
1132 log_assert (hd->magic == HTTP_CONTEXT_MAGIC);
1134 /* First remove the close notifications for the streams. */
1136 es_onclose (hd->fp_read, 0, fp_onclose_notification, hd);
1138 es_onclose (hd->fp_write, 0, fp_onclose_notification, hd);
1140 /* Now we can close the streams. */
1141 my_socket_unref (hd->sock, NULL, NULL);
1142 if (hd->fp_read && !keep_read_stream)
1143 es_fclose (hd->fp_read);
1145 es_fclose (hd->fp_write);
1146 http_session_unref (hd->session);
1147 hd->magic = 0xdeadbeef;
1148 http_release_parsed_uri (hd->uri);
1151 header_t tmp = hd->headers->next;
1152 xfree (hd->headers->value);
1153 xfree (hd->headers);
1162 http_get_read_ptr (http_t hd)
1164 return hd?hd->fp_read:NULL;
1168 http_get_write_ptr (http_t hd)
1170 return hd?hd->fp_write:NULL;
1174 http_get_status_code (http_t hd)
1176 return hd?hd->status_code:0;
1179 /* Return information pertaining to TLS. If TLS is not in use for HD,
1180 NULL is returned. WHAT is used ask for specific information:
1182 (NULL) := Only check whether TLS is in use. Returns an
1183 unspecified string if TLS is in use. That string may
1184 even be the empty string.
1187 http_get_tls_info (http_t hd, const char *what)
1194 return hd->uri->use_tls? "":NULL;
1200 parse_uri (parsed_uri_t *ret_uri, const char *uri,
1201 int no_scheme_check, int force_tls)
1205 *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri));
1207 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1208 strcpy ((*ret_uri)->buffer, uri);
1209 ec = do_parse_uri (*ret_uri, 0, no_scheme_check, force_tls);
1215 return gpg_err_make (default_errsource, ec);
1220 * Parse an URI and put the result into the newly allocated RET_URI.
1221 * On success the caller must use http_release_parsed_uri() to
1222 * releases the resources. If NO_SCHEME_CHECK is set, the function
1223 * tries to parse the URL in the same way it would do for an HTTP
1227 http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
1228 int no_scheme_check)
1230 return parse_uri (ret_uri, uri, no_scheme_check, 0);
1235 http_release_parsed_uri (parsed_uri_t uri)
1241 for (r = uri->query; r; r = r2)
1251 static gpg_err_code_t
1252 do_parse_uri (parsed_uri_t uri, int only_local_part,
1253 int no_scheme_check, int force_tls)
1256 char *p, *p2, *p3, *pp;
1260 n = strlen (uri->buffer);
1262 /* Initialize all fields to an empty string or an empty list. */
1263 uri->scheme = uri->host = uri->path = p + n;
1265 uri->params = uri->query = NULL;
1271 uri->explicit_port = 0;
1273 /* A quick validity check. */
1274 if (strspn (p, VALID_URI_CHARS) != n)
1275 return GPG_ERR_BAD_URI; /* Invalid characters found. */
1277 if (!only_local_part)
1279 /* Find the scheme. */
1280 if (!(p2 = strchr (p, ':')) || p2 == p)
1281 return GPG_ERR_BAD_URI; /* No scheme. */
1283 for (pp=p; *pp; pp++)
1284 *pp = tolower (*(unsigned char*)pp);
1286 if (!strcmp (uri->scheme, "http") && !force_tls)
1291 else if (!strcmp (uri->scheme, "hkp") && !force_tls)
1297 else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")
1298 || (force_tls && (!strcmp (uri->scheme, "http")
1299 || !strcmp (uri->scheme,"hkp"))))
1306 else if (!no_scheme_check)
1307 return GPG_ERR_INV_URI; /* Unsupported scheme */
1311 if (*p == '/' && p[1] == '/' ) /* There seems to be a hostname. */
1314 if ((p2 = strchr (p, '/')))
1317 /* Check for username/password encoding */
1318 if ((p3 = strchr (p, '@')))
1325 for (pp=p; *pp; pp++)
1326 *pp = tolower (*(unsigned char*)pp);
1328 /* Handle an IPv6 literal */
1329 if( *p == '[' && (p3=strchr( p, ']' )) )
1332 /* worst case, uri->host should have length 0, points to \0 */
1340 if ((p3 = strchr (p, ':')))
1343 uri->port = atoi (p3);
1344 uri->explicit_port = 1;
1347 if ((n = remove_escapes (uri->host)) < 0)
1348 return GPG_ERR_BAD_URI;
1349 if (n != strlen (uri->host))
1350 return GPG_ERR_BAD_URI; /* Hostname includes a Nul. */
1353 else if (uri->is_http)
1354 return GPG_ERR_INV_URI; /* No Leading double slash for HTTP. */
1359 if (is_onion_address (uri->path))
1364 } /* End global URI part. */
1366 /* Parse the pathname part if any. */
1369 /* TODO: Here we have to check params. */
1371 /* Do we have a query part? */
1372 if ((p2 = strchr (p, '?')))
1376 if ((n = remove_escapes (p)) < 0)
1377 return GPG_ERR_BAD_URI;
1378 if (n != strlen (p))
1379 return GPG_ERR_BAD_URI; /* Path includes a Nul. */
1382 /* Parse a query string if any. */
1390 if ((p2 = strchr (p, '&')))
1392 if (!(elem = parse_tuple (p)))
1393 return GPG_ERR_BAD_URI;
1404 if (is_onion_address (uri->host))
1412 * Remove all %xx escapes; this is done in-place. Returns: New length
1416 remove_escapes (char *string)
1419 unsigned char *p, *s;
1421 for (p = s = (unsigned char*)string; *s; s++)
1425 if (s[1] && s[2] && isxdigit (s[1]) && isxdigit (s[2]))
1428 *p = *s >= '0' && *s <= '9' ? *s - '0' :
1429 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1432 *p |= *s >= '0' && *s <= '9' ? *s - '0' :
1433 *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10;
1446 return -1; /* Bad URI. */
1455 *p = 0; /* Make sure to keep a string terminator. */
1460 /* If SPECIAL is NULL this function escapes in forms mode. */
1462 escape_data (char *buffer, const void *data, size_t datalen,
1463 const char *special)
1465 int forms = !special;
1466 const unsigned char *s;
1472 for (s = data; datalen; s++, datalen--)
1474 if (forms && *s == ' ')
1480 else if (forms && *s == '\n')
1483 memcpy (buffer, "%0D%0A", 6);
1486 else if (forms && *s == '\r' && datalen > 1 && s[1] == '\n')
1489 memcpy (buffer, "%0D%0A", 6);
1494 else if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s))
1497 *(unsigned char*)buffer++ = *s;
1504 snprintf (buffer, 4, "%%%02X", *s);
1515 insert_escapes (char *buffer, const char *string,
1516 const char *special)
1518 return escape_data (buffer, string, strlen (string), special);
1522 /* Allocate a new string from STRING using standard HTTP escaping as
1523 well as escaping of characters given in SPECIALS. A common pattern
1524 for SPECIALS is "%;?&=". However it depends on the needs, for
1525 example "+" and "/: often needs to be escaped too. Returns NULL on
1526 failure and sets ERRNO. If SPECIAL is NULL a dedicated forms
1527 encoding mode is used. */
1529 http_escape_string (const char *string, const char *specials)
1534 n = insert_escapes (NULL, string, specials);
1535 buf = xtrymalloc (n+1);
1538 insert_escapes (buf, string, specials);
1544 /* Allocate a new string from {DATA,DATALEN} using standard HTTP
1545 escaping as well as escaping of characters given in SPECIALS. A
1546 common pattern for SPECIALS is "%;?&=". However it depends on the
1547 needs, for example "+" and "/: often needs to be escaped too.
1548 Returns NULL on failure and sets ERRNO. If SPECIAL is NULL a
1549 dedicated forms encoding mode is used. */
1551 http_escape_data (const void *data, size_t datalen, const char *specials)
1556 n = escape_data (NULL, data, datalen, specials);
1557 buf = xtrymalloc (n+1);
1560 escape_data (buf, data, datalen, specials);
1568 parse_tuple (char *string)
1575 if ((p2 = strchr (p, '=')))
1577 if ((n = remove_escapes (p)) < 0)
1578 return NULL; /* Bad URI. */
1579 if (n != strlen (p))
1580 return NULL; /* Name with a Nul in it. */
1581 tuple = xtrycalloc (1, sizeof *tuple);
1583 return NULL; /* Out of core. */
1585 if (!p2) /* We have only the name, so we assume an empty value string. */
1587 tuple->value = p + strlen (p);
1588 tuple->valuelen = 0;
1589 tuple->no_value = 1; /* Explicitly mark that we have seen no '='. */
1591 else /* Name and value. */
1593 if ((n = remove_escapes (p2)) < 0)
1596 return NULL; /* Bad URI. */
1599 tuple->valuelen = n;
1605 /* Return true if STRING is likely "hostname:port" or only "hostname". */
1607 is_hostname_port (const char *string)
1611 if (!string || !*string)
1613 for (; *string; string++)
1623 else if (!colons && strchr (" \t\f\n\v_@[]/", *string))
1624 return 0; /* Invalid characters in hostname. */
1625 else if (colons && !digitp (string))
1626 return 0; /* Not a digit in the port. */
1633 * Send a HTTP request to the server
1634 * Returns 0 if the request was successful
1637 send_request (http_t hd, const char *httphost, const char *auth,
1638 const char *proxy, const char *srvtag, strlist_t headers)
1643 unsigned short port;
1644 const char *http_proxy = NULL;
1645 char *proxy_authstr = NULL;
1646 char *authstr = NULL;
1649 if (hd->uri->use_tls && !hd->session)
1651 log_error ("TLS requested but no session object provided\n");
1652 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1655 if (hd->uri->use_tls && !hd->session->tls_session)
1657 log_error ("TLS requested but no GNUTLS context available\n");
1658 return gpg_err_make (default_errsource, GPG_ERR_INTERNAL);
1662 if ((hd->flags & HTTP_FLAG_FORCE_TOR))
1666 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
1668 log_error ("Tor support is not available\n");
1669 return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED);
1673 server = *hd->uri->host ? hd->uri->host : "localhost";
1674 port = hd->uri->port ? hd->uri->port : 80;
1676 /* Try to use SNI. */
1678 if (hd->uri->use_tls)
1680 # if HTTP_USE_GNUTLS
1684 xfree (hd->session->servername);
1685 hd->session->servername = xtrystrdup (httphost? httphost : server);
1686 if (!hd->session->servername)
1688 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1692 # if HTTP_USE_NTBTLS
1693 err = ntbtls_set_hostname (hd->session->tls_session,
1694 hd->session->servername);
1697 log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err));
1700 # elif HTTP_USE_GNUTLS
1701 rc = gnutls_server_name_set (hd->session->tls_session,
1703 hd->session->servername,
1704 strlen (hd->session->servername));
1706 log_info ("gnutls_server_name_set failed: %s\n", gnutls_strerror (rc));
1707 # endif /*HTTP_USE_GNUTLS*/
1711 if ( (proxy && *proxy)
1712 || ( (hd->flags & HTTP_FLAG_TRY_PROXY)
1713 && (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 err = connect_server (*uri->host ? uri->host : "localhost",
1764 uri->port ? uri->port : 80,
1765 hd->flags, srvtag, &sock);
1766 http_release_parsed_uri (uri);
1770 err = connect_server (server, port, hd->flags, srvtag, &sock);
1775 xfree (proxy_authstr);
1778 hd->sock = my_socket_new (sock);
1781 xfree (proxy_authstr);
1782 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1787 if (hd->uri->use_tls)
1791 my_socket_ref (hd->sock);
1793 /* Until we support send/recv in estream under Windows we need
1794 * to use es_fopencookie. */
1795 #ifdef HAVE_W32_SYSTEM
1796 in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb",
1797 simple_cookie_functions);
1799 in = es_fdopen_nc (hd->sock->fd, "rb");
1803 err = gpg_error_from_syserror ();
1804 xfree (proxy_authstr);
1808 #ifdef HAVE_W32_SYSTEM
1809 out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb",
1810 simple_cookie_functions);
1812 out = es_fdopen_nc (hd->sock->fd, "wb");
1816 err = gpg_error_from_syserror ();
1818 xfree (proxy_authstr);
1822 err = ntbtls_set_transport (hd->session->tls_session, in, out);
1825 log_info ("TLS set_transport failed: %s <%s>\n",
1826 gpg_strerror (err), gpg_strsource (err));
1827 xfree (proxy_authstr);
1831 #ifdef HTTP_USE_NTBTLS
1832 if (hd->session->verify_cb)
1834 err = ntbtls_set_verify_cb (hd->session->tls_session,
1835 my_ntbtls_verify_cb, hd);
1838 log_error ("ntbtls_set_verify_cb failed: %s\n",
1839 gpg_strerror (err));
1840 xfree (proxy_authstr);
1844 #endif /*HTTP_USE_NTBTLS*/
1846 while ((err = ntbtls_handshake (hd->session->tls_session)))
1851 log_info ("TLS handshake failed: %s <%s>\n",
1852 gpg_strerror (err), gpg_strsource (err));
1853 xfree (proxy_authstr);
1858 hd->session->verify.done = 0;
1860 /* Try the available verify callbacks until one returns success
1861 * or a real error. Note that NTBTLS does the verification
1862 * during the handshake via */
1863 #ifdef HTTP_USE_NTBTLS
1864 err = 0; /* Fixme check that the CB has been called. */
1866 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1869 if (hd->session->verify_cb
1870 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1871 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1872 err = hd->session->verify_cb (hd->session->verify_cb_value,
1874 (hd->flags | hd->session->flags),
1875 hd->session->tls_session);
1878 && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1879 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1880 err = tls_callback (hd, hd->session, 0);
1882 if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR
1883 && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
1884 err = http_verify_server_credentials (hd->session);
1888 log_info ("TLS connection authentication failed: %s <%s>\n",
1889 gpg_strerror (err), gpg_strsource (err));
1890 xfree (proxy_authstr);
1895 #elif HTTP_USE_GNUTLS
1896 if (hd->uri->use_tls)
1900 my_socket_ref (hd->sock);
1901 gnutls_transport_set_ptr (hd->session->tls_session, hd->sock);
1902 gnutls_transport_set_pull_function (hd->session->tls_session,
1904 gnutls_transport_set_push_function (hd->session->tls_session,
1910 rc = gnutls_handshake (hd->session->tls_session);
1912 while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
1915 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1916 || rc == GNUTLS_E_FATAL_ALERT_RECEIVED)
1918 gnutls_alert_description_t alertno;
1919 const char *alertstr;
1921 alertno = gnutls_alert_get (hd->session->tls_session);
1922 alertstr = gnutls_alert_get_name (alertno);
1923 log_info ("TLS handshake %s: %s (alert %d)\n",
1924 rc == GNUTLS_E_WARNING_ALERT_RECEIVED
1925 ? "warning" : "failed",
1926 alertstr, (int)alertno);
1927 if (alertno == GNUTLS_A_UNRECOGNIZED_NAME && server)
1928 log_info (" (sent server name '%s')\n", server);
1930 if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED)
1931 goto handshake_again;
1934 log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc));
1935 xfree (proxy_authstr);
1936 return gpg_err_make (default_errsource, GPG_ERR_NETWORK);
1939 hd->session->verify.done = 0;
1941 err = tls_callback (hd, hd->session, 0);
1943 err = http_verify_server_credentials (hd->session);
1946 log_info ("TLS connection authentication failed: %s\n",
1947 gpg_strerror (err));
1948 xfree (proxy_authstr);
1952 #endif /*HTTP_USE_GNUTLS*/
1954 if (auth || hd->uri->auth)
1960 myauth = xtrystrdup (auth);
1963 xfree (proxy_authstr);
1964 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1966 remove_escapes (myauth);
1970 remove_escapes (hd->uri->auth);
1971 myauth = hd->uri->auth;
1974 authstr = make_header_line ("Authorization: Basic ", "\r\n",
1975 myauth, strlen (myauth));
1981 xfree (proxy_authstr);
1982 return gpg_err_make (default_errsource,
1983 gpg_err_code_from_syserror ());
1987 p = build_rel_path (hd->uri);
1989 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
1991 if (http_proxy && *http_proxy)
1993 request = es_bsprintf
1994 ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s",
1995 hd->req_type == HTTP_REQ_GET ? "GET" :
1996 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
1997 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
1998 hd->uri->use_tls? "https" : "http",
1999 httphost? httphost : server,
2000 port, *p == '/' ? "" : "/", p,
2001 authstr ? authstr : "",
2002 proxy_authstr ? proxy_authstr : "");
2008 if (port == (hd->uri->use_tls? 443 : 80))
2011 snprintf (portstr, sizeof portstr, ":%u", port);
2013 request = es_bsprintf
2014 ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
2015 hd->req_type == HTTP_REQ_GET ? "GET" :
2016 hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
2017 hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS",
2018 *p == '/' ? "" : "/", p,
2019 httphost? httphost : server,
2021 authstr? authstr:"");
2026 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2028 xfree (proxy_authstr);
2032 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2033 log_debug_with_string (request, "http.c:request:");
2035 /* First setup estream so that we can write even the first line
2036 using estream. This is also required for the sake of gnutls. */
2040 cookie = xtrycalloc (1, sizeof *cookie);
2043 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2046 cookie->sock = my_socket_ref (hd->sock);
2047 hd->write_cookie = cookie;
2048 cookie->use_tls = hd->uri->use_tls;
2049 cookie->session = http_session_ref (hd->session);
2051 hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
2054 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2055 my_socket_unref (cookie->sock, NULL, NULL);
2057 hd->write_cookie = NULL;
2059 else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
2060 err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2066 for (;headers; headers=headers->next)
2068 if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP))
2069 log_debug_with_string (headers->d, "http.c:request-header:");
2070 if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
2071 || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
2073 err = gpg_err_make (default_errsource,
2074 gpg_err_code_from_syserror ());
2084 xfree (proxy_authstr);
2091 * Build the relative path from the parsed URI. Minimal
2092 * implementation. May return NULL in case of memory failure; errno
2093 * is then set accordingly.
2096 build_rel_path (parsed_uri_t uri)
2102 /* Count the needed space. */
2103 n = insert_escapes (NULL, uri->path, "%;?&");
2104 /* TODO: build params. */
2105 for (r = uri->query; r; r = r->next)
2108 n += insert_escapes (NULL, r->name, "%;?&=");
2112 n += insert_escapes (NULL, r->value, "%;?&=");
2117 /* Now allocate and copy. */
2118 p = rel_path = xtrymalloc (n);
2121 n = insert_escapes (p, uri->path, "%;?&");
2123 /* TODO: add params. */
2124 for (r = uri->query; r; r = r->next)
2126 *p++ = r == uri->query ? '?' : '&';
2127 n = insert_escapes (p, r->name, "%;?&=");
2132 /* TODO: Use valuelen. */
2133 n = insert_escapes (p, r->value, "%;?&=");
2142 /* Transform a header name into a standard capitalized format; e.g.
2143 "Content-Type". Conversion stops at the colon. As usual we don't
2144 use the localized versions of ctype.h. */
2146 capitalize_header_name (char *name)
2150 for (; *name && *name != ':'; name++)
2156 if (*name >= 'a' && *name <= 'z')
2157 *name = *name - 'a' + 'A';
2160 else if (*name >= 'A' && *name <= 'Z')
2161 *name = *name - 'A' + 'a';
2166 /* Store an HTTP header line in LINE away. Line continuation is
2167 supported as well as merging of headers with the same name. This
2168 function may modify LINE. */
2169 static gpg_err_code_t
2170 store_header (http_t hd, char *line)
2177 if (n && line[n-1] == '\n')
2180 if (n && line[n-1] == '\r')
2183 if (!n) /* we are never called to hit this. */
2185 if (*line == ' ' || *line == '\t')
2187 /* Continuation. This won't happen too often as it is not
2188 recommended. We use a straightforward implementation. */
2190 return GPG_ERR_PROTOCOL_VIOLATION;
2191 n += strlen (hd->headers->value);
2192 p = xtrymalloc (n+1);
2194 return gpg_err_code_from_syserror ();
2195 strcpy (stpcpy (p, hd->headers->value), line);
2196 xfree (hd->headers->value);
2197 hd->headers->value = p;
2201 capitalize_header_name (line);
2202 p = strchr (line, ':');
2204 return GPG_ERR_PROTOCOL_VIOLATION;
2206 while (*p == ' ' || *p == '\t')
2210 for (h=hd->headers; h; h = h->next)
2211 if ( !strcmp (h->name, line) )
2215 /* We have already seen a line with that name. Thus we assume
2216 * it is a comma separated list and merge them. */
2217 p = strconcat (h->value, ",", value, NULL);
2219 return gpg_err_code_from_syserror ();
2225 /* Append a new header. */
2226 h = xtrymalloc (sizeof *h + strlen (line));
2228 return gpg_err_code_from_syserror ();
2229 strcpy (h->name, line);
2230 h->value = xtrymalloc (strlen (value)+1);
2234 return gpg_err_code_from_syserror ();
2236 strcpy (h->value, value);
2237 h->next = hd->headers;
2244 /* Return the header NAME from the last response. The returned value
2245 is valid as along as HD has not been closed and no other request
2246 has been send. If the header was not found, NULL is returned. NAME
2247 must be canonicalized, that is the first letter of each dash
2248 delimited part must be uppercase and all other letters lowercase. */
2250 http_get_header (http_t hd, const char *name)
2254 for (h=hd->headers; h; h = h->next)
2255 if ( !strcmp (h->name, name) )
2261 /* Return a newly allocated and NULL terminated array with pointers to
2262 header names. The array must be released with xfree() and its
2263 content is only values as long as no other request has been
2266 http_get_header_names (http_t hd)
2272 for (n=0, h = hd->headers; h; h = h->next)
2274 array = xtrycalloc (n+1, sizeof *array);
2277 for (n=0, h = hd->headers; h; h = h->next)
2278 array[n++] = h->name;
2286 * Parse the response from a server.
2287 * Returns: Errorcode and sets some files in the handle
2289 static gpg_err_code_t
2290 parse_response (http_t hd)
2292 char *line, *p, *p2;
2294 cookie_t cookie = hd->read_cookie;
2297 /* Delete old header lines. */
2300 header_t tmp = hd->headers->next;
2301 xfree (hd->headers->value);
2302 xfree (hd->headers);
2306 /* Wait for the status line. */
2309 maxlen = MAX_LINELEN;
2310 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2313 return gpg_err_code_from_syserror (); /* Out of core. */
2315 return GPG_ERR_TRUNCATED; /* Line has been truncated. */
2319 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2320 log_debug_with_string (line, "http.c:response:\n");
2324 if ((p = strchr (line, '/')))
2326 if (!p || strcmp (line, "HTTP"))
2327 return 0; /* Assume http 0.9. */
2329 if ((p2 = strpbrk (p, " \t")))
2332 p2 += strspn (p2, " \t");
2335 return 0; /* Also assume http 0.9. */
2337 /* TODO: Add HTTP version number check. */
2338 if ((p2 = strpbrk (p, " \t")))
2340 if (!isdigit ((unsigned int)p[0]) || !isdigit ((unsigned int)p[1])
2341 || !isdigit ((unsigned int)p[2]) || p[3])
2343 /* Malformed HTTP status code - assume http 0.9. */
2344 hd->is_http_0_9 = 1;
2345 hd->status_code = 200;
2348 hd->status_code = atoi (p);
2350 /* Skip all the header lines and wait for the empty line. */
2353 maxlen = MAX_LINELEN;
2354 len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
2357 return gpg_err_code_from_syserror (); /* Out of core. */
2358 /* Note, that we can silently ignore truncated lines. */
2361 /* Trim line endings of empty lines. */
2362 if ((*line == '\r' && line[1] == '\n') || *line == '\n')
2364 if ((hd->flags & HTTP_FLAG_LOG_RESP))
2365 log_info ("http.c:RESP: '%.*s'\n",
2366 (int)strlen(line)-(*line&&line[1]?2:0),line);
2369 gpg_err_code_t ec = store_header (hd, line);
2374 while (len && *line);
2376 cookie->content_length_valid = 0;
2377 if (!(hd->flags & HTTP_FLAG_IGNORE_CL))
2379 s = http_get_header (hd, "Content-Length");
2382 cookie->content_length_valid = 1;
2383 cookie->content_length = string_to_u64 (s);
2394 struct sockaddr_in mya;
2395 struct sockaddr_in peer;
2401 if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
2403 log_error ("socket() failed: %s\n", strerror (errno));
2407 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (byte *) & i, sizeof (i)))
2408 log_info ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
2410 mya.sin_family = AF_INET;
2411 memset (&mya.sin_addr, 0, sizeof (mya.sin_addr));
2412 mya.sin_port = htons (11371);
2414 if (bind (fd, (struct sockaddr *) &mya, sizeof (mya)))
2416 log_error ("bind to port 11371 failed: %s\n", strerror (errno));
2423 log_error ("listen failed: %s\n", strerror (errno));
2433 if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0)
2434 continue; /* ignore any errors */
2436 if (!FD_ISSET (fd, &rfds))
2439 addrlen = sizeof peer;
2440 client = my_accept (fd, (struct sockaddr *) &peer, &addrlen);
2442 continue; /* oops */
2444 log_info ("connect from %s\n", inet_ntoa (peer.sin_addr));
2453 fp = fdopen (client, "r");
2454 while ((c = getc (fp)) != EOF)
2459 sock_close (client);
2469 /* Return true if SOCKS shall be used. This is the case if tor_mode
2470 * is enabled and the desired address is not the loopback address.
2471 * This function is basically a copy of the same internal function in
2474 use_socks (struct sockaddr_storage *addr)
2478 if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
2479 return 0; /* Not in Tor mode. */
2480 else if (addr->ss_family == AF_INET6)
2482 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
2483 const unsigned char *s;
2486 s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
2488 return 1; /* Last octet is not 1 - not the loopback address. */
2489 for (i=0; i < 15; i++, s++)
2491 return 1; /* Non-zero octet found - not the loopback address. */
2493 return 0; /* This is the loopback address. */
2495 else if (addr->ss_family == AF_INET)
2497 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
2499 if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
2500 return 0; /* Loopback (127.0.0.0/8) */
2509 /* Wrapper around assuan_sock_new which takes the domain from an
2510 * address parameter. */
2512 my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
2516 if (use_socks (addr))
2518 /* Libassaun always uses 127.0.0.1 to connect to the socks
2519 * server (i.e. the Tor daemon). */
2523 domain = addr->ss_family;
2525 return assuan_sock_new (domain, type, proto);
2529 /* Actually connect to a server. On success 0 is returned and the
2530 * file descriptor for the socket is stored at R_SOCK; on error an
2531 * error code is returned and ASSUAN_INVALID_FD is stored at
2534 connect_server (const char *server, unsigned short port,
2535 unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
2538 assuan_fd_t sock = ASSUAN_INVALID_FD;
2539 unsigned int srvcount = 0;
2541 int anyhostaddr = 0;
2543 gpg_error_t last_err = 0;
2544 struct srventry *serverlist = NULL;
2546 *r_sock = ASSUAN_INVALID_FD;
2548 #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
2552 /* Onion addresses require special treatment. */
2553 if (is_onion_address (server))
2555 #ifdef ASSUAN_SOCK_TOR
2558 log_debug ("http.c:connect_server:onion: name='%s' port=%hu\n",
2560 sock = assuan_sock_connect_byname (server, port, 0, NULL,
2562 if (sock == ASSUAN_INVALID_FD)
2564 err = gpg_err_make (default_errsource,
2565 (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
2566 : gpg_err_code_from_syserror ());
2567 log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
2571 notify_netactivity ();
2575 #else /*!ASSUAN_SOCK_TOR*/
2577 err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
2578 return ASSUAN_INVALID_FD;
2580 #endif /*!HASSUAN_SOCK_TOR*/
2583 /* Do the SRV thing */
2586 err = get_dns_srv (server, srvtag, NULL, &serverlist, &srvcount);
2588 log_info ("getting '%s' SRV for '%s' failed: %s\n",
2589 srvtag, server, gpg_strerror (err));
2590 /* Note that on error SRVCOUNT is zero. */
2596 /* Either we're not using SRV, or the SRV lookup failed. Make
2597 up a fake SRV record. */
2598 serverlist = xtrycalloc (1, sizeof *serverlist);
2600 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
2602 serverlist->port = port;
2603 strncpy (serverlist->target, server, DIMof (struct srventry, target));
2604 serverlist->target[DIMof (struct srventry, target)-1] = '\0';
2609 for (srv=0; srv < srvcount && !connected; srv++)
2611 dns_addrinfo_t aibuf, ai;
2614 log_debug ("http.c:connect_server: trying name='%s' port=%hu\n",
2615 serverlist[srv].target, port);
2616 err = resolve_dns_name (serverlist[srv].target, port, 0, SOCK_STREAM,
2620 log_info ("resolving '%s' failed: %s\n",
2621 serverlist[srv].target, gpg_strerror (err));
2623 continue; /* Not found - try next one. */
2627 for (ai = aibuf; ai && !connected; ai = ai->next)
2629 if (ai->family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
2631 if (ai->family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
2634 if (sock != ASSUAN_INVALID_FD)
2635 assuan_sock_close (sock);
2636 sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
2637 if (sock == ASSUAN_INVALID_FD)
2639 err = gpg_err_make (default_errsource,
2640 gpg_err_code_from_syserror ());
2641 log_error ("error creating socket: %s\n", gpg_strerror (err));
2642 free_dns_addrinfo (aibuf);
2648 if (assuan_sock_connect (sock, (struct sockaddr *)ai->addr,
2651 last_err = gpg_err_make (default_errsource,
2652 gpg_err_code_from_syserror ());
2657 notify_netactivity ();
2660 free_dns_addrinfo (aibuf);
2668 log_error ("can't connect to '%s': %s\n",
2669 server, "host not found");
2670 else if (!anyhostaddr)
2671 log_error ("can't connect to '%s': %s\n",
2672 server, "no IP address for host");
2675 #ifdef HAVE_W32_SYSTEM
2676 log_error ("can't connect to '%s': ec=%d\n",
2677 server, (int)WSAGetLastError());
2679 log_error ("can't connect to '%s': %s\n",
2680 server, gpg_strerror (last_err));
2683 err = last_err? last_err : gpg_err_make (default_errsource,
2684 GPG_ERR_UNKNOWN_HOST);
2685 if (sock != ASSUAN_INVALID_FD)
2686 assuan_sock_close (sock);
2695 /* Helper to read from a socket. This handles npth things and
2697 static gpgrt_ssize_t
2698 read_server (assuan_fd_t sock, void *buffer, size_t size)
2704 #ifdef HAVE_W32_SYSTEM
2705 /* Under Windows we need to use recv for a socket. */
2706 # if defined(USE_NPTH)
2709 nread = recv (FD2INT (sock), buffer, size, 0);
2710 # if defined(USE_NPTH)
2714 #else /*!HAVE_W32_SYSTEM*/
2717 nread = npth_read (sock, buffer, size);
2719 nread = read (sock, buffer, size);
2722 #endif /*!HAVE_W32_SYSTEM*/
2724 while (nread == -1 && errno == EINTR);
2731 write_server (assuan_fd_t sock, const char *data, size_t length)
2739 #if defined(HAVE_W32_SYSTEM)
2740 # if defined(USE_NPTH)
2743 nwritten = send (FD2INT (sock), data, nleft, 0);
2744 # if defined(USE_NPTH)
2747 if ( nwritten == SOCKET_ERROR )
2749 log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
2750 return gpg_error (GPG_ERR_NETWORK);
2752 #else /*!HAVE_W32_SYSTEM*/
2754 nwritten = npth_write (sock, data, nleft);
2756 nwritten = write (sock, data, nleft);
2762 if (errno == EAGAIN)
2768 my_select (0, NULL, NULL, NULL, &tv);
2771 log_info ("network write failed: %s\n", strerror (errno));
2772 return gpg_error_from_syserror ();
2774 #endif /*!HAVE_W32_SYSTEM*/
2784 /* Read handler for estream. */
2785 static gpgrt_ssize_t
2786 cookie_read (void *cookie, void *buffer, size_t size)
2788 cookie_t c = cookie;
2791 if (c->content_length_valid)
2793 if (!c->content_length)
2795 if (c->content_length < size)
2796 size = c->content_length;
2800 if (c->use_tls && c->session && c->session->tls_session)
2804 ntbtls_get_stream (c->session->tls_session, &in, &out);
2805 nread = es_fread (buffer, 1, size, in);
2807 log_debug ("TLS network read: %d/%zu\n", nread, size);
2810 #elif HTTP_USE_GNUTLS
2811 if (c->use_tls && c->session && c->session->tls_session)
2814 nread = gnutls_record_recv (c->session->tls_session, buffer, size);
2817 if (nread == GNUTLS_E_INTERRUPTED)
2819 if (nread == GNUTLS_E_AGAIN)
2825 my_select (0, NULL, NULL, NULL, &tv);
2828 if (nread == GNUTLS_E_REHANDSHAKE)
2829 goto again; /* A client is allowed to just ignore this request. */
2830 if (nread == GNUTLS_E_PREMATURE_TERMINATION)
2832 /* The server terminated the connection. Close the TLS
2833 session, and indicate EOF using a short read. */
2834 close_tls_session (c->session);
2837 log_info ("TLS network read failed: %s\n", gnutls_strerror (nread));
2838 gpg_err_set_errno (EIO);
2843 #endif /*HTTP_USE_GNUTLS*/
2845 nread = read_server (c->sock->fd, buffer, size);
2848 if (c->content_length_valid && nread > 0)
2850 if (nread < c->content_length)
2851 c->content_length -= nread;
2853 c->content_length = 0;
2856 return (gpgrt_ssize_t)nread;
2859 /* Write handler for estream. */
2860 static gpgrt_ssize_t
2861 cookie_write (void *cookie, const void *buffer_arg, size_t size)
2863 const char *buffer = buffer_arg;
2864 cookie_t c = cookie;
2868 if (c->use_tls && c->session && c->session->tls_session)
2872 ntbtls_get_stream (c->session->tls_session, &in, &out);
2876 nwritten = es_fwrite (buffer, 1, size, out);
2878 log_debug ("TLS network write: %d/%zu\n", nwritten, size);
2881 #elif HTTP_USE_GNUTLS
2882 if (c->use_tls && c->session && c->session->tls_session)
2887 nwritten = gnutls_record_send (c->session->tls_session,
2891 if (nwritten == GNUTLS_E_INTERRUPTED)
2893 if (nwritten == GNUTLS_E_AGAIN)
2899 my_select (0, NULL, NULL, NULL, &tv);
2902 log_info ("TLS network write failed: %s\n",
2903 gnutls_strerror (nwritten));
2904 gpg_err_set_errno (EIO);
2912 #endif /*HTTP_USE_GNUTLS*/
2914 if ( write_server (c->sock->fd, buffer, size) )
2916 gpg_err_set_errno (EIO);
2923 return (gpgrt_ssize_t)nwritten;
2927 #if defined(HAVE_W32_SYSTEM) && defined(HTTP_USE_NTBTLS)
2928 static gpgrt_ssize_t
2929 simple_cookie_read (void *cookie, void *buffer, size_t size)
2931 assuan_fd_t sock = (assuan_fd_t)cookie;
2932 return read_server (sock, buffer, size);
2935 static gpgrt_ssize_t
2936 simple_cookie_write (void *cookie, const void *buffer_arg, size_t size)
2938 assuan_fd_t sock = (assuan_fd_t)cookie;
2939 const char *buffer = buffer_arg;
2942 if (write_server (sock, buffer, size))
2944 gpg_err_set_errno (EIO);
2950 return (gpgrt_ssize_t)nwritten;
2952 #endif /*HAVE_W32_SYSTEM*/
2955 #ifdef HTTP_USE_GNUTLS
2956 /* Wrapper for gnutls_bye used by my_socket_unref. */
2958 send_gnutls_bye (void *opaque)
2960 tls_session_t tls_session = opaque;
2965 ret = gnutls_bye (tls_session, GNUTLS_SHUT_RDWR);
2966 while (ret == GNUTLS_E_INTERRUPTED);
2967 if (ret == GNUTLS_E_AGAIN)
2973 my_select (0, NULL, NULL, NULL, &tv);
2977 #endif /*HTTP_USE_GNUTLS*/
2979 /* Close handler for estream. */
2981 cookie_close (void *cookie)
2983 cookie_t c = cookie;
2989 if (c->use_tls && c->session && c->session->tls_session)
2991 /* FIXME!! Possibly call ntbtls_close_notify for close
2993 my_socket_unref (c->sock, NULL, NULL);
2996 #elif HTTP_USE_GNUTLS
2997 if (c->use_tls && c->session && c->session->tls_session)
2998 my_socket_unref (c->sock, send_gnutls_bye, c->session->tls_session);
3000 #endif /*HTTP_USE_GNUTLS*/
3002 my_socket_unref (c->sock, NULL, NULL);
3005 http_session_unref (c->session);
3013 /* Verify the credentials of the server. Returns 0 on success and
3014 store the result in the session object. */
3016 http_verify_server_credentials (http_session_t sess)
3019 static const char const errprefix[] = "TLS verification of peer failed";
3021 unsigned int status;
3022 const char *hostname;
3023 const gnutls_datum_t *certlist;
3024 unsigned int certlistlen;
3025 gnutls_x509_crt_t cert;
3026 gpg_error_t err = 0;
3028 sess->verify.done = 1;
3029 sess->verify.status = 0;
3030 sess->verify.rc = GNUTLS_E_CERTIFICATE_ERROR;
3032 if (gnutls_certificate_type_get (sess->tls_session) != GNUTLS_CRT_X509)
3034 log_error ("%s: %s\n", errprefix, "not an X.509 certificate");
3035 sess->verify.rc = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
3036 return gpg_error (GPG_ERR_GENERAL);
3039 rc = gnutls_certificate_verify_peers2 (sess->tls_session, &status);
3042 log_error ("%s: %s\n", errprefix, gnutls_strerror (rc));
3044 err = gpg_error (GPG_ERR_GENERAL);
3048 log_error ("%s: status=0x%04x\n", errprefix, status);
3049 #if GNUTLS_VERSION_NUMBER >= 0x030104
3051 gnutls_datum_t statusdat;
3053 if (!gnutls_certificate_verification_status_print
3054 (status, GNUTLS_CRT_X509, &statusdat, 0))
3056 log_info ("%s: %s\n", errprefix, statusdat.data);
3057 gnutls_free (statusdat.data);
3060 #endif /*gnutls >= 3.1.4*/
3062 sess->verify.status = status;
3064 err = gpg_error (GPG_ERR_GENERAL);
3067 hostname = sess->servername;
3068 if (!hostname || !strchr (hostname, '.'))
3070 log_error ("%s: %s\n", errprefix, "hostname missing");
3072 err = gpg_error (GPG_ERR_GENERAL);
3075 certlist = gnutls_certificate_get_peers (sess->tls_session, &certlistlen);
3078 log_error ("%s: %s\n", errprefix, "server did not send a certificate");
3080 err = gpg_error (GPG_ERR_GENERAL);
3082 /* Need to stop here. */
3087 rc = gnutls_x509_crt_init (&cert);
3091 err = gpg_error (GPG_ERR_GENERAL);
3096 rc = gnutls_x509_crt_import (cert, &certlist[0], GNUTLS_X509_FMT_DER);
3099 log_error ("%s: %s: %s\n", errprefix, "error importing certificate",
3100 gnutls_strerror (rc));
3102 err = gpg_error (GPG_ERR_GENERAL);
3105 if (!gnutls_x509_crt_check_hostname (cert, hostname))
3107 log_error ("%s: %s\n", errprefix, "hostname does not match");
3109 err = gpg_error (GPG_ERR_GENERAL);
3112 gnutls_x509_crt_deinit (cert);
3115 sess->verify.rc = 0;
3117 if (sess->cert_log_cb)
3119 const void *bufarr[10];
3120 size_t buflenarr[10];
3123 for (n = 0; n < certlistlen && n < DIM (bufarr)-1; n++)
3125 bufarr[n] = certlist[n].data;
3126 buflenarr[n] = certlist[n].size;
3130 sess->cert_log_cb (sess, err, hostname, bufarr, buflenarr);
3134 #else /*!HTTP_USE_GNUTLS*/
3136 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3140 /* Return the first query variable with the specified key. If there
3141 is no such variable, return NULL. */
3142 struct uri_tuple_s *
3143 uri_query_lookup (parsed_uri_t uri, const char *key)
3145 struct uri_tuple_s *t;
3147 for (t = uri->query; t; t = t->next)
3148 if (strcmp (t->name, key) == 0)