@@ -2272,33 +2272,47 @@ _included_ssh_config_files()
2272
2272
local configfile i files f
2273
2273
configfile=$1
2274
2274
2275
+ # From man ssh_config:
2276
+ # "Files without absolute paths are assumed to be in ~/.ssh if included
2277
+ # in a user configuration file or /etc/ssh if included from the system
2278
+ # configuration file."
2279
+ # This behavior is not affected by the the including file location -
2280
+ # if the system configuration file is included from the user's config,
2281
+ # relative includes are still resolved in the user's ssh config directory.
2282
+ local relative_include_base
2283
+ if [[ $configfile == /etc/ssh* ]]; then
2284
+ relative_include_base=" /etc/ssh"
2285
+ else
2286
+ relative_include_base=" $HOME /.ssh"
2287
+ fi
2288
+
2289
+ local depth=1
2275
2290
local -a included
2276
- _comp_split included " $( command sed -ne ' s/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\(.*\)$/\1/p ' " ${configfile} " ) " || return
2277
-
2278
- for i in " ${included[@]} " ; do
2279
- # Check the origin of $configfile to complete relative included paths on included
2280
- # files according to ssh_config(5):
2281
- # "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user
2282
- # configuration file or /etc/ssh if included from the system configuration file.[...]"
2283
- if ! [[ $i =~ ^ \~ . * | ^ \/ . * ]] ; then
2284
- if [[ $configfile =~ ^ \/ etc \/ ssh. * ]] ; then
2285
- i= " /etc/ssh/ $i "
2286
- else
2287
- i=" $HOME /.ssh/ $i "
2291
+ local -a include_files
2292
+ included=( " $configfile " )
2293
+
2294
+ # Max recursion depth per openssh's READCONF_MAX_DEPTH:
2295
+ # https://github.com/openssh/openssh-portable/blob/5ec5504f1d328d5bfa64280cd617c3efec4f78f3/readconf.c#L2240
2296
+ local max_depth=16
2297
+ while (( ${ # included[@]} > 0 && depth ++ < max_depth )) ; do
2298
+ _comp_split include_files " $( command sed -ne ' s/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\(.*\)$/\1/p ' " ${included[@]} " ) " || return
2299
+ included=()
2300
+ for i in " ${include_files[@]} " ; do
2301
+ if [[ $i != [~/] * ]] ; then
2302
+ i=" ${relative_include_base} / ${i} "
2288
2303
fi
2289
- fi
2290
- __expand_tilde_by_ref i
2291
- # In case the expanded variable contains multiple paths
2292
- _comp_expand_glob files ' $i'
2293
- if (( ${# files[@]} )) ; then
2294
- for f in " ${files[@]} " ; do
2295
- if [[ -r $f && ! -d $f ]]; then
2296
- config+=(" $f " )
2297
- # The Included file is processed to look for Included files in itself
2298
- _included_ssh_config_files " $f "
2299
- fi
2300
- done
2301
- fi
2304
+ __expand_tilde_by_ref i
2305
+ # In case the expanded variable contains multiple paths
2306
+ _comp_expand_glob files ' $i'
2307
+ if (( ${# files[@]} )) ; then
2308
+ for f in " ${files[@]} " ; do
2309
+ if [[ -r $f && ! -d $f ]]; then
2310
+ config+=(" $f " )
2311
+ included+=(" $f " )
2312
+ fi
2313
+ done
2314
+ fi
2315
+ done
2302
2316
done
2303
2317
} # _included_ssh_config_files()
2304
2318
0 commit comments