From 633c20a2e622555365d649911acf5996838244a0 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sat, 28 Jun 2014 12:01:00 +0200 Subject: [PATCH] libfetch: merge TLS SNI support from NetBSD with some other random changes. Close GH #41 --- NEWS | 5 +++++ lib/fetch/common.c | 26 ++++++++++++++++++++++---- lib/fetch/common.h | 2 +- lib/fetch/http.c | 3 ++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/fetch/common.c b/lib/fetch/common.c index 8d7d3f5..5b03348 100644 --- lib/fetch/common.c +++ 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 4e4408c..231fb02 100644 --- lib/fetch/common.h +++ 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 adc5590..122d9c1 100644 --- lib/fetch/http.c +++ 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 -- 2.0.1