Add TLS session support to ftp(1).
authorjsing <jsing@openbsd.org>
Sat, 10 Feb 2018 06:25:16 +0000 (06:25 +0000)
committerjsing <jsing@openbsd.org>
Sat, 10 Feb 2018 06:25:16 +0000 (06:25 +0000)
If a session file is specified via the `-S session=...', ftp(1) will
attempt to resume TLS sessions based on the session data contained within
this file. Upon completion of a successful TLS handshake the session file
will be updated with new session data, if available.

Discussed with deraadt@ and beck@.

Requested by and input from espie@.

usr.bin/ftp/fetch.c
usr.bin/ftp/ftp.1
usr.bin/ftp/ftp_var.h
usr.bin/ftp/main.c

index 7c3363c..30f7312 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fetch.c,v 1.166 2018/02/07 23:04:50 procter Exp $     */
+/*     $OpenBSD: fetch.c,v 1.167 2018/02/10 06:25:16 jsing Exp $       */
 /*     $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
 
 /*-
@@ -1037,6 +1037,9 @@ improper:
 cleanup_url_get:
 #ifndef NOSSL
        if (tls != NULL) {
+               if (tls_session_fd != -1)
+                       dprintf(STDERR_FILENO, "tls session resumed: %s\n",
+                           tls_conn_session_resumed(tls) ? "yes" : "no");
                do {
                        i = tls_close(tls);
                } while (i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);
index 3f93dbb..2527b7e 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ftp.1,v 1.107 2017/01/25 07:21:18 jmc Exp $
+.\"    $OpenBSD: ftp.1,v 1.108 2018/02/10 06:25:16 jsing Exp $
 .\"    $NetBSD: ftp.1,v 1.22 1997/08/18 10:20:22 lukem Exp $
 .\"
 .\" Copyright (c) 1985, 1989, 1990, 1993
@@ -30,7 +30,7 @@
 .\"
 .\"    @(#)ftp.1       8.3 (Berkeley) 10/9/94
 .\"
-.Dd $Mdocdate: January 25 2017 $
+.Dd $Mdocdate: February 10 2018 $
 .Dt FTP 1
 .Os
 .Sh NAME
@@ -253,6 +253,13 @@ Don't perform server certificate validation.
 Require the server to present a valid OCSP stapling in the TLS handshake.
 .It Cm noverifytime
 Disable validation of certificate times and OCSP validation.
+.It Cm session Ns = Ns Ar /path/to/session
+Specify a file to use for TLS session data.
+If this file has a non-zero length, the session data will be read from this file
+and the client will attempt to resume the TLS session with the server.
+Upon completion of a successful TLS handshake this file will be updated
+with new session data, if available.
+This file will be created if it does not already exist.
 .El
 .Pp
 By default, server certificate validation is performed, and if it fails
index 952eb94..de6b1b1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ftp_var.h,v 1.40 2017/01/21 08:33:07 krw Exp $        */
+/*     $OpenBSD: ftp_var.h,v 1.41 2018/02/10 06:25:16 jsing Exp $      */
 /*     $NetBSD: ftp_var.h,v 1.18 1997/08/18 10:20:25 lukem Exp $       */
 
 /*
@@ -227,4 +227,5 @@ extern struct cmd cmdtab[];
 
 #ifndef NOSSL
 extern struct tls_config *tls_config;
+extern int tls_session_fd;
 #endif /* !NOSSL */
index 66642f9..eae8ec8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.119 2017/01/24 23:47:34 beck Exp $ */
+/*     $OpenBSD: main.c,v 1.120 2018/02/10 06:25:16 jsing Exp $        */
 /*     $NetBSD: main.c,v 1.24 1997/08/18 10:20:26 lukem Exp $  */
 
 /*
@@ -67,6 +67,7 @@
 
 #include <ctype.h>
 #include <err.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <stdio.h>
@@ -84,26 +85,29 @@ int connect_timeout;
 
 #ifndef NOSSL
 char * const ssl_verify_opts[] = {
-#define SSL_CAFILE     0
+#define SSL_CAFILE             0
        "cafile",
-#define SSL_CAPATH     1
+#define SSL_CAPATH             1
        "capath",
-#define SSL_CIPHERS    2
+#define SSL_CIPHERS            2
        "ciphers",
-#define SSL_DONTVERIFY 3
+#define SSL_DONTVERIFY         3
        "dont",
-#define SSL_DOVERIFY   4
+#define SSL_DOVERIFY           4
        "do",
-#define SSL_VERIFYDEPTH        5
+#define SSL_VERIFYDEPTH                5
        "depth",
-#define SSL_MUSTSTAPLE 6
+#define SSL_MUSTSTAPLE         6
        "muststaple",
 #define SSL_NOVERIFYTIME       7
        "noverifytime",
+#define SSL_SESSION            8
+       "session",
        NULL
 };
 
 struct tls_config *tls_config;
+int tls_session_fd = -1;
 
 static void
 process_ssl_options(char *cp)
@@ -157,6 +161,18 @@ process_ssl_options(char *cp)
                case SSL_NOVERIFYTIME:
                        tls_config_insecure_noverifytime(tls_config);
                        break;
+               case SSL_SESSION:
+                       if (str == NULL)
+                               errx(1, "missing session file");
+                       if ((tls_session_fd = open(str, O_RDWR|O_CREAT,
+                           0600)) == -1)
+                               err(1, "failed to open or create session file "
+                                   "'%s'", str);
+                       if (tls_config_set_session_fd(tls_config,
+                           tls_session_fd) == -1)
+                               errx(1, "failed to set session: %s",
+                                   tls_config_error(tls_config));
+                       break;
                default:
                        errx(1, "unknown -S suboption `%s'",
                            suboptarg ? suboptarg : "");
@@ -276,7 +292,7 @@ main(volatile int argc, char *argv[])
                        errx(1, "tls set ciphers failed: %s",
                            tls_config_error(tls_config));
        }
-#endif /* !SMALL */
+#endif /* !NOSSL */
 
        httpuseragent = NULL;