diff --git a/NEWS b/NEWS index f93c1ed2..ada03481 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +xbps-0.38 (???): + + * libfetch: add support for TLS SNI (Server Name Identification) from NetBSD, with + some minor debug changes. This fixes GH issue #41 (https://github.com/voidlinux/xbps/issues/41). + xbps-0.37 (2014-06-06): * Enabled syslog logging by default, may be still disabled via xbps.conf. diff --git a/lib/fetch/common.c b/lib/fetch/common.c index 8d7d3f5f..5b033481 100644 --- a/lib/fetch/common.c +++ b/lib/fetch/common.c @@ -434,10 +434,12 @@ fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *)) * Enable SSL on a connection. */ int -fetch_ssl(conn_t *conn, int verbose) +fetch_ssl(conn_t *conn, const struct url *URL, int verbose) { #ifdef WITH_SSL + int ret; + /* Init the SSL library and context */ if (!SSL_library_init()){ fprintf(stderr, "SSL library init failed\n"); @@ -455,9 +457,21 @@ fetch_ssl(conn_t *conn, int verbose) fprintf(stderr, "SSL context creation failed\n"); return (-1); } - SSL_set_fd(conn->ssl, conn->sd); - if (SSL_connect(conn->ssl) == -1){ - ERR_print_errors_fp(stderr); + SSL_set_connect_state(conn->ssl); + if (!SSL_set_fd(conn->ssl, conn->sd)) { + fprintf(stderr, "SSL_set_fd failed\n"); + return (-1); + } +#ifndef OPENSSL_NO_TLSEXT + if (!SSL_set_tlsext_host_name(conn->ssl, URL->host)) { + fprintf(stderr, + "TLS server name indication extension failed for host %s\n", + URL->host); + return (-1); + } +#endif + if ((ret = SSL_connect(conn->ssl)) <= 0){ + fprintf(stderr, "SSL_connect returned %d\n", SSL_get_error(conn->ssl, ret)); return (-1); } @@ -717,6 +731,10 @@ fetch_close(conn_t *conn) { int ret; +#ifdef WITH_SSL + SSL_shutdown(conn->ssl); + SSL_free(conn->ssl); +#endif ret = close(conn->sd); if (conn->cache_url) fetchFreeURL(conn->cache_url); diff --git a/lib/fetch/common.h b/lib/fetch/common.h index 4e4408cb..231fb022 100644 --- a/lib/fetch/common.h +++ b/lib/fetch/common.h @@ -98,7 +98,7 @@ conn_t *fetch_cache_get(const struct url *, int); void fetch_cache_put(conn_t *, int (*)(conn_t *)); conn_t *fetch_connect(struct url *, int, int); conn_t *fetch_reopen(int); -int fetch_ssl(conn_t *, int); +int fetch_ssl(conn_t *, const struct url *, int); ssize_t fetch_read(conn_t *, char *, size_t); int fetch_getln(conn_t *); ssize_t fetch_write(conn_t *, const void *, size_t); diff --git a/lib/fetch/http.c b/lib/fetch/http.c index adc55902..122d9c15 100644 --- a/lib/fetch/http.c +++ b/lib/fetch/http.c @@ -740,8 +740,9 @@ http_connect(struct url *URL, struct url *purl, const char *flags, int *cached) if ((conn = fetch_connect(URL, af, verbose)) == NULL) /* fetch_connect() has already set an error code */ return (NULL); + if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && - fetch_ssl(conn, verbose) == -1) { + fetch_ssl(conn, URL, verbose) != 0) { fetch_close(conn); /* grrr */ #ifdef EAUTH