Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix for "scp: error: unexpected filename " #515

Closed

Conversation

@dancret
Copy link

dancret commented Feb 10, 2019

Replace string.Empty with file name for UploadFileModeAndName serverFileName parameter.

@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Feb 11, 2019

Please submit an issue with detailed info on how to reproduce this.

@ccic

This comment has been minimized.

Copy link

ccic commented Feb 11, 2019

I also encountered this issue.

@jhenkens

This comment has been minimized.

Copy link

jhenkens commented Feb 11, 2019

@drieseng This issue is because of a change in the OpenSSH server code, which is due to a security vulterability CVE-2018-20685.
openssh/openssh-portable@6010c03
http://changelogs.ubuntu.com/changelogs/pool/main/o/openssh/openssh_7.2p2-4ubuntu2.7/changelog

Note that this PR is incomplete:

UploadDirectoryModeAndName(channel, input, ".");

must also be changed, though there may be even more that I haven't found.

To reproduce, simply try to call any of those methods when SCPing to a server running the patched version of OpenSSH.

This is a game-breaking bug for RenciSSH's SCP capabilities. If all the changes in develop are not ready to be released, it might be warranted to apply this change ontop of master and bump just that to nuget.

@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Feb 11, 2019

@jhenkens Thanks for the info. I'll need to check how we update SSH.NET, but still keep the existing behavior for our users.

@dancret I'll have to check, but I'm pretty sure this PR will cause user-visible changes.

@dancret

This comment has been minimized.

Copy link
Author

dancret commented Feb 11, 2019

@drieseng I agree it is a breaking change, and might be incomplete. With this change I managed to make file copy work, but as @jhenkens mentioned, another change is required for directory copy, but it will break that as well, since it will not work as before, but create the target directory inside the target directory, and copy that contents there (e.g. if I want to copy to /var/something/foobar, changing "." with directory.Name will create /var/something/foobar/foobar, and copy everything there ).

I can do some more tests, but it reproduces with basically every file.
This however does not reproduce in version 2016.0.0, but the file/directory copy behavior is different there, so downgrading still requires adapting any code that uses the library.

I will continue investigating the issue to some degree, and let you know of any updates.

@petrkrcmarik

This comment has been minimized.

Copy link

petrkrcmarik commented Feb 21, 2019

Is there any known workaround to this issue if I am using nuget package?

@uniederer

This comment has been minimized.

Copy link

uniederer commented Feb 22, 2019

Is there any known workaround to this issue if I am using nuget package?

What worked for me was going back to 2016.0.0 based on the hint of @dancret .

To be honest I didn't understand exactly what he meant with "different file/directory copy behavior" as I didn't experience differences. However I'm copying files one-by-one from given streams, so maybe that won't trigger the differences.

@dancret

This comment has been minimized.

Copy link
Author

dancret commented Feb 22, 2019

Is there any known workaround to this issue if I am using nuget package?

What worked for me was going back to 2016.0.0 based on the hint of @dancret .

To be honest I didn't understand exactly what he meant with "different file/directory copy behavior" as I didn't experience differences. However I'm copying files one-by-one from given streams, so maybe that won't trigger the differences.

I will give you an example from what I have experienced.
For an app that I am working on, I need to copy files from windows to an ubuntu machine.
We have the path C:\work\tmp\builds\build1 on the windows machine, and the contents of that folder need to be copied to the target machine folder /var/www/site1.
In version 2016.1.0, this worked fine, contents from build1 were transfered to site1.
In version 2016.0.0, when I try to do the same thing, it copies the contents from C:\work\tmp\builds\build1 to /var/www/site1/build1, so it is creating a new folder.
The piece of code that I am using looks like this:

using (var scpClient = new ScpClient(engineOptions.ServerHost, engineOptions.ServerUser, engineOptions.ServerPassword))
{
    scpClient.Connect();
    scpClient.Upload(new DirectoryInfo(dirPath), targetPath);
}

In this case, dirPath would be the source path on windows, and targetPath is the one on the ubuntu machine.
@uniederer - hope this clarifies what I meant with different directory copy behavior.

@petrkrcmarik

This comment has been minimized.

Copy link

petrkrcmarik commented Mar 1, 2019

Is there any known workaround to this issue if I am using nuget package?

What worked for me was going back to 2016.0.0 based on the hint of @dancret .
To be honest I didn't understand exactly what he meant with "different file/directory copy behavior" as I didn't experience differences. However I'm copying files one-by-one from given streams, so maybe that won't trigger the differences.

I will give you an example from what I have experienced.
For an app that I am working on, I need to copy files from windows to an ubuntu machine.
We have the path C:\work\tmp\builds\build1 on the windows machine, and the contents of that folder need to be copied to the target machine folder /var/www/site1.
In version 2016.1.0, this worked fine, contents from build1 were transfered to site1.
In version 2016.0.0, when I try to do the same thing, it copies the contents from C:\work\tmp\builds\build1 to /var/www/site1/build1, so it is creating a new folder.
The piece of code that I am using looks like this:

using (var scpClient = new ScpClient(engineOptions.ServerHost, engineOptions.ServerUser, engineOptions.ServerPassword))
{
    scpClient.Connect();
    scpClient.Upload(new DirectoryInfo(dirPath), targetPath);
}

In this case, dirPath would be the source path on windows, and targetPath is the one on the ubuntu machine.
@uniederer - hope this clarifies what I meant with different directory copy behavior.

Thank you, will try that, on the other hand going back to the previous version is not a usual solution, I am already seeing comments on PR :). Is there any chance to fix this in some new version and maybe finally create a new nuget package? I am not saying that we cannot live with this workaround, but we build a lot of functionality around SSH.NET library in our project and some of it may stop working if we go to the older version. @drieseng ?

@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Mar 1, 2019

@petrkrcmarik I'll try to find time this weekend to dig a little deeper. My time is limited though (after work, family and other OSS involvement).

@petrkrcmarik

This comment has been minimized.

Copy link

petrkrcmarik commented Mar 7, 2019

@drieseng understand we workaround issue by using sftp instead scp for now.

@darkoperator

This comment has been minimized.

Copy link

darkoperator commented May 30, 2019

@drieseng any update on this?

@krjw

This comment has been minimized.

Copy link

krjw commented Jul 31, 2019

Are there any updates on this?

@hmihail

This comment has been minimized.

Copy link

hmihail commented Aug 27, 2019

Any news on this issue?

@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Aug 27, 2019

Not yet, sorry. I'm crazy busy at work and at home :(

@cjordan6

This comment has been minimized.

Copy link

cjordan6 commented Sep 4, 2019

I encountred with this issue. The problem is in the class ScpClient in the function Upload(Stream source, string path).
I 'm going to copy the solution that works for me.
public void Upload(Stream source, string path)
{
using (var input = ServiceFactory.CreatePipeStream())
using (var channel = Session.CreateChannelSession())
{
channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length);
channel.Open();

            // pass the full path to ensure the server does not create the directory part
            // as a file in case the directory does not exist
            if (!channel.SendExecRequest(string.Format("scp -t {0}", _remotePathTransformation.Transform(path))))
            {
                throw SecureExecutionRequestRejectedException();
            }
            CheckReturnCode(input);

            // specify a zero-length file name to avoid creating a file with absolute
            // path '<path>/<filename part of path>' if directory '<path>' already exists
            
            //UploadFileModeAndName(channel, input, source.Length, string.Empty);
            //UploadFileContent(channel, input, source, PosixPath.GetFileName(path));

            UploadFileModeAndName(channel, input, source.Length, PosixPath.GetFileName(path));
            UploadFileContent(channel, input, source, path);
        }
    }
@cjordan6

This comment has been minimized.

Copy link

cjordan6 commented Sep 23, 2019

Hello, can you update the nugget with the solution for this issue?

@biocoder-frodo

This comment has been minimized.

Copy link

biocoder-frodo commented Oct 12, 2019

Thanks for reporting, your pull request fixed my SCP issue with DSM 6.2.2-24922 Update 3.
SCP upload command here:
https://github.com/biocoder-frodo/SynoDuplicateFolders/blob/e7cc22acb6dac010ff892ee5d0c1c76b43b8f2e0/SynoDuplicateFolders.Data/SecureShell/ConsoleCommandDSM6.cs#L102

@jhenkens

This comment has been minimized.

Copy link

jhenkens commented Oct 22, 2019

@drieseng Outlook on your future availability? Repo is already in a lovely path, if your time is limited, perhaps a set of community moderators needs to be instated.

It’s been a long time since any updates were provided in commits, and longer still since Nuget was updated.

I’m sure the community would appreciate the future of this library remaining un-forked. I know I would.

babskig added a commit to babskig/SSH.NET that referenced this pull request Nov 21, 2019
@soul4soul

This comment has been minimized.

Copy link

soul4soul commented Dec 17, 2019

Is there any known workaround to this issue if I am using nuget package?

What worked for me was going back to 2016.0.0 based on the hint of @dancret .

To be honest I didn't understand exactly what he meant with "different file/directory copy behavior" as I didn't experience differences. However I'm copying files one-by-one from given streams, so maybe that won't trigger the differences.

Rolling back to 2016.0.0 was a good tip. I was able to replace ScpClient.cs and ScpClient.NET.cs with 2016.0.0 files. I made the rollback on top of master plus a patch for #355.

I tested the changes against openssh server running on Debian-6-ppc, Fedora-16-x86, Ubuntu-16.04-aarch64, Ubuntu-18.04-x64, Fedora-23-x64, Fedora-31-x64, and Windows-10-x64. I was able to SCP to and from all of these servers with no change in behavior.

@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Jan 30, 2020

I'm working on a fix for this issue. With my fix there's one a small behavior change when uploading a directory. More specifically, the timestamp of the main directory that is being uploaded with no longer be set on the corresponding remote directory. The timestamp of all files and subdirectories will be set correctly though.

@mauroa mauroa mentioned this pull request Feb 13, 2020
@drieseng

This comment has been minimized.

Copy link
Member

drieseng commented Feb 15, 2020

@dancret , thanks for the PR.
I've committed a more complete fix as part of #625.

@drieseng drieseng closed this Feb 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

You can’t perform that action at this time.