Bug 1814 - scp get file prepends -- before filename
Summary: scp get file prepends -- before filename
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: scp (show other bugs)
Version: 5.5p1
Hardware: Other Linux
: P2 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_6_0
  Show dependency treegraph
 
Reported: 2010-09-03 18:34 AEST by Sam
Modified: 2015-08-11 23:02 AEST (History)
6 users (show)

See Also:


Attachments
change triggering the behavior (4.25 KB, patch)
2010-09-05 17:55 AEST, Darren Tucker
no flags Details | Diff
Adds -- only when next argument starts with - or wildcard (3.55 KB, patch)
2011-07-14 04:24 AEST, petiepooo@yahoo.com
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sam 2010-09-03 18:34:53 AEST
Hi,

First bug file, so bear with me.
I am trying to use openssh scp to retrieve a file from a router.
This works with previous versions of openssh, but for some reason this version is inserting -- into the command, confusing the router.

The command I am using is:
scp username@IP_address:file_name Destination_file_name

The debug output is:
sam@Laptop:~$ scp -v  sam@router:ns_sys_config config
Executing: program /usr/bin/ssh host router, user sam, command scp -v -f -- ns_sys_config
OpenSSH_5.5p1 Debian-4ubuntu3, OpenSSL 0.9.8o 01 Jun 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to router [172.16.16.189] port 22.
debug1: Connection established.
debug1: identity file /home/sam/.ssh/id_rsa type -1
debug1: identity file /home/sam/.ssh/id_rsa-cert type -1
debug1: identity file /home/sam/.ssh/id_dsa type -1
debug1: identity file /home/sam/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 2.0, remote software version NetScreen
debug1: no match: NetScreen
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.5p1 Debian-4ubuntu3
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-cbc hmac-sha1 none
debug1: kex: client->server aes128-cbc hmac-sha1 none
debug1: sending SSH2_MSG_KEXDH_INIT
debug1: expecting SSH2_MSG_KEXDH_REPLY
debug1: Host 'vpnfwpr01' is known and matches the DSA host key.
debug1: Found key in /home/sam/.ssh/known_hosts:12
debug1: ssh_dss_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: password
debug1: Next authentication method: password
sam@router's password: 
debug1: Authentication succeeded (password).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_GB.utf8
debug1: Sending command: scp -v -f -- ns_sys_config
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 1488, received 1064 bytes, in 0.0 seconds
Bytes per second: sent 30047.3, received 21485.4
debug1: Exit status 1



The router debug shows:
## 2010-09-02 14:18:42 : SSH conn: command = scp -f -- ns_sys_config ## 2010-09-02 14:18:42 : >>> ssh_2nd_scp_authentication(un='srigelsford', vsys='Root') ## 2010-09-02 14:18:42 : <<< ssh_2nd_scp_authentication(aaid=30) = 1 ## 2010-09-02 14:18:42 : SCP: >>> scp_create_session(command=scp -f -- ns_sys_config) ## 2010-09-02 14:18:42 : SCP: <<< scp_create_session() = 0 ## 2010-09-02 14:18:42 : SSH state trans: SSH_STATE_CONNECTING(9) -> SSH_STATE_DISCONNECTING(11) 


A working version of OpenSSH does the following:
## 2010-09-03 19:33:53 : SSH conn: command = scp -f ns_sys_config ## 2010-09-03 19:33:53 : >>> ssh_2nd_scp_authentication(un='netscreen', vsys='Root') ## 2010-09-03 19:33:53 : <<< ssh_2nd_scp_authentication(aaid=4) = 1 ## 2010-09-03 19:33:53 : SCP: >>> scp_create_session(command=scp -f ns_sys_config) ## 2010-09-03 19:33:53 : SCP: >>> scp_ctx_alloc() ## 2010-09-03 19:33:53 : SCP: <<< scp_ctx_alloc() ## 2010-09-03 19:33:53 : SCP: >>> scp_file_init(fn=ns_sys_config) ## 2010-09-03 19:33:53 : SCP: <<< scp_file_init(fh=00000000, fs=5566) ## 2010-09-03 19:33:53 : SCP: <<< scp_create_session() = 1


The issue seems to be the -- between the -f argument and the filename.
I have exhausted my googling abilities to no avail, so guess i might be one of the first to have this problem.
Comment 1 Darren Tucker 2010-09-05 17:55:46 AEST
Created attachment 1919 [details]
change triggering the behavior

It was triggered by this change (you can feed it into patch -R to confirm).  The "--" means the end of the option list to most getopt implementations (it's specified by SUSv2: http://www.opengroup.org/onlinepubs/007908799/xsh/getopt.html) and it means that file names begining with "-" can't be mistaken for arguments.  I'm not sure if we can do anything about it without removing that safety.

What kind of router is it?
Comment 2 Damien Miller 2010-09-06 10:45:41 AEST
Maybe we could only prepend if the filename list contains an entry that starts with '-'?
Comment 3 Sam 2010-09-06 17:11:54 AEST
(In reply to comment #2)
> Maybe we could only prepend if the filename list contains an entry that
> starts with '-'?

Echo the above.
It is a Juniper router (massive enterprise market share, second only to Cisco).
Comment 4 Tomas Mraz 2010-09-06 17:23:08 AEST
But can you really detect it? The command is executed in the remote shell and there happens potential shell wildcard expansion of the arguments.
Comment 5 gmueller 2010-11-16 20:16:23 AEDT
Our routers (Nortel) don't understand the new syntax, too. They will refuse sending the file "--". 

ERROR Task=tScp --: S_dosFsLib_FILE_NOT_FOUND

Please implement the old syntax or at least a flag or option to force the old style command.
Comment 6 Darren Tucker 2010-11-24 12:28:08 AEDT
I'll point out that handling of "--" is mandated by POSIX for getopt (http://www.opengroup.org/onlinepubs/007908799/xsh/getopt.html).

On the flip side, there's nothing that says an scp implementation must use getopt (but since there's no spec, nothing says otherwise either).
Comment 7 petiepooo@yahoo.com 2010-12-07 08:44:38 AEDT
It seems like the fix is worse than the danger for this issue.  Patchset 3682 clearly breaks scp compatibility with a good portion of the existing (difficult to upgrade) getopt-noncompliant routing infrastructure in order to prevent a possible vulnerability with names that start with a dash.  Can anyone point me to an organization that really uses user, host, or file names that start with a dash?

I didn't think so..  8-)

There's a common expression I've heard about "throwing the baby out with the bathwater."  It seems that is what is happening here.

At the very least, could you check for existence of a name starting with a character in the set [-?*] before adding the double-dash?  I think that would allow non-wildcard copies with getopt-noncompliant implementations while still giving protection against names starting with a dash.  Not a perfect solution, but it would at keep Nortel/Juniper users from having to maintain an out-of-date scp binary.
Comment 8 markbowen 2011-07-12 06:19:54 AEST
This is my first post, so please ALSO bear with me.

I've been working with APC PDU's that don't seem to understand the -- either ...

The  first example below using Sun_SSH DOES work.
The second example below using Open_SSH does NOT work ...

Unfortunately the PDU's do not produce very verbose logs.

AM I just grasping at straws here??

If indeed this is an Open_SSH bug, is there a work around until it gets fixed?

Thanks!

--- First Example ---
mfb750@vista$ /bin/scp -v ticadmin@192.168.33.193:/config.ini 193.ini
Executing: program /usr/bin/ssh host 192.168.33.193, user ticadmin, command scp -v -f /config.ini
Sun_SSH_1.1, SSH protocols 1.5/2.0, OpenSSL 0x0090704f
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Rhosts Authentication disabled, originating port will not be trusted.
debug1: ssh_connect: needpriv 0
debug1: Connecting to 192.168.33.193 [192.168.33.193] port 22.
debug1: Connection established.
debug1: identity file /export/home/mfb750/.ssh/id_rsa type 1
debug1: identity file /export/home/mfb750/.ssh/id_dsa type -1
debug1: Remote protocol version 1.99, remote software version cryptlib
debug1: no match: cryptlib
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-Sun_SSH_1.1
debug1: Failed to acquire GSS-API credentials for any mechanisms (No credentials were supplied, or the credentials were unavailable or inaccessible
Unknown code 0
)
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client 3des-cbc hmac-md5 none
debug1: kex: client->server 3des-cbc hmac-md5 none
debug1: Peer sent proposed langtags, ctos:
debug1: Peer sent proposed langtags, stoc:
debug1: We proposed langtags, ctos: i-default
debug1: We proposed langtags, stoc: i-default
debug1: dh_gen_key: priv key bits set: 195/384
debug1: bits set: 489/1024
debug1: sending SSH2_MSG_KEXDH_INIT
debug1: expecting SSH2_MSG_KEXDH_REPLY
debug1: Host '192.168.33.193' is known and matches the RSA host key.
debug1: Found key in /export/home/mfb750/.ssh/known_hosts:25
debug1: bits set: 482/1024
debug1: ssh_rsa_verify: signature correct
debug1: newkeys: mode 1
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: newkeys: mode 0
debug1: SSH2_MSG_NEWKEYS received
debug1: done: ssh_kex2.
debug1: send SSH2_MSG_SERVICE_REQUEST
debug1: got SSH2_MSG_SERVICE_ACCEPT
Authenticated with partial success.
debug1: Authentications that can continue: password
debug1: Next authentication method: password
ticadmin@192.168.33.193's password:
debug1: Authentication succeeded (password)
debug1: fd 6 setting O_NONBLOCK
debug1: fd 7 setting O_NONBLOCK
debug1: channel 0: new [client-session]
debug1: send channel open 0
debug1: Entering interactive session.
debug1: ssh_session2_setup: id 0
debug1: Sending command: scp -v -f /config.ini
debug1: channel request 0: exec
debug1: channel 0: open confirm rwindow 8192 rmax 1024
config.ini           100% |*****************************| 24605       00:13
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: rcvd eof
debug1: channel 0: output open -> drain
debug1: channel 0: obuf empty
debug1: channel 0: close_write
debug1: channel 0: output drain -> closed
debug1: channel 0: rcvd close
debug1: channel 0: close_read
debug1: channel 0: input open -> closed
debug1: channel 0: almost dead
debug1: channel 0: gc: notify user
debug1: channel 0: gc: user detached
debug1: channel 0: send close
debug1: channel 0: is dead
debug1: channel 0: garbage collecting
debug1: channel_free: channel 0: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
debug1: Transferred: stdin 0, stdout 0, stderr 0 bytes in 17.5 seconds
debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 0.0
debug1: Exit status 0
mfb750@vista$

--- Second Example ---
mfb750@vista$ scp -v ticadmin@192.168.33.193:/config.ini 193.ini
Executing: program /usr/local/openssh/5.6/bin/ssh host 192.168.33.193, user ticadmin, command scp -v -f -- /config.ini
OpenSSH_5.6p1, OpenSSL 1.0.0a 1 Jun 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to 192.168.33.193 [192.168.33.193] port 22.
debug1: Connection established.
debug1: identity file /export/home/mfb750/.ssh/id_rsa type 1
debug1: identity file /export/home/mfb750/.ssh/id_rsa-cert type -1
debug1: identity file /export/home/mfb750/.ssh/id_dsa type -1
debug1: identity file /export/home/mfb750/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 1.99, remote software version cryptlib
debug1: no match: cryptlib
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.6
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client 3des-cbc hmac-md5 none
debug1: kex: client->server 3des-cbc hmac-md5 none
debug1: sending SSH2_MSG_KEXDH_INIT
debug1: expecting SSH2_MSG_KEXDH_REPLY
debug1: Host '192.168.33.193' is known and matches the RSA host key.
debug1: Found key in /export/home/mfb750/.ssh/known_hosts:25
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
Authenticated with partial success.
debug1: Authentications that can continue: password
debug1: Next authentication method: password
ticadmin@192.168.33.193's password:
debug1: Authentication succeeded (password).
Authenticated to 192.168.33.193 ([192.168.33.193]:22).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending command: scp -v -f -- /config.ini
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 1456, received 872 bytes, in 0.3 seconds
Bytes per second: sent 5807.1, received 3477.9
debug1: Exit status 1
mfb750@vista$
Comment 9 petiepooo@yahoo.com 2011-07-14 04:24:54 AEST
Created attachment 2064 [details]
Adds -- only when next argument starts with - or wildcard

Adds a check before adding each "--" getopt flag to command lines.  Flag is only added if the following argument starts with '-' or wildcard (* or ?).

My first patch submission, please let me know if I did it wrong.
Comment 10 Damien Miller 2012-03-09 11:48:10 AEDT
we have something roughly equivalent in the forthcoming 6.0 release. If you want to try it out now (rather than waiting a week or two) you can grab a snapshot from http://www.mindrot.org/openssh_snap
Comment 11 Damien Miller 2015-08-11 23:02:25 AEST
Set all RESOLVED bugs to CLOSED with release of OpenSSH 7.1