Module Name:    src
Committed By:   mlelstv
Date:           Sat Feb 25 12:07:25 UTC 2023

Modified Files:
        src/usr.bin/ftp: cmdtab.c extern.h fetch.c ftp.1 main.c ssl.c util.c
            version.h

Log Message:
Add option sslnoverify to control validation of SSL certificates.
Add netrc processing to fetch-mode (URL on command line) to enable options and 
autologin
via netrc.
Fix SSL cleanup in some error paths.

Certificate validation is now enabled by default. Set FTPSSLNOVERIFY=1 in 
environment
or configure a corresponding init macro via netrc to not validate certs 
(required if
you haven't installed a required CA certificate for OpenSSL).

Discussed with lukem@ on icb.


To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/usr.bin/ftp/cmdtab.c
cvs rdiff -u -r1.82 -r1.83 src/usr.bin/ftp/extern.h
cvs rdiff -u -r1.235 -r1.236 src/usr.bin/ftp/fetch.c
cvs rdiff -u -r1.147 -r1.148 src/usr.bin/ftp/ftp.1
cvs rdiff -u -r1.128 -r1.129 src/usr.bin/ftp/main.c
cvs rdiff -u -r1.12 -r1.13 src/usr.bin/ftp/ssl.c
cvs rdiff -u -r1.165 -r1.166 src/usr.bin/ftp/util.c
cvs rdiff -u -r1.95 -r1.96 src/usr.bin/ftp/version.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/ftp/cmdtab.c
diff -u src/usr.bin/ftp/cmdtab.c:1.52 src/usr.bin/ftp/cmdtab.c:1.53
--- src/usr.bin/ftp/cmdtab.c:1.52	Sat Dec 22 16:57:09 2012
+++ src/usr.bin/ftp/cmdtab.c	Sat Feb 25 12:07:25 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: cmdtab.c,v 1.52 2012/12/22 16:57:09 christos Exp $	*/
+/*	$NetBSD: cmdtab.c,v 1.53 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
- * Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -63,7 +63,7 @@
 #if 0
 static char sccsid[] = "@(#)cmdtab.c	8.4 (Berkeley) 10/9/94";
 #else
-__RCSID("$NetBSD: cmdtab.c,v 1.52 2012/12/22 16:57:09 christos Exp $");
+__RCSID("$NetBSD: cmdtab.c,v 1.53 2023/02/25 12:07:25 mlelstv Exp $");
 #endif
 #endif /* not lint */
 
@@ -295,13 +295,14 @@ struct cmd cmdtab[] = {
 };
 
 struct option optiontab[] = {
-	{ "anonpass",	NULL },
-	{ "ftp_proxy",	NULL },
-	{ "http_proxy",	NULL },
-	{ "https_proxy",NULL },
-	{ "no_proxy",	NULL },
-	{ "pager",	NULL },
-	{ "prompt",	NULL },
-	{ "rprompt",	NULL },
-	{ NULL,		NULL },
+	{ "anonpass",	   NULL },
+	{ "ftp_proxy",	   NULL },
+	{ "http_proxy",	   NULL },
+	{ "https_proxy",   NULL },
+	{ "no_proxy",	   NULL },
+	{ "pager",	   NULL },
+	{ "prompt",	   NULL },
+	{ "rprompt",	   NULL },
+	{ "sslnoverify"   ,NULL },
+	{ NULL,		   NULL },
 };

Index: src/usr.bin/ftp/extern.h
diff -u src/usr.bin/ftp/extern.h:1.82 src/usr.bin/ftp/extern.h:1.83
--- src/usr.bin/ftp/extern.h:1.82	Sat Jun 22 23:40:53 2019
+++ src/usr.bin/ftp/extern.h	Sat Feb 25 12:07:25 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: extern.h,v 1.82 2019/06/22 23:40:53 christos Exp $	*/
+/*	$NetBSD: extern.h,v 1.83 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
- * Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -243,6 +243,7 @@ void	user(int, char **);
 int	ftp_connect(int, const struct sockaddr *, socklen_t, int);
 int	ftp_listen(int, int);
 int	ftp_poll(struct pollfd *, int, int);
+int	ftp_truthy(const char *, const char *, int);
 #ifndef SMALL
 void   *ftp_malloc(size_t);
 StringList *ftp_sl_init(void);

Index: src/usr.bin/ftp/fetch.c
diff -u src/usr.bin/ftp/fetch.c:1.235 src/usr.bin/ftp/fetch.c:1.236
--- src/usr.bin/ftp/fetch.c:1.235	Sun Sep 11 20:49:27 2022
+++ src/usr.bin/ftp/fetch.c	Sat Feb 25 12:07:25 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: fetch.c,v 1.235 2022/09/11 20:49:27 christos Exp $	*/
+/*	$NetBSD: fetch.c,v 1.236 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1997-2015 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.235 2022/09/11 20:49:27 christos Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.236 2023/02/25 12:07:25 mlelstv Exp $");
 #endif /* not lint */
 
 /*
@@ -617,13 +617,15 @@ parse_url(const char *url, const char *d
 sigjmp_buf	httpabort;
 
 static int
-ftp_socket(const struct urlinfo *ui, void **ssl)
+ftp_socket(const struct urlinfo *ui, void **ssl, struct authinfo *auth)
 {
 	struct addrinfo hints, *res, *res0 = NULL;
 	int error;
 	int s;
 	const char *host = ui->host;
 	const char *port = ui->port;
+	char *fuser = NULL, *pass = NULL, *facct = NULL;
+	int n;
 
 	if (ui->utype != HTTPS_URL_T)
 		ssl = NULL;
@@ -688,6 +690,28 @@ ftp_socket(const struct urlinfo *ui, voi
 			continue;
 		}
 
+		if (ruserpass("", &fuser, &pass, &facct) < 0) {
+			close(s);
+			s = -1;
+			continue;
+		}
+
+		if (autologin) {
+			if (fuser != NULL && auth->user == NULL)
+				auth->user = ftp_strdup(fuser);
+			if (pass != NULL && auth->pass == NULL)
+				auth->pass = ftp_strdup(pass);
+		}
+
+		for (n = 0; n < macnum; ++n) {
+			if (!strcmp("init", macros[n].mac_name)) {
+				(void)strlcpy(line, "$init", sizeof(line));
+				makeargv();
+				domacro(margc, margv);
+				break;
+			}
+		}
+
 #ifdef WITH_SSL
 		if (ssl) {
 			if ((*ssl = fetch_start_ssl(s, host)) == NULL) {
@@ -699,6 +723,15 @@ ftp_socket(const struct urlinfo *ui, voi
 #endif
 		break;
 	}
+
+	FREEPTR(fuser);
+	if (pass != NULL)
+		memset(pass, 0, strlen(pass));
+	FREEPTR(pass);
+	if (facct != NULL)
+		memset(facct, 0, strlen(facct));
+	FREEPTR(facct);
+
 	if (res0)
 		freeaddrinfo(res0);
 	return s;
@@ -1484,6 +1517,10 @@ fetch_url(const char *url, const char *p
 		}
 	} else {				/* ftp:// or http:// URLs */
 		int hasleading;
+		static char hostnamebuf[MAXHOSTNAMELEN];
+
+		(void)strlcpy(hostnamebuf, ui.host, sizeof(hostnamebuf));
+		hostname = hostnamebuf;
 
 		if (penv == NULL) {
 #ifdef WITH_SSL
@@ -1517,7 +1554,7 @@ fetch_url(const char *url, const char *p
 			}
 		} /* ! EMPTYSTRING(penv) */
 
-		s = ftp_socket(&ui, &ssl);
+		s = ftp_socket(&ui, &ssl, &wauth);
 		if (s < 0) {
 			warnx("Can't connect to `%s:%s'", ui.host, ui.port);
 			goto cleanup_fetch_url;

Index: src/usr.bin/ftp/ftp.1
diff -u src/usr.bin/ftp/ftp.1:1.147 src/usr.bin/ftp/ftp.1:1.148
--- src/usr.bin/ftp/ftp.1:1.147	Tue Aug 30 08:51:28 2022
+++ src/usr.bin/ftp/ftp.1	Sat Feb 25 12:07:25 2023
@@ -1,6 +1,6 @@
-.\" 	$NetBSD: ftp.1,v 1.147 2022/08/30 08:51:28 christos Exp $
+.\" 	$NetBSD: ftp.1,v 1.148 2023/02/25 12:07:25 mlelstv Exp $
 .\"
-.\" Copyright (c) 1996-2021 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -57,7 +57,7 @@
 .\"
 .\"	@(#)ftp.1	8.3 (Berkeley) 10/9/94
 .\"
-.Dd August 29, 2022
+.Dd February 25, 2023
 .Dt FTP 1
 .Os
 .Sh NAME
@@ -1382,7 +1382,7 @@ and
 .Ar value
 are not given, display all of the options and their values.
 The currently supported options are:
-.Bl -tag -width "https_proxy" -offset indent
+.Bl -tag -width "sslnoverify" -offset indent
 .It Cm anonpass
 Defaults to
 .Ev $FTPANONPASS
@@ -1407,6 +1407,9 @@ Defaults to
 .It Cm rprompt
 Defaults to
 .Ev $FTPRPROMPT .
+.It Cm sslnoverify
+Defaults to
+.Ev $FTPSSLNOVERIFY .
 .El
 .It Ic site Op Ar arg ...
 The arguments specified are sent, verbatim, to the remote
@@ -2312,6 +2315,8 @@ The value to send for the
 .Tn HTTP
 User-Agent
 header.
+.It Ev FTPSSLNOVERIFY
+Set to 1 to not verify SSL certificates.
 .It Ev HOME
 For default location of a
 .Pa .netrc
@@ -2320,8 +2325,6 @@ file, if one exists.
 An alternate location of the
 .Pa .netrc
 file.
-.It Ev NO_CERT_VERIFY
-Don't verify SSL certificates.
 .It Ev PAGER
 Used by various commands to display files.
 Defaults to

Index: src/usr.bin/ftp/main.c
diff -u src/usr.bin/ftp/main.c:1.128 src/usr.bin/ftp/main.c:1.129
--- src/usr.bin/ftp/main.c:1.128	Sat Oct  9 09:07:20 2021
+++ src/usr.bin/ftp/main.c	Sat Feb 25 12:07:25 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: main.c,v 1.128 2021/10/09 09:07:20 lukem Exp $	*/
+/*	$NetBSD: main.c,v 1.129 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
- * Copyright (c) 1996-2015 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -98,7 +98,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 19
 #if 0
 static char sccsid[] = "@(#)main.c	8.6 (Berkeley) 10/9/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.128 2021/10/09 09:07:20 lukem Exp $");
+__RCSID("$NetBSD: main.c,v 1.129 2023/02/25 12:07:25 mlelstv Exp $");
 #endif
 #endif /* not lint */
 
@@ -512,6 +512,7 @@ main(int volatile argc, char **volatile 
 	setupoption("pager",		getenv("PAGER"),	DEFAULTPAGER);
 	setupoption("prompt",		getenv("FTPPROMPT"),	DEFAULTPROMPT);
 	setupoption("rprompt",		getenv("FTPRPROMPT"),	DEFAULTRPROMPT);
+	setupoption("sslnoverify",   	getenv("FTPSSLNOVERIFY"),	"");
 
 	free(anonpass);
 

Index: src/usr.bin/ftp/ssl.c
diff -u src/usr.bin/ftp/ssl.c:1.12 src/usr.bin/ftp/ssl.c:1.13
--- src/usr.bin/ftp/ssl.c:1.12	Mon Sep 12 15:10:31 2022
+++ src/usr.bin/ftp/ssl.c	Sat Feb 25 12:07:25 2023
@@ -1,9 +1,10 @@
-/*	$NetBSD: ssl.c,v 1.12 2022/09/12 15:10:31 christos Exp $	*/
+/*	$NetBSD: ssl.c,v 1.13 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
  * Copyright (c) 2008, 2010 Joerg Sonnenberger <jo...@netbsd.org>
  * Copyright (c) 2015 Thomas Klausner <w...@netbsd.org>
+ * Copyright (c) 2023 Michael van Elst <mlel...@netbsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ssl.c,v 1.12 2022/09/12 15:10:31 christos Exp $");
+__RCSID("$NetBSD: ssl.c,v 1.13 2023/02/25 12:07:25 mlelstv Exp $");
 #endif
 
 #include <errno.h>
@@ -63,6 +64,11 @@ __RCSID("$NetBSD: ssl.c,v 1.12 2022/09/1
 
 #include "ssl.h"
 
+#include <stringlist.h>
+#include <histedit.h>
+#include <sys/poll.h>
+#include "extern.h"
+
 extern int quit_time, verbose, ftp_debug;
 extern FILE *ttyout;
 
@@ -589,7 +595,7 @@ fetch_start_ssl(int sock, const char *se
 	SSL_CTX *ctx;
 	X509_VERIFY_PARAM *param;
 	int ret, ssl_err;
-	int verify = 0;	// getenv("NO_CERT_VERIFY") == NULL;
+	int verify = !ftp_truthy("sslnoverify", getoptionvalue("sslnoverify"), 0);
 
 	/* Init the SSL library and context */
 	if (!SSL_library_init()){
@@ -618,6 +624,8 @@ fetch_start_ssl(int sock, const char *se
 		if (!X509_VERIFY_PARAM_set1_host(param, servername,
 		    strlen(servername))) {
 			fprintf(ttyout, "SSL verification setup failed\n");
+			SSL_free(ssl);
+			SSL_CTX_free(ctx);
 			return NULL;
 		}
 
@@ -628,6 +636,7 @@ fetch_start_ssl(int sock, const char *se
 	SSL_set_fd(ssl, sock);
 	if (!SSL_set_tlsext_host_name(ssl, __UNCONST(servername))) {
 		fprintf(ttyout, "SSL hostname setting failed\n");
+		SSL_free(ssl);
 		SSL_CTX_free(ctx);
 		return NULL;
 	}
@@ -637,6 +646,7 @@ fetch_start_ssl(int sock, const char *se
 		    ssl_err != SSL_ERROR_WANT_WRITE) {
 			ERR_print_errors_fp(ttyout);
 			SSL_free(ssl);
+			SSL_CTX_free(ctx);
 			return NULL;
 		}
 	}

Index: src/usr.bin/ftp/util.c
diff -u src/usr.bin/ftp/util.c:1.165 src/usr.bin/ftp/util.c:1.166
--- src/usr.bin/ftp/util.c:1.165	Fri Jan 20 22:08:48 2023
+++ src/usr.bin/ftp/util.c	Sat Feb 25 12:07:25 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: util.c,v 1.165 2023/01/20 22:08:48 andvar Exp $	*/
+/*	$NetBSD: util.c,v 1.166 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
- * Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -64,7 +64,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.165 2023/01/20 22:08:48 andvar Exp $");
+__RCSID("$NetBSD: util.c,v 1.166 2023/02/25 12:07:25 mlelstv Exp $");
 #endif /* not lint */
 
 /*
@@ -1495,6 +1495,26 @@ ftp_poll(struct pollfd *fds, int nfds, i
 	return poll(fds, nfds, timeout);
 }
 
+/*
+ * Evaluate a "boolean" string, accept only "1" as true and "0" as false
+ * Anything else returns the default value.
+ * Warn about an invalid value that isn't empty.
+ */
+int
+ftp_truthy(const char *name, const char *str, int defvalue)
+{
+
+	if (strcmp(str, "1") == 0)
+		return 1;
+	else if (strcmp(str, "0") == 0)
+		return 0;
+
+	if (*str)
+		warn("Option %s must be boolean (1 or 0)\n", name);
+
+	return defvalue;
+}
+
 #ifndef SMALL
 /*
  * malloc() with inbuilt error checking

Index: src/usr.bin/ftp/version.h
diff -u src/usr.bin/ftp/version.h:1.95 src/usr.bin/ftp/version.h:1.96
--- src/usr.bin/ftp/version.h:1.95	Thu Sep 22 03:31:04 2022
+++ src/usr.bin/ftp/version.h	Sat Feb 25 12:07:25 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: version.h,v 1.95 2022/09/22 03:31:04 lukem Exp $	*/
+/*	$NetBSD: version.h,v 1.96 2023/02/25 12:07:25 mlelstv Exp $	*/
 
 /*-
- * Copyright (c) 1999-2022 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -34,5 +34,5 @@
 #endif
 
 #ifndef FTP_VERSION
-#define	FTP_VERSION	"20220911"
+#define	FTP_VERSION	"20230225"
 #endif

Reply via email to