Subject: install/7520: sysinst can't use absolute directory names with ftp
To: None <gnats-bugs@gnats.netbsd.org>
From: None <apb@iafrica.com>
List: netbsd-bugs
Date: 05/05/1999 04:51:30
>Number:         7520
>Category:       install
>Synopsis:       sysinst can't use absolute directory names with ftp
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed May  5 04:50:01 1999
>Last-Modified:
>Originator:     Alan Barrett
>Organization:
not much
>Release:        NetBSD-current 1999-05-05
>Environment:
NetBSD 1.4_BETA i386, -current sources suped on 1999-05-05
>Description:
        When using sysinst to fetch distribution sets from an FTP
        server, the user is prompted for a directory name.  If the user
        gives an absolute directory name (say "/foo/bar"), then sysinst
        will later invoke ftp with an URL like

	    ftp://user:password@host//foo/bar/1.4/i386/base.tgz   [A]

        (where "1.4" is the version and "i386" is the port), but url [A]
        in fact refers to a relative directory on the FTP server.

	It would be better if sysinst used an URL like
	 
	    ftp://user:password@host/%2Ffoo/bar/1.4/i386/base.tgz   [B]

	or

	    ftp://user:password@host/%2Ffoo%2Fbar%2F1.4%2Fi386/base.tgz   [C]


>How-To-Repeat:
	Inspect the code, or read recent messages in tech-install mailing
	list.

>Fix:
	The following patch makes sysinst use url's like [B] above.
	The patch to use [C] instead would be simpler (just change
	RFC_1738_SAFE_LESS_SHELL_PLUS_SLASH to RFC_1738_SAFE_LESS_SHELL
	in two places in net.c).

--- current/src/distrib/utils/sysinst/net.c	Tue Apr 20 13:03:06 1999
+++ toplayer/src/distrib/utils/sysinst/net.c	Wed May  5 13:17:04 1999
@@ -423,13 +423,28 @@
 		 * paranoid and also encode ftp_user and ftp_dir.  (For
 		 * example, ftp_dir could easily contain '~', which is
 		 * unsafe by a strict reading of RFC 1738).
+		 *
+		 * When we encode ftp_dir, we change any leading "/" to
+		 * "%2F", but we leave other slashes alone.  So if the
+		 * user specifies a relative directory name "foo/bar"
+		 * then we get a URL like "ftp://host/foo.bar/file",
+		 * and if the user specifies an absolute directory
+		 * name like "/foo/bar" then we get a URL like
+		 * "ftp://host/%2Ffoo/bar/file".
 		 */
+		if (ftp_dir[0] == '/') {
+		    strcpy(ftp_dir_encoded, "%2F");
+		    url_encode(ftp_dir_encoded+3, ftp_dir+1, STRSIZE-3,
+				RFC1738_SAFE_LESS_SHELL_PLUS_SLASH);
+		} else {
+		    url_encode(ftp_dir_encoded, ftp_dir, STRSIZE,
+				RFC1738_SAFE_LESS_SHELL_PLUS_SLASH);
+		}
 		if (strcmp ("ftp", ftp_user) == 0)
 			ret = run_prog(0, 1, NULL, 
 			    "/usr/bin/ftp -a ftp://%s/%s/%s",
 			    ftp_host,
-			    url_encode(ftp_dir_encoded, ftp_dir, STRSIZE,
-					RFC1738_SAFE_LESS_SHELL_PLUS_SLASH),
+			    ftp_dir_encoded,
 			    filename);
 		else {
 			ret = run_prog(0, 1, NULL, 
@@ -439,8 +454,7 @@
 			    url_encode(ftp_pass_encoded, ftp_pass, STRSIZE,
 					RFC1738_SAFE_LESS_SHELL),
 			    ftp_host,
-			    url_encode(ftp_dir_encoded, ftp_dir, STRSIZE,
-					RFC1738_SAFE_LESS_SHELL_PLUS_SLASH),
+			    ftp_dir_encoded,
 			    filename);
 		}
 		if (ret) {

(end)
>Audit-Trail:
>Unformatted: