[openssh-commits] [openssh] 05/08: upstream: when scp is in SFTP mode, try to deal better with ~

git+noreply at mindrot.org git+noreply at mindrot.org
Tue Aug 10 12:48:03 AEST 2021


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Mon Aug 9 23:44:32 2021 +0000

    upstream: when scp is in SFTP mode, try to deal better with ~
    
    prefixed paths. ~user paths aren't supported, but ~/ paths will be accepted
    and prefixed with the SFTP server starting directory (more to come)
    
    prompted by and discussed with deraadt@
    ok markus@
    
    OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
---
 scp.c | 44 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/scp.c b/scp.c
index 21467c46..fe3ac701 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.225 2021/08/09 07:21:01 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.226 2021/08/09 23:44:32 djm Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
@@ -1253,6 +1253,29 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct)
 	free(src);
 }
 
+/* Canonicalise a remote path, handling ~ by assuming cwd is the homedir */
+static char *
+absolute_remote_path(const char *path, const char *remote_path)
+{
+	char *ret;
+
+	/* Handle ~ prefixed paths */
+	if (*path != '~')
+		ret = xstrdup(path);
+	else {
+		if (strcmp(path, "~") == 0)
+			ret = xstrdup("");
+		else if (strncmp(path, "~/", 2) == 0)
+			ret = xstrdup(path + 2);
+		else {
+			/* XXX could be supported with protocol extension */
+			error("~user paths are not currently supported");
+			return NULL;
+		}
+	}
+	return make_absolute(ret, remote_path);
+}
+
 void
 source_sftp(int argc, char *src, char *targ,
     struct sftp_conn *conn, char **remote_path)
@@ -1273,8 +1296,8 @@ source_sftp(int argc, char *src, char *targ,
 	 * No need to glob here - the local shell already took care of
 	 * the expansions
 	 */
-	target = xstrdup(targ);
-	target = make_absolute(target, *remote_path);
+	if ((target = absolute_remote_path(targ, *remote_path)) == NULL)
+		cleanup_exit(255);
 	target_is_dir = remote_is_dir(conn, target);
 	if (targetshouldbedirectory && !target_is_dir) {
 		fatal("Target is not a directory, but more files selected "
@@ -1471,6 +1494,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
 	char *filename, *tmp = NULL, *remote_path = NULL;
 	int i, r, err = 0;
 
+	memset(&g, 0, sizeof(g));
 	/*
 	 * Here, we need remote glob as SFTP can not depend on remote shell
 	 * expansions
@@ -1484,10 +1508,11 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
 		goto out;
 	}
 
-	abs_src = xstrdup(src);
-	abs_src = make_absolute(abs_src, remote_path);
+	if ((abs_src = absolute_remote_path(src, remote_path)) == NULL) {
+		err = -1;
+		goto out;
+	}
 	free(remote_path);
-	memset(&g, 0, sizeof(g));
 
 	debug3_f("copying remote %s to local %s", abs_src, dst);
 	if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
@@ -1895,11 +1920,10 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
 	if ((filename = basename(src)) == NULL)
 		fatal("basename %s: %s", src, strerror(errno));
 
-	abs_src = xstrdup(src);
-	abs_src = make_absolute(abs_src, from_remote_path);
+	if ((abs_src = absolute_remote_path(src, from_remote_path)) == NULL ||
+	    (target = absolute_remote_path(targ, *to_remote_path)) == NULL)
+		cleanup_exit(255);
 	free(from_remote_path);
-	target = xstrdup(targ);
-	target = make_absolute(target, *to_remote_path);
 	memset(&g, 0, sizeof(g));
 
 	targetisdir = remote_is_dir(to, target);

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list