summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2013-12-24 13:01:00 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2013-12-24 13:01:00 +0000
commit8be85f5850c9adb577e41267cd070c25cf45b2a7 (patch)
tree9c599aa33d06086ebd58046b87f6ec6e49d85efb
parentc8249d6af55d0a23e836050106639b02a3464f42 (diff)
Add support for SSL/TLS server certificate validation, enabled by
default. See the documentation for the `-S' switch. This also allows setting the preferred ciphers for the communication. Documentation bits ok'ed by jmc@, ok beck@ sthen@.
-rw-r--r--usr.bin/ftp/fetch.c23
-rw-r--r--usr.bin/ftp/ftp.142
-rw-r--r--usr.bin/ftp/ftp_var.h13
-rw-r--r--usr.bin/ftp/main.c77
4 files changed, 148 insertions, 7 deletions
diff --git a/usr.bin/ftp/fetch.c b/usr.bin/ftp/fetch.c
index 752d6f55663..b88be007762 100644
--- a/usr.bin/ftp/fetch.c
+++ b/usr.bin/ftp/fetch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fetch.c,v 1.111 2013/11/13 20:41:10 deraadt Exp $ */
+/* $OpenBSD: fetch.c,v 1.112 2013/12/24 13:00:59 jca Exp $ */
/* $NetBSD: fetch.c,v 1.14 1997/08/18 10:20:20 lukem Exp $ */
/*-
@@ -606,8 +606,27 @@ again:
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);
+ goto cleanup_url_get;
+ }
+ if (ssl_verify) {
+ if (ssl_ca_file == NULL && ssl_ca_path == NULL)
+ ssl_ca_file = _PATH_SSL_CAFILE;
+ if (SSL_CTX_load_verify_locations(ssl_ctx,
+ ssl_ca_file, ssl_ca_path) != 1) {
+ ERR_print_errors_fp(ttyout);
+ goto cleanup_url_get;
+ }
+ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+ if (ssl_verify_depth != -1)
+ SSL_CTX_set_verify_depth(ssl_ctx,
+ ssl_verify_depth);
+ }
+ if (ssl_ciphers != NULL)
+ SSL_CTX_set_cipher_list(ssl_ctx, ssl_ciphers);
ssl = SSL_new(ssl_ctx);
- if (ssl == NULL || ssl_ctx == NULL) {
+ if (ssl == NULL) {
ERR_print_errors_fp(ttyout);
goto cleanup_url_get;
}
diff --git a/usr.bin/ftp/ftp.1 b/usr.bin/ftp/ftp.1
index ab5406b2e1f..2cf1b625d0f 100644
--- a/usr.bin/ftp/ftp.1
+++ b/usr.bin/ftp/ftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ftp.1,v 1.88 2013/04/28 18:03:40 lteo Exp $
+.\" $OpenBSD: ftp.1,v 1.89 2013/12/24 13:00:59 jca 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: April 28 2013 $
+.Dd $Mdocdate: December 24 2013 $
.Dt FTP 1
.Os
.Sh NAME
@@ -59,6 +59,7 @@
.Op Fl C
.Op Fl c Ar cookie
.Op Fl o Ar output
+.Op Fl S Ar ssl_options
.Op Fl s Ar srcaddr
.Sm off
.No http[s]:// Oo Ar user : password No @
@@ -216,6 +217,43 @@ if the server does not support passive connections.
.It Fl r Ar seconds
Retry to connect if failed, pausing for number of
.Ar seconds .
+.It Fl S Ar ssl_options
+SSL/TLS options to use with HTTPS transfers.
+The following settings are available:
+.Bl -tag -width Ds
+.It Cm cafile Ns = Ns Ar /path/to/cert.pem
+PEM encoded file containing CA certificates used for certificate
+validation.
+.It Cm capath Ns = Ns Ar /path/to/certs/
+Directory containing PEM encoded CA certificates used for certificate
+validation.
+Such a directory can be prepared using the c_rehash OpenSSL utility.
+.It Cm ciphers Ns = Ns Ar cipher_list
+Specify the list of ciphers that will be used by
+.Nm .
+See the
+.Xr openssl 1
+.Cm ciphers
+subcommand.
+.It Cm depth Ns = Ns Ar max_depth
+Maximum depth of the certificate chain allowed when performing
+validation.
+.It Cm do
+Perform server certificate validation.
+.It Cm dont
+Don't perform server certificate validation.
+.El
+.Pp
+By default, server certificate validation is performed, and if it fails
+.Nm
+will abort.
+If no
+.Cm cafile
+or
+.Cm capath
+setting is provided,
+.Pa /etc/ssl/cert.pem
+will be used.
.It Fl s Ar srcaddr
Use
.Ar srcaddr
diff --git a/usr.bin/ftp/ftp_var.h b/usr.bin/ftp/ftp_var.h
index 3ec69627b67..f68f547bf9a 100644
--- a/usr.bin/ftp/ftp_var.h
+++ b/usr.bin/ftp/ftp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp_var.h,v 1.32 2012/04/30 13:41:26 haesbaert Exp $ */
+/* $OpenBSD: ftp_var.h,v 1.33 2013/12/24 13:00:59 jca Exp $ */
/* $NetBSD: ftp_var.h,v 1.18 1997/08/18 10:20:25 lukem Exp $ */
/*
@@ -229,3 +229,14 @@ char macbuf[4096];
FILE *ttyout; /* stdout or stderr, depending on interactive */
extern struct cmd cmdtab[];
+
+#ifndef SMALL
+extern char *ssl_ciphers;
+extern char *ssl_ca_file;
+extern char *ssl_ca_path;
+extern int ssl_verify;
+extern int ssl_verify_depth;
+# ifndef _PATH_SSL_CAFILE
+# define _PATH_SSL_CAFILE "/etc/ssl/cert.pem"
+# endif
+#endif /* !SMALL */
diff --git a/usr.bin/ftp/main.c b/usr.bin/ftp/main.c
index 492eb2bfc9c..ecaf06adca8 100644
--- a/usr.bin/ftp/main.c
+++ b/usr.bin/ftp/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.85 2012/08/26 02:16:02 lteo Exp $ */
+/* $OpenBSD: main.c,v 1.86 2013/12/24 13:00:59 jca 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 <limits.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
@@ -78,6 +79,29 @@
#include "ftp_var.h"
#include "cmds.h"
+#ifndef SMALL
+char * const ssl_verify_opts[] = {
+#define SSL_CAFILE 0
+ "cafile",
+#define SSL_CAPATH 1
+ "capath",
+#define SSL_CIPHERS 2
+ "ciphers",
+#define SSL_DONTVERIFY 3
+ "dont",
+#define SSL_DOVERIFY 4
+ "do",
+#define SSL_VERIFYDEPTH 5
+ "depth",
+ NULL
+};
+char *ssl_ciphers;
+int ssl_verify = 1;
+int ssl_verify_depth = -1;
+char *ssl_ca_file;
+char *ssl_ca_path;
+#endif /* !SMALL */
+
int family = PF_UNSPEC;
int pipeout;
@@ -175,7 +199,8 @@ main(volatile int argc, char *argv[])
cookiefile = getenv("http_cookies");
#endif /* !SMALL */
- while ((ch = getopt(argc, argv, "46AaCc:dEegik:mno:pP:r:s:tvV")) != -1) {
+ while ((ch = getopt(argc, argv,
+ "46AaCc:dEegik:mno:pP:r:S:s:tvV")) != -1) {
switch (ch) {
case '4':
family = PF_INET;
@@ -276,6 +301,53 @@ main(volatile int argc, char *argv[])
}
break;
+ case 'S':
+#ifndef SMALL
+ cp = optarg;
+ while (*cp) {
+ char *str;
+ switch (getsubopt(&cp, ssl_verify_opts, &str)) {
+ case SSL_CAFILE:
+ if (str == NULL)
+ errx(1, "missing CA file");
+ ssl_ca_file = str;
+ break;
+ case SSL_CAPATH:
+ if (str == NULL)
+ errx(1, "missing CA directory"
+ " path");
+ ssl_ca_path = str;
+ break;
+ case SSL_CIPHERS:
+ if (str == NULL)
+ errx(1, "missing cipher list");
+ ssl_ciphers = str;
+ break;
+ case SSL_DONTVERIFY:
+ ssl_verify = 0;
+ break;
+ case SSL_DOVERIFY:
+ ssl_verify = 1;
+ break;
+ case SSL_VERIFYDEPTH:
+ if (str == NULL)
+ errx(1, "missing depth");
+ ssl_verify_depth = strtonum(str, 0,
+ INT_MAX, &errstr);
+ if (errstr)
+ errx(1, "certificate "
+ "validation depth is %s",
+ errstr);
+ break;
+ default:
+ errx(1, "unknown -S suboption `%s'",
+ suboptarg ? suboptarg : "");
+ /* NOTREACHED */
+ }
+ }
+#endif
+ break;
+
case 's':
#ifndef SMALL
srcaddr = optarg;
@@ -775,6 +847,7 @@ usage(void)
#endif /* !SMALL */
"[-o output] "
#ifndef SMALL
+ "[-S ssl_options] "
"[-s srcaddr]\n"
" "
#endif /* !SMALL */