madsmith / bash-completion-lib

Automatically exported from code.google.com/p/bash-completion-lib
GNU General Public License v2.0
0 stars 0 forks source link

shell func _known_hosts is broken when multiple UserKnownHostsFile entries are defined in ~/.ssh/config #47

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Put multiple UserKnownHosts entries in ~/.ssh/config.
2. Type ssh, then a space, then hit <tab>

Another way to reproduce it:
1. Put multiple UserKnownHosts entries in ~/.ssh/config.
2. Type _known_hosts and hit enter

What is the expected output? What do you see instead?
It is expected that the (possibly empty) list of completion candidates will 
be shown.

Instead I get this warning, and no candidates are shown:
-bash: /data/home/fhanson/.ssh/known_hosts: Permission denied

If I remove my second UserKnownHostsFile entry from ~/.ssh/config, then I 
see the list of completion candidates as expected.

What version of the product are you using? On what operating system?
Ubuntu 9.10
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)
bash-completion 1:1.0-3ubuntu2

Note that having multiple UserKnownHostsFile entries is actually a useful 
and valid configuration.
UserKnownHostsFile may be defined on a per-host basis.

For example, my own ~/.ssh/config file at work starts with this:

StrictHostKeyChecking   no 
UserKnownHostsFile  /dev/null
CheckHostIP     no

Host home myhomeserver.homelinux.org
    Hostname myhomeserver.homelinux.org
    User fraser
    ForwardX11 yes
    Port 8022
    StrictHostKeyChecking   yes
    VisualHostKey yes
    UserKnownHostsFile      ~/.ssh/known_hosts

I define /dev/null as my global UserKnownHostsFile because I don't want to 
capture the host keys of most servers.  Most of the servers I connect to 
are test machines on the company intranet that are re-installed nightly, so 
their host keys always change.  I don't want warnings when I connect to 
them.
OTOH, I do want to capture host keys for the small number of external 
servers that I connect to.  So, I define UserKnownHostsFile on a per-server 
basis for those.

The cause of this bug:
I investigated what's going on and I think I've figured it out.

It is simple to trace what's going on by putting the _get_cword and 
_known_hosts shell functions in a separate file, with an invocation of 
_known_hosts at the end, and then executing that file with bash -x. 
Like this: 
    bash -x file 2>&1 | grep -B10 Permission

The problem is this line (line # 2680) in /etc/bash-completion:
        user_kh=$( eval echo "$( sed -ne 's/^[ 
\t]*[Uu][Ss][Ee][Rr][Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee]
['"$'\t '"']*\(.*\)$/\1/p' "${config[@]}" )" );

The sed part finds the two UserKnownHostsFile entries in my ~/.ssh/config.  
They are captured as a string with a newline between the two values.
Then the 'eval' part runs, using that string as input, like this:
++ eval echo '/dev/null
~/.ssh/known_hosts'

So, it echoes my first UserKnownHostsFile, which is correct:
+++ echo /dev/null

Then the second UserKnownHostsFile appears on its own line, and is treated 
as an executable command:
+++ /data/home/fhanson/.ssh/known_hosts
file: line 63: /data/home/fhanson/.ssh/known_hosts: Permission denied

Original issue reported on code.google.com by Fraser.H...@gmail.com on 16 Mar 2010 at 7:35