Skip to content

Commit 9d183fe

Browse files
committed
Added support for parsing 'Include' directive in ssh config file.
1 parent d6d54df commit 9d183fe

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

paramiko/config.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import re
2727
import shlex
2828
import socket
29+
import glob
2930

3031
SSH_PORT = 22
3132

@@ -49,7 +50,7 @@ def __init__(self):
4950
"""
5051
self._config = []
5152

52-
def parse(self, file_obj):
53+
def parse(self, file_obj,parsed_files=None):
5354
"""
5455
Read an OpenSSH config from the given file object.
5556
@@ -68,7 +69,7 @@ def parse(self, file_obj):
6869
raise Exception("Unparsable line %s" % line)
6970
key = match.group(1).lower()
7071
value = match.group(2)
71-
72+
7273
if key == 'host':
7374
self._config.append(host)
7475
host = {
@@ -80,6 +81,27 @@ def parse(self, file_obj):
8081
# at the end (for compatibility with issue #415). After 3.x, it
8182
# will simply not get stripped, leaving a nice explicit marker.
8283
host['config'][key] = None
84+
elif key == 'include':
85+
# support for Include directive in ssh_config
86+
87+
path = value
88+
# according to SSH documentation if the path is relative, we look forward in ~/.ssh
89+
if path[0] != '/' and path[0]!='~':
90+
path = '~/.ssh/'+path
91+
#expand the user home path
92+
path = os.path.expanduser(path)
93+
94+
if parsed_files == None:
95+
parsed_files = []
96+
97+
#parse every included file
98+
for filename in glob.iglob(path):
99+
if os.path.isfile(filename):
100+
if path in parsed_files:
101+
raise Exception("Include loop detected in ssh config file: %s" %path)
102+
with open(filename) as fd:
103+
parsed_files.append(path);
104+
self.parse(fd,parsed_files)
83105
else:
84106
if value.startswith('"') and value.endswith('"'):
85107
value = value[1:-1]

0 commit comments

Comments
 (0)