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

SCP server side does not return error info when the file does not exist on remote host #1284

Closed
jborean93 opened this issue Oct 29, 2018 · 7 comments

Comments

@jborean93
Copy link

"OpenSSH for Windows" version
7.7.2.0

Server OperatingSystem
Windows Server 2016 Standard

Client OperatingSystem
MacOS

What is failing
Using scp from a host to another Windows host when the path has been escaped with ' and not ".

Run the following command to create a file on the Windows host

$folder = "C:\temp\some folder"
if (Test-Path -Path $folder) {
    Remove-Item -Path $folder -Force -Recurse
}
New-Item -Path $folder -ItemType Directory > $null
New-Item -Path "$folder\cafe.txt" -ItemType File > $null
Set-Content -Path "$folder\cafe.txt" -Value cafe

One created, run the following scp command from another host scp -o User=vagrant "[server2016.domain.local]:'/C:/temp/some folder/cafe.txt'" cafe.txt.

Expected output
At the very minimum I expect to get an error message saying that path was not found. I'm honestly not sure whether single quotes in the path as escape chars should be supported or not but I thought it best to ask anyway.

Actual output

No output on the client but the file isn't copied and scp exited with an rc of 1. When running sshd.exe in debug I get the following output

debug1: sshd version OpenSSH_for_Windows_7.7, LibreSSL 2.6.4
debug1: private host key #0: ssh-rsa SHA256:7GGi7UOBB+I5aK+QdioNFFqO+Mky9QY7ClkWnxD3ZKw
debug1: private host key #1: ecdsa-sha2-nistp256 SHA256:8egsTLWBltO/YvM86Yhn4/x35g4QAKEA7DlqSupQAYQ
debug1: private host key #2: ssh-ed25519 SHA256:ARo29uJwScbkdC/RMiG81aYLtZU2M87UwAtJ0IxAID8
debug1: rexec_argv[0]='C:\\Program Files\\OpenSSH-Win64\\sshd.exe'
debug1: rexec_argv[1]='-d'
debug1: Bind to port 22 on ::.
Server listening on :: port 22.
debug1: Bind to port 22 on 0.0.0.0.
Server listening on 0.0.0.0 port 22.
debug1: Server will not fork when running in debugging mode.
Connection from 192.168.56.1 port 56276 on 192.168.56.16 port 22
debug1: Client protocol version 2.0; client software version OpenSSH_7.7
debug1: match: OpenSSH_7.7 pat OpenSSH* compat 0x04000000
debug1: Local version string SSH-2.0-OpenSSH_for_Windows_7.7
debug1: sshd version OpenSSH_for_Windows_7.7, LibreSSL 2.6.4
debug1: list_hostkey_types: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519 [preauth]
debug1: SSH2_MSG_KEXINIT sent [preauth]
debug1: SSH2_MSG_KEXINIT received [preauth]
debug1: kex: algorithm: curve25519-sha256 [preauth]
debug1: kex: host key algorithm: ecdsa-sha2-nistp256 [preauth]
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: expecting SSH2_MSG_KEX_ECDH_INIT [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS sent [preauth]
debug1: expecting SSH2_MSG_NEWKEYS [preauth]
debug1: SSH2_MSG_NEWKEYS received [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: KEX done [preauth]
debug1: userauth-request for user vagrant service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: userauth-request for user vagrant service ssh-connection method publickey [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: userauth_pubkey: test pkalg rsa-sha2-512 pkblob RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLpZmxfTs [preauth]
debug1: trying public key file C:\\Users\\vagrant\\.ssh/authorized_keys
debug1: C:\\Users\\vagrant\\.ssh/authorized_keys:1: matching key found: RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLp
ZmxfTs
debug1: C:\\Users\\vagrant\\.ssh/authorized_keys:1: key options: agent-forwarding port-forwarding pty user-rc x11-forwar
ding
Accepted key RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLpZmxfTs found at C:\\Users\\vagrant\\.ssh/authorized_keys:1
Postponed publickey for vagrant from 192.168.56.1 port 56276 ssh2 [preauth]
debug1: userauth-request for user vagrant service ssh-connection method publickey [preauth]
debug1: attempt 2 failures 0 [preauth]
debug1: trying public key file C:\\Users\\vagrant\\.ssh/authorized_keys
debug1: C:\\Users\\vagrant\\.ssh/authorized_keys:1: matching key found: RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLp
ZmxfTs
debug1: C:\\Users\\vagrant\\.ssh/authorized_keys:1: key options: agent-forwarding port-forwarding pty user-rc x11-forwar
ding
Accepted key RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLpZmxfTs found at C:\\Users\\vagrant\\.ssh/authorized_keys:1
debug1: auth_activate_options: setting new authentication options
Accepted publickey for vagrant from 192.168.56.1 port 56276 ssh2: RSA SHA256:KtETvRbhLLECRy/N3N/kSfoZ8KroJFoEOvzLpZmxfTs
debug1: monitor_child_preauth: vagrant has been authenticated by privileged process
debug1: auth_activate_options: setting new authentication options [preauth]
debug1: monitor_read_log: child log fd closed
debug1: Not running as SYSTEM: skipping loading user profile
User child is on pid 2380
debug1: sshd version OpenSSH_for_Windows_7.7, LibreSSL 2.6.4
debug1: rekey after 134217728 blocks
debug1: rekey after 134217728 blocks
debug1: ssh_packet_set_postauth: called
debug1: active: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding
debug1: Entering interactive session for SSH2.
debug1: server_init_dispatch
debug1: server_input_channel_open: ctype session rchan 0 win 2097152 max 32768
debug1: input_session_request
debug1: channel 0: new [server-session]
debug1: session_new: session 0
debug1: session_open: channel 0
debug1: session_open: session 0: link with channel 0
debug1: server_input_channel_open: confirm session
debug1: server_input_global_request: rtype [email protected] want_reply 0
debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
Starting session: command for vagrant from 192.168.56.1 port 56276 id 0
debug1: Executing command: "c:\\windows\\system32\\cmd.exe" /c ""C:\\Program Files\\OpenSSH-Win64\\scp.exe" -f '/C:/temp
/some folder/cafe.txt'" with no pty
debug1: Received SIGCHLD.
debug1: session_by_pid: pid 4180
debug1: session_exit_message: session 0 channel 0 pid 4180
debug1: session_exit_message: release channel 0
debug1: session_by_channel: session 0 channel 0
debug1: session_close_by_channel: channel 0 child 0
Close session: user vagrant from 192.168.56.1 port 56276 id 0
debug1: channel 0: free: server-session, nchannels 1
Received disconnect from 192.168.56.1 port 56276:11: disconnected by user
Disconnected from 192.168.56.1 port 56276
debug1: do_cleanup
debug1: do_cleanup

In the output we can see the following command running "c:\\windows\\system32\\cmd.exe" /c ""C:\\Program Files\\OpenSSH-Win64\\scp.exe" -f '/C:/temp /some folder/cafe.txt'". This tells us that sshd.exe executes cmd.exe which then executes scp.exe and encloses the file in single quotes based on our input from the client as expected. Unfortunately single quotes are not interpreted in both cmd.exe and CreateProcess as escape characters so it is looking for a file with the literal path '/C:\temp\some folder/cafe.txt'.

** Extra Notes **

Using double quotes for the path portion works just fine as expected as both cmd and CreateProcess use that as an escape character. The trouble I have is that I'm working with a Python application that is using shlex.quote to create a shell escaped string as the path is defined by the user input. If the value contains certain characters (like non-ascii chars) then it will automatically enclose the value with a single quote.

I'm also wondering why sshd.exe calls cmd.exe which then calls scp.exe, seems like this should just call scp.exe and not have to deal with cmd altogether.

@bingbing8
Copy link
Contributor

@jborean93, we are solving on the escaping issue in a central place. this issue is part of the fix

@jborean93
Copy link
Author

@bingbing8 thanks for the info, would you like me to close this issue and have it tracked in 1 central one? Is there a link to that issue?

@bingbing8
Copy link
Contributor

Let's leave it open so we are sure we fix and validate the scenario. if you are interested, this is the PR, it is not ready yet.

@jborean93
Copy link
Author

Thanks

@bingbing8
Copy link
Contributor

bingbing8 commented Oct 30, 2018

@jborean93, this actually is not related with the double quotes escaping issue. the server side scp slip 'c:/temp/some folder/cafe.txt' to two parts: "'c:/temp/some" and "folder/cafe.txt'". I agree it return an some error. If you supplied -ddd to sshd.exe, you will see more information.

If you update the command to, it will work. (I only test it from windows client)
``
.\scp.exe "[server2016.domain.local]:"C:/temp/some folder/cafe.txt"" c:\test\cafe.txt

@bingbing8 bingbing8 changed the title Single quotes in SCP command fails and doesn't indicate why SCP command does not return error info when the file does not exist on remote host Oct 30, 2018
@bingbing8 bingbing8 changed the title SCP command does not return error info when the file does not exist on remote host SCP server side does not return error info when the file does not exist on remote host Nov 1, 2018
@jborean93
Copy link
Author

@bingbing8 it's more these 2 issues I wanted to bring up

  • scp won't return an error if it cannot find a file, it just exits leaving the user clueless as to what has happened
  • It does not handle single quotes as Windows does not support them as a way to escape spaces in an argument.

I've able to get this working when quoting the with double quotes, unfortunately a few linux tools use single quotes to safely escape values that come from an unknown source. I'm not sure whether this is something that would be supported by this port though.

@bingbing8
Copy link
Contributor

bingbing8 commented Nov 2, 2018

@jborean93, the second issue is the windows CRT rule limitation. Windows cmd does not escape single quotes. If you change the default shell to powershell, single quotes should be recognized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants