Thanks sthen@ for noticing it, ftp(1) doesn't perform SNI, Server Name
Indication. (try eg. https://www.stunnel.org/)
Here's a diff to improve the situation (first and last hunks). While
I can get some eyes for a review, let's add some more changes. ;)
Second hunk: SSLeay_add_ssl_algorithms() is just a #define for
SSL_library_init().
Third hunk: SSL_CTX_set_cipher_list() can return an error if no cipher
can be selected (ftp -S ciphers=junk). Yes, SSL_connect() would then
fail but doing no check here seems inconsistent.
Dunno whether you'll find the addrbuf union appropriate...
ok / comments?
Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.114
diff -u -p -p -u -r1.114 fetch.c
--- fetch.c 2 Mar 2014 17:57:18 -0000 1.114
+++ fetch.c 27 Mar 2014 01:52:13 -0000
@@ -598,6 +598,8 @@ again:
#ifndef SMALL
if (ishttpsurl) {
+ union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
+
if (proxyenv && sslpath) {
ishttpsurl = 0;
proxyurl = NULL;
@@ -605,7 +607,6 @@ again:
}
SSL_library_init();
SSL_load_error_strings();
- SSLeay_add_ssl_algorithms();
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
if (ssl_ctx == NULL) {
ERR_print_errors_fp(ttyout);
@@ -624,8 +625,11 @@ again:
SSL_CTX_set_verify_depth(ssl_ctx,
ssl_verify_depth);
}
- if (ssl_ciphers != NULL)
- SSL_CTX_set_cipher_list(ssl_ctx, ssl_ciphers);
+ if (ssl_ciphers != NULL &&
+ SSL_CTX_set_cipher_list(ssl_ctx, ssl_ciphers) == -1) {
+ ERR_print_errors_fp(ttyout);
+ goto cleanup_url_get;
+ }
ssl = SSL_new(ssl_ctx);
if (ssl == NULL) {
ERR_print_errors_fp(ttyout);
@@ -634,6 +638,17 @@ again:
if (SSL_set_fd(ssl, s) == 0) {
ERR_print_errors_fp(ttyout);
goto cleanup_url_get;
+ }
+ /*
+ * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not
+ * permitted in "HostName".
+ */
+ if (inet_pton(AF_INET, host, &addrbuf) != 1 &&
+ inet_pton(AF_INET6, host, &addrbuf) != 1) {
+ if (SSL_set_tlsext_host_name(ssl, host) == 0) {
+ ERR_print_errors_fp(ttyout);
+ goto cleanup_url_get;
+ }
}
if (SSL_connect(ssl) <= 0) {
ERR_print_errors_fp(ttyout);
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE