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

Reply via email to