Module Name: othersrc Committed By: lukem Date: Sun Apr 9 00:56:07 UTC 2023
Modified Files: othersrc/usr.bin/tnftp/src: cmdtab.c extern.h fetch.c ftp.1 ftp_var.h main.c ssl.c util.c version.h Log Message: Merge from tag NetBSD-20210826 to tag NetBSD-20230226 To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 othersrc/usr.bin/tnftp/src/cmdtab.c cvs rdiff -u -r1.14 -r1.15 othersrc/usr.bin/tnftp/src/extern.h cvs rdiff -u -r1.26 -r1.27 othersrc/usr.bin/tnftp/src/fetch.c cvs rdiff -u -r1.18 -r1.19 othersrc/usr.bin/tnftp/src/ftp.1 cvs rdiff -u -r1.13 -r1.14 othersrc/usr.bin/tnftp/src/ftp_var.h cvs rdiff -u -r1.22 -r1.23 othersrc/usr.bin/tnftp/src/main.c cvs rdiff -u -r1.7 -r1.8 othersrc/usr.bin/tnftp/src/ssl.c cvs rdiff -u -r1.25 -r1.26 othersrc/usr.bin/tnftp/src/util.c cvs rdiff -u -r1.10 -r1.11 othersrc/usr.bin/tnftp/src/version.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: othersrc/usr.bin/tnftp/src/cmdtab.c diff -u othersrc/usr.bin/tnftp/src/cmdtab.c:1.12 othersrc/usr.bin/tnftp/src/cmdtab.c:1.13 --- othersrc/usr.bin/tnftp/src/cmdtab.c:1.12 Sun May 5 11:17:30 2013 +++ othersrc/usr.bin/tnftp/src/cmdtab.c Sun Apr 9 00:56:07 2023 @@ -1,8 +1,8 @@ -/* $NetBSD: cmdtab.c,v 1.12 2013/05/05 11:17:30 lukem Exp $ */ -/* from NetBSD: cmdtab.c,v 1.52 2012/12/22 16:57:09 christos Exp */ +/* $NetBSD: cmdtab.c,v 1.13 2023/04/09 00:56:07 lukem Exp $ */ +/* from 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 @@ -68,7 +68,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 */ @@ -303,13 +303,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: othersrc/usr.bin/tnftp/src/extern.h diff -u othersrc/usr.bin/tnftp/src/extern.h:1.14 othersrc/usr.bin/tnftp/src/extern.h:1.15 --- othersrc/usr.bin/tnftp/src/extern.h:1.14 Sat Jul 4 09:59:07 2020 +++ othersrc/usr.bin/tnftp/src/extern.h Sun Apr 9 00:56:07 2023 @@ -1,8 +1,8 @@ -/* $NetBSD: extern.h,v 1.14 2020/07/04 09:59:07 lukem Exp $ */ -/* from NetBSD: extern.h,v 1.82 2019/06/22 23:40:53 christos Exp */ +/* $NetBSD: extern.h,v 1.15 2023/04/09 00:56:07 lukem Exp $ */ +/* from 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 @@ -244,6 +244,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: othersrc/usr.bin/tnftp/src/fetch.c diff -u othersrc/usr.bin/tnftp/src/fetch.c:1.26 othersrc/usr.bin/tnftp/src/fetch.c:1.27 --- othersrc/usr.bin/tnftp/src/fetch.c:1.26 Fri Aug 27 01:38:49 2021 +++ othersrc/usr.bin/tnftp/src/fetch.c Sun Apr 9 00:56:07 2023 @@ -1,5 +1,5 @@ -/* $NetBSD: fetch.c,v 1.26 2021/08/27 01:38:49 lukem Exp $ */ -/* from NetBSD: fetch.c,v 1.234 2021/08/01 15:29:30 andvar Exp */ +/* $NetBSD: fetch.c,v 1.27 2023/04/09 00:56:07 lukem Exp $ */ +/* from NetBSD: fetch.c,v 1.236 2023/02/25 12:07:25 mlelstv Exp */ /*- * Copyright (c) 1997-2015 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID(" NetBSD: fetch.c,v 1.234 2021/08/01 15:29:30 andvar Exp "); +__RCSID(" NetBSD: fetch.c,v 1.236 2023/02/25 12:07:25 mlelstv Exp "); #endif /* not lint */ /* @@ -113,12 +113,13 @@ __dead static void timeouthttp(int); static int auth_url(const char *, char **, const struct authinfo *); static void base64_encode(const unsigned char *, size_t, unsigned char *); #endif -static int go_fetch(const char *); +static int go_fetch(const char *, struct urlinfo *); static int fetch_ftp(const char *); -static int fetch_url(const char *, const char *, char *, char *); +static int fetch_url(const char *, const char *, char *, char *, + struct urlinfo *); static const char *match_token(const char **, const char *); static int parse_url(const char *, const char *, struct urlinfo *, - struct authinfo *); + struct authinfo *, struct urlinfo *); static void url_decode(char *); static void freeauthinfo(struct authinfo *); static void freeurlinfo(struct urlinfo *); @@ -281,7 +282,7 @@ auth_url(const char *challenge, char **r scheme = "Basic"; /* only support Basic authentication */ gotpass = NULL; - DPRINTF("auth_url: challenge `%s'\n", challenge); + DPRINTF("%s: challenge `%s'\n", __func__, challenge); if (! match_token(&cp, scheme)) { warnx("Unsupported authentication challenge `%s'", @@ -343,7 +344,7 @@ auth_url(const char *challenge, char **r *response = ftp_malloc(rlen); (void)strlcpy(*response, scheme, rlen); len = strlcat(*response, " ", rlen); - /* use `clen - 1' to not encode the trailing NUL */ + /* use `clen - 1' to not encode the trailing NUL */ base64_encode((unsigned char *)clear, clen - 1, (unsigned char *)*response + len); memset(clear, 0, clen); @@ -374,7 +375,7 @@ base64_encode(const unsigned char *clear | ((clear[i + 1] >> 4) & 0x0f)]; *(cp++) = enc[((clear[i + 1] << 2) & 0x3c) | ((clear[i + 2] >> 6) & 0x03)]; - *(cp++) = enc[((clear[i + 2] ) & 0x3f)]; + *(cp++) = enc[((clear[i + 2] ) & 0x3f)]; } *cp = '\0'; while (i-- > len) @@ -407,6 +408,42 @@ url_decode(char *url) *q = '\0'; } +static const char * +get_port(const struct urlinfo *ui) +{ + + switch(ui->utype) { + case HTTP_URL_T: + return httpport; + case FTP_URL_T: + return ftpport; + case FILE_URL_T: + return ""; +#ifdef WITH_SSL + case HTTPS_URL_T: + return httpsport; +#endif + default: + return NULL; + } +} + +static int +use_relative(const struct urlinfo *ui) +{ + if (ui == NULL) + return 0; + switch (ui->utype) { + case HTTP_URL_T: + case FILE_URL_T: +#ifdef WITH_SSL + case HTTPS_URL_T: +#endif + return 1; + default: + return 0; + } +} /* * Parse URL of form (per RFC 3986): @@ -442,7 +479,7 @@ url_decode(char *url) static int parse_url(const char *url, const char *desc, struct urlinfo *ui, - struct authinfo *auth) + struct authinfo *auth, struct urlinfo *rui) { const char *origurl, *tport; char *cp, *ep, *thost; @@ -453,29 +490,26 @@ parse_url(const char *url, const char *d DPRINTF("parse_url: %s `%s'\n", desc, url); origurl = url; - tport = NULL; if (STRNEQUAL(url, HTTP_URL)) { url += sizeof(HTTP_URL) - 1; ui->utype = HTTP_URL_T; ui->portnum = HTTP_PORT; - tport = httpport; } else if (STRNEQUAL(url, FTP_URL)) { url += sizeof(FTP_URL) - 1; ui->utype = FTP_URL_T; ui->portnum = FTP_PORT; - tport = ftpport; } else if (STRNEQUAL(url, FILE_URL)) { url += sizeof(FILE_URL) - 1; ui->utype = FILE_URL_T; - tport = ""; #ifdef WITH_SSL } else if (STRNEQUAL(url, HTTPS_URL)) { url += sizeof(HTTPS_URL) - 1; ui->utype = HTTPS_URL_T; ui->portnum = HTTPS_PORT; - tport = httpsport; #endif + } else if (rui != NULL) { + copyurlinfo(ui, rui); } else { warnx("Invalid %s `%s'", desc, url); cleanup_parse_url: @@ -484,6 +518,7 @@ parse_url(const char *url, const char *d return (-1); } + if (*url == '\0') return (0); @@ -548,7 +583,8 @@ parse_url(const char *url, const char *d #endif /* INET6 */ if ((cp = strchr(thost, ':')) != NULL) *cp++ = '\0'; - ui->host = thost; + if (*thost != '\0') + ui->host = thost; /* look for [:port] */ if (cp != NULL) { @@ -563,7 +599,9 @@ parse_url(const char *url, const char *d } ui->portnum = nport; tport = cp; - } + } else + tport = get_port(ui); + if (tport != NULL) ui->port = ftp_strdup(tport); @@ -574,8 +612,8 @@ parse_url(const char *url, const char *d ui->path = ftp_strdup(emptypath); } - DPRINTF("parse_url: user `%s' pass `%s' host %s port %s(%d) " - "path `%s'\n", + DPRINTF("%s: user `%s' pass `%s' host %s port %s(%d) " + "path `%s'\n", __func__, STRorNULL(auth->user), STRorNULL(auth->pass), STRorNULL(ui->host), STRorNULL(ui->port), ui->portnum ? ui->portnum : -1, STRorNULL(ui->path)); @@ -586,13 +624,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; + 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; @@ -657,6 +697,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) { @@ -668,6 +730,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; @@ -693,7 +764,7 @@ handle_noproxy(const char *host, in_port if (*cp == '\0') continue; if ((np = strrchr(cp, ':')) != NULL) { - *np++ = '\0'; + *np++ = '\0'; np_port = strtoul(np, &ep, 10); if (*np == '\0' || *ep != '\0') continue; @@ -725,7 +796,7 @@ handle_proxy(const char *url, const char } initurlinfo(&pui); - if (parse_url(penv, "proxy URL", &pui, pauth) == -1) + if (parse_url(penv, "proxy URL", &pui, pauth, NULL) == -1) return -1; if ((!IS_HTTP_TYPE(pui.utype) && pui.utype != FTP_URL_T) || @@ -896,9 +967,9 @@ print_connect(FETCH *fin, const struct u } #endif -#define C_OK 0 -#define C_CLEANUP 1 -#define C_IMPROPER 2 +#define C_OK 0 +#define C_CLEANUP 1 +#define C_IMPROPER 2 static int getresponseline(FETCH *fin, char *buf, size_t buflen, int *len) @@ -997,7 +1068,7 @@ parse_posinfo(const char **cp, struct po static void do_auth(int hcode, const char *url, const char *penv, struct authinfo *wauth, struct authinfo *pauth, char **auth, const char *message, - volatile int *rval) + volatile int *rval, struct urlinfo *ui) { struct authinfo aauth; char *response; @@ -1032,7 +1103,8 @@ do_auth(int hcode, const char *url, cons if (auth_url(*auth, &response, &aauth) == 0) { *rval = fetch_url(url, penv, hcode == 401 ? pauth->auth : response, - hcode == 401 ? response: wauth->auth); + hcode == 401 ? response : wauth->auth, + ui); memset(response, 0, strlen(response)); FREEPTR(response); } @@ -1043,12 +1115,12 @@ static int negotiate_connection(FETCH *fin, const char *url, const char *penv, struct posinfo *pi, time_t *mtime, struct authinfo *wauth, struct authinfo *pauth, volatile int *rval, volatile int *ischunked, - char **auth) + char **auth, struct urlinfo *ui) { int len, hcode, rv; char buf[FTPBUFLEN], *ep; const char *cp, *token; - char *location, *message; + char *location, *message; *auth = message = location = NULL; @@ -1163,18 +1235,19 @@ negotiate_connection(FETCH *fin, const c fprintf(ttyout, "Redirected via %s\n", location); *rval = fetch_url(url, location, - pauth->auth, wauth->auth); + pauth->auth, wauth->auth, ui); } else { if (verbose) fprintf(ttyout, "Redirected to %s\n", location); - *rval = go_fetch(location); + *rval = go_fetch(location, ui); } goto cleanup_fetch_url; #ifndef NO_AUTH case 401: case 407: - do_auth(hcode, url, penv, wauth, pauth, auth, message, rval); + do_auth(hcode, url, penv, wauth, pauth, auth, message, rval, + ui); goto cleanup_fetch_url; #endif default: @@ -1239,7 +1312,7 @@ connectmethod(FETCH *fin, const char *ur message = ftp_strdup(ep); break; } - + for (;;) { int len; if (getresponseline(fin, buf, sizeof(buf), &len) != C_OK) @@ -1268,7 +1341,8 @@ connectmethod(FETCH *fin, const char *ur break; #ifndef NO_AUTH case 407: - do_auth(hcode, url, penv, wauth, pauth, auth, message, rval); + do_auth(hcode, url, penv, wauth, pauth, auth, message, rval, + ui); goto cleanup_fetch_url; #endif default: @@ -1306,7 +1380,8 @@ out: * is still open (e.g, ftp xfer with trailing /) */ static int -fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth) +fetch_url(const char *url, const char *proxyenv, char *proxyauth, + char *wwwauth, struct urlinfo *rui) { sigfunc volatile oldint; sigfunc volatile oldpipe; @@ -1315,7 +1390,7 @@ fetch_url(const char *url, const char *p int volatile s; struct stat sb; int volatile isproxy; - int volatile rval, ischunked; + int volatile rval, ischunked; size_t flen; static size_t bufsize; static char *xferbuf; @@ -1326,7 +1401,7 @@ fetch_url(const char *url, const char *p char *volatile location; char *volatile message; char *volatile decodedpath; - struct authinfo wauth, pauth; + struct authinfo wauth, pauth; struct posinfo pi; off_t hashbytes; int (*volatile closefunc)(FILE *); @@ -1359,7 +1434,7 @@ fetch_url(const char *url, const char *p if (sigsetjmp(httpabort, 1)) goto cleanup_fetch_url; - if (parse_url(url, "URL", &ui, &wauth) == -1) + if (parse_url(url, "URL", &ui, &wauth, rui) == -1) goto cleanup_fetch_url; copyurlinfo(&oui, &ui); @@ -1375,7 +1450,7 @@ fetch_url(const char *url, const char *p rval = fetch_ftp(url); goto cleanup_fetch_url; } - if (!IS_HTTP_TYPE(ui.utype) || outfile == NULL) { + if (!IS_HTTP_TYPE(ui.utype) || outfile == NULL) { warnx("Invalid URL (no file after host) `%s'", url); goto cleanup_fetch_url; } @@ -1430,7 +1505,8 @@ fetch_url(const char *url, const char *p filesize = sb.st_size; } if (restart_point) { - if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) < 0) { + if (lseek(fetch_fileno(fin), restart_point, SEEK_SET) + < 0) { warn("Can't seek to restart `%s'", decodedpath); goto cleanup_fetch_url; @@ -1448,6 +1524,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 @@ -1481,7 +1561,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; @@ -1542,7 +1622,7 @@ fetch_url(const char *url, const char *p switch (negotiate_connection(fin, url, penv, &pi, &mtime, &wauth, &pauth, &rval, &ischunked, - __UNVOLATILE(&auth))) { + __UNVOLATILE(&auth), &ui)) { case C_OK: break; case C_CLEANUP: @@ -1649,7 +1729,7 @@ fetch_url(const char *url, const char *p } /* - * XXX: Work around bug in Apache 1.3.9 and + * XXX: Work around bug in Apache 1.3.9 and * 1.3.11, which incorrectly put trailing * space after the chunk-size. */ @@ -1857,10 +1937,10 @@ fetch_ftp(const char *url) char dirbuf[4]; int dirhasglob, filehasglob, rval, transtype, xargc; int oanonftp, oautologin; - struct authinfo auth; + struct authinfo auth; struct urlinfo ui; - DPRINTF("fetch_ftp: `%s'\n", url); + DPRINTF("%s: `%s'\n", __func__, url); dir = file = NULL; rval = 1; transtype = TYPE_I; @@ -1869,7 +1949,7 @@ fetch_ftp(const char *url) initauthinfo(&auth, NULL); if (STRNEQUAL(url, FTP_URL)) { - if ((parse_url(url, "URL", &ui, &auth) == -1) || + if ((parse_url(url, "URL", &ui, &auth, NULL) == -1) || (auth.user != NULL && *auth.user == '\0') || EMPTYSTRING(ui.host)) { warnx("Invalid URL `%s'", url); @@ -1881,7 +1961,8 @@ fetch_ftp(const char *url) */ /* check for trailing ';type=[aid]' */ - if (! EMPTYSTRING(ui.path) && (cp = strrchr(ui.path, ';')) != NULL) { + if (! EMPTYSTRING(ui.path) + && (cp = strrchr(ui.path, ';')) != NULL) { if (strcasecmp(cp, ";type=a") == 0) transtype = TYPE_A; else if (strcasecmp(cp, ";type=i") == 0) @@ -1923,12 +2004,12 @@ fetch_ftp(const char *url) * If we are dealing with classic `[user@]host:[path]' syntax, * then a path of the form `/file' (resulting from input of the * form `host:/file') means that we should do "CWD /" before - * retrieving the file. So we set dir="/" and file="file". + * retrieving the file. So we set dir="/" and file="file". * * But if we are dealing with URLs like `ftp://host/path' then * a path of the form `/file' (resulting from a URL of the form * `ftp://host//file') means that we should do `CWD ' (with an - * empty argument) before retrieving the file. So we set + * empty argument) before retrieving the file. So we set * dir="" and file="file". * * If the path does not contain / at all, we set dir=NULL. @@ -1959,8 +2040,8 @@ fetch_ftp(const char *url) url_decode(file); /* but still don't url_decode(dir) */ } - DPRINTF("fetch_ftp: user `%s' pass `%s' host %s port %s " - "path `%s' dir `%s' file `%s'\n", + DPRINTF("%s: user `%s' pass `%s' host %s port %s " + "path `%s' dir `%s' file `%s'\n", __func__, STRorNULL(auth.user), STRorNULL(auth.pass), STRorNULL(ui.host), STRorNULL(ui.port), STRorNULL(ui.path), STRorNULL(dir), STRorNULL(file)); @@ -2009,7 +2090,7 @@ fetch_ftp(const char *url) setbinary(1, xargv); break; default: - errx(1, "fetch_ftp: unknown transfer type %d", transtype); + errx(1, "%s: unknown transfer type %d", __func__, transtype); } /* @@ -2031,7 +2112,7 @@ fetch_ftp(const char *url) * (urltype is FTP_URL_T), then RFC 3986 says we need to * send a separate CWD command for each unescaped "/" * in the path, and we have to interpret %hex escaping - * *after* we find the slashes. It's possible to get + * *after* we find the slashes. It's possible to get * empty components here, (from multiple adjacent * slashes in the path) and RFC 3986 says that we should * still do `CWD ' (with a null argument) in such cases. @@ -2074,7 +2155,7 @@ fetch_ftp(const char *url) * "CWD /", "CWD foo", "CWD bar", "RETR file" * ftp://host/%2Ffoo/bar/file dir="%2Ffoo/bar" * "CWD /foo", "CWD bar", "RETR file" - * ftp://host/%2Ffoo%2Fbar/file dir="%2Ffoo%2Fbar" + * ftp://host/%2Ffoo%2Fbar/file dir="%2Ffoo%2Fbar" * "CWD /foo/bar", "RETR file" * ftp://host/%2Ffoo%2Fbar%2Ffile dir=NULL * "RETR /foo/bar/file" @@ -2091,7 +2172,7 @@ fetch_ftp(const char *url) url_decode(dir); } else nextpart = NULL; - DPRINTF("fetch_ftp: dir `%s', nextpart `%s'\n", + DPRINTF("%s: dir `%s', nextpart `%s'\n", __func__, STRorNULL(dir), STRorNULL(nextpart)); if (ui.utype == FTP_URL_T || *dir != '\0') { (void)strlcpy(cmdbuf, "cd", sizeof(cmdbuf)); @@ -2186,7 +2267,7 @@ fetch_ftp(const char *url) * is still open (e.g, ftp xfer with trailing /) */ static int -go_fetch(const char *url) +go_fetch(const char *url, struct urlinfo *rui) { char *proxyenv; char *p; @@ -2235,7 +2316,7 @@ go_fetch(const char *url) || STRNEQUAL(url, HTTPS_URL) #endif || STRNEQUAL(url, FILE_URL)) - return (fetch_url(url, NULL, NULL, NULL)); + return (fetch_url(url, NULL, NULL, NULL, rui)); /* * If it contains "://" but does not begin with ftp:// @@ -2250,13 +2331,20 @@ go_fetch(const char *url) errx(1, "Unsupported URL scheme `%.*s'", (int)(p - url), url); /* + * Refer to previous urlinfo if provided. This makes relative + * redirects work. + */ + if (use_relative(rui)) + return fetch_url(url, NULL, NULL, NULL, rui); + + /* * Try FTP URL-style and host:file arguments next. * If ftpproxy is set with an FTP URL, use fetch_url() * Otherwise, use fetch_ftp(). */ proxyenv = getoptionvalue("ftp_proxy"); if (!EMPTYSTRING(proxyenv) && STRNEQUAL(url, FTP_URL)) - return (fetch_url(url, NULL, NULL, NULL)); + return (fetch_url(url, NULL, NULL, NULL, rui)); return (fetch_ftp(url)); } @@ -2299,7 +2387,7 @@ auto_fetch(int argc, char *argv[]) redirect_loop = 0; if (!anonftp) anonftp = 2; /* Handle "automatic" transfers. */ - rval = go_fetch(argv[argpos]); + rval = go_fetch(argv[argpos], NULL); if (outfile != NULL && strcmp(outfile, "-") != 0 && outfile[0] != '|') { FREEPTR(outfile); @@ -2338,7 +2426,7 @@ auto_put(int argc, char **argv, const ch pathsep = NULL; rval = 1; - DPRINTF("auto_put: target `%s'\n", uploadserver); + DPRINTF("%s: target `%s'\n", __func__, uploadserver); path = ftp_strdup(uploadserver); len = strlen(path); @@ -2347,7 +2435,7 @@ auto_put(int argc, char **argv, const ch * make sure we always pass a directory to auto_fetch */ if (argc > 1) { /* more than one file to upload */ - len = strlen(uploadserver) + 2; /* path + "/" + "\0" */ + len = strlen(uploadserver) + 2; /* path + "/" + "\0" */ free(path); path = (char *)ftp_malloc(len); (void)strlcpy(path, uploadserver, len); @@ -2371,7 +2459,7 @@ auto_put(int argc, char **argv, const ch uargc++; } } - DPRINTF("auto_put: URL `%s' argv[2] `%s'\n", + DPRINTF("%s: URL `%s' argv[2] `%s'\n", __func__, path, STRorNULL(uargv[2])); /* connect and cwd */ Index: othersrc/usr.bin/tnftp/src/ftp.1 diff -u othersrc/usr.bin/tnftp/src/ftp.1:1.18 othersrc/usr.bin/tnftp/src/ftp.1:1.19 --- othersrc/usr.bin/tnftp/src/ftp.1:1.18 Fri Aug 27 01:38:49 2021 +++ othersrc/usr.bin/tnftp/src/ftp.1 Sun Apr 9 00:56:07 2023 @@ -1,7 +1,7 @@ -.\" $NetBSD: ftp.1,v 1.18 2021/08/27 01:38:49 lukem Exp $ -.\" from NetBSD: ftp.1,v 1.146 2021/04/25 09:09:55 lukem Exp +.\" $NetBSD: ftp.1,v 1.19 2023/04/09 00:56:07 lukem Exp $ +.\" from NetBSD: ftp.1,v 1.150 2023/02/25 17:37:09 uwe 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 @@ -58,7 +58,7 @@ .\" .\" @(#)ftp.1 8.3 (Berkeley) 10/9/94 .\" -.Dd April 25, 2021 +.Dd February 25, 2023 .Dt FTP 1 .Os .Sh NAME @@ -78,9 +78,9 @@ .Oo .Fl T Xo .Sm off -.Ar dir , +.Ar dir Cm \&, .Ar max -.Op , Ar inc +.Op Cm \&, Ar inc .Sm on .Xc .Oc @@ -240,11 +240,14 @@ will check the an account on the remote machine. If no entry exists, .Nm -will prompt for the remote machine login name (default is the user -identity on the local machine), and, if necessary, prompt for a password +will prompt for the remote machine login name +.Pq default is the user identity on the local machine , +and, if necessary, prompt for a password and an account with which to login. To override the auto-login for auto-fetch transfers, specify the -username (and optionally, password) as appropriate. +username +.Pq and optionally, password +as appropriate. .It Fl o Ar output When auto-fetching files, save the contents in .Ar output . @@ -255,9 +258,9 @@ below. If .Ar output is not -.Sq - +.Sq Fl or doesn't start with -.Sq \&| , +.Sq Cm \&| , then only the first file specified will be retrieved into .Ar output ; all other files will be retrieved into the basename of their @@ -287,7 +290,7 @@ Uses as the local IP address for all connections. .It Fl t Enables packet tracing. -.It Fl T Ar direction Ns , Ns Ar maximum Ns Oo , Ns Ar increment Oc +.It Fl T Ar direction Ns Cm \&, Ns Ar maximum\| Ns Oo Cm \&, Ns Ar increment Oc Set the maximum transfer rate for .Ar direction to @@ -305,9 +308,10 @@ Upload files on the command line to where .Ar url is one of the -.Sq Li ftp:// +.Ql ftp:// URL types as supported by auto-fetch -(with an optional target filename for single file uploads), and +.Pq with an optional target filename for single file uploads , +and .Ar file is one or more local files to be uploaded. .It Fl V @@ -321,10 +325,13 @@ Enable .Ic verbose and .Ic progress . -This is the default if output is to a terminal (and in the case of +This is the default if output is to a terminal +.Po +and in the case of .Ic progress , .Nm -is the foreground process). +is the foreground process +.Pc . Forces .Nm to show all responses from the remote server, as well @@ -335,7 +342,7 @@ Set the size of the socket send and rece Refer to .Ic xferbuf for more information. -.It Fl ? +.It Fl \&? Display help to stdout, and exit. .El .Pp @@ -357,7 +364,7 @@ is awaiting commands from the user the p is provided to the user. The following commands are recognized by -.Nm ftp : +.Nm : .Bl -tag -width Ic .It Ic \&! Op Ar command Op Ar args Invoke an interactive shell on the local machine. @@ -455,7 +462,7 @@ sequence to conform with the single linefeed record delimiter. Records on -.Pf non\- Ns Ux +.Pf non\- Ux remote systems may contain single linefeeds; when an ascii type transfer is made, these linefeeds may be distinguished from a record delimiter only when @@ -528,9 +535,8 @@ is executed again. A synonym for .Ic bye . .It Ic features -Display what features the remote server supports (using the -.Dv FEAT -command). +Display what features the remote server supports +.Pq using the Dv FEAT No command . .It Ic fget Ar localfile Retrieve the files listed in .Ar localfile , @@ -542,7 +548,7 @@ to .Ar format . The default (and only supported) format is -.Dq non-print . +.Ql non-print . .It Ic ftp Ar host Op Ar port A synonym for .Ic open . @@ -552,9 +558,11 @@ TIS FWTK and Gauntlet .Tn FTP proxies. This will not be permitted if the gate-ftp server hasn't been set -(either explicitly by the user, or from the +.Po +either explicitly by the user, or from the .Ev FTPSERVER -environment variable). +environment variable +.Pc . If .Ar host is given, @@ -626,7 +634,7 @@ transferring a archive of the subtree (in binary mode). .It Ic hash Op Ar size Toggle hash-sign -.Pq Sq # +.Pq Ql # printing for each data block transferred. The size of a data block defaults to 1024 bytes. This can be changed by specifying @@ -676,16 +684,24 @@ A synonym for Define a macro. Subsequent lines are stored as the macro .Ar macro-name ; -a null line (consecutive newline characters in a file or carriage -returns from the terminal) terminates macro input mode. +a null line +.Po +consecutive newline characters in a file or carriage +returns from the terminal +.Pc +terminates macro input mode. There is a limit of 16 macros and 4096 total characters in all defined macros. Macro names can be a maximum of 8 characters. Macros are only applicable to the current session they are -defined within (or if defined outside a session, to the session +defined within +.Po +or if defined outside a session, to the session invoked with the next .Ic open -command), and remain defined until a +command +.Pc , +and remain defined until a .Ic close command is executed. To invoke a macro, use the @@ -751,9 +767,9 @@ and settings. Files are transferred into the local working directory, which can be changed with -.Ql lcd directory ; +.Ic lcd Ar directory ; new local directories can be created with -.Sq Li "\&! mkdir directory" . +.Ic \&! mkdir Ar directory . .It Ic mkdir Ar directory-name Make a directory on the remote machine. .It Ic mls Ar remote-files local-file @@ -772,27 +788,28 @@ output. .It Ic mlsd Op Ar remote-path Display the contents of .Ar remote-path -(which should default to the current directory if not given) +.Pq which should default to the current directory if not given in a machine-parsable form, using .Dv MLSD . The format of display can be changed with -.Sq Li "remopts mlst ..." . +.Sq Ic remopts mlst Ar \&... . .It Ic mlst Op Ar remote-path Display the details about .Ar remote-path -(which should default to the current directory if not given) +.Pq which should default to the current directory if not given in a machine-parsable form, using .Dv MLST . The format of display can be changed with -.Sq Li "remopts mlst ..." . +.Sq Ic remopts mlst Ar \&... . .It Ic mode Ar mode-name Set the file transfer .Ic mode to .Ar mode-name . -The default (and only supported) +The default +.Pq and only supported mode is -.Dq stream . +.Ql stream . .It Ic modtime Ar remote-file Show the last modification time of the file on the remote machine, in .Li RFC 2822 @@ -857,12 +874,14 @@ and .Ar outpattern . .Pp .Ar inpattern -is a template for incoming filenames (which may have already been -processed according to the +is a template for incoming filenames +.Po +which may have already been processed according to the .Ic ntrans and .Ic case -settings). +settings +.Pc . Variable templating is accomplished by including the sequences .Ql $1 , @@ -882,16 +901,16 @@ All other characters are treated literal variable values. For example, given .Ar inpattern -.Sq Li $1.$2 +.Ql $1.$2 and the remote file name -.Sq Li mydata.data , +.Ql mydata.data , .Ql $1 would have the value -.Sq Li mydata , +.Ql mydata , and .Ql $2 would have the value -.Sq Li data . +.Ql data . .Pp The .Ar outpattern @@ -908,7 +927,9 @@ The sequence .Ql $0 is replaced by the original filename. Additionally, the sequence -.Dq Op Ar seq1 , Ar seq2 +.Sm off +.Li \&[ Ar seq1 Li \&, Ar seq2 Li \&] +.Sm on is replaced by .Ar seq1 if @@ -921,18 +942,18 @@ For example, the command .Pp would yield the output filename -.Sq Li myfile.data +.Ql myfile.data for input filenames -.Sq Li myfile.data +.Ql myfile.data and -.Sq Li myfile.data.old , -.Sq Li myfile.file +.Ql myfile.data.old , +.Ql myfile.file for the input filename -.Sq Li myfile , +.Ql myfile , and -.Sq Li myfile.myfile +.Ql myfile.myfile for the input filename -.Sq Li "\&.myfile" . +.Ql \&.myfile . Spaces may be included in .Ar outpattern , as in the example: @@ -1031,13 +1052,15 @@ Passive mode is useful when using .Nm through a gateway router or host that controls the directionality of traffic. -(Note that though +.Po +Note that though .Tn FTP servers are required to support the .Dv PASV command by .Li RFC 1123 , -some do not.) +some do not. +.Pc .It Ic pdir Op Ar remote-path Perform .Ic dir @@ -1105,9 +1128,11 @@ and do not transfer the file. Answer .Sq yes to the current file, and turn off prompt mode -(as is -.Dq prompt off -had been given). +.Po +as if +.Ic prompt off +had been given +.Pc . .It Cm q Terminate the current operation. .It Cm y @@ -1265,15 +1290,17 @@ server for .Ar command to .Ar command-options -(whose absence is handled on a command-specific basis). +.Pq whose absence is handled on a command-specific basis . Remote .Tn FTP commands known to support options include: .Dv MLST -(used for +.Po +used for .Dv MLSD and -.Dv MLST ) . +.Dv MLST +.Pc . .It Ic rename Op Ar from Op Ar to Rename the file .Ar from @@ -1383,7 +1410,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 ".Cm sslnoverify" -offset indent .It Cm anonpass Defaults to .Ev $FTPANONPASS @@ -1408,6 +1435,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 @@ -1432,7 +1462,7 @@ to .Ar struct-name . The default (and only supported) structure is -.Dq file . +.Ql file . .It Ic sunique Toggle storing of files on remote machine under unique file names. The remote @@ -1540,11 +1570,13 @@ or argument to force the setting appropriately. .Pp Commands which take a byte count as an argument -(e.g., +.Po +e.g., .Ic hash , .Ic rate , and -.Ic xferbuf ) +.Ic xferbuf +.Pc support an optional suffix on the argument which changes the interpretation of the argument. Supported suffixes are: @@ -1564,10 +1596,12 @@ If .Nm receives a .Dv SIGINFO -(see the +.Po +see the .Cm status argument of -.Xr stty 1 ) +.Xr stty 1 +.Pc or .Dv SIGQUIT signal whilst a transfer is in progress, the current transfer rate @@ -1595,7 +1629,7 @@ contains a glob character and globbing i (see .Ic glob ) , then the equivalent of -.Sq Li mget path +.Ic mget Ar path is performed. .Pp If the directory component of @@ -1634,9 +1668,9 @@ In this case, use if supplied, otherwise prompt the user for one. .Pp If a suffix of -.Sq Li \&;type=A +.Ql \&;type=A or -.Sq Li \&;type=I +.Ql \&;type=I is supplied, then the transfer type will take place as ascii or binary (respectively). The default transfer type is binary. @@ -1647,12 +1681,12 @@ In order to be compliant with interprets the .Ar path part of an -.Sq Li ftp:// +.Ql ftp:// auto-fetch URL as follows: .Bl -bullet .It The -.Sq Li / +.Ql / immediately after the .Ar host Ns Oo Li \&: Ns Ar port Oc is interpreted as a separator before the @@ -1679,11 +1713,11 @@ command. .It Empty name components, which result from -.Sq Li // +.Ql // within the .Ar path , or from an extra -.Sq Li / +.Ql / at the beginning of the .Ar path , will cause the equivalent of a @@ -1692,7 +1726,7 @@ command without a directory name. This is unlikely to be useful. .It Any -.Sq Li \&% Ns Ar XX +.Sq Cm \&% Ns Ar XX\^ codes (per .Li RFC 3986 ) @@ -1708,13 +1742,15 @@ or .Ic get command. Some often-used codes are -.Sq Li \&%2F +.Ql \&%2F (which represents -.Sq Li / ) +.Ql / ) and -.Sq Li \&%7E -(which represents -.Sq Li ~ ) . +.Ql \&%7E +.Po +which represents +.Ql ~ +.Pc . .El .Pp The above interpretation has the following consequences: @@ -1727,20 +1763,21 @@ user. If the .Pa / directory is required, use a leading path of -.Sq Li \&%2F . -If a user's home directory is required (and the remote server supports -the syntax), use a leading path of -.Sq Li \&%7E Ns Ar user Ns Li / . +.Ql \&%2F . +If a user's home directory is required +.Pq and the remote server supports the syntax , +use a leading path of +.Ql \&%7E Ns Ar user Ns Li / . For example, to retrieve .Pa /etc/motd from -.Sq Li localhost +.Ql localhost as the user -.Sq Li myname +.Ql myname with the password -.Sq Li mypass , +.Ql mypass , use -.Sq Li ftp://myname:mypass@localhost/%2fetc/motd +.Ql ftp://myname:mypass@localhost/%2fetc/motd .It The exact .Ic cd @@ -1748,32 +1785,46 @@ and .Ic get commands can be controlled by careful choice of where to use -.Sq Li / +.Ql / and where to use -.Sq Li \&%2F +.Ql \&%2F (or -.Sq Li %2f ) . +.Ql %2f ) . For example, the following URLs correspond to the equivalents of the indicated commands: .Bl -tag -width "ftp://host/%2Fdir1%2Fdir2%2Ffile" -.It ftp://host/dir1/dir2/file -.Dq "cd dir1" , -.Dq "cd dir2" , -.Dq "get file" . -.It ftp://host/%2Fdir1/dir2/file -.Dq "cd /dir1" , -.Dq "cd dir2" , -.Dq "get file" . -.It ftp://host/dir1%2Fdir2/file -.Dq "cd dir1/dir2" , -.Dq "get file" . -.It ftp://host/%2Fdir1%2Fdir2/file -.Dq "cd /dir1/dir2" , -.Dq "get file" . -.It ftp://host/dir1%2Fdir2%2Ffile -.Dq "get dir1/dir2/file" . -.It ftp://host/%2Fdir1%2Fdir2%2Ffile -.Dq "get /dir1/dir2/file" . +.It Xo \" ftp://host/dir1/dir2/file +.Sm off +.Ic ftp:// Ar host +.Ic / Ar dir1 +.Ic / Ar dir2 +.Ic / Ar file +.Sm on +.Xc +.Ic cd Ar dir1 , +.Ic cd Ar dir2 , +.Ic get Ar file . +.It Xo \" ftp://host/%2Fdir1/dir2/file +.Sm off +.Ic ftp:// Ar host +.Ic /%2F Ar dir1 +.Ic / Ar dir2 +.Ic / Ar file +.Sm on +.Xc +.Ic cd / Ns Ar dir1 , +.Ic cd Ar dir2 , +.Ic get Ar file . +.It Xo \" ftp://host/dir1%2Fdir2/file +.Sm off +.Ic ftp:// Ar host +.Ic / Ar dir1 +.Ic %2F Ar dir2 +.Ic / Ar file +.Sm on +.Xc +.Ic cd Ar dir1 Ns Ic / Ns Ar dir2 , +.Ic get Ar file . .El .It You must have appropriate access permission for each of the @@ -1914,7 +1965,7 @@ to enter a username and password to auth When specifying IPv6 numeric addresses in a URL, you need to surround the address in square brackets. E.g.: -.Sq Li ftp://[::1]:21/ . +.Ql ftp://[::1]:21/ . This is because colons are used in IPv6 numeric address as well as being the separator for the port number. .Sh ABORTING A FILE TRANSFER @@ -1968,10 +2019,10 @@ with the argument supplied, and reads (w (stdin). If the shell command includes spaces, the argument must be quoted; e.g. -.Sq Li \(dq|\~ls\~\-lt\(dq . +.Ql \*q|\~ls\~\-lt\*q . A particularly useful example of this mechanism is: -.Sq Li dir\~\(dq\(dq\~|more . +.Ql dir\~\*q\*q\~|more . .It Failing the above checks, if globbing is enabled, local file names are expanded according to the rules @@ -2313,6 +2364,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 @@ -2360,7 +2413,7 @@ or .Ql / ) , encode them with .Li RFC 3986 -.Sq Li \&% Ns Ar XX +.Ql \&% Ns Ar XX\^ encoding. .Pp Note that the use of a username and password in @@ -2388,7 +2441,7 @@ for further notes about proxy use. A space or comma separated list of hosts (or domains) for which proxying is not to be used. Each entry may have an optional trailing -.Sq Li \&: Ns Ar port , +.Ql \&: Ns Ar port , which restricts the matching to connections to that port. .El Index: othersrc/usr.bin/tnftp/src/ftp_var.h diff -u othersrc/usr.bin/tnftp/src/ftp_var.h:1.13 othersrc/usr.bin/tnftp/src/ftp_var.h:1.14 --- othersrc/usr.bin/tnftp/src/ftp_var.h:1.13 Sat Jul 4 09:59:07 2020 +++ othersrc/usr.bin/tnftp/src/ftp_var.h Sun Apr 9 00:56:07 2023 @@ -1,5 +1,5 @@ -/* $NetBSD: ftp_var.h,v 1.13 2020/07/04 09:59:07 lukem Exp $ */ -/* from NetBSD: ftp_var.h,v 1.85 2017/11/20 21:11:36 kre Exp */ +/* $NetBSD: ftp_var.h,v 1.14 2023/04/09 00:56:07 lukem Exp $ */ +/* from NetBSD: ftp_var.h,v 1.86 2021/09/10 21:52:17 rillig Exp */ /*- * Copyright (c) 1996-2009 The NetBSD Foundation, Inc. @@ -346,7 +346,7 @@ extern struct option optiontab[]; #define DPRINTF(...) (void)0 #define DWARN(...) (void)0 #else -#define DWFTP(a) do a; while (/*CONSTCOND*/0) +#define DWFTP(a) do a; while (0) #define DPRINTF(...) DWFTP(if (ftp_debug) (void)fprintf(ttyout, __VA_ARGS__)) #define DWARN(...) DWFTP(if (ftp_debug) warn(__VA_ARGS__)) #endif Index: othersrc/usr.bin/tnftp/src/main.c diff -u othersrc/usr.bin/tnftp/src/main.c:1.22 othersrc/usr.bin/tnftp/src/main.c:1.23 --- othersrc/usr.bin/tnftp/src/main.c:1.22 Sun Apr 25 07:50:37 2021 +++ othersrc/usr.bin/tnftp/src/main.c Sun Apr 9 00:56:07 2023 @@ -1,8 +1,8 @@ -/* $NetBSD: main.c,v 1.22 2021/04/25 07:50:37 lukem Exp $ */ -/* from NetBSD: main.c,v 1.127 2020/07/18 03:00:37 lukem Exp */ +/* $NetBSD: main.c,v 1.23 2023/04/09 00:56:07 lukem Exp $ */ +/* from 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 @@ -103,7 +103,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.127 2020/07/18 03:00:37 lukem Exp "); +__RCSID(" NetBSD: main.c,v 1.129 2023/02/25 12:07:25 mlelstv Exp "); #endif #endif /* not lint */ @@ -276,7 +276,7 @@ main(int volatile argc, char **volatile } } - while ((ch = getopt(argc, argv, "?46AadefginN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) { + while ((ch = getopt(argc, argv, ":46AadefginN:o:pP:q:r:Rs:tT:u:vVx:")) != -1) { switch (ch) { case '4': family = AF_INET; @@ -429,6 +429,11 @@ main(int volatile argc, char **volatile if (optopt == '?') { return usage_help(); } + warnx("-%c: unknown option", optopt); + return usage(); + + case ':': + warnx("-%c: missing argument", optopt); return usage(); default: @@ -516,6 +521,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: othersrc/usr.bin/tnftp/src/ssl.c diff -u othersrc/usr.bin/tnftp/src/ssl.c:1.7 othersrc/usr.bin/tnftp/src/ssl.c:1.8 --- othersrc/usr.bin/tnftp/src/ssl.c:1.7 Fri Aug 27 01:48:01 2021 +++ othersrc/usr.bin/tnftp/src/ssl.c Sun Apr 9 00:56:07 2023 @@ -1,10 +1,11 @@ -/* $NetBSD: ssl.c,v 1.7 2021/08/27 01:48:01 lukem Exp $ */ -/* from NetBSD: ssl.c,v 1.10 2021/06/03 10:23:33 lukem Exp */ +/* $NetBSD: ssl.c,v 1.8 2023/04/09 00:56:07 lukem Exp $ */ +/* from 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 @@ -39,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID(" NetBSD: ssl.c,v 1.10 2021/06/03 10:23:33 lukem Exp "); +__RCSID(" NetBSD: ssl.c,v 1.13 2023/02/25 12:07:25 mlelstv Exp "); #endif #include <errno.h> @@ -70,6 +71,11 @@ __RCSID(" NetBSD: ssl.c,v 1.10 2021/06/0 #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; @@ -594,7 +600,9 @@ fetch_start_ssl(int sock, const char *se { SSL *ssl; SSL_CTX *ctx; + X509_VERIFY_PARAM *param; int ret, ssl_err; + int verify = !ftp_truthy("sslnoverify", getoptionvalue("sslnoverify"), 0); /* Init the SSL library and context */ if (!SSL_library_init()){ @@ -606,6 +614,10 @@ fetch_start_ssl(int sock, const char *se ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); + if (verify) { + SSL_CTX_set_default_verify_paths(ctx); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); + } ssl = SSL_new(ctx); if (ssl == NULL){ @@ -613,9 +625,25 @@ fetch_start_ssl(int sock, const char *se SSL_CTX_free(ctx); return NULL; } + + if (verify) { + param = SSL_get0_param(ssl); + 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; + } + + /* Enable peer verification, (using the default callback) */ + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + } + 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; } @@ -625,6 +653,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: othersrc/usr.bin/tnftp/src/util.c diff -u othersrc/usr.bin/tnftp/src/util.c:1.25 othersrc/usr.bin/tnftp/src/util.c:1.26 --- othersrc/usr.bin/tnftp/src/util.c:1.25 Fri Aug 27 01:38:49 2021 +++ othersrc/usr.bin/tnftp/src/util.c Sun Apr 9 00:56:07 2023 @@ -1,8 +1,8 @@ -/* $NetBSD: util.c,v 1.25 2021/08/27 01:38:49 lukem Exp $ */ -/* from NetBSD: util.c,v 1.162 2021/04/25 08:26:35 lukem Exp */ +/* $NetBSD: util.c,v 1.26 2023/04/09 00:56:07 lukem Exp $ */ +/* from 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 @@ -69,7 +69,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID(" NetBSD: util.c,v 1.162 2021/04/25 08:26:35 lukem Exp "); +__RCSID(" NetBSD: util.c,v 1.166 2023/02/25 12:07:25 mlelstv Exp "); #endif /* not lint */ /* @@ -178,7 +178,7 @@ parse_feat(const char *fline) * work-around broken ProFTPd servers that can't * even obey RFC 2389. */ - while (*fline && isspace((int)*fline)) + while (*fline && isspace((unsigned char)*fline)) fline++; if (strcasecmp(fline, "MDTM") == 0) @@ -216,7 +216,7 @@ getremoteinfo(void) os_len, reply_string + 4); } /* - * Decide whether we should default to bninary. + * Decide whether we should default to binary. * Traditionally checked for "215 UNIX Type: L8", but * some printers report "Linux" ! so be more forgiving. * In reality we probably almost never want text any more. @@ -627,7 +627,7 @@ remglob(char *argv[], int doswitch, cons * return value. Can't control multiple values being expanded from the * expression, we return only the first. * Returns NULL on error, or a pointer to a buffer containing the filename - * that's the caller's responsiblity to free(3) when finished with. + * that's the caller's responsibility to free(3) when finished with. */ char * globulize(const char *pattern) @@ -1564,6 +1564,26 @@ ftp_poll(struct pollfd *fds, int nfds, i #endif } +/* + * 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: othersrc/usr.bin/tnftp/src/version.h diff -u othersrc/usr.bin/tnftp/src/version.h:1.10 othersrc/usr.bin/tnftp/src/version.h:1.11 --- othersrc/usr.bin/tnftp/src/version.h:1.10 Fri Aug 27 01:38:49 2021 +++ othersrc/usr.bin/tnftp/src/version.h Sun Apr 9 00:56:07 2023 @@ -1,8 +1,8 @@ -/* $NetBSD: version.h,v 1.10 2021/08/27 01:38:49 lukem Exp $ */ -/* from NetBSD: version.h,v 1.94 2021/08/26 06:25:59 lukem Exp */ +/* $NetBSD: version.h,v 1.11 2023/04/09 00:56:07 lukem Exp $ */ +/* from NetBSD: version.h,v 1.96 2023/02/25 12:07:25 mlelstv Exp */ /*- - * Copyright (c) 1999-2021 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 @@ -35,5 +35,5 @@ #endif #ifndef FTP_VERSION -#define FTP_VERSION "20210826" +#define FTP_VERSION "20230225" #endif