def agent_wrapper(self): """Run a test coroutine after connecting to an SSH agent""" agent = yield from asyncssh.connect_agent() yield from agent.remove_all() yield from asyncio.coroutine(func)(self, agent) agent.close()
def test_errors(self): """Test getting error responses from SSH agent""" # pylint: disable=bad-whitespace key = asyncssh.generate_private_key('ssh-rsa') keypair = asyncssh.load_keypairs(key)[0] for response in (b'', String(b''), String(Byte(SSH_AGENT_FAILURE)), String(b'\xff')): mock_agent = _Agent(response) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') for request in (agent.get_keys(), agent.sign(b'xxx', b'test'), agent.add_keys([key]), agent.add_smartcard_keys('xxx'), agent.remove_keys([keypair]), agent.remove_smartcard_keys('xxx'), agent.remove_all(), agent.lock('passphrase'), agent.unlock('passphrase')): with self.assertRaises(ValueError): yield from request agent.close() yield from mock_agent.stop()
async def test_errors(self): """Test getting error responses from SSH agent""" key = asyncssh.generate_private_key('ssh-rsa') keypair = asyncssh.load_keypairs(key)[0] for response in (None, b'', Byte(SSH_AGENT_FAILURE), b'\xff'): mock_agent = _Agent(response) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: for request in (agent.get_keys(), agent.sign(b'xxx', b'test'), agent.add_keys([key]), agent.add_smartcard_keys('xxx'), agent.remove_keys([keypair]), agent.remove_smartcard_keys('xxx'), agent.remove_all(), agent.lock('passphrase'), agent.unlock('passphrase')): async with agent: with self.assertRaises(ValueError): await request await mock_agent.stop()
def test_double_close(self): """Test calling close more than once on the agent""" agent = yield from asyncssh.connect_agent() self.assertIsNotNone(agent) agent.close() agent.close()
def test_explicit_loop(self): """Test passing the event loop explicitly""" loop = asyncio.get_event_loop() agent = yield from asyncssh.connect_agent(loop=loop) self.assertIsNotNone(agent) agent.close()
def test_sign(self): """Test signing a block of data using the agent""" agent = yield from asyncssh.connect_agent() keys = yield from agent.get_keys() sig = yield from keys[0].sign(b'test') self.assertTrue(self._public_key.verify(b'test', sig)) agent.close()
def test_get_keys(self): """Test getting keys from the agent""" agent = yield from asyncssh.connect_agent() keys = yield from agent.get_keys() agent.close() self.assertEqual(len(keys), 1)
def test_unknown_key(self): """Test failure when signing with an unknown key""" agent = yield from asyncssh.connect_agent() with self.assertRaises(ValueError): yield from agent.sign(b'xxx', b'test') agent.close()
def test_reconnect(self): """Test reconnecting to the agent after closing it""" agent = yield from asyncssh.connect_agent() keys = yield from agent.get_keys() agent.close() sig = yield from keys[0].sign(b'test') self.assertTrue(self._public_key.verify(b'test', sig)) agent.close()
def test_query_extensions(self): """Test query of supported extensions""" mock_agent = _Agent(String(Byte(SSH_AGENT_SUCCESS) + String('xxx'))) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') extensions = yield from agent.query_extensions() self.assertEqual(extensions, ['xxx']) agent.close() yield from mock_agent.stop() mock_agent = _Agent(String(Byte(SSH_AGENT_SUCCESS) + String(b'\xff'))) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') with self.assertRaises(ValueError): yield from agent.query_extensions() agent.close() yield from mock_agent.stop() mock_agent = _Agent(String(Byte(SSH_AGENT_FAILURE))) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') extensions = yield from agent.query_extensions() self.assertEqual(extensions, []) agent.close() yield from mock_agent.stop() mock_agent = _Agent(String(b'\xff')) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') with self.assertRaises(ValueError): yield from agent.query_extensions() agent.close() yield from mock_agent.stop()
async def test_add_remove_smartcard_keys(self): """Test adding and removing smart card keys""" mock_agent = _Agent(Byte(SSH_AGENT_SUCCESS)) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: result = await agent.add_smartcard_keys('provider') self.assertIsNone(result) await mock_agent.stop() mock_agent = _Agent(Byte(SSH_AGENT_SUCCESS)) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: result = await agent.remove_smartcard_keys('provider') self.assertIsNone(result) await mock_agent.stop()
def test_callback_sshkeypair(self): """Test client key passed in as an SSHKeyPair by callback""" agent = yield from asyncssh.connect_agent() keylist = yield from agent.get_keys() with (yield from self._connect_publickey(keylist)) as conn: pass yield from conn.wait_closed() agent.close()
def test_add_remove_smartcard_keys(self): """Test adding and removing smart card keys""" mock_agent = _Agent(String(Byte(SSH_AGENT_SUCCESS))) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') result = yield from agent.add_smartcard_keys('provider') self.assertIsNone(result) agent.close() yield from mock_agent.stop() mock_agent = _Agent(String(Byte(SSH_AGENT_SUCCESS))) yield from mock_agent.start('mock_agent') agent = yield from asyncssh.connect_agent('mock_agent') result = yield from agent.remove_smartcard_keys('provider') self.assertIsNone(result) agent.close() yield from mock_agent.stop()
def test_client_key_sshkeypairs(self): """Test client keys passed in as a list of SSHKeyPairs""" agent = yield from asyncssh.connect_agent() keylist = yield from agent.get_keys() with (yield from self.connect(username='******', client_keys=keylist)) as conn: pass yield from conn.wait_closed() agent.close()
def test_client_key_agent_keypairs(self): """Test client keys passed in as a list of SSHAgentKeyPairs""" agent = yield from asyncssh.connect_agent() for key in (yield from agent.get_keys()): with (yield from self.connect(username='******', client_keys=[key])) as conn: pass yield from conn.wait_closed() agent.close()
async def test_query_extensions(self): """Test query of supported extensions""" mock_agent = _Agent(Byte(SSH_AGENT_SUCCESS) + String('xxx')) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: extensions = await agent.query_extensions() self.assertEqual(extensions, ['xxx']) await mock_agent.stop() mock_agent = _Agent(Byte(SSH_AGENT_SUCCESS) + String(b'\xff')) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: with self.assertRaises(ValueError): await agent.query_extensions() await mock_agent.stop() mock_agent = _Agent(Byte(SSH_AGENT_FAILURE)) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: extensions = await agent.query_extensions() self.assertEqual(extensions, []) await mock_agent.stop() mock_agent = _Agent(b'\xff') await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: with self.assertRaises(ValueError): await agent.query_extensions() await mock_agent.stop()
def test_callback_sshkeypair(self): """Test client key passed in as an SSHKeyPair by callback""" if not self.agent_available(): # pragma: no cover self.skipTest('ssh-agent not available') agent = yield from asyncssh.connect_agent() keylist = yield from agent.get_keys() with (yield from self._connect_publickey(keylist)) as conn: pass yield from conn.wait_closed() agent.close()
def check_invalid_response(self, failmode="", request=""): """Test getting invalid responses from SSH agent""" mock_agent = _Agent(failmode) path = yield from mock_agent.start() agent = yield from asyncssh.connect_agent(path) with self.assertRaises(ValueError): if request == "sign": yield from agent.sign(b"xxx", b"test") else: yield from agent.get_keys() agent.close() yield from mock_agent.stop()
def test_client_key_agent_keypairs(self): """Test client keys passed in as a list of SSHAgentKeyPairs""" if not self.agent_available(): # pragma: no cover self.skipTest('ssh-agent not available') agent = yield from asyncssh.connect_agent() for key in (yield from agent.get_keys()): with (yield from self.connect(username='******', client_keys=[key])) as conn: pass yield from conn.wait_closed() agent.close()
def check_invalid_response(self, failmode='', request=''): """Test getting invalid responses from SSH agent""" mock_agent = _Agent(failmode) path = yield from mock_agent.start() agent = yield from asyncssh.connect_agent(path) with self.assertRaises(ValueError): if request == 'sign': yield from agent.sign(b'xxx', b'test') else: yield from agent.get_keys() agent.close() yield from mock_agent.stop()
def check_invalid_response(self, failmode='', request=''): """Test getting invalid responses from SSH agent""" mock_agent = _Agent(failmode) yield from mock_agent.start('bad_agent') agent = yield from asyncssh.connect_agent('bad_agent') with self.assertRaises(ValueError): if request == 'sign': yield from agent.sign(b'xxx', b'test') else: yield from agent.get_keys() agent.close() yield from mock_agent.stop()
async def test_get_sk_keys(self): """Test getting U2F security keys""" key = asyncssh.generate_private_key( '*****@*****.**') cert = key.generate_user_certificate(key, 'test') mock_agent = _Agent(Byte(SSH_AGENT_IDENTITIES_ANSWER) + UInt32(2) + String(key.public_data) + String('') + String(cert.public_data) + String('')) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: await agent.get_keys() await mock_agent.stop()
async def test_add_sk_keys(self): """Test adding U2F security keys""" key = asyncssh.generate_private_key( '*****@*****.**') cert = key.generate_user_certificate(key, 'test') mock_agent = _Agent(Byte(SSH_AGENT_SUCCESS)) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: for keypair in asyncssh.load_keypairs([key, (key, cert)]): async with agent: self.assertIsNone(await agent.add_keys([keypair])) async with agent: with self.assertRaises(asyncssh.KeyExportError): await agent.add_keys([key.convert_to_public()]) await mock_agent.stop()
async def test_add_keys_failure(self, agent): """Test getting keys from the agent""" os.mkdir('.ssh', 0o700) key = asyncssh.generate_private_key('ssh-rsa') key.write_private_key(Path('.ssh', 'id_rsa')) try: mock_agent = _Agent(Byte(SSH_AGENT_FAILURE)) await mock_agent.start('mock_agent') async with asyncssh.connect_agent('mock_agent') as agent: async with agent: await agent.add_keys() async with agent: with self.assertRaises(ValueError): await agent.add_keys([key]) finally: os.remove(os.path.join('.ssh', 'id_rsa')) os.rmdir('.ssh')
def asyncSetUpClass(cls): """Set up keys, an SSH server, and an SSH agent for the tests to use""" # pylint: disable=too-many-statements ckey = asyncssh.generate_private_key('ssh-rsa') ckey.write_private_key('ckey') ckey.write_private_key('ckey_encrypted', passphrase='passphrase') ckey.write_public_key('ckey.pub') ckey_ecdsa = asyncssh.generate_private_key('ecdsa-sha2-nistp256') ckey_ecdsa.write_private_key('ckey_ecdsa') ckey_ecdsa.write_public_key('ckey_ecdsa.pub') ckey_cert = ckey.generate_user_certificate(ckey, 'name', principals=['ckey']) ckey_cert.write_certificate('ckey-cert.pub') skey = asyncssh.generate_private_key('ssh-rsa') skey.write_private_key('skey') skey.write_public_key('skey.pub') skey_ecdsa = asyncssh.generate_private_key('ecdsa-sha2-nistp256') skey_ecdsa.write_private_key('skey_ecdsa') skey_ecdsa.write_public_key('skey_ecdsa.pub') skey_cert = skey.generate_host_certificate(skey, 'name', principals=['127.0.0.1']) skey_cert.write_certificate('skey-cert.pub') exp_cert = skey.generate_host_certificate(skey, 'name', valid_after='-2d', valid_before='-1d') skey.write_private_key('exp_skey') exp_cert.write_certificate('exp_skey-cert.pub') if x509_available: # pragma: no branch ckey_x509_self = ckey_ecdsa.generate_x509_user_certificate( ckey_ecdsa, 'OU=name', principals=['ckey']) ckey_ecdsa.write_private_key('ckey_x509_self') ckey_x509_self.append_certificate('ckey_x509_self', 'pem') ckey_x509_self.write_certificate('ckey_x509_self.pem', 'pem') ckey_x509_self.write_certificate('ckey_x509_self.pub') skey_x509_self = skey_ecdsa.generate_x509_host_certificate( skey_ecdsa, 'OU=name', principals=['127.0.0.1']) skey_ecdsa.write_private_key('skey_x509_self') skey_x509_self.append_certificate('skey_x509_self', 'pem') skey_x509_self.write_certificate('skey_x509_self.pem', 'pem') root_ca_key = asyncssh.generate_private_key('ssh-rsa') root_ca_key.write_private_key('root_ca_key') root_ca_cert = root_ca_key.generate_x509_ca_certificate( root_ca_key, 'OU=RootCA', ca_path_len=1) root_ca_cert.write_certificate('root_ca_cert.pem', 'pem') root_ca_cert.write_certificate('root_ca_cert.pub') int_ca_key = asyncssh.generate_private_key('ssh-rsa') int_ca_key.write_private_key('int_ca_key') int_ca_cert = root_ca_key.generate_x509_ca_certificate( int_ca_key, 'OU=IntCA', 'OU=RootCA', ca_path_len=0) int_ca_cert.write_certificate('int_ca_cert.pem', 'pem') ckey_x509_chain = int_ca_key.generate_x509_user_certificate( ckey, 'OU=name', 'OU=IntCA', principals=['ckey']) ckey.write_private_key('ckey_x509_chain') ckey_x509_chain.append_certificate('ckey_x509_chain', 'pem') int_ca_cert.append_certificate('ckey_x509_chain', 'pem') ckey_x509_chain.write_certificate('ckey_x509_partial.pem', 'pem') skey_x509_chain = int_ca_key.generate_x509_host_certificate( skey, 'OU=name', 'OU=IntCA', principals=['127.0.0.1']) skey.write_private_key('skey_x509_chain') skey_x509_chain.append_certificate('skey_x509_chain', 'pem') int_ca_cert.append_certificate('skey_x509_chain', 'pem') root_hash = root_ca_cert.x509_cert.subject_hash os.mkdir('cert_path') shutil.copy('root_ca_cert.pem', os.path.join('cert_path', root_hash + '.0')) # Intentional hash mismatch shutil.copy('int_ca_cert.pem', os.path.join('cert_path', root_hash + '.1')) for f in ('ckey', 'ckey_ecdsa', 'skey', 'exp_skey', 'skey_ecdsa'): os.chmod(f, 0o600) os.mkdir('.ssh', 0o700) os.mkdir('.ssh/crt', 0o700) shutil.copy('ckey_ecdsa', os.path.join('.ssh', 'id_ecdsa')) shutil.copy('ckey_ecdsa.pub', os.path.join('.ssh', 'id_ecdsa.pub')) shutil.copy('ckey_encrypted', os.path.join('.ssh', 'id_rsa')) shutil.copy('ckey.pub', os.path.join('.ssh', 'id_rsa.pub')) with open('authorized_keys', 'w') as auth_keys: with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) with open('ckey_ecdsa.pub') as ckey_ecdsa_pub: shutil.copyfileobj(ckey_ecdsa_pub, auth_keys) auth_keys.write('cert-authority,principals="ckey",' 'permitopen=:* ') with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) if x509_available: # pragma: no branch with open('authorized_keys_x509', 'w') as auth_keys_x509: with open('ckey_x509_self.pub') as ckey_self_pub: shutil.copyfileobj(ckey_self_pub, auth_keys_x509) auth_keys_x509.write('cert-authority,principals="ckey" ') with open('root_ca_cert.pub') as root_pub: shutil.copyfileobj(root_pub, auth_keys_x509) cls._server = yield from cls.start_server() sock = cls._server.sockets[0] cls._server_addr = '127.0.0.1' cls._server_port = sock.getsockname()[1] host = '[%s]:%d,localhost ' % (cls._server_addr, cls._server_port) with open('known_hosts', 'w') as known_hosts: known_hosts.write(host) with open('skey.pub') as skey_pub: shutil.copyfileobj(skey_pub, known_hosts) known_hosts.write('@cert-authority ' + host) with open('skey.pub') as skey_pub: shutil.copyfileobj(skey_pub, known_hosts) shutil.copy('known_hosts', os.path.join('.ssh', 'known_hosts')) os.environ['LOGNAME'] = 'guest' os.environ['HOME'] = '.' if 'DISPLAY' in os.environ: # pragma: no cover del os.environ['DISPLAY'] if 'SSH_ASKPASS' in os.environ: # pragma: no cover del os.environ['SSH_ASKPASS'] if 'SSH_AUTH_SOCK' in os.environ: # pragma: no cover del os.environ['SSH_AUTH_SOCK'] if 'XAUTHORITY' in os.environ: # pragma: no cover del os.environ['XAUTHORITY'] try: output = run('ssh-agent -a agent 2>/dev/null') except subprocess.CalledProcessError: # pragma: no cover cls._agent_pid = None else: cls._agent_pid = int(output.splitlines()[2].split()[3][:-1]) os.environ['SSH_AUTH_SOCK'] = 'agent' agent = yield from asyncssh.connect_agent() yield from agent.add_keys([ckey_ecdsa, (ckey, ckey_cert)]) agent.close() with open('ssh-keysign', 'wb'): pass
def test_no_auth_sock(self): """Test failure when no auth sock is set""" del os.environ['SSH_AUTH_SOCK'] self.assertIsNone((yield from asyncssh.connect_agent())) os.environ['SSH_AUTH_SOCK'] = 'agent'
def test_connection_failed(self): """Test failure in opening a connection to the agent""" self.assertIsNone((yield from asyncssh.connect_agent('xxx')))
async def agent_wrapper(self): """Run a test after connecting to an SSH agent""" async with asyncssh.connect_agent() as agent: await agent.remove_all() await func(self, agent)
async def _begin_session(self, stdin, stdout, stderr): """Begin processing a new session""" # pylint: disable=too-many-statements action = stdin.channel.get_command() or stdin.channel.get_subsystem() if not action: action = 'echo' if action == 'echo': await echo(stdin, stdout, stderr) elif action == 'conn_close': await stdin.read(1) stdout.write('\n') self._conn.close() elif action == 'close': await stdin.read(1) stdout.write('\n') elif action == 'agent': try: async with asyncssh.connect_agent(self._conn) as agent: stdout.write(str(len((await agent.get_keys()))) + '\n') except (OSError, asyncssh.ChannelOpenError): stdout.channel.exit(1) elif action == 'agent_sock': agent_path = stdin.channel.get_agent_path() if agent_path: async with asyncssh.connect_agent(agent_path) as agent: stdout.write(str(len((await agent.get_keys()))) + '\n') else: stdout.channel.exit(1) elif action == 'rejected_agent': agent_path = stdin.channel.get_agent_path() stdout.write(str(bool(agent_path)) + '\n') chan = self._conn.create_agent_channel() try: await chan.open(SSHUNIXStreamSession) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_session': chan = _ServerChannel(self._conn, asyncio.get_event_loop(), False, False, 0, None, 'strict', 1, 32768) try: await chan.open_session() except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_tcpip_direct': chan = self._conn.create_tcp_channel() try: await chan.connect(SSHTCPStreamSession, '', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'unknown_tcpip_listener': chan = self._conn.create_tcp_channel() try: await chan.accept(SSHTCPStreamSession, 'xxx', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'invalid_tcpip_listener': chan = self._conn.create_tcp_channel() try: await chan.accept(SSHTCPStreamSession, b'\xff', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_unix_direct': chan = self._conn.create_unix_channel() try: await chan.connect(SSHUNIXStreamSession, '') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'unknown_unix_listener': chan = self._conn.create_unix_channel() try: await chan.accept(SSHUNIXStreamSession, 'xxx') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'invalid_unix_listener': chan = self._conn.create_unix_channel() try: await chan.accept(SSHUNIXStreamSession, b'\xff') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'late_auth_banner': try: self._conn.send_auth_banner('auth banner') except OSError: stdin.channel.exit(1) elif action == 'invalid_open_confirm': stdin.channel.send_packet(MSG_CHANNEL_OPEN_CONFIRMATION, UInt32(0), UInt32(0), UInt32(0)) elif action == 'invalid_open_failure': stdin.channel.send_packet(MSG_CHANNEL_OPEN_FAILURE, UInt32(0), String(''), String('')) elif action == 'env': value = stdin.channel.get_environment().get('TEST', '') stdout.write(value + '\n') elif action == 'term': chan = stdin.channel info = str((chan.get_terminal_type(), chan.get_terminal_size(), chan.get_terminal_mode(asyncssh.PTY_OP_OSPEED))) stdout.write(info + '\n') elif action == 'xon_xoff': stdin.channel.set_xon_xoff(True) elif action == 'no_xon_xoff': stdin.channel.set_xon_xoff(False) elif action == 'signals': try: await stdin.readline() except asyncssh.BreakReceived as exc: stdin.channel.exit_with_signal('ABRT', False, str(exc.msec)) except asyncssh.SignalReceived as exc: stdin.channel.exit_with_signal('ABRT', False, exc.signal) except asyncssh.TerminalSizeChanged as exc: size = (exc.width, exc.height, exc.pixwidth, exc.pixheight) stdin.channel.exit_with_signal('ABRT', False, str(size)) elif action == 'exit_status': stdin.channel.exit(1) elif action == 'closed_status': stdin.channel.close() stdin.channel.exit(1) elif action == 'exit_signal': stdin.channel.exit_with_signal('INT', False, 'exit_signal') elif action == 'unknown_signal': stdin.channel.exit_with_signal('unknown', False, 'unknown_signal') elif action == 'closed_signal': stdin.channel.close() stdin.channel.exit_with_signal('INT', False, 'closed_signal') elif action == 'invalid_exit_signal': stdin.channel.exit_with_signal('invalid') elif action == 'invalid_exit_lang': stdin.channel.exit_with_signal('INT', False, '', 'invalid') elif action == 'window_after_close': stdin.channel.send_packet(MSG_CHANNEL_CLOSE) stdin.channel.send_packet(MSG_CHANNEL_WINDOW_ADJUST, UInt32(0)) elif action == 'empty_data': stdin.channel.send_packet(MSG_CHANNEL_DATA, String('')) elif action == 'partial_unicode': data = '\xff\xff'.encode('utf-8') stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[:3])) stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[3:])) elif action == 'partial_unicode_at_eof': data = '\xff\xff'.encode('utf-8') stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[:3])) elif action == 'unicode_error': stdin.channel.send_packet(MSG_CHANNEL_DATA, String(b'\xff')) elif action == 'data_past_window': stdin.channel.send_packet(MSG_CHANNEL_DATA, String(2 * 1025 * 1024 * '\0')) elif action == 'data_after_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdout.write('xxx') elif action == 'data_after_close': await asyncio.sleep(0.1) stdout.write('xxx') elif action == 'ext_data_after_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdin.channel.write_stderr('xxx') elif action == 'invalid_datatype': stdin.channel.send_packet(MSG_CHANNEL_EXTENDED_DATA, UInt32(255), String('')) elif action == 'double_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdin.channel.write_eof() elif action == 'double_close': await asyncio.sleep(0.1) stdout.write('xxx') stdin.channel.send_packet(MSG_CHANNEL_CLOSE) elif action == 'request_after_close': stdin.channel.send_packet(MSG_CHANNEL_CLOSE) stdin.channel.exit(1) elif action == 'unexpected_auth': self._conn.send_packet(MSG_USERAUTH_REQUEST, String('guest'), String('ssh-connection'), String('none')) elif action == 'invalid_response': stdin.channel.send_packet(MSG_CHANNEL_SUCCESS) else: stdin.channel.exit(255) stdin.channel.close() await stdin.channel.wait_closed()
def asyncSetUpClass(cls): """Set up keys, an SSH server, and an SSH agent for the tests to use""" ckey_dsa = asyncssh.generate_private_key('ssh-dss') ckey_dsa.write_private_key('ckey_dsa') ckey_dsa.write_public_key('ckey_dsa.pub') ckey = asyncssh.generate_private_key('ssh-rsa') ckey.write_private_key('ckey') ckey.write_public_key('ckey.pub') ckey_cert = ckey.generate_user_certificate(ckey, 'name') ckey_cert.write_certificate('ckey-cert.pub') skey = asyncssh.generate_private_key('ssh-rsa') skey.write_private_key('skey') skey.write_public_key('skey.pub') skey_cert = skey.generate_host_certificate(skey, 'name') skey_cert.write_certificate('skey-cert.pub') exp_cert = skey.generate_host_certificate(skey, 'name', valid_after='-2d', valid_before='-1d') skey.write_private_key('exp_skey') exp_cert.write_certificate('exp_skey-cert.pub') run('chmod 600 ckey_dsa ckey skey exp_skey') run('mkdir .ssh') run('chmod 700 .ssh') run('cp ckey_dsa .ssh/id_dsa') run('cp ckey_dsa.pub .ssh/id_dsa.pub') run('cp ckey .ssh/id_rsa') run('cp ckey.pub .ssh/id_rsa.pub') run('printf "cert-authority,principals=\"ckey\" " > authorized_keys') run('cat ckey.pub >> authorized_keys') run('printf "permitopen=\":*\" " >> authorized_keys') run('cat ckey.pub >> authorized_keys') run('cat ckey_dsa.pub >> authorized_keys') cls._server = yield from cls.start_server() sock = cls._server.sockets[0] cls._server_addr, cls._server_port = sock.getsockname()[:2] run('printf "[%s]:%s " > .ssh/known_hosts' % (cls._server_addr, cls._server_port)) run('cat skey.pub >> .ssh/known_hosts') output = run('ssh-agent -a agent 2>/dev/null') cls._agent_pid = int(output.splitlines()[2].split()[3][:-1]) os.environ['SSH_AUTH_SOCK'] = 'agent' agent = yield from asyncssh.connect_agent() yield from agent.add_keys([ckey_dsa, (ckey, ckey_cert)]) agent.close() os.environ['LOGNAME'] = 'guest' os.environ['HOME'] = '.'
def asyncSetUpClass(cls): """Set up keys, an SSH server, and an SSH agent for the tests to use""" ckey_dsa = asyncssh.generate_private_key('ssh-dss') ckey_dsa.write_private_key('ckey_dsa') ckey_dsa.write_public_key('ckey_dsa.pub') ckey = asyncssh.generate_private_key('ssh-rsa') ckey.write_private_key('ckey') ckey.write_public_key('ckey.pub') ckey_cert = ckey.generate_user_certificate(ckey, 'name') ckey_cert.write_certificate('ckey-cert.pub') skey = asyncssh.generate_private_key('ssh-rsa') skey.write_private_key('skey') skey.write_public_key('skey.pub') skey_cert = skey.generate_host_certificate(skey, 'name') skey_cert.write_certificate('skey-cert.pub') exp_cert = skey.generate_host_certificate(skey, 'name', valid_after='-2d', valid_before='-1d') skey.write_private_key('exp_skey') exp_cert.write_certificate('exp_skey-cert.pub') run('chmod 600 ckey_dsa ckey skey exp_skey') run('mkdir .ssh') run('chmod 700 .ssh') run('cp ckey_dsa .ssh/id_dsa') run('cp ckey_dsa.pub .ssh/id_dsa.pub') run('cp ckey .ssh/id_rsa') run('cp ckey.pub .ssh/id_rsa.pub') run('printf "cert-authority,principals=\"ckey\" " > authorized_keys') run('cat ckey.pub >> authorized_keys') run('printf "permitopen=\":*\" " >> authorized_keys') run('cat ckey.pub >> authorized_keys') run('cat ckey_dsa.pub >> authorized_keys') cls._server = yield from cls.start_server() sock = cls._server.sockets[0] cls._server_addr, cls._server_port = sock.getsockname()[:2] run('printf "[%s]:%s " > .ssh/known_hosts' % (cls._server_addr, cls._server_port)) run('cat skey.pub >> .ssh/known_hosts') os.environ = {'LOGNAME': 'guest', 'HOME': '.'} try: output = run('ssh-agent -a agent 2>/dev/null') except subprocess.CalledProcessError: # pragma: no cover cls._agent_pid = None else: cls._agent_pid = int(output.splitlines()[2].split()[3][:-1]) os.environ['SSH_AUTH_SOCK'] = 'agent' agent = yield from asyncssh.connect_agent() yield from agent.add_keys([ckey_dsa, (ckey, ckey_cert)]) agent.close()
def test_connection(self): """Test opening a connection to the agent""" agent = yield from asyncssh.connect_agent() self.assertIsNotNone(agent) agent.close()
def asyncSetUpClass(cls): """Set up keys, an SSH server, and an SSH agent for the tests to use""" ckey_dsa = asyncssh.generate_private_key('ssh-dss') ckey_dsa.write_private_key('ckey_dsa') ckey_dsa.write_public_key('ckey_dsa.pub') ckey = asyncssh.generate_private_key('ssh-rsa') ckey.write_private_key('ckey') ckey.write_public_key('ckey.pub') ckey_cert = ckey.generate_user_certificate(ckey, 'name') ckey_cert.write_certificate('ckey-cert.pub') skey = asyncssh.generate_private_key('ssh-rsa') skey.write_private_key('skey') skey.write_public_key('skey.pub') skey_cert = skey.generate_host_certificate(skey, 'name') skey_cert.write_certificate('skey-cert.pub') exp_cert = skey.generate_host_certificate(skey, 'name', valid_after='-2d', valid_before='-1d') skey.write_private_key('exp_skey') exp_cert.write_certificate('exp_skey-cert.pub') for f in ('ckey_dsa', 'ckey', 'skey', 'exp_skey'): os.chmod(f, 0o600) os.mkdir('.ssh', 0o700) shutil.copy('ckey_dsa', os.path.join('.ssh', 'id_dsa')) shutil.copy('ckey_dsa.pub', os.path.join('.ssh', 'id_dsa.pub')) shutil.copy('ckey', os.path.join('.ssh', 'id_rsa')) shutil.copy('ckey.pub', os.path.join('.ssh', 'id_rsa.pub')) with open('authorized_keys', 'w') as auth_keys: auth_keys.write('cert-authority,principals="ckey" ') with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) auth_keys.write('permitopen=":*" ') with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) with open('ckey_dsa.pub') as ckey_dsa_pub: shutil.copyfileobj(ckey_dsa_pub, auth_keys) cls._server = yield from cls.start_server() sock = cls._server.sockets[0] cls._server_addr = '127.0.0.1' cls._server_port = sock.getsockname()[1] with open(os.path.join('.ssh', 'known_hosts'), 'w') as known_hosts: known_hosts.write('[%s]:%s ' % (cls._server_addr, cls._server_port)) with open('skey.pub') as skey_pub: shutil.copyfileobj(skey_pub, known_hosts) os.environ['LOGNAME'] = 'guest' os.environ['HOME'] = '.' if 'DISPLAY' in os.environ: # pragma: no cover del os.environ['DISPLAY'] if 'SSH_ASKPASS' in os.environ: # pragma: no cover del os.environ['SSH_ASKPASS'] if 'SSH_AUTH_SOCK' in os.environ: # pragma: no cover del os.environ['SSH_AUTH_SOCK'] if 'XAUTHORITY' in os.environ: # pragma: no cover del os.environ['XAUTHORITY'] try: output = run('ssh-agent -a agent 2>/dev/null') except subprocess.CalledProcessError: # pragma: no cover cls._agent_pid = None else: cls._agent_pid = int(output.splitlines()[2].split()[3][:-1]) os.environ['SSH_AUTH_SOCK'] = 'agent' agent = yield from asyncssh.connect_agent() yield from agent.add_keys([ckey_dsa, (ckey, ckey_cert)]) agent.close()
def _begin_session(self, stdin, stdout, stderr): """Begin processing a new session""" # pylint: disable=too-many-statements action = stdin.channel.get_command() or stdin.channel.get_subsystem() if not action: action = 'echo' if action == 'echo': yield from echo(stdin, stdout, stderr) elif action == 'conn_close': yield from stdin.read(1) stdout.write('\n') self._conn.close() elif action == 'close': yield from stdin.read(1) stdout.write('\n') elif action == 'agent': agent = yield from asyncssh.connect_agent(self._conn) if agent: stdout.write(str(len((yield from agent.get_keys()))) + '\n') agent.close() else: stdout.channel.exit(1) elif action == 'rejected_agent': chan = SSHAgentChannel(self._conn, asyncio.get_event_loop(), None, 1, 32768) try: yield from chan.open(SSHUNIXStreamSession) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_session': chan = SSHClientChannel(self._conn, asyncio.get_event_loop(), None, 1, 32768) try: yield from chan.create(SSHClientStreamSession, None, None, {}, None, None, None, False) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_tcpip_direct': chan = self._conn.create_tcp_channel() try: yield from chan.connect(SSHTCPStreamSession, '', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'unknown_tcpip_listener': chan = self._conn.create_tcp_channel() try: yield from chan.accept(SSHTCPStreamSession, 'xxx', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'invalid_tcpip_listener': chan = self._conn.create_tcp_channel() try: yield from chan.accept(SSHTCPStreamSession, b'\xff', 0, '', 0) except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'rejected_unix_direct': chan = self._conn.create_unix_channel() try: yield from chan.connect(SSHUNIXStreamSession, '') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'unknown_unix_listener': chan = self._conn.create_unix_channel() try: yield from chan.accept(SSHUNIXStreamSession, 'xxx') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'invalid_unix_listener': chan = self._conn.create_unix_channel() try: yield from chan.accept(SSHUNIXStreamSession, b'\xff') except asyncssh.ChannelOpenError: stdout.channel.exit(1) elif action == 'late_auth_banner': try: self._conn.send_auth_banner('auth banner') except OSError: stdin.channel.exit(1) elif action == 'invalid_open_confirm': stdin.channel.send_packet(MSG_CHANNEL_OPEN_CONFIRMATION, UInt32(0), UInt32(0), UInt32(0)) elif action == 'invalid_open_failure': stdin.channel.send_packet(MSG_CHANNEL_OPEN_FAILURE, UInt32(0), String(''), String('')) elif action == 'env': value = stdin.channel.get_environment().get('TEST', '') stdout.write(value + '\n') elif action == 'term': chan = stdin.channel info = str((chan.get_terminal_type(), chan.get_terminal_size(), chan.get_terminal_mode(asyncssh.PTY_OP_OSPEED))) stdout.write(info + '\n') elif action == 'xon_xoff': stdin.channel.set_xon_xoff(True) elif action == 'no_xon_xoff': stdin.channel.set_xon_xoff(False) elif action == 'signals': try: yield from stdin.readline() except asyncssh.BreakReceived as exc: stdin.channel.exit_with_signal('ABRT', False, str(exc.msec)) except asyncssh.SignalReceived as exc: stdin.channel.exit_with_signal('ABRT', False, exc.signal) except asyncssh.TerminalSizeChanged as exc: size = (exc.width, exc.height, exc.pixwidth, exc.pixheight) stdin.channel.exit_with_signal('ABRT', False, str(size)) elif action == 'exit_status': stdin.channel.exit(1) elif action == 'closed_status': stdin.channel.close() stdin.channel.exit(1) elif action == 'exit_signal': stdin.channel.exit_with_signal('ABRT', False, 'exit_signal') elif action == 'closed_signal': stdin.channel.close() stdin.channel.exit_with_signal('ABRT', False, 'closed_signal') elif action == 'invalid_exit_signal': stdin.channel.exit_with_signal('invalid') elif action == 'invalid_exit_lang': stdin.channel.exit_with_signal('ABRT', False, '', 'invalid') elif action == 'window_after_close': stdin.channel.send_packet(MSG_CHANNEL_CLOSE) stdin.channel.send_packet(MSG_CHANNEL_WINDOW_ADJUST, UInt32(0)) elif action == 'empty_data': stdin.channel.send_packet(MSG_CHANNEL_DATA, String('')) elif action == 'partial_unicode': data = '\xff\xff'.encode('utf-8') stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[:3])) stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[3:])) elif action == 'partial_unicode_at_eof': data = '\xff\xff'.encode('utf-8') stdin.channel.send_packet(MSG_CHANNEL_DATA, String(data[:3])) elif action == 'unicode_error': stdin.channel.send_packet(MSG_CHANNEL_DATA, String(b'\xff')) elif action == 'data_past_window': stdin.channel.send_packet(MSG_CHANNEL_DATA, String(2*1025*1024*'\0')) elif action == 'data_after_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdout.write('xxx') elif action == 'data_after_close': yield from asyncio.sleep(0.1) stdout.write('xxx') elif action == 'ext_data_after_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdin.channel.write_stderr('xxx') elif action == 'invalid_datatype': stdin.channel.send_packet(MSG_CHANNEL_EXTENDED_DATA, UInt32(255), String('')) elif action == 'double_eof': stdin.channel.send_packet(MSG_CHANNEL_EOF) stdin.channel.write_eof() elif action == 'double_close': yield from asyncio.sleep(0.1) stdout.write('xxx') stdin.channel.send_packet(MSG_CHANNEL_CLOSE) elif action == 'request_after_close': stdin.channel.send_packet(MSG_CHANNEL_CLOSE) stdin.channel.exit(1) elif action == 'unexpected_auth': self._conn.send_packet(Byte(MSG_USERAUTH_REQUEST), String('guest'), String('ssh-connection'), String('none')) elif action == 'invalid_response': stdin.channel.send_packet(MSG_CHANNEL_SUCCESS) else: stdin.channel.exit(255) stdin.channel.close() yield from stdin.channel.wait_closed()
async def asyncSetUpClass(cls): """Set up keys, an SSH server, and an SSH agent for the tests to use""" # pylint: disable=too-many-statements ckey = asyncssh.generate_private_key('ssh-rsa') ckey.write_private_key('ckey') ckey.write_private_key('ckey_encrypted', passphrase='passphrase') ckey.write_public_key('ckey.pub') ckey_ecdsa = asyncssh.generate_private_key('ecdsa-sha2-nistp256') ckey_ecdsa.write_private_key('ckey_ecdsa') ckey_ecdsa.write_public_key('ckey_ecdsa.pub') ckey_cert = ckey.generate_user_certificate(ckey, 'name', principals=['ckey']) ckey_cert.write_certificate('ckey-cert.pub') skey = asyncssh.generate_private_key('ssh-rsa') skey.write_private_key('skey') skey.write_public_key('skey.pub') skey_ecdsa = asyncssh.generate_private_key('ecdsa-sha2-nistp256') skey_ecdsa.write_private_key('skey_ecdsa') skey_ecdsa.write_public_key('skey_ecdsa.pub') skey_cert = skey.generate_host_certificate( skey, 'name', principals=['127.0.0.1', 'localhost']) skey_cert.write_certificate('skey-cert.pub') exp_cert = skey.generate_host_certificate(skey, 'name', valid_after='-2d', valid_before='-1d') skey.write_private_key('exp_skey') exp_cert.write_certificate('exp_skey-cert.pub') if x509_available: # pragma: no branch ckey_x509_self = ckey_ecdsa.generate_x509_user_certificate( ckey_ecdsa, 'OU=name', principals=['ckey']) ckey_ecdsa.write_private_key('ckey_x509_self') ckey_x509_self.append_certificate('ckey_x509_self', 'pem') ckey_x509_self.write_certificate('ckey_x509_self.pem', 'pem') ckey_x509_self.write_certificate('ckey_x509_self.pub') skey_x509_self = skey_ecdsa.generate_x509_host_certificate( skey_ecdsa, 'OU=name', principals=['127.0.0.1']) skey_ecdsa.write_private_key('skey_x509_self') skey_x509_self.append_certificate('skey_x509_self', 'pem') skey_x509_self.write_certificate('skey_x509_self.pem', 'pem') root_ca_key = asyncssh.generate_private_key('ssh-rsa') root_ca_key.write_private_key('root_ca_key') root_ca_cert = root_ca_key.generate_x509_ca_certificate( root_ca_key, 'OU=RootCA', ca_path_len=1) root_ca_cert.write_certificate('root_ca_cert.pem', 'pem') root_ca_cert.write_certificate('root_ca_cert.pub') int_ca_key = asyncssh.generate_private_key('ssh-rsa') int_ca_key.write_private_key('int_ca_key') int_ca_cert = root_ca_key.generate_x509_ca_certificate( int_ca_key, 'OU=IntCA', 'OU=RootCA', ca_path_len=0) int_ca_cert.write_certificate('int_ca_cert.pem', 'pem') ckey_x509_chain = int_ca_key.generate_x509_user_certificate( ckey, 'OU=name', 'OU=IntCA', principals=['ckey']) ckey.write_private_key('ckey_x509_chain') ckey_x509_chain.append_certificate('ckey_x509_chain', 'pem') int_ca_cert.append_certificate('ckey_x509_chain', 'pem') ckey_x509_chain.write_certificate('ckey_x509_partial.pem', 'pem') skey_x509_chain = int_ca_key.generate_x509_host_certificate( skey, 'OU=name', 'OU=IntCA', principals=['127.0.0.1']) skey.write_private_key('skey_x509_chain') skey_x509_chain.append_certificate('skey_x509_chain', 'pem') int_ca_cert.append_certificate('skey_x509_chain', 'pem') root_hash = root_ca_cert.x509_cert.subject_hash os.mkdir('cert_path') shutil.copy('root_ca_cert.pem', os.path.join('cert_path', root_hash + '.0')) # Intentional hash mismatch shutil.copy('int_ca_cert.pem', os.path.join('cert_path', root_hash + '.1')) for f in ('ckey', 'ckey_ecdsa', 'skey', 'exp_skey', 'skey_ecdsa'): os.chmod(f, 0o600) os.mkdir('.ssh', 0o700) os.mkdir(os.path.join('.ssh', 'crt'), 0o700) shutil.copy('ckey_ecdsa', os.path.join('.ssh', 'id_ecdsa')) shutil.copy('ckey_ecdsa.pub', os.path.join('.ssh', 'id_ecdsa.pub')) shutil.copy('ckey_encrypted', os.path.join('.ssh', 'id_rsa')) shutil.copy('ckey.pub', os.path.join('.ssh', 'id_rsa.pub')) shutil.copy('ckey-cert.pub', os.path.join('.ssh', 'id_rsa-cert.pub')) with open('authorized_keys', 'w') as auth_keys: with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) with open('ckey_ecdsa.pub') as ckey_ecdsa_pub: shutil.copyfileobj(ckey_ecdsa_pub, auth_keys) auth_keys.write('cert-authority,principals="ckey",' 'permitopen=:* ') with open('ckey.pub') as ckey_pub: shutil.copyfileobj(ckey_pub, auth_keys) if x509_available: # pragma: no branch with open('authorized_keys_x509', 'w') as auth_keys_x509: with open('ckey_x509_self.pub') as ckey_self_pub: shutil.copyfileobj(ckey_self_pub, auth_keys_x509) auth_keys_x509.write('cert-authority,principals="ckey" ') with open('root_ca_cert.pub') as root_pub: shutil.copyfileobj(root_pub, auth_keys_x509) shutil.copy('skey_x509_self.pem', os.path.join('.ssh', 'ca-bundle.crt')) os.environ['LOGNAME'] = 'guest' os.environ['HOME'] = '.' os.environ['USERPROFILE'] = '.' cls._server = await cls.start_server() sock = cls._server.sockets[0] cls._server_addr = '127.0.0.1' cls._server_port = sock.getsockname()[1] host = '[%s]:%d,localhost ' % (cls._server_addr, cls._server_port) with open('known_hosts', 'w') as known_hosts: known_hosts.write(host) with open('skey.pub') as skey_pub: shutil.copyfileobj(skey_pub, known_hosts) known_hosts.write('@cert-authority * ') with open('skey.pub') as skey_pub: shutil.copyfileobj(skey_pub, known_hosts) shutil.copy('known_hosts', os.path.join('.ssh', 'known_hosts')) if 'DISPLAY' in os.environ: # pragma: no cover del os.environ['DISPLAY'] if 'SSH_ASKPASS' in os.environ: # pragma: no cover del os.environ['SSH_ASKPASS'] if 'SSH_AUTH_SOCK' in os.environ: # pragma: no cover del os.environ['SSH_AUTH_SOCK'] if 'XAUTHORITY' in os.environ: # pragma: no cover del os.environ['XAUTHORITY'] try: output = run('ssh-agent -a agent 2>/dev/null') except subprocess.CalledProcessError: # pragma: no cover cls._agent_pid = None else: cls._agent_pid = int(output.splitlines()[2].split()[3][:-1]) os.environ['SSH_AUTH_SOCK'] = 'agent' async with asyncssh.connect_agent() as agent: await agent.add_keys([ckey_ecdsa, (ckey, ckey_cert)]) with open('ssh-keysign', 'wb'): pass