From 38246ac903db567f149dad428403f2182ea03b4e Mon Sep 17 00:00:00 2001 From: Mats Erik Andersson Date: Thu, 5 Jun 2014 23:31:56 +0200 Subject: [PATCH] ftp: Allow other locations of netrc file. Introduce a command line option and an environment variable to override the legacy location $HOME/.netrc. --- ChangeLog | 17 ++++++++++++++++ NEWS | 9 +++++++++ doc/inetutils.texi | 22 ++++++++++++++++++-- ftp/ftp_var.h | 1 + ftp/main.c | 7 +++++++ ftp/ruserpass.c | 30 +++++++++++++++++++++++++++ tests/ftp-localhost.sh | 46 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3a04705..9967cf88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2014-06-05 Mats Erik Andersson + + ftp: Alternate selection of .netrc file. + + * ftp/ftp_var.h (netrc): New variable. + * ftp/main.c (argp_options) <-N/--netrc>: New option. + (parse_opt) <'N'>: New case. + (main): Initialize `netrc'. + * ftp/ruserpass.c (remote_userpass): If `netrc' is NULL, + check NETRC in environment. Whenever `netrc' has content, + us it instead of `~/.netrc'. Once CFILE is valid, make + sure that the file location is a regular file, otherwise + returning to the interpreter. + + * tests/ftp-localhost.sh: Two new test cases, checking the + functionality of NETRC in environment, and the option `-N'. + 2014-05-16 Mats Erik Andersson ftp: Size multipliers for hash increments. diff --git a/NEWS b/NEWS index ec498484..ec41f5fd 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,15 @@ Please send inetutils bug reports to . Version 1.9.3: +* ftp + +The internal command `hash' accepts a suffixed letter to the +size argument, like `12k', instead of 12288. Also, the .netrc +file can be overridden by the environment variable NETRC. +Of even higher precedence is the new option `-N/--netrc'. +The access to the resulting file, whatever method, is now +denied unless it as a regular file. + * syslogd A new switch `-T/--local-time' makes the service ignore a time diff --git a/doc/inetutils.texi b/doc/inetutils.texi index aff02e9d..21a33b5c 100644 --- a/doc/inetutils.texi +++ b/doc/inetutils.texi @@ -1381,6 +1381,15 @@ Disables file name globbing. @opindex --no-prompt Turns off interactive prompting during multiple file transfers. +@item -N @var{netrc} +@itemx --netrc=@var{netrc} +@opindex -N +@opindex --netrc +Set a preferred location of the @file{.netrc} file, +thus overriding any environment setting in @env{NETRC}, +as well as the default location @file{$HOME/.netrc}, +@pxref{The .netrc file}. + @item -n @itemx --no-login @opindex -n @@ -2046,8 +2055,13 @@ Avoid this problem by using the binary image type. @flindex .netrc The @file{.netrc} file contains login and initialization information -used by the auto-login process. It resides in the user's home -directory. The following tokens are recognized; they may be separated +used by the auto-login process. It generally resides in the user's +home directory, but a location outside of the home directory +can be set using the environment variable @env{NETRC}. +Both locations are overridden by the command line option @option{-N}. +The selected file must be a regular file, or access will be denied. + +The following tokens are recognized; they may be separated by spaces, tabs, or new-lines: @table @samp @@ -2108,6 +2122,10 @@ executed as the last step in the auto-login process. @item HOME Used for locating a @file{.netrc} file, if one exists. +@item NETRC +Alternate location of the @file{.netrc} file, +taking precedence over the standard location. + @item SHELL For determining the default shell interpreter. @end table diff --git a/ftp/ftp_var.h b/ftp/ftp_var.h index 02ea7ba4..ebe2c10a 100644 --- a/ftp/ftp_var.h +++ b/ftp/ftp_var.h @@ -108,6 +108,7 @@ FTP_EXTERN char bytename[32]; /* local byte size in ascii */ FTP_EXTERN int bytesize; /* local byte size in binary */ FTP_EXTERN char *hostname; /* name of host connected to */ +FTP_EXTERN char *netrc; /* netrc file chosen on command line */ FTP_EXTERN int unix_server; /* server is unix, can use binary for ascii */ FTP_EXTERN int unix_proxy; /* proxy is unix, can use binary for ascii */ diff --git a/ftp/main.c b/ftp/main.c index cb527295..a3d252e9 100644 --- a/ftp/main.c +++ b/ftp/main.c @@ -134,6 +134,8 @@ static struct argp_option argp_options[] = { {"verbose", 'v', NULL, 0, "verbose output", GRP+1}, {"ipv4", '4', NULL, 0, "contact IPv4 hosts", GRP+1}, {"ipv6", '6', NULL, 0, "contact IPv6 hosts", GRP+1}, + {"netrc", 'N', "NETRC", 0, "select a specific initialization file", + GRP+1}, #undef GRP {NULL, 0, NULL, 0, NULL, 0} }; @@ -192,6 +194,10 @@ parse_opt (int key, char *arg, struct argp_state *state _GL_UNUSED_PARAMETER) usefamily = AF_INET6; break; + case 'N': + netrc = arg; + break; + default: return ARGP_ERR_UNKNOWN; } @@ -228,6 +234,7 @@ main (int argc, char *argv[]) line = NULL; /* reset global input */ linelen = 0; argbuf = NULL; + netrc = NULL; /* Invoked as `pftp'? Then set passive mode. */ cp = strrchr (argv[0], '/'); diff --git a/ftp/ruserpass.c b/ftp/ruserpass.c index 2b8edeca..953c853b 100644 --- a/ftp/ruserpass.c +++ b/ftp/ruserpass.c @@ -123,6 +123,14 @@ remote_userpass (char *host, char **aname, char **apass, char **aacct) if (hdir == NULL) hdir = "."; snprintf (buf, sizeof buf, "%s/.netrc", hdir); + + /* The switch `-N/--netrc' would have set this. */ + if (!netrc) + netrc = getenv ("NETRC"); + + if (netrc && netrc[0]) + snprintf (buf, sizeof buf, "%s", netrc); + cfile = fopen (buf, "r"); if (cfile == NULL) { @@ -131,6 +139,28 @@ remote_userpass (char *host, char **aname, char **apass, char **aacct) return (0); } + /* The .netrc is now opened and is thus fixed. + * Check that it is a regular file, and not a + * soft link in particular. + */ + if (lstat (buf, &stb) < 0) + { + error (0, errno, "%s", buf); + fclose (cfile); + return (-1); + } + + if (!S_ISREG (stb.st_mode)) + { + if (S_ISLNK (stb.st_mode)) + error (0, 0, "the .netrc file is symbolic link: %s", buf); + else + error (0, 0, "the .netrc file is no regular file: %s", buf); + + fclose (cfile); + return (-1); + } + myname = localhost (); if (!myname) myname = xstrdup (""); diff --git a/tests/ftp-localhost.sh b/tests/ftp-localhost.sh index 592fa1aa..dc140097 100755 --- a/tests/ftp-localhost.sh +++ b/tests/ftp-localhost.sh @@ -393,6 +393,37 @@ HOME=$TMPDIR $FTP "$TARGET" $PORT -4 -v -p -t >$TMPDIR/ftp.stdout 2>&1 test_report $? "$TMPDIR/ftp.stdout" "EPSV/$TARGET" +# Test a passive connection: EPSV and IPv4. +# +# Set NETRC in environment to regulate login. +# +echo "EPSV to $TARGET (IPv4) using inetd, setting NETRC." +cat <$TMPDIR/ftp.stdout 2>&1 + +test_report $? "$TMPDIR/ftp.stdout" "EPSV/$TARGET with NETRC" + +$do_transfer && \ + if cmp -s "$TMPDIR/$GETME" "$FTPHOME$DLDIR/$PUTME"; then + test "${VERBOSE+yes}" && echo >&2 'Binary transfer succeeded.' + date "+%s" >> "$TMPDIR/$GETME" + else + echo >&2 'Binary transfer failed.' + exit 1 + fi + # Test an active connection: EPRT and IPv4. # echo "EPRT to $TARGET (IPv4) using inetd." @@ -420,6 +451,21 @@ $do_transfer && \ exit 1 fi +# Test an active connection: EPRT and IPv4. +# +# Use `-N' to set location of .netrc file. +# +echo "EPRT to $TARGET (IPv4) using inetd, apply the switch -N." +cat <$TMPDIR/ftp.stdout 2>&1 + +test_report $? "$TMPDIR/ftp.stdout" "EPRT/$TARGET" + # Test a passive connection: EPSV and IPv6. # echo "EPSV to $TARGET6 (IPv6) using inetd."