Re: SCP in SFTP mode

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



Dear Damien,

Here is a proof-of-concept patch fixing this issue for me. If it could be
polished, it would be great.

Many thanks in advance!

On Wed, Feb 2, 2022 at 10:57 PM Damien Miller <djm@xxxxxxxxxxx> wrote:

> I haven't had time to investigate this yet
>
> On Wed, 2 Feb 2022, Dmitry Belyavskiy wrote:
>
> > Dear Damien,
> > Sorry for being repetitive - but should we consider it to be a known
> > limitation?
> >
> > Many thanks in advance!
> >
> > On Fri, Jan 28, 2022 at 10:53 AM Dmitry Belyavskiy <dbelyavs@xxxxxxxxxx>
> > wrote:
> >       Dear Damien,
> >
> > On Fri, Jan 28, 2022 at 1:40 AM Damien Miller <djm@xxxxxxxxxxx> wrote:
> >       On Thu, 27 Jan 2022, Dmitry Belyavskiy wrote:
> >
> >       > Hello,
> >       >
> >       > When we use scp in sftp mode to copy folder to the
> >       machines with the "old"
> >       > version of ssh, we get the following error:
> >       > ======
> >       > $ scp -vvv -r test/ touser@machine:/home/touser
> >
> >       What version of OpenSSH are you using? There are a bunch
> >       of fixes in git
> >       HEAD after 8.8.
> >
> >       > If I understand correctly, the failure is caused by the
> >       lack of the "
> >       > expand-path@xxxxxxxxxxx"
> >       > extension to sftp protocol in old releases and (lack of)
> >       processing it on
> >       > the server side.
> >
> >       No, that extension is only invoked when a ~-prefixed path
> >       is used.
> >
> >       AFAIK this was juat a behaviour difference: scp in sftp
> >       mode wasn't
> >       creating the destination directory if it didn't exist,
> >       whereas legacy
> >       scp would do so. It was fixed in the commit you identify
> >       below.
> >
> >       > For the recent version self-compatibility it was fixed
> >       in
> >       >
> https://github.com/openssh/openssh-portable/commit/ac7c9ec894ed0825d04ef69c
> >       55babb49bab1d32e
> >
> >       -d
> >
> > I've just retested with the recent master
> > $ ./scp -S `pwd`/ssh -vvv -r -s `pwd`/openbsd-compat/ user@machine:
> >
> > debug2: subsystem request accepted on channel 0
> > ./scp: debug2: Remote version: 3
> > ./scp: debug2: Server supports extension "posix-rename@xxxxxxxxxxx"
> > revision 1
> > ./scp: debug2: Server supports extension "statvfs@xxxxxxxxxxx"
> > revision 2
> > ./scp: debug2: Server supports extension "fstatvfs@xxxxxxxxxxx"
> > revision 2
> > ./scp: debug2: Server supports extension "hardlink@xxxxxxxxxxx"
> > revision 1
> > ./scp: debug2: Server supports extension "fsync@xxxxxxxxxxx" revision
> > 1
> > ./scp: debug2: Server supports extension "lsetstat@xxxxxxxxxxx"
> > revision 1
> > ./scp: debug2: Sending SSH2_FXP_STAT "/root"
> > ./scp: debug3: Sent message fd 6 T:17 I:1
> > ./scp: debug3: Received stat reply T:105 I:1 F:0x000f M:40550
> > ./scp: debug3: source_sftp: copying local
> > /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat to remote
> > /root/openbsd-compat
> > ./scp: debug2: Sending SSH2_FXP_REALPATH "/root/openbsd-compat"
> > ./scp: debug3: Sent message fd 6 T:16 I:2
> > ./scp: realpath /root/openbsd-compat: No such file
> > ./scp: upload "/root/openbsd-compat": path canonicalization failed
> > ./scp: failed to upload directory
> > /home/dbelyavs/work/upstream/openssh-portable/openbsd-compat to
> > /root/openbsd-compat
> >
> > The failure occurs even when I specify absolute paths on the
> > source/destination machine.
> >
> > The destination machine has OpenSSH_8.0p1 with patches.
> >
> > --
> > Dmitry Belyavskiy
> >
> >
> >
> > --
> > Dmitry Belyavskiy
> >
> >



-- 
Dmitry Belyavskiy
diff --git a/sftp-client.c b/sftp-client.c
index c7565755..98f986d6 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1028,11 +1028,42 @@ do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
 		if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
 		    (r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
 			fatal_fr(r, "parse status");
-		error("%s %s: %s", expand ? "expand" : "realpath",
-		    path, *errmsg == '\0' ? fx2txt(status) : errmsg);
-		free(errmsg);
-		sshbuf_free(msg);
-		return NULL;
+		if (status != SSH2_FX_NO_SUCH_FILE) {
+			error("%s %s: %s", expand ? "expand" : "realpath",
+			    path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+			free(errmsg);
+			sshbuf_free(msg);
+			return NULL;
+		} else {
+			if((r = do_mkdir(conn, path, &a, 0)) != 0) {
+				return NULL;
+			}
+
+			send_string_request(conn, id, SSH2_FXP_REALPATH,
+					path, strlen(path));
+
+			get_msg(conn, msg);
+			if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
+					(r = sshbuf_get_u32(msg, &id)) != 0)
+				fatal_fr(r, "parse");
+
+			if (id != expected_id)
+				fatal("ID mismatch (%u != %u)", id, expected_id);
+
+			if (type == SSH2_FXP_STATUS) {
+				u_int status;
+				char *errmsg;
+
+				if ((r = sshbuf_get_u32(msg, &status)) != 0 ||
+						(r = sshbuf_get_cstring(msg, &errmsg, NULL)) != 0)
+					fatal_fr(r, "parse status");
+				error("%s %s: %s", expand ? "expand" : "realpath",
+						path, *errmsg == '\0' ? fx2txt(status) : errmsg);
+				free(errmsg);
+				sshbuf_free(msg);
+				return NULL;
+			}
+		}
 	} else if (type != SSH2_FXP_NAME)
 		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
 		    SSH2_FXP_NAME, type);
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux