Skip to content

Commit 8a7cfe3

Browse files
committed
Added fake SSH agent to fake_server module. Added SSH agent forwarding support to fake server. Added unittest for client authentication via SSH agent.
1 parent 2695d3a commit 8a7cfe3

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

fake_server/fake_agent.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Fake SSH Agent for testing ssh agent forwarding and agent based key
3+
authentication
4+
"""
5+
6+
import paramiko.agent
7+
8+
class FakeAgent(paramiko.agent.AgentSSH):
9+
10+
def __init__(self):
11+
self._conn = None
12+
self.keys = []
13+
14+
def add_key(self, key):
15+
"""Add key to agent.
16+
:param key: Key to add
17+
:type key: :mod:`paramiko.pkey.PKey`
18+
"""
19+
self.keys.append(key)
20+
21+
def _connect(self, conn):
22+
pass
23+
24+
def _close(self):
25+
self._keys = []
26+
27+
def get_keys(self):
28+
return tuple(self.keys)

fake_server/fake_server.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ def check_channel_pty_request(self, channel, term, width, height, pixelwidth,
5353
pixelheight, modes):
5454
return True
5555

56+
def check_channel_forward_agent_request(self, channel):
57+
logger.debug("Forward agent key request for channel %s" % (channel,))
58+
return True
59+
5660
def check_channel_exec_request(self, channel, cmd):
5761
logger.debug("Got exec request on channel %s for cmd %s" % (channel, cmd,))
5862
# Remove any 'bash -c' and/or quotes from command

tests/test_ssh_client.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,18 @@
2222
from pssh import SSHClient, ParallelSSHClient, UnknownHostException, AuthenticationException, _setup_logger, logger
2323
from fake_server.fake_server import start_server, make_socket, logger as server_logger, \
2424
paramiko_logger
25+
from fake_server.fake_agent import FakeAgent
26+
import paramiko
2527
import os
2628
from test_pssh_client import USER_KEY
2729

2830
# _setup_logger(server_logger)
2931
# _setup_logger(logger)
3032
# _setup_logger(paramiko_logger)
3133

34+
USER_KEY = paramiko.RSAKey.from_private_key_file(
35+
os.path.sep.join([os.path.dirname(__file__), 'test_client_private_key']))
36+
3237
class SSHClientTest(unittest.TestCase):
3338

3439
def setUp(self):
@@ -70,5 +75,27 @@ def test_ssh_client_sftp(self):
7075
del client
7176
server.join()
7277

78+
def test_ssh_agent_authentication(self):
79+
"""Test authentication via SSH agent.
80+
Do not provide public key to use when creating SSHClient,
81+
instead override the client's agent with our own fake SSH agent,
82+
add our to key to agent and try to login to server.
83+
Key should be automatically picked up from the overriden agent"""
84+
agent = FakeAgent()
85+
agent.add_key(USER_KEY)
86+
server = start_server({ self.fake_cmd : self.fake_resp },
87+
self.listen_socket)
88+
client = SSHClient('127.0.0.1', port=self.listen_port)
89+
client.client._agent = agent
90+
channel, host, _stdout, _stderr = client.exec_command(self.fake_cmd)
91+
output = (line.strip() for line in _stdout)
92+
channel.close()
93+
output = list(output)
94+
expected = [self.fake_resp]
95+
self.assertEqual(expected, output,
96+
msg = "Got unexpected command output - %s" % (output,))
97+
del client
98+
server.join()
99+
73100
if __name__ == '__main__':
74101
unittest.main()

0 commit comments

Comments
 (0)