Skip to content

Commit

Permalink
Add support for Include in ssh config (#70) (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
edlmo authored and scop committed Oct 19, 2016
1 parent 4dc0016 commit 1016e43
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 0 deletions.
38 changes: 38 additions & 0 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,39 @@ _known_hosts()
_known_hosts_real $options -- "$cur"
} # _known_hosts()

# Helper function to locate ssh included files in configs
# This function look for the "Include" keyword in ssh config files and include
# them recursively adding each result to the config variable
_included_ssh_config_files()
{
[[ $# -lt 1 ]] && echo "error: $FUNCNAME: missing mandatory argument CONFIG"
local configfile i f
configfile=$1
local included=$( command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\{1,\}\([^#%]*\)\(#.*\)\{0,1\}$/\1/p' "${configfile}" )
for i in ${included[@]}; do
# Check the origin of $configfile to complete relative included paths on included
# files according to ssh_config(5):
# "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user
# configuration file or /etc/ssh if included from the system configuration file.[...]"
if ! [[ "$i" =~ ^\~.*|^\/.* ]]; then
if [[ "$configfile" =~ ^\/etc\/ssh.* ]]; then
i="/etc/ssh/$i"
else
i="$HOME/.ssh/$i"
fi
fi
__expand_tilde_by_ref i
# In case the expanded variable contains multiple paths
for f in ${i}; do
if [ -r $f ]; then
config+=( "$f" )
# The Included file is processed to look for Included files in itself
_included_ssh_config_files $f
fi
done
done
} # _included_ssh_config_files()

# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's config and known_hosts
# files, as well as hostnames reported by avahi-browse if
Expand Down Expand Up @@ -1500,6 +1533,11 @@ _known_hosts_real()
done
fi

# "Include" keyword in ssh config files
for i in "${config[@]}"; do
_included_ssh_config_files "$i"
done

# Known hosts files from configs
if [[ ${#config[@]} -gt 0 ]]; then
local OIFS=$IFS IFS=$'\n' j
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/_known_hosts_real/.ssh/config_relative_path
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Host relative_path
1 change: 1 addition & 0 deletions test/fixtures/_known_hosts_real/config_full_path
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Include ~/config_include_recursion
5 changes: 5 additions & 0 deletions test/fixtures/_known_hosts_real/config_include
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#$HOME set to fixtures/_known_hosts_real in unit test
# Include with full path (recursive one)
Include ~/config_full_path
# Include with relative path
Include config_relative_path
1 change: 1 addition & 0 deletions test/fixtures/_known_hosts_real/config_include_recursion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Host recursion
28 changes: 28 additions & 0 deletions test/unit/_known_hosts_real.exp
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,32 @@ assert_bash_exec "unset -v COMP_KNOWN_HOSTS_WITH_HOSTFILE"
sync_after_int


set test "Included config files should work"
set hosts [get_hosts -unsorted]
# Host 'recursion' is defined in ./fixtures/_known_hosts_real/config_include_recursion
# Host 'relative_path' is defined in ./fixtures/_known_hosts_real/.ssh/config_relative_path
lappend hosts recursion relative_path
set hosts [join [bash_sort $hosts] "\\s+"]
# Setup environment
# Redefined HOME to handle relative path inclusions on $HOME/.ssh
set cmd {OLDHOME=$HOME; HOME="$SRCDIRABS/fixtures/_known_hosts_real"}
send "$cmd\r"
expect -ex "$cmd\r\n/@"
# Call _known_hosts
set cmd {unset COMPREPLY; _known_hosts_real -aF fixtures/_known_hosts_real/config_include ''; echo_array COMPREPLY}
send "$cmd\r"
expect -ex "$cmd\r\n"
expect {
-re "^$hosts\r\n/@$" { pass "$test" }
default { unresolved "$test" }
}
# Teardown environment
set cmd {HOME=$OLDHOME}
send "$cmd\r"
expect -ex "$cmd\r\n/@"


sync_after_int


teardown

0 comments on commit 1016e43

Please sign in to comment.