Teh man page states that scp returns 0 for success and >0 for failure. This is non-standard. Worse, it may return 0 after a failure. scp -B bogus@system:file1 file1 If authentication fails, the string "Permision denied" is sent to STDERR, but the status is 0, making this indistinguishable from success without an extra check of the test sent to STDERR.
0 for success and >0 for failure _is_ standard on unix.
scp chould check ssh's exit status.
I confirm that this bug does exist. It's especially annoying since we use here a lot of scripts which check for the return values of scp to indicate success or failure. In fact it does the good thing on nonexistent files/dirs/etc, but fails in case of auth failure, name resolution failures and so on (the number after "rtfm" in the prompt reports the cmd exit status): fg!rtfm 0 (pts/2) ~ $ scp -v root@mod-tsf.pitux.com:.bashrc /tmp Executing: program /usr/bin/ssh host mod-tsf.pitux.com, user root, command scp -v -f .bashrc OpenSSH_3.4p1, SSH protocols 1.5/2.0, OpenSSL 0x0090602f debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Rhosts Authentication disabled, originating port will not be trusted. debug1: ssh_connect: needpriv 0 ssh: mod-tsf.pitux.com: Name or service not known fg!rtfm 0 (pts/2) ~ $ scp -v root@mod-tsd.pitux.com:fartr /tmp Executing: program /usr/bin/ssh host mod-tsd.pitux.com, user root, command scp -v -f fartr OpenSSH_3.4p1, SSH protocols 1.5/2.0, OpenSSL 0x0090602f debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Rhosts Authentication disabled, originating port will not be trusted. debug1: ssh_connect: needpriv 0 debug1: Connecting to mod-tsd.pitux.com [212.67.34.43] port 22. debug1: Connection established. debug1: identity file /home/fg/.ssh/identity type 0 debug1: identity file /home/fg/.ssh/id_rsa type -1 debug1: identity file /home/fg/.ssh/id_dsa type -1 debug1: Remote protocol version 1.5, remote software version OpenSSH_3.2.2p1 debug1: match: OpenSSH_3.2.2p1 pat OpenSSH* debug1: Local version string SSH-1.5-OpenSSH_3.4p1 debug1: Waiting for server public key. debug1: Received server public key (768 bits) and host key (1024 bits). debug1: Host 'mod-tsd.pitux.com' is known and matches the RSA1 host key. debug1: Found key in /home/fg/.ssh/known_hosts:17 debug1: Encryption type: 3des debug1: Sent encrypted session key. debug1: cipher_init: set keylen (16 -> 32) debug1: cipher_init: set keylen (16 -> 32) debug1: Installing crc compensation attack detector. debug1: Received encrypted confirmation. debug1: Trying RSA authentication via agent with 'fgaliegue@ovh.tbs-internet.com' debug1: Received RSA challenge from server. debug1: Sending response to RSA challenge. debug1: Remote: RSA authentication accepted. debug1: RSA authentication accepted by server. debug1: Sending command: scp -v -f fartr debug1: Entering interactive session. debug1: fd 0 setting O_NONBLOCK debug1: fd 1 setting O_NONBLOCK scp: fartr: No such file or directory debug1: fd 1 clearing O_NONBLOCK debug1: Transferred: stdin 1, stdout 39, stderr 0 bytes in 0.3 seconds debug1: Bytes per second: stdin 3.5, stdout 136.5, stderr 0.0 debug1: Exit status 1 fg!rtfm 1 (pts/2) ~ $ scp -v fg@mod-tsd.pitux.com:fartr /tmp Executing: program /usr/bin/ssh host mod-tsd.pitux.com, user fg, command scp -v -f fartr OpenSSH_3.4p1, SSH protocols 1.5/2.0, OpenSSL 0x0090602f debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Rhosts Authentication disabled, originating port will not be trusted. debug1: ssh_connect: needpriv 0 debug1: Connecting to mod-tsd.pitux.com [212.67.34.43] port 22. debug1: Connection established. debug1: identity file /home/fg/.ssh/identity type 0 debug1: identity file /home/fg/.ssh/id_rsa type -1 debug1: identity file /home/fg/.ssh/id_dsa type -1 debug1: Remote protocol version 1.5, remote software version OpenSSH_3.2.2p1 debug1: match: OpenSSH_3.2.2p1 pat OpenSSH* debug1: Local version string SSH-1.5-OpenSSH_3.4p1 debug1: Waiting for server public key. debug1: Received server public key (768 bits) and host key (1024 bits). debug1: Host 'mod-tsd.pitux.com' is known and matches the RSA1 host key. debug1: Found key in /home/fg/.ssh/known_hosts:17 debug1: Encryption type: 3des debug1: Sent encrypted session key. debug1: cipher_init: set keylen (16 -> 32) debug1: cipher_init: set keylen (16 -> 32) debug1: Installing crc compensation attack detector. debug1: Received encrypted confirmation. debug1: Trying RSA authentication via agent with 'fgaliegue@ovh.tbs-internet.com' debug1: Server refused our key. debug1: RSA authentication using agent refused. debug1: Trying RSA authentication with key '/home/fg/.ssh/identity' debug1: Server refused our key. debug1: Doing challenge response authentication. debug1: No challenge. Permission denied. debug1: Calling cleanup 0x8067140(0x0) fg!rtfm 0 (pts/2) ~ $
do you have a patch for checking the exit status of ssh?
I have no patch for this. I simply reported the problem I discovered when running scp from a Perl script and checking for errors.
In response to #4: I attempted to do a patch to scp.c which adds a call to waitpid() in do_cmd() in order to check for the exit status in the parent. Unfortunately, while it does the right thing on ssh failures, it just hangs the command in case it is bound to succeed. I'll investigate some more when I have the time.
Created attachment 144 [details] Check ssh's exit status in scp The attached rough patch should do the trick. Note that you have to close() the file handles used to communicate with the ssh process, as otherwise the remote scp (when copying to remote) will continue waiting for data, causing waitpid() to wait forever. Also note that this patch may cause hangs of the local scp client when the remote sshd should have been compiled with USE_PIPES defined, but hasn't.
Forgot to mention that the patch in attachment #144 [details] also adds a check for fork() failure.
Congratulations Thomas, it Works Wonderfully For Me(tm). I've retried all test cases in #3 and it returned the good error code each time. Problem solved for me, I just recompiled my 3.4p1 with this patch and so far so good.
patch applied.
Unfortunately this bug still exists in 3.5p1 and 3.4p1 versions. I've checked it on Sun Solaris 2.6 and HP 11.00 platforms and on both has this problem. If the failure based on scp function itself like "file not found" i've got correct (>0) exit status. If the failure conection related like "Connection refused" or "bad hostname" i've got exit status 0. It denies using scp (and ssh in general) in scripts.
The fix was applied after OpenSSh 3.5 was released, i.e. 3.5 does not yet contain the patch.
Mass change of RESOLVED bugs to CLOSED