mirror of
				https://github.com/jtesta/ssh-audit.git
				synced 2025-10-30 04:55:26 +01:00 
			
		
		
		
	Split ssh_audit.py into separate files (#47).
This commit is contained in:
		| @@ -1,18 +1,22 @@ | ||||
| import pytest | ||||
| 
 | ||||
| from ssh_audit.algorithm import Algorithm | ||||
| from ssh_audit.timeframe import Timeframe | ||||
| 
 | ||||
| 
 | ||||
| # pylint: disable=attribute-defined-outside-init | ||||
| class TestSSHAlgorithm: | ||||
| class TestAlgorithm: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.algorithm = Algorithm | ||||
|         self.timeframe = Timeframe | ||||
| 
 | ||||
|     def _tf(self, v, s=None): | ||||
|         return self.ssh.Algorithm.Timeframe().update(v, s) | ||||
|         return self.timeframe().update(v, s) | ||||
| 
 | ||||
|     def test_get_ssh_version(self): | ||||
|         def ver(v): | ||||
|             return self.ssh.Algorithm.get_ssh_version(v) | ||||
|             return self.algorithm.get_ssh_version(v) | ||||
| 
 | ||||
|         assert ver('7.5') == ('OpenSSH', '7.5', False) | ||||
|         assert ver('7.5C') == ('OpenSSH', '7.5', True) | ||||
| @@ -22,7 +26,7 @@ class TestSSHAlgorithm: | ||||
| 
 | ||||
|     def test_get_since_text(self): | ||||
|         def gst(v): | ||||
|             return self.ssh.Algorithm.get_since_text(v) | ||||
|             return self.algorithm.get_since_text(v) | ||||
| 
 | ||||
|         assert gst(['7.5']) == 'available since OpenSSH 7.5' | ||||
|         assert gst(['7.5C']) == 'available since OpenSSH 7.5 (client only)' | ||||
| @@ -1,4 +1,5 @@ | ||||
| import pytest | ||||
| from ssh_audit.ssh_audit import process_commandline | ||||
|  | ||||
|  | ||||
| # pylint: disable=attribute-defined-outside-init | ||||
| @@ -7,6 +8,7 @@ class TestAuditConf: | ||||
|     def init(self, ssh_audit): | ||||
|         self.AuditConf = ssh_audit.AuditConf | ||||
|         self.usage = ssh_audit.usage | ||||
|         self.process_commandline = process_commandline | ||||
|  | ||||
|     @staticmethod | ||||
|     def _test_conf(conf, **kwargs): | ||||
| @@ -123,9 +125,9 @@ class TestAuditConf: | ||||
|                 conf.level = level | ||||
|             excinfo.match(r'.*invalid level.*') | ||||
|  | ||||
|     def test_audit_conf_cmdline(self): | ||||
|     def test_audit_conf_process_commandline(self): | ||||
|         # pylint: disable=too-many-statements | ||||
|         c = lambda x: self.AuditConf.from_cmdline(x.split(), self.usage)  # noqa | ||||
|         c = lambda x: self.process_commandline(x.split(), self.usage)  # noqa | ||||
|         with pytest.raises(SystemExit): | ||||
|             conf = c('') | ||||
|         with pytest.raises(SystemExit): | ||||
|   | ||||
| @@ -1,14 +1,16 @@ | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.banner import Banner | ||||
|  | ||||
|  | ||||
| # pylint: disable=line-too-long,attribute-defined-outside-init | ||||
| class TestBanner: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.banner = Banner | ||||
|  | ||||
|     def test_simple_banners(self): | ||||
|         banner = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         banner = lambda x: self.banner.parse(x)  # noqa | ||||
|         b = banner('SSH-2.0-OpenSSH_7.3') | ||||
|         assert b.protocol == (2, 0) | ||||
|         assert b.software == 'OpenSSH_7.3' | ||||
| @@ -26,12 +28,12 @@ class TestBanner: | ||||
|         assert str(b) == 'SSH-1.5-Cisco-1.25' | ||||
|  | ||||
|     def test_invalid_banners(self): | ||||
|         b = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         b = lambda x: self.banner.parse(x)  # noqa | ||||
|         assert b('Something') is None | ||||
|         assert b('SSH-XXX-OpenSSH_7.3') is None | ||||
|  | ||||
|     def test_banners_with_spaces(self): | ||||
|         b = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         b = lambda x: self.banner.parse(x)  # noqa | ||||
|         s = 'SSH-2.0-OpenSSH_4.3p2' | ||||
|         assert str(b('SSH-2.0-OpenSSH_4.3p2    ')) == s | ||||
|         assert str(b('SSH-2.0-    OpenSSH_4.3p2')) == s | ||||
| @@ -42,7 +44,7 @@ class TestBanner: | ||||
|         assert str(b('SSH-2.0-  OpenSSH_4.3p2 Debian-9etch3   on   i686-pc-linux-gnu  ')) == s | ||||
|  | ||||
|     def test_banners_without_software(self): | ||||
|         b = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         b = lambda x: self.banner.parse(x)  # noqa | ||||
|         assert b('SSH-2.0').protocol == (2, 0) | ||||
|         assert b('SSH-2.0').software is None | ||||
|         assert b('SSH-2.0').comments is None | ||||
| @@ -53,13 +55,13 @@ class TestBanner: | ||||
|         assert str(b('SSH-2.0-')) == 'SSH-2.0-' | ||||
|  | ||||
|     def test_banners_with_comments(self): | ||||
|         b = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         b = lambda x: self.banner.parse(x)  # noqa | ||||
|         assert repr(b('SSH-2.0-OpenSSH_7.2p2 Ubuntu-1')) == '<Banner(protocol=2.0, software=OpenSSH_7.2p2, comments=Ubuntu-1)>' | ||||
|         assert repr(b('SSH-1.99-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3')) == '<Banner(protocol=1.99, software=OpenSSH_3.4p1, comments=Debian 1:3.4p1-1.woody.3)>' | ||||
|         assert repr(b('SSH-1.5-1.3.7 F-SECURE SSH')) == '<Banner(protocol=1.5, software=1.3.7, comments=F-SECURE SSH)>' | ||||
|  | ||||
|     def test_banners_with_multiple_protocols(self): | ||||
|         b = lambda x: self.ssh.Banner.parse(x)  # noqa | ||||
|         b = lambda x: self.banner.parse(x)  # noqa | ||||
|         assert str(b('SSH-1.99-SSH-1.99-OpenSSH_3.6.1p2')) == 'SSH-1.99-OpenSSH_3.6.1p2' | ||||
|         assert str(b('SSH-2.0-SSH-2.0-OpenSSH_4.3p2 Debian-9')) == 'SSH-2.0-OpenSSH_4.3p2 Debian-9' | ||||
|         assert str(b('SSH-1.99-SSH-2.0-dropbear_0.5')) == 'SSH-1.99-dropbear_0.5' | ||||
|   | ||||
| @@ -1,13 +1,16 @@ | ||||
| import re | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.readbuf import ReadBuf | ||||
| from ssh_audit.writebuf import WriteBuf | ||||
|  | ||||
|  | ||||
| # pylint: disable=attribute-defined-outside-init,bad-whitespace | ||||
| class TestBuffer: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.rbuf = ssh_audit.ReadBuf | ||||
|         self.wbuf = ssh_audit.WriteBuf | ||||
|         self.rbuf = ReadBuf | ||||
|         self.wbuf = WriteBuf | ||||
|         self.utf8rchar = b'\xef\xbf\xbd' | ||||
|  | ||||
|     @classmethod | ||||
|   | ||||
| @@ -1,17 +1,19 @@ | ||||
| import os | ||||
|  | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.ssh2_kex import SSH2_Kex | ||||
| from ssh_audit.ssh2_kexparty import SSH2_KexParty | ||||
|  | ||||
|  | ||||
| @pytest.fixture | ||||
| def kex(ssh_audit): | ||||
|     kex_algs, key_algs = [], [] | ||||
|     enc, mac, compression, languages = [], [], ['none'], [] | ||||
|     cli = ssh_audit.SSH2.KexParty(enc, mac, compression, languages) | ||||
|     cli = SSH2_KexParty(enc, mac, compression, languages) | ||||
|     enc, mac, compression, languages = [], [], ['none'], [] | ||||
|     srv = ssh_audit.SSH2.KexParty(enc, mac, compression, languages) | ||||
|     srv = SSH2_KexParty(enc, mac, compression, languages) | ||||
|     cookie = os.urandom(16) | ||||
|     kex = ssh_audit.SSH2.Kex(cookie, kex_algs, key_algs, cli, srv, 0) | ||||
|     kex = SSH2_Kex(cookie, kex_algs, key_algs, cli, srv, 0) | ||||
|     return kex | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2,13 +2,17 @@ import hashlib | ||||
| import pytest | ||||
| from datetime import date | ||||
|  | ||||
| from ssh_audit.policy import Policy | ||||
| from ssh_audit.ssh2_kex import SSH2_Kex | ||||
| from ssh_audit.writebuf import WriteBuf | ||||
|  | ||||
|  | ||||
| class TestPolicy: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.Policy = ssh_audit.Policy | ||||
|         self.wbuf = ssh_audit.WriteBuf | ||||
|         self.ssh2 = ssh_audit.SSH2 | ||||
|         self.Policy = Policy | ||||
|         self.wbuf = WriteBuf | ||||
|         self.ssh2_kex = SSH2_Kex | ||||
|  | ||||
|  | ||||
|     def _get_kex(self): | ||||
| @@ -28,7 +32,7 @@ class TestPolicy: | ||||
|         w.write_list(['']) | ||||
|         w.write_byte(False) | ||||
|         w.write_int(0) | ||||
|         return self.ssh2.Kex.parse(w.write_flush()) | ||||
|         return self.ssh2_kex.parse(w.write_flush()) | ||||
|  | ||||
|  | ||||
|     def test_policy_basic(self): | ||||
|   | ||||
| @@ -8,7 +8,7 @@ class TestResolve: | ||||
|     def init(self, ssh_audit): | ||||
|         self.AuditConf = ssh_audit.AuditConf | ||||
|         self.audit = ssh_audit.audit | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.ssh_socket = ssh_audit.SSH_Socket | ||||
|  | ||||
|     def _conf(self): | ||||
|         conf = self.AuditConf('localhost', 22) | ||||
| @@ -19,7 +19,7 @@ class TestResolve: | ||||
|     def test_resolve_error(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         vsocket.gsock.addrinfodata['localhost#22'] = socket.gaierror(8, 'hostname nor servname provided, or not known') | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         conf = self._conf() | ||||
|         output_spy.begin() | ||||
|         with pytest.raises(SystemExit): | ||||
| @@ -31,7 +31,7 @@ class TestResolve: | ||||
|     def test_resolve_hostname_without_records(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         vsocket.gsock.addrinfodata['localhost#22'] = [] | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         conf = self._conf() | ||||
|         output_spy.begin() | ||||
|         r = list(s._resolve(conf.ipvo)) | ||||
| @@ -40,13 +40,13 @@ class TestResolve: | ||||
|     def test_resolve_ipv4(self, virtual_socket): | ||||
|         conf = self._conf() | ||||
|         conf.ipv4 = True | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         r = list(s._resolve(conf.ipvo)) | ||||
|         assert len(r) == 1 | ||||
|         assert r[0] == (socket.AF_INET, ('127.0.0.1', 22)) | ||||
|  | ||||
|     def test_resolve_ipv6(self, virtual_socket): | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         conf = self._conf() | ||||
|         conf.ipv6 = True | ||||
|         r = list(s._resolve(conf.ipvo)) | ||||
| @@ -54,7 +54,7 @@ class TestResolve: | ||||
|         assert r[0] == (socket.AF_INET6, ('::1', 22)) | ||||
|  | ||||
|     def test_resolve_ipv46_both(self, virtual_socket): | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         conf = self._conf() | ||||
|         r = list(s._resolve(conf.ipvo)) | ||||
|         assert len(r) == 2 | ||||
| @@ -62,7 +62,7 @@ class TestResolve: | ||||
|         assert r[1] == (socket.AF_INET6, ('::1', 22)) | ||||
|  | ||||
|     def test_resolve_ipv46_order(self, virtual_socket): | ||||
|         s = self.ssh.Socket('localhost', 22) | ||||
|         s = self.ssh_socket('localhost', 22) | ||||
|         conf = self._conf() | ||||
|         conf.ipv4 = True | ||||
|         conf.ipv6 = True | ||||
|   | ||||
| @@ -1,28 +1,30 @@ | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.ssh_socket import SSH_Socket | ||||
|  | ||||
|  | ||||
| # pylint: disable=attribute-defined-outside-init | ||||
| class TestSocket: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.ssh_socket = SSH_Socket | ||||
|  | ||||
|     def test_invalid_host(self, virtual_socket): | ||||
|         with pytest.raises(ValueError): | ||||
|             self.ssh.Socket(None, 22) | ||||
|             self.ssh_socket(None, 22) | ||||
|  | ||||
|     def test_invalid_port(self, virtual_socket): | ||||
|         with pytest.raises(ValueError): | ||||
|             self.ssh.Socket('localhost', 'abc') | ||||
|             self.ssh_socket('localhost', 'abc') | ||||
|         with pytest.raises(ValueError): | ||||
|             self.ssh.Socket('localhost', -1) | ||||
|             self.ssh_socket('localhost', -1) | ||||
|         with pytest.raises(ValueError): | ||||
|             self.ssh.Socket('localhost', 0) | ||||
|             self.ssh_socket('localhost', 0) | ||||
|         with pytest.raises(ValueError): | ||||
|             self.ssh.Socket('localhost', 65536) | ||||
|             self.ssh_socket('localhost', 65536) | ||||
|  | ||||
|     def test_not_connected_socket(self, virtual_socket): | ||||
|         sock = self.ssh.Socket('localhost', 22) | ||||
|         sock = self.ssh_socket('localhost', 22) | ||||
|         banner, header, err = sock.get_banner() | ||||
|         assert banner is None | ||||
|         assert len(header) == 0 | ||||
|   | ||||
| @@ -1,21 +1,25 @@ | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.banner import Banner | ||||
| from ssh_audit.software import Software | ||||
|  | ||||
|  | ||||
| # pylint: disable=line-too-long,attribute-defined-outside-init | ||||
| class TestSoftware: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.software = Software | ||||
|         self.banner = Banner | ||||
|  | ||||
|     def test_unknown_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         assert ps('SSH-1.5') is None | ||||
|         assert ps('SSH-1.99-AlfaMegaServer') is None | ||||
|         assert ps('SSH-2.0-BetaMegaServer 0.0.1') is None | ||||
|  | ||||
|     def test_openssh_software(self): | ||||
|         # pylint: disable=too-many-statements | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-2.0-OpenSSH_7.3') | ||||
|         assert s.vendor is None | ||||
| @@ -102,7 +106,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(product=OpenSSH, version=5.9, patch=CASPUR)>' | ||||
|  | ||||
|     def test_dropbear_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-2.0-dropbear_2016.74') | ||||
|         assert s.vendor is None | ||||
| @@ -153,7 +157,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(product=Dropbear SSH, version=2014.66, patch=agbn_1)>' | ||||
|  | ||||
|     def test_libssh_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-2.0-libssh-0.2') | ||||
|         assert s.vendor is None | ||||
| @@ -179,7 +183,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(product=libssh, version=0.7.4)>' | ||||
|  | ||||
|     def test_romsshell_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-2.0-RomSShell_5.40') | ||||
|         assert s.vendor == 'Allegro Software' | ||||
| @@ -194,7 +198,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(vendor=Allegro Software, product=RomSShell, version=5.40)>' | ||||
|  | ||||
|     def test_hp_ilo_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-2.0-mpSSH_0.2.1') | ||||
|         assert s.vendor == 'HP' | ||||
| @@ -209,7 +213,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(vendor=HP, product=iLO (Integrated Lights-Out) sshd, version=0.2.1)>' | ||||
|  | ||||
|     def test_cisco_software(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # common | ||||
|         s = ps('SSH-1.5-Cisco-1.25') | ||||
|         assert s.vendor == 'Cisco' | ||||
| @@ -224,7 +228,7 @@ class TestSoftware: | ||||
|         assert repr(s) == '<Software(vendor=Cisco, product=IOS/PIX sshd, version=1.25)>' | ||||
|  | ||||
|     def test_software_os(self): | ||||
|         ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x))  # noqa | ||||
|         ps = lambda x: self.software.parse(self.banner.parse(x))  # noqa | ||||
|         # unknown | ||||
|         s = ps('SSH-2.0-OpenSSH_3.7.1 MegaOperatingSystem 123') | ||||
|         assert s.os is None | ||||
|   | ||||
| @@ -1,17 +1,28 @@ | ||||
| import struct | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.auditconf import AuditConf | ||||
| from ssh_audit.fingerprint import Fingerprint | ||||
| from ssh_audit.protocol import Protocol | ||||
| from ssh_audit.readbuf import ReadBuf | ||||
| from ssh_audit.ssh1 import SSH1 | ||||
| from ssh_audit.ssh1_publickeymessage import SSH1_PublicKeyMessage | ||||
| from ssh_audit.ssh_audit import audit | ||||
| from ssh_audit.writebuf import WriteBuf | ||||
|  | ||||
|  | ||||
| # pylint: disable=line-too-long,attribute-defined-outside-init | ||||
| class TestSSH1: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.ssh1 = ssh_audit.SSH1 | ||||
|         self.rbuf = ssh_audit.ReadBuf | ||||
|         self.wbuf = ssh_audit.WriteBuf | ||||
|         self.audit = ssh_audit.audit | ||||
|         self.AuditConf = ssh_audit.AuditConf | ||||
|         self.protocol = Protocol | ||||
|         self.ssh1 = SSH1 | ||||
|         self.PublicKeyMessage = SSH1_PublicKeyMessage | ||||
|         self.rbuf = ReadBuf | ||||
|         self.wbuf = WriteBuf | ||||
|         self.audit = audit | ||||
|         self.AuditConf = AuditConf | ||||
|         self.fingerprint = Fingerprint | ||||
|  | ||||
|     def _conf(self): | ||||
|         conf = self.AuditConf('localhost', 22) | ||||
| @@ -59,7 +70,7 @@ class TestSSH1: | ||||
|         b, e, m = self._host_key() | ||||
|         fpd = self.wbuf._create_mpint(m, False) | ||||
|         fpd += self.wbuf._create_mpint(e, False) | ||||
|         fp = self.ssh.Fingerprint(fpd) | ||||
|         fp = self.fingerprint(fpd) | ||||
|         assert b == 2048 | ||||
|         assert fp.md5 == 'MD5:9d:26:f8:39:fc:20:9d:9b:ca:cc:4a:0f:e1:93:f5:96' | ||||
|         assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs' | ||||
| @@ -83,7 +94,7 @@ class TestSSH1: | ||||
|         assert pkm.supported_ciphers == ['3des', 'blowfish'] | ||||
|         assert pkm.supported_authentications_mask == 36 | ||||
|         assert pkm.supported_authentications == ['rsa', 'tis'] | ||||
|         fp = self.ssh.Fingerprint(pkm.host_key_fingerprint_data) | ||||
|         fp = self.fingerprint(pkm.host_key_fingerprint_data) | ||||
|         assert fp.md5 == 'MD5:9d:26:f8:39:fc:20:9d:9b:ca:cc:4a:0f:e1:93:f5:96' | ||||
|         assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs' | ||||
|  | ||||
| @@ -91,32 +102,32 @@ class TestSSH1: | ||||
|         cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff' | ||||
|         pflags, cmask, amask = 2, 72, 36 | ||||
|         skey, hkey = self._server_key(), self._host_key() | ||||
|         pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask) | ||||
|         pkm = self.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask) | ||||
|         self._assert_pkm_fields(pkm, skey, hkey) | ||||
|         for skey2 in ([], [0], [0, 1], [0, 1, 2, 3]): | ||||
|             with pytest.raises(ValueError): | ||||
|                 pkm = self.ssh1.PublicKeyMessage(cookie, skey2, hkey, pflags, cmask, amask) | ||||
|                 pkm = self.PublicKeyMessage(cookie, skey2, hkey, pflags, cmask, amask) | ||||
|         for hkey2 in ([], [0], [0, 1], [0, 1, 2, 3]): | ||||
|             with pytest.raises(ValueError): | ||||
|                 print(hkey2) | ||||
|                 pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask) | ||||
|                 pkm = self.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask) | ||||
|  | ||||
|     def test_pkm_read(self): | ||||
|         pkm = self.ssh1.PublicKeyMessage.parse(self._pkm_payload()) | ||||
|         pkm = self.PublicKeyMessage.parse(self._pkm_payload()) | ||||
|         self._assert_pkm_fields(pkm, self._server_key(), self._host_key()) | ||||
|  | ||||
|     def test_pkm_payload(self): | ||||
|         cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff' | ||||
|         skey, hkey = self._server_key(), self._host_key() | ||||
|         pflags, cmask, amask = 2, 72, 36 | ||||
|         pkm1 = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask) | ||||
|         pkm2 = self.ssh1.PublicKeyMessage.parse(self._pkm_payload()) | ||||
|         pkm1 = self.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask) | ||||
|         pkm2 = self.PublicKeyMessage.parse(self._pkm_payload()) | ||||
|         assert pkm1.payload == pkm2.payload | ||||
|  | ||||
|     def test_ssh1_server_simple(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         w = self.wbuf() | ||||
|         w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY) | ||||
|         w.write_byte(self.protocol.SMSG_PUBLIC_KEY) | ||||
|         w.write(self._pkm_payload()) | ||||
|         vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n') | ||||
|         vsocket.rdata.append(self._create_ssh1_packet(w.write_flush())) | ||||
| @@ -128,7 +139,7 @@ class TestSSH1: | ||||
|     def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         w = self.wbuf() | ||||
|         w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1) | ||||
|         w.write_byte(self.protocol.SMSG_PUBLIC_KEY + 1) | ||||
|         w.write(self._pkm_payload()) | ||||
|         vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n') | ||||
|         vsocket.rdata.append(self._create_ssh1_packet(w.write_flush())) | ||||
| @@ -142,7 +153,7 @@ class TestSSH1: | ||||
|     def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         w = self.wbuf() | ||||
|         w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1) | ||||
|         w.write_byte(self.protocol.SMSG_PUBLIC_KEY + 1) | ||||
|         w.write(self._pkm_payload()) | ||||
|         vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n') | ||||
|         vsocket.rdata.append(self._create_ssh1_packet(w.write_flush(), False)) | ||||
|   | ||||
| @@ -2,17 +2,26 @@ import os | ||||
| import struct | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.auditconf import AuditConf | ||||
| from ssh_audit.protocol import Protocol | ||||
| from ssh_audit.readbuf import ReadBuf | ||||
| from ssh_audit.ssh2_kex import SSH2_Kex | ||||
| from ssh_audit.ssh2_kexparty import SSH2_KexParty | ||||
| from ssh_audit.ssh_audit import audit | ||||
| from ssh_audit.writebuf import WriteBuf | ||||
|  | ||||
|  | ||||
| # pylint: disable=line-too-long,attribute-defined-outside-init | ||||
| class TestSSH2: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.ssh2 = ssh_audit.SSH2 | ||||
|         self.rbuf = ssh_audit.ReadBuf | ||||
|         self.wbuf = ssh_audit.WriteBuf | ||||
|         self.audit = ssh_audit.audit | ||||
|         self.AuditConf = ssh_audit.AuditConf | ||||
|         self.protocol = Protocol | ||||
|         self.ssh2_kex = SSH2_Kex | ||||
|         self.ssh2_kexparty = SSH2_KexParty | ||||
|         self.rbuf = ReadBuf | ||||
|         self.wbuf = WriteBuf | ||||
|         self.audit = audit | ||||
|         self.AuditConf = AuditConf | ||||
|  | ||||
|     def _conf(self): | ||||
|         conf = self.AuditConf('localhost', 22) | ||||
| @@ -51,7 +60,7 @@ class TestSSH2: | ||||
|         return w.write_flush() | ||||
|  | ||||
|     def test_kex_read(self): | ||||
|         kex = self.ssh2.Kex.parse(self._kex_payload()) | ||||
|         kex = self.ssh2_kex.parse(self._kex_payload()) | ||||
|         assert kex is not None | ||||
|         assert kex.cookie == b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff' | ||||
|         assert kex.kex_algorithms == ['bogus_kex1', 'bogus_kex2'] | ||||
| @@ -72,12 +81,12 @@ class TestSSH2: | ||||
|     def _get_empty_kex(self, cookie=None): | ||||
|         kex_algs, key_algs = [], [] | ||||
|         enc, mac, compression, languages = [], [], ['none'], [] | ||||
|         cli = self.ssh2.KexParty(enc, mac, compression, languages) | ||||
|         cli = self.ssh2_kexparty(enc, mac, compression, languages) | ||||
|         enc, mac, compression, languages = [], [], ['none'], [] | ||||
|         srv = self.ssh2.KexParty(enc, mac, compression, languages) | ||||
|         srv = self.ssh2_kexparty(enc, mac, compression, languages) | ||||
|         if cookie is None: | ||||
|             cookie = os.urandom(16) | ||||
|         kex = self.ssh2.Kex(cookie, kex_algs, key_algs, cli, srv, 0) | ||||
|         kex = self.ssh2_kex(cookie, kex_algs, key_algs, cli, srv, 0) | ||||
|         return kex | ||||
|  | ||||
|     def _get_kex_variat1(self): | ||||
| @@ -121,13 +130,13 @@ class TestSSH2: | ||||
|  | ||||
|     def test_key_payload(self): | ||||
|         kex1 = self._get_kex_variat1() | ||||
|         kex2 = self.ssh2.Kex.parse(self._kex_payload()) | ||||
|         kex2 = self.ssh2_kex.parse(self._kex_payload()) | ||||
|         assert kex1.payload == kex2.payload | ||||
|  | ||||
|     def test_ssh2_server_simple(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         w = self.wbuf() | ||||
|         w.write_byte(self.ssh.Protocol.MSG_KEXINIT) | ||||
|         w.write_byte(self.protocol.MSG_KEXINIT) | ||||
|         w.write(self._kex_payload()) | ||||
|         vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n') | ||||
|         vsocket.rdata.append(self._create_ssh2_packet(w.write_flush())) | ||||
| @@ -139,7 +148,7 @@ class TestSSH2: | ||||
|     def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket): | ||||
|         vsocket = virtual_socket | ||||
|         w = self.wbuf() | ||||
|         w.write_byte(self.ssh.Protocol.MSG_KEXINIT + 1) | ||||
|         w.write_byte(self.protocol.MSG_KEXINIT + 1) | ||||
|         vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n') | ||||
|         vsocket.rdata.append(self._create_ssh2_packet(w.write_flush())) | ||||
|         output_spy.begin() | ||||
|   | ||||
| @@ -1,23 +1,27 @@ | ||||
| import pytest | ||||
|  | ||||
| from ssh_audit.banner import Banner | ||||
| from ssh_audit.software import Software | ||||
|  | ||||
|  | ||||
| # pylint: disable=attribute-defined-outside-init | ||||
| class TestVersionCompare: | ||||
|     @pytest.fixture(autouse=True) | ||||
|     def init(self, ssh_audit): | ||||
|         self.ssh = ssh_audit.SSH | ||||
|         self.software = Software | ||||
|         self.banner = Banner | ||||
|  | ||||
|     def get_dropbear_software(self, v): | ||||
|         b = self.ssh.Banner.parse('SSH-2.0-dropbear_{}'.format(v)) | ||||
|         return self.ssh.Software.parse(b) | ||||
|         b = self.banner.parse('SSH-2.0-dropbear_{}'.format(v)) | ||||
|         return self.software.parse(b) | ||||
|  | ||||
|     def get_openssh_software(self, v): | ||||
|         b = self.ssh.Banner.parse('SSH-2.0-OpenSSH_{}'.format(v)) | ||||
|         return self.ssh.Software.parse(b) | ||||
|         b = self.banner.parse('SSH-2.0-OpenSSH_{}'.format(v)) | ||||
|         return self.software.parse(b) | ||||
|  | ||||
|     def get_libssh_software(self, v): | ||||
|         b = self.ssh.Banner.parse('SSH-2.0-libssh-{}'.format(v)) | ||||
|         return self.ssh.Software.parse(b) | ||||
|         b = self.banner.parse('SSH-2.0-libssh-{}'.format(v)) | ||||
|         return self.software.parse(b) | ||||
|  | ||||
|     def test_dropbear_compare_version_pre_years(self): | ||||
|         s = self.get_dropbear_software('0.44') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Joe Testa
					Joe Testa