mirror of
https://github.com/jtesta/ssh-audit.git
synced 2024-11-22 10:31:41 +01:00
Converted tab indents to spaces.
This commit is contained in:
parent
246a41d46f
commit
22ac41bfb8
5893
ssh-audit.py
5893
ssh-audit.py
File diff suppressed because it is too large
Load Diff
214
test/conftest.py
214
test/conftest.py
@ -8,149 +8,149 @@ import pytest
|
|||||||
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
if sys.version_info[0] == 2:
|
||||||
import StringIO # pylint: disable=import-error
|
import StringIO # pylint: disable=import-error
|
||||||
StringIO = StringIO.StringIO
|
StringIO = StringIO.StringIO
|
||||||
else:
|
else:
|
||||||
StringIO = io.StringIO
|
StringIO = io.StringIO
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='module')
|
@pytest.fixture(scope='module')
|
||||||
def ssh_audit():
|
def ssh_audit():
|
||||||
__rdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
__rdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
||||||
sys.path.append(os.path.abspath(__rdir))
|
sys.path.append(os.path.abspath(__rdir))
|
||||||
return __import__('ssh-audit')
|
return __import__('ssh-audit')
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class _OutputSpy(list):
|
class _OutputSpy(list):
|
||||||
def begin(self):
|
def begin(self):
|
||||||
self.__out = StringIO()
|
self.__out = StringIO()
|
||||||
self.__old_stdout = sys.stdout
|
self.__old_stdout = sys.stdout
|
||||||
sys.stdout = self.__out
|
sys.stdout = self.__out
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
lines = self.__out.getvalue().splitlines()
|
lines = self.__out.getvalue().splitlines()
|
||||||
sys.stdout = self.__old_stdout
|
sys.stdout = self.__old_stdout
|
||||||
self.__out = None
|
self.__out = None
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='module')
|
@pytest.fixture(scope='module')
|
||||||
def output_spy():
|
def output_spy():
|
||||||
return _OutputSpy()
|
return _OutputSpy()
|
||||||
|
|
||||||
|
|
||||||
class _VirtualGlobalSocket(object):
|
class _VirtualGlobalSocket(object):
|
||||||
def __init__(self, vsocket):
|
def __init__(self, vsocket):
|
||||||
self.vsocket = vsocket
|
self.vsocket = vsocket
|
||||||
self.addrinfodata = {}
|
self.addrinfodata = {}
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def create_connection(self, address, timeout=0, source_address=None):
|
def create_connection(self, address, timeout=0, source_address=None):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
return self.vsocket._connect(address, True)
|
return self.vsocket._connect(address, True)
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def socket(self,
|
def socket(self,
|
||||||
family=socket.AF_INET,
|
family=socket.AF_INET,
|
||||||
socktype=socket.SOCK_STREAM,
|
socktype=socket.SOCK_STREAM,
|
||||||
proto=0,
|
proto=0,
|
||||||
fileno=None):
|
fileno=None):
|
||||||
return self.vsocket
|
return self.vsocket
|
||||||
|
|
||||||
def getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0):
|
def getaddrinfo(self, host, port, family=0, socktype=0, proto=0, flags=0):
|
||||||
key = '{0}#{1}'.format(host, port)
|
key = '{0}#{1}'.format(host, port)
|
||||||
if key in self.addrinfodata:
|
if key in self.addrinfodata:
|
||||||
data = self.addrinfodata[key]
|
data = self.addrinfodata[key]
|
||||||
if isinstance(data, Exception):
|
if isinstance(data, Exception):
|
||||||
raise data
|
raise data
|
||||||
return data
|
return data
|
||||||
if host == 'localhost':
|
if host == 'localhost':
|
||||||
r = []
|
r = []
|
||||||
if family in (0, socket.AF_INET):
|
if family in (0, socket.AF_INET):
|
||||||
r.append((socket.AF_INET, 1, 6, '', ('127.0.0.1', port)))
|
r.append((socket.AF_INET, 1, 6, '', ('127.0.0.1', port)))
|
||||||
if family in (0, socket.AF_INET6):
|
if family in (0, socket.AF_INET6):
|
||||||
r.append((socket.AF_INET6, 1, 6, '', ('::1', port)))
|
r.append((socket.AF_INET6, 1, 6, '', ('::1', port)))
|
||||||
return r
|
return r
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
class _VirtualSocket(object):
|
class _VirtualSocket(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sock_address = ('127.0.0.1', 0)
|
self.sock_address = ('127.0.0.1', 0)
|
||||||
self.peer_address = None
|
self.peer_address = None
|
||||||
self._connected = False
|
self._connected = False
|
||||||
self.timeout = -1.0
|
self.timeout = -1.0
|
||||||
self.rdata = []
|
self.rdata = []
|
||||||
self.sdata = []
|
self.sdata = []
|
||||||
self.errors = {}
|
self.errors = {}
|
||||||
self.gsock = _VirtualGlobalSocket(self)
|
self.gsock = _VirtualGlobalSocket(self)
|
||||||
|
|
||||||
def _check_err(self, method):
|
def _check_err(self, method):
|
||||||
method_error = self.errors.get(method)
|
method_error = self.errors.get(method)
|
||||||
if method_error:
|
if method_error:
|
||||||
raise method_error
|
raise method_error
|
||||||
|
|
||||||
def connect(self, address):
|
def connect(self, address):
|
||||||
return self._connect(address, False)
|
return self._connect(address, False)
|
||||||
|
|
||||||
def _connect(self, address, ret=True):
|
def _connect(self, address, ret=True):
|
||||||
self.peer_address = address
|
self.peer_address = address
|
||||||
self._connected = True
|
self._connected = True
|
||||||
self._check_err('connect')
|
self._check_err('connect')
|
||||||
return self if ret else None
|
return self if ret else None
|
||||||
|
|
||||||
def settimeout(self, timeout):
|
def settimeout(self, timeout):
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
def gettimeout(self):
|
def gettimeout(self):
|
||||||
return self.timeout
|
return self.timeout
|
||||||
|
|
||||||
def getpeername(self):
|
def getpeername(self):
|
||||||
if self.peer_address is None or not self._connected:
|
if self.peer_address is None or not self._connected:
|
||||||
raise socket.error(57, 'Socket is not connected')
|
raise socket.error(57, 'Socket is not connected')
|
||||||
return self.peer_address
|
return self.peer_address
|
||||||
|
|
||||||
def getsockname(self):
|
def getsockname(self):
|
||||||
return self.sock_address
|
return self.sock_address
|
||||||
|
|
||||||
def bind(self, address):
|
def bind(self, address):
|
||||||
self.sock_address = address
|
self.sock_address = address
|
||||||
|
|
||||||
def listen(self, backlog):
|
def listen(self, backlog):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
conn = _VirtualSocket()
|
conn = _VirtualSocket()
|
||||||
conn.sock_address = self.sock_address
|
conn.sock_address = self.sock_address
|
||||||
conn.peer_address = ('127.0.0.1', 0)
|
conn.peer_address = ('127.0.0.1', 0)
|
||||||
conn._connected = True
|
conn._connected = True
|
||||||
return conn, conn.peer_address
|
return conn, conn.peer_address
|
||||||
|
|
||||||
def recv(self, bufsize, flags=0):
|
def recv(self, bufsize, flags=0):
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
if not self._connected:
|
if not self._connected:
|
||||||
raise socket.error(54, 'Connection reset by peer')
|
raise socket.error(54, 'Connection reset by peer')
|
||||||
if not len(self.rdata) > 0:
|
if not len(self.rdata) > 0:
|
||||||
return b''
|
return b''
|
||||||
data = self.rdata.pop(0)
|
data = self.rdata.pop(0)
|
||||||
if isinstance(data, Exception):
|
if isinstance(data, Exception):
|
||||||
raise data
|
raise data
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
if self.peer_address is None or not self._connected:
|
if self.peer_address is None or not self._connected:
|
||||||
raise socket.error(32, 'Broken pipe')
|
raise socket.error(32, 'Broken pipe')
|
||||||
self._check_err('send')
|
self._check_err('send')
|
||||||
self.sdata.append(data)
|
self.sdata.append(data)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def virtual_socket(monkeypatch):
|
def virtual_socket(monkeypatch):
|
||||||
vsocket = _VirtualSocket()
|
vsocket = _VirtualSocket()
|
||||||
gsock = vsocket.gsock
|
gsock = vsocket.gsock
|
||||||
monkeypatch.setattr(socket, 'create_connection', gsock.create_connection)
|
monkeypatch.setattr(socket, 'create_connection', gsock.create_connection)
|
||||||
monkeypatch.setattr(socket, 'socket', gsock.socket)
|
monkeypatch.setattr(socket, 'socket', gsock.socket)
|
||||||
monkeypatch.setattr(socket, 'getaddrinfo', gsock.getaddrinfo)
|
monkeypatch.setattr(socket, 'getaddrinfo', gsock.getaddrinfo)
|
||||||
return vsocket
|
return vsocket
|
||||||
|
@ -5,196 +5,196 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestAuditConf(object):
|
class TestAuditConf(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
self.usage = ssh_audit.usage
|
self.usage = ssh_audit.usage
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _test_conf(conf, **kwargs):
|
def _test_conf(conf, **kwargs):
|
||||||
options = {
|
options = {
|
||||||
'host': None,
|
'host': None,
|
||||||
'port': 22,
|
'port': 22,
|
||||||
'ssh1': True,
|
'ssh1': True,
|
||||||
'ssh2': True,
|
'ssh2': True,
|
||||||
'batch': False,
|
'batch': False,
|
||||||
'colors': True,
|
'colors': True,
|
||||||
'verbose': False,
|
'verbose': False,
|
||||||
'level': 'info',
|
'level': 'info',
|
||||||
'ipv4': True,
|
'ipv4': True,
|
||||||
'ipv6': True,
|
'ipv6': True,
|
||||||
'ipvo': ()
|
'ipvo': ()
|
||||||
}
|
}
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
options[k] = v
|
options[k] = v
|
||||||
assert conf.host == options['host']
|
assert conf.host == options['host']
|
||||||
assert conf.port == options['port']
|
assert conf.port == options['port']
|
||||||
assert conf.ssh1 is options['ssh1']
|
assert conf.ssh1 is options['ssh1']
|
||||||
assert conf.ssh2 is options['ssh2']
|
assert conf.ssh2 is options['ssh2']
|
||||||
assert conf.batch is options['batch']
|
assert conf.batch is options['batch']
|
||||||
assert conf.colors is options['colors']
|
assert conf.colors is options['colors']
|
||||||
assert conf.verbose is options['verbose']
|
assert conf.verbose is options['verbose']
|
||||||
assert conf.level == options['level']
|
assert conf.level == options['level']
|
||||||
assert conf.ipv4 == options['ipv4']
|
assert conf.ipv4 == options['ipv4']
|
||||||
assert conf.ipv6 == options['ipv6']
|
assert conf.ipv6 == options['ipv6']
|
||||||
assert conf.ipvo == options['ipvo']
|
assert conf.ipvo == options['ipvo']
|
||||||
|
|
||||||
def test_audit_conf_defaults(self):
|
def test_audit_conf_defaults(self):
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
self._test_conf(conf)
|
self._test_conf(conf)
|
||||||
|
|
||||||
def test_audit_conf_booleans(self):
|
def test_audit_conf_booleans(self):
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
for p in ['ssh1', 'ssh2', 'batch', 'colors', 'verbose']:
|
for p in ['ssh1', 'ssh2', 'batch', 'colors', 'verbose']:
|
||||||
for v in [True, 1]:
|
for v in [True, 1]:
|
||||||
setattr(conf, p, v)
|
setattr(conf, p, v)
|
||||||
assert getattr(conf, p) is True
|
assert getattr(conf, p) is True
|
||||||
for v in [False, 0]:
|
for v in [False, 0]:
|
||||||
setattr(conf, p, v)
|
setattr(conf, p, v)
|
||||||
assert getattr(conf, p) is False
|
assert getattr(conf, p) is False
|
||||||
|
|
||||||
def test_audit_conf_port(self):
|
def test_audit_conf_port(self):
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
for port in [22, 2222]:
|
for port in [22, 2222]:
|
||||||
conf.port = port
|
conf.port = port
|
||||||
assert conf.port == port
|
assert conf.port == port
|
||||||
for port in [-1, 0, 65536, 99999]:
|
for port in [-1, 0, 65536, 99999]:
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
conf.port = port
|
conf.port = port
|
||||||
excinfo.match(r'.*invalid port.*')
|
excinfo.match(r'.*invalid port.*')
|
||||||
|
|
||||||
def test_audit_conf_ipvo(self):
|
def test_audit_conf_ipvo(self):
|
||||||
# ipv4-only
|
# ipv4-only
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
assert conf.ipv4 is True
|
assert conf.ipv4 is True
|
||||||
assert conf.ipv6 is False
|
assert conf.ipv6 is False
|
||||||
assert conf.ipvo == (4,)
|
assert conf.ipvo == (4,)
|
||||||
# ipv6-only
|
# ipv6-only
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
assert conf.ipv4 is False
|
assert conf.ipv4 is False
|
||||||
assert conf.ipv6 is True
|
assert conf.ipv6 is True
|
||||||
assert conf.ipvo == (6,)
|
assert conf.ipvo == (6,)
|
||||||
# ipv4-only (by removing ipv6)
|
# ipv4-only (by removing ipv6)
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv6 = False
|
conf.ipv6 = False
|
||||||
assert conf.ipv4 is True
|
assert conf.ipv4 is True
|
||||||
assert conf.ipv6 is False
|
assert conf.ipv6 is False
|
||||||
assert conf.ipvo == (4, )
|
assert conf.ipvo == (4, )
|
||||||
# ipv6-only (by removing ipv4)
|
# ipv6-only (by removing ipv4)
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv4 = False
|
conf.ipv4 = False
|
||||||
assert conf.ipv4 is False
|
assert conf.ipv4 is False
|
||||||
assert conf.ipv6 is True
|
assert conf.ipv6 is True
|
||||||
assert conf.ipvo == (6, )
|
assert conf.ipvo == (6, )
|
||||||
# ipv4-preferred
|
# ipv4-preferred
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
assert conf.ipv4 is True
|
assert conf.ipv4 is True
|
||||||
assert conf.ipv6 is True
|
assert conf.ipv6 is True
|
||||||
assert conf.ipvo == (4, 6)
|
assert conf.ipvo == (4, 6)
|
||||||
# ipv6-preferred
|
# ipv6-preferred
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
assert conf.ipv4 is True
|
assert conf.ipv4 is True
|
||||||
assert conf.ipv6 is True
|
assert conf.ipv6 is True
|
||||||
assert conf.ipvo == (6, 4)
|
assert conf.ipvo == (6, 4)
|
||||||
# ipvo empty
|
# ipvo empty
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipvo = ()
|
conf.ipvo = ()
|
||||||
assert conf.ipv4 is True
|
assert conf.ipv4 is True
|
||||||
assert conf.ipv6 is True
|
assert conf.ipv6 is True
|
||||||
assert conf.ipvo == ()
|
assert conf.ipvo == ()
|
||||||
# ipvo validation
|
# ipvo validation
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
conf.ipvo = (1, 2, 3, 4, 5, 6)
|
conf.ipvo = (1, 2, 3, 4, 5, 6)
|
||||||
assert conf.ipvo == (4, 6)
|
assert conf.ipvo == (4, 6)
|
||||||
conf.ipvo = (4, 4, 4, 6, 6)
|
conf.ipvo = (4, 4, 4, 6, 6)
|
||||||
assert conf.ipvo == (4, 6)
|
assert conf.ipvo == (4, 6)
|
||||||
|
|
||||||
def test_audit_conf_level(self):
|
def test_audit_conf_level(self):
|
||||||
conf = self.AuditConf()
|
conf = self.AuditConf()
|
||||||
for level in ['info', 'warn', 'fail']:
|
for level in ['info', 'warn', 'fail']:
|
||||||
conf.level = level
|
conf.level = level
|
||||||
assert conf.level == level
|
assert conf.level == level
|
||||||
for level in ['head', 'good', 'unknown', None]:
|
for level in ['head', 'good', 'unknown', None]:
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
conf.level = level
|
conf.level = level
|
||||||
excinfo.match(r'.*invalid level.*')
|
excinfo.match(r'.*invalid level.*')
|
||||||
|
|
||||||
def test_audit_conf_cmdline(self):
|
def test_audit_conf_cmdline(self):
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
c = lambda x: self.AuditConf.from_cmdline(x.split(), self.usage) # noqa
|
c = lambda x: self.AuditConf.from_cmdline(x.split(), self.usage) # noqa
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('')
|
conf = c('')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-x')
|
conf = c('-x')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-h')
|
conf = c('-h')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('--help')
|
conf = c('--help')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c(':')
|
conf = c(':')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c(':22')
|
conf = c(':22')
|
||||||
conf = c('localhost')
|
conf = c('localhost')
|
||||||
self._test_conf(conf, host='localhost')
|
self._test_conf(conf, host='localhost')
|
||||||
conf = c('github.com')
|
conf = c('github.com')
|
||||||
self._test_conf(conf, host='github.com')
|
self._test_conf(conf, host='github.com')
|
||||||
conf = c('localhost:2222')
|
conf = c('localhost:2222')
|
||||||
self._test_conf(conf, host='localhost', port=2222)
|
self._test_conf(conf, host='localhost', port=2222)
|
||||||
conf = c('-p 2222 localhost')
|
conf = c('-p 2222 localhost')
|
||||||
self._test_conf(conf, host='localhost', port=2222)
|
self._test_conf(conf, host='localhost', port=2222)
|
||||||
conf = c('2001:4860:4860::8888')
|
conf = c('2001:4860:4860::8888')
|
||||||
self._test_conf(conf, host='2001:4860:4860::8888')
|
self._test_conf(conf, host='2001:4860:4860::8888')
|
||||||
conf = c('[2001:4860:4860::8888]:22')
|
conf = c('[2001:4860:4860::8888]:22')
|
||||||
self._test_conf(conf, host='2001:4860:4860::8888')
|
self._test_conf(conf, host='2001:4860:4860::8888')
|
||||||
conf = c('[2001:4860:4860::8888]:2222')
|
conf = c('[2001:4860:4860::8888]:2222')
|
||||||
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
|
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
|
||||||
conf = c('-p 2222 2001:4860:4860::8888')
|
conf = c('-p 2222 2001:4860:4860::8888')
|
||||||
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
|
self._test_conf(conf, host='2001:4860:4860::8888', port=2222)
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('localhost:')
|
conf = c('localhost:')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('localhost:abc')
|
conf = c('localhost:abc')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-p abc localhost')
|
conf = c('-p abc localhost')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('localhost:-22')
|
conf = c('localhost:-22')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-p -22 localhost')
|
conf = c('-p -22 localhost')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('localhost:99999')
|
conf = c('localhost:99999')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-p 99999 localhost')
|
conf = c('-p 99999 localhost')
|
||||||
conf = c('-1 localhost')
|
conf = c('-1 localhost')
|
||||||
self._test_conf(conf, host='localhost', ssh1=True, ssh2=False)
|
self._test_conf(conf, host='localhost', ssh1=True, ssh2=False)
|
||||||
conf = c('-2 localhost')
|
conf = c('-2 localhost')
|
||||||
self._test_conf(conf, host='localhost', ssh1=False, ssh2=True)
|
self._test_conf(conf, host='localhost', ssh1=False, ssh2=True)
|
||||||
conf = c('-12 localhost')
|
conf = c('-12 localhost')
|
||||||
self._test_conf(conf, host='localhost', ssh1=True, ssh2=True)
|
self._test_conf(conf, host='localhost', ssh1=True, ssh2=True)
|
||||||
conf = c('-4 localhost')
|
conf = c('-4 localhost')
|
||||||
self._test_conf(conf, host='localhost', ipv4=True, ipv6=False, ipvo=(4,))
|
self._test_conf(conf, host='localhost', ipv4=True, ipv6=False, ipvo=(4,))
|
||||||
conf = c('-6 localhost')
|
conf = c('-6 localhost')
|
||||||
self._test_conf(conf, host='localhost', ipv4=False, ipv6=True, ipvo=(6,))
|
self._test_conf(conf, host='localhost', ipv4=False, ipv6=True, ipvo=(6,))
|
||||||
conf = c('-46 localhost')
|
conf = c('-46 localhost')
|
||||||
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(4, 6))
|
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(4, 6))
|
||||||
conf = c('-64 localhost')
|
conf = c('-64 localhost')
|
||||||
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(6, 4))
|
self._test_conf(conf, host='localhost', ipv4=True, ipv6=True, ipvo=(6, 4))
|
||||||
conf = c('-b localhost')
|
conf = c('-b localhost')
|
||||||
self._test_conf(conf, host='localhost', batch=True, verbose=True)
|
self._test_conf(conf, host='localhost', batch=True, verbose=True)
|
||||||
conf = c('-n localhost')
|
conf = c('-n localhost')
|
||||||
self._test_conf(conf, host='localhost', colors=False)
|
self._test_conf(conf, host='localhost', colors=False)
|
||||||
conf = c('-v localhost')
|
conf = c('-v localhost')
|
||||||
self._test_conf(conf, host='localhost', verbose=True)
|
self._test_conf(conf, host='localhost', verbose=True)
|
||||||
conf = c('-l info localhost')
|
conf = c('-l info localhost')
|
||||||
self._test_conf(conf, host='localhost', level='info')
|
self._test_conf(conf, host='localhost', level='info')
|
||||||
conf = c('-l warn localhost')
|
conf = c('-l warn localhost')
|
||||||
self._test_conf(conf, host='localhost', level='warn')
|
self._test_conf(conf, host='localhost', level='warn')
|
||||||
conf = c('-l fail localhost')
|
conf = c('-l fail localhost')
|
||||||
self._test_conf(conf, host='localhost', level='fail')
|
self._test_conf(conf, host='localhost', level='fail')
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
conf = c('-l something localhost')
|
conf = c('-l something localhost')
|
||||||
|
@ -5,65 +5,65 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=line-too-long,attribute-defined-outside-init
|
# pylint: disable=line-too-long,attribute-defined-outside-init
|
||||||
class TestBanner(object):
|
class TestBanner(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def test_simple_banners(self):
|
def test_simple_banners(self):
|
||||||
banner = lambda x: self.ssh.Banner.parse(x) # noqa
|
banner = lambda x: self.ssh.Banner.parse(x) # noqa
|
||||||
b = banner('SSH-2.0-OpenSSH_7.3')
|
b = banner('SSH-2.0-OpenSSH_7.3')
|
||||||
assert b.protocol == (2, 0)
|
assert b.protocol == (2, 0)
|
||||||
assert b.software == 'OpenSSH_7.3'
|
assert b.software == 'OpenSSH_7.3'
|
||||||
assert b.comments is None
|
assert b.comments is None
|
||||||
assert str(b) == 'SSH-2.0-OpenSSH_7.3'
|
assert str(b) == 'SSH-2.0-OpenSSH_7.3'
|
||||||
b = banner('SSH-1.99-Sun_SSH_1.1.3')
|
b = banner('SSH-1.99-Sun_SSH_1.1.3')
|
||||||
assert b.protocol == (1, 99)
|
assert b.protocol == (1, 99)
|
||||||
assert b.software == 'Sun_SSH_1.1.3'
|
assert b.software == 'Sun_SSH_1.1.3'
|
||||||
assert b.comments is None
|
assert b.comments is None
|
||||||
assert str(b) == 'SSH-1.99-Sun_SSH_1.1.3'
|
assert str(b) == 'SSH-1.99-Sun_SSH_1.1.3'
|
||||||
b = banner('SSH-1.5-Cisco-1.25')
|
b = banner('SSH-1.5-Cisco-1.25')
|
||||||
assert b.protocol == (1, 5)
|
assert b.protocol == (1, 5)
|
||||||
assert b.software == 'Cisco-1.25'
|
assert b.software == 'Cisco-1.25'
|
||||||
assert b.comments is None
|
assert b.comments is None
|
||||||
assert str(b) == 'SSH-1.5-Cisco-1.25'
|
assert str(b) == 'SSH-1.5-Cisco-1.25'
|
||||||
|
|
||||||
def test_invalid_banners(self):
|
def test_invalid_banners(self):
|
||||||
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
||||||
assert b('Something') is None
|
assert b('Something') is None
|
||||||
assert b('SSH-XXX-OpenSSH_7.3') is None
|
assert b('SSH-XXX-OpenSSH_7.3') is None
|
||||||
|
|
||||||
def test_banners_with_spaces(self):
|
def test_banners_with_spaces(self):
|
||||||
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
||||||
s = 'SSH-2.0-OpenSSH_4.3p2'
|
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
|
||||||
assert str(b('SSH-2.0- OpenSSH_4.3p2')) == s
|
assert str(b('SSH-2.0- OpenSSH_4.3p2')) == s
|
||||||
assert str(b('SSH-2.0- OpenSSH_4.3p2 ')) == s
|
assert str(b('SSH-2.0- OpenSSH_4.3p2 ')) == s
|
||||||
s = 'SSH-2.0-OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu'
|
s = 'SSH-2.0-OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu'
|
||||||
assert str(b('SSH-2.0- OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu')) == s
|
assert str(b('SSH-2.0- OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu')) == s
|
||||||
assert str(b('SSH-2.0-OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu ')) == s
|
assert str(b('SSH-2.0-OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu ')) == s
|
||||||
assert str(b('SSH-2.0- OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu ')) == s
|
assert str(b('SSH-2.0- OpenSSH_4.3p2 Debian-9etch3 on i686-pc-linux-gnu ')) == s
|
||||||
|
|
||||||
def test_banners_without_software(self):
|
def test_banners_without_software(self):
|
||||||
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
||||||
assert b('SSH-2.0').protocol == (2, 0)
|
assert b('SSH-2.0').protocol == (2, 0)
|
||||||
assert b('SSH-2.0').software is None
|
assert b('SSH-2.0').software is None
|
||||||
assert b('SSH-2.0').comments is None
|
assert b('SSH-2.0').comments is None
|
||||||
assert str(b('SSH-2.0')) == 'SSH-2.0'
|
assert str(b('SSH-2.0')) == 'SSH-2.0'
|
||||||
assert b('SSH-2.0-').protocol == (2, 0)
|
assert b('SSH-2.0-').protocol == (2, 0)
|
||||||
assert b('SSH-2.0-').software == ''
|
assert b('SSH-2.0-').software == ''
|
||||||
assert b('SSH-2.0-').comments is None
|
assert b('SSH-2.0-').comments is None
|
||||||
assert str(b('SSH-2.0-')) == 'SSH-2.0-'
|
assert str(b('SSH-2.0-')) == 'SSH-2.0-'
|
||||||
|
|
||||||
def test_banners_with_comments(self):
|
def test_banners_with_comments(self):
|
||||||
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
b = lambda x: self.ssh.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-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.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)>'
|
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):
|
def test_banners_with_multiple_protocols(self):
|
||||||
b = lambda x: self.ssh.Banner.parse(x) # noqa
|
b = lambda x: self.ssh.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-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-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'
|
assert str(b('SSH-1.99-SSH-2.0-dropbear_0.5')) == 'SSH-1.99-dropbear_0.5'
|
||||||
assert str(b('SSH-2.0-SSH-1.99-OpenSSH_4.2p1 SSH Secure Shell (non-commercial)')) == 'SSH-1.99-OpenSSH_4.2p1 SSH Secure Shell (non-commercial)'
|
assert str(b('SSH-2.0-SSH-1.99-OpenSSH_4.2p1 SSH Secure Shell (non-commercial)')) == 'SSH-1.99-OpenSSH_4.2p1 SSH Secure Shell (non-commercial)'
|
||||||
assert str(b('SSH-1.99-SSH-1.99-SSH-1.99-OpenSSH_3.9p1')) == 'SSH-1.99-OpenSSH_3.9p1'
|
assert str(b('SSH-1.99-SSH-1.99-SSH-1.99-OpenSSH_3.9p1')) == 'SSH-1.99-OpenSSH_3.9p1'
|
||||||
|
@ -6,128 +6,128 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init,bad-whitespace
|
# pylint: disable=attribute-defined-outside-init,bad-whitespace
|
||||||
class TestBuffer(object):
|
class TestBuffer(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.rbuf = ssh_audit.ReadBuf
|
self.rbuf = ssh_audit.ReadBuf
|
||||||
self.wbuf = ssh_audit.WriteBuf
|
self.wbuf = ssh_audit.WriteBuf
|
||||||
self.utf8rchar = b'\xef\xbf\xbd'
|
self.utf8rchar = b'\xef\xbf\xbd'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _b(cls, v):
|
def _b(cls, v):
|
||||||
v = re.sub(r'\s', '', v)
|
v = re.sub(r'\s', '', v)
|
||||||
data = [int(v[i * 2:i * 2 + 2], 16) for i in range(len(v) // 2)]
|
data = [int(v[i * 2:i * 2 + 2], 16) for i in range(len(v) // 2)]
|
||||||
return bytes(bytearray(data))
|
return bytes(bytearray(data))
|
||||||
|
|
||||||
def test_unread(self):
|
def test_unread(self):
|
||||||
w = self.wbuf().write_byte(1).write_int(2).write_flush()
|
w = self.wbuf().write_byte(1).write_int(2).write_flush()
|
||||||
r = self.rbuf(w)
|
r = self.rbuf(w)
|
||||||
assert r.unread_len == 5
|
assert r.unread_len == 5
|
||||||
r.read_byte()
|
r.read_byte()
|
||||||
assert r.unread_len == 4
|
assert r.unread_len == 4
|
||||||
r.read_int()
|
r.read_int()
|
||||||
assert r.unread_len == 0
|
assert r.unread_len == 0
|
||||||
|
|
||||||
def test_byte(self):
|
def test_byte(self):
|
||||||
w = lambda x: self.wbuf().write_byte(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_byte(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_byte() # noqa
|
r = lambda x: self.rbuf(x).read_byte() # noqa
|
||||||
tc = [(0x00, '00'),
|
tc = [(0x00, '00'),
|
||||||
(0x01, '01'),
|
(0x01, '01'),
|
||||||
(0x10, '10'),
|
(0x10, '10'),
|
||||||
(0xff, 'ff')]
|
(0xff, 'ff')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert w(p[0]) == self._b(p[1])
|
assert w(p[0]) == self._b(p[1])
|
||||||
assert r(self._b(p[1])) == p[0]
|
assert r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_bool(self):
|
def test_bool(self):
|
||||||
w = lambda x: self.wbuf().write_bool(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_bool(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_bool() # noqa
|
r = lambda x: self.rbuf(x).read_bool() # noqa
|
||||||
tc = [(True, '01'),
|
tc = [(True, '01'),
|
||||||
(False, '00')]
|
(False, '00')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert w(p[0]) == self._b(p[1])
|
assert w(p[0]) == self._b(p[1])
|
||||||
assert r(self._b(p[1])) == p[0]
|
assert r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_int(self):
|
def test_int(self):
|
||||||
w = lambda x: self.wbuf().write_int(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_int(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_int() # noqa
|
r = lambda x: self.rbuf(x).read_int() # noqa
|
||||||
tc = [(0x00, '00 00 00 00'),
|
tc = [(0x00, '00 00 00 00'),
|
||||||
(0x01, '00 00 00 01'),
|
(0x01, '00 00 00 01'),
|
||||||
(0xabcd, '00 00 ab cd'),
|
(0xabcd, '00 00 ab cd'),
|
||||||
(0xffffffff, 'ff ff ff ff')]
|
(0xffffffff, 'ff ff ff ff')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert w(p[0]) == self._b(p[1])
|
assert w(p[0]) == self._b(p[1])
|
||||||
assert r(self._b(p[1])) == p[0]
|
assert r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_string(self):
|
def test_string(self):
|
||||||
w = lambda x: self.wbuf().write_string(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_string(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_string() # noqa
|
r = lambda x: self.rbuf(x).read_string() # noqa
|
||||||
tc = [(u'abc1', '00 00 00 04 61 62 63 31'),
|
tc = [(u'abc1', '00 00 00 04 61 62 63 31'),
|
||||||
(b'abc2', '00 00 00 04 61 62 63 32')]
|
(b'abc2', '00 00 00 04 61 62 63 32')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
v = p[0]
|
v = p[0]
|
||||||
assert w(v) == self._b(p[1])
|
assert w(v) == self._b(p[1])
|
||||||
if not isinstance(v, bytes):
|
if not isinstance(v, bytes):
|
||||||
v = bytes(bytearray(v, 'utf-8'))
|
v = bytes(bytearray(v, 'utf-8'))
|
||||||
assert r(self._b(p[1])) == v
|
assert r(self._b(p[1])) == v
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
w = lambda x: self.wbuf().write_list(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_list(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_list() # noqa
|
r = lambda x: self.rbuf(x).read_list() # noqa
|
||||||
tc = [(['d', 'ef', 'ault'], '00 00 00 09 64 2c 65 66 2c 61 75 6c 74')]
|
tc = [(['d', 'ef', 'ault'], '00 00 00 09 64 2c 65 66 2c 61 75 6c 74')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert w(p[0]) == self._b(p[1])
|
assert w(p[0]) == self._b(p[1])
|
||||||
assert r(self._b(p[1])) == p[0]
|
assert r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_list_nonutf8(self):
|
def test_list_nonutf8(self):
|
||||||
r = lambda x: self.rbuf(x).read_list() # noqa
|
r = lambda x: self.rbuf(x).read_list() # noqa
|
||||||
src = self._b('00 00 00 04 de ad be ef')
|
src = self._b('00 00 00 04 de ad be ef')
|
||||||
dst = [(b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')]
|
dst = [(b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')]
|
||||||
assert r(src) == dst
|
assert r(src) == dst
|
||||||
|
|
||||||
def test_line(self):
|
def test_line(self):
|
||||||
w = lambda x: self.wbuf().write_line(x).write_flush() # noqa
|
w = lambda x: self.wbuf().write_line(x).write_flush() # noqa
|
||||||
r = lambda x: self.rbuf(x).read_line() # noqa
|
r = lambda x: self.rbuf(x).read_line() # noqa
|
||||||
tc = [(u'example line', '65 78 61 6d 70 6c 65 20 6c 69 6e 65 0d 0a')]
|
tc = [(u'example line', '65 78 61 6d 70 6c 65 20 6c 69 6e 65 0d 0a')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert w(p[0]) == self._b(p[1])
|
assert w(p[0]) == self._b(p[1])
|
||||||
assert r(self._b(p[1])) == p[0]
|
assert r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_line_nonutf8(self):
|
def test_line_nonutf8(self):
|
||||||
r = lambda x: self.rbuf(x).read_line() # noqa
|
r = lambda x: self.rbuf(x).read_line() # noqa
|
||||||
src = self._b('de ad be af')
|
src = self._b('de ad be af')
|
||||||
dst = (b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')
|
dst = (b'\xde\xad' + self.utf8rchar + self.utf8rchar).decode('utf-8')
|
||||||
assert r(src) == dst
|
assert r(src) == dst
|
||||||
|
|
||||||
def test_bitlen(self):
|
def test_bitlen(self):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
class Py26Int(int):
|
class Py26Int(int):
|
||||||
def bit_length(self):
|
def bit_length(self):
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
assert self.wbuf._bitlength(42) == 6
|
assert self.wbuf._bitlength(42) == 6
|
||||||
assert self.wbuf._bitlength(Py26Int(42)) == 6
|
assert self.wbuf._bitlength(Py26Int(42)) == 6
|
||||||
|
|
||||||
def test_mpint1(self):
|
def test_mpint1(self):
|
||||||
mpint1w = lambda x: self.wbuf().write_mpint1(x).write_flush() # noqa
|
mpint1w = lambda x: self.wbuf().write_mpint1(x).write_flush() # noqa
|
||||||
mpint1r = lambda x: self.rbuf(x).read_mpint1() # noqa
|
mpint1r = lambda x: self.rbuf(x).read_mpint1() # noqa
|
||||||
tc = [(0x0, '00 00'),
|
tc = [(0x0, '00 00'),
|
||||||
(0x1234, '00 0d 12 34'),
|
(0x1234, '00 0d 12 34'),
|
||||||
(0x12345, '00 11 01 23 45'),
|
(0x12345, '00 11 01 23 45'),
|
||||||
(0xdeadbeef, '00 20 de ad be ef')]
|
(0xdeadbeef, '00 20 de ad be ef')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert mpint1w(p[0]) == self._b(p[1])
|
assert mpint1w(p[0]) == self._b(p[1])
|
||||||
assert mpint1r(self._b(p[1])) == p[0]
|
assert mpint1r(self._b(p[1])) == p[0]
|
||||||
|
|
||||||
def test_mpint2(self):
|
def test_mpint2(self):
|
||||||
mpint2w = lambda x: self.wbuf().write_mpint2(x).write_flush() # noqa
|
mpint2w = lambda x: self.wbuf().write_mpint2(x).write_flush() # noqa
|
||||||
mpint2r = lambda x: self.rbuf(x).read_mpint2() # noqa
|
mpint2r = lambda x: self.rbuf(x).read_mpint2() # noqa
|
||||||
tc = [(0x0, '00 00 00 00'),
|
tc = [(0x0, '00 00 00 00'),
|
||||||
(0x80, '00 00 00 02 00 80'),
|
(0x80, '00 00 00 02 00 80'),
|
||||||
(0x9a378f9b2e332a7, '00 00 00 08 09 a3 78 f9 b2 e3 32 a7'),
|
(0x9a378f9b2e332a7, '00 00 00 08 09 a3 78 f9 b2 e3 32 a7'),
|
||||||
(-0x1234, '00 00 00 02 ed cc'),
|
(-0x1234, '00 00 00 02 ed cc'),
|
||||||
(-0xdeadbeef, '00 00 00 05 ff 21 52 41 11'),
|
(-0xdeadbeef, '00 00 00 05 ff 21 52 41 11'),
|
||||||
(-0x8000, '00 00 00 02 80 00'),
|
(-0x8000, '00 00 00 02 80 00'),
|
||||||
(-0x80, '00 00 00 01 80')]
|
(-0x80, '00 00 00 01 80')]
|
||||||
for p in tc:
|
for p in tc:
|
||||||
assert mpint2w(p[0]) == self._b(p[1])
|
assert mpint2w(p[0]) == self._b(p[1])
|
||||||
assert mpint2r(self._b(p[1])) == p[0]
|
assert mpint2r(self._b(p[1])) == p[0]
|
||||||
assert mpint2r(self._b('00 00 00 02 ff 80')) == -0x80
|
assert mpint2r(self._b('00 00 00 02 ff 80')) == -0x80
|
||||||
|
@ -7,155 +7,155 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestErrors(object):
|
class TestErrors(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
self.audit = ssh_audit.audit
|
self.audit = ssh_audit.audit
|
||||||
|
|
||||||
def _conf(self):
|
def _conf(self):
|
||||||
conf = self.AuditConf('localhost', 22)
|
conf = self.AuditConf('localhost', 22)
|
||||||
conf.colors = False
|
conf.colors = False
|
||||||
conf.batch = True
|
conf.batch = True
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
def _audit(self, spy, conf=None, sysexit=True):
|
def _audit(self, spy, conf=None, sysexit=True):
|
||||||
if conf is None:
|
if conf is None:
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
spy.begin()
|
spy.begin()
|
||||||
if sysexit:
|
if sysexit:
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
self.audit(conf)
|
self.audit(conf)
|
||||||
else:
|
else:
|
||||||
self.audit(conf)
|
self.audit(conf)
|
||||||
lines = spy.flush()
|
lines = spy.flush()
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def test_connection_unresolved(self, output_spy, virtual_socket):
|
def test_connection_unresolved(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.gsock.addrinfodata['localhost#22'] = []
|
vsocket.gsock.addrinfodata['localhost#22'] = []
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'has no DNS records' in lines[-1]
|
assert 'has no DNS records' in lines[-1]
|
||||||
|
|
||||||
def test_connection_refused(self, output_spy, virtual_socket):
|
def test_connection_refused(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.errors['connect'] = socket.error(errno.ECONNREFUSED, 'Connection refused')
|
vsocket.errors['connect'] = socket.error(errno.ECONNREFUSED, 'Connection refused')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'Connection refused' in lines[-1]
|
assert 'Connection refused' in lines[-1]
|
||||||
|
|
||||||
def test_connection_timeout(self, output_spy, virtual_socket):
|
def test_connection_timeout(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.errors['connect'] = socket.timeout('timed out')
|
vsocket.errors['connect'] = socket.timeout('timed out')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'timed out' in lines[-1]
|
assert 'timed out' in lines[-1]
|
||||||
|
|
||||||
def test_recv_empty(self, output_spy, virtual_socket):
|
def test_recv_empty(self, output_spy, virtual_socket):
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
|
|
||||||
def test_recv_timeout(self, output_spy, virtual_socket):
|
def test_recv_timeout(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(socket.timeout('timed out'))
|
vsocket.rdata.append(socket.timeout('timed out'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
assert 'timed out' in lines[-1]
|
assert 'timed out' in lines[-1]
|
||||||
|
|
||||||
def test_recv_retry_till_timeout(self, output_spy, virtual_socket):
|
def test_recv_retry_till_timeout(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.timeout('timed out'))
|
vsocket.rdata.append(socket.timeout('timed out'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
assert 'timed out' in lines[-1]
|
assert 'timed out' in lines[-1]
|
||||||
|
|
||||||
def test_recv_retry_till_reset(self, output_spy, virtual_socket):
|
def test_recv_retry_till_reset(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EWOULDBLOCK, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
vsocket.rdata.append(socket.error(errno.EAGAIN, 'Resource temporarily unavailable'))
|
||||||
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
assert 'reset by peer' in lines[-1]
|
assert 'reset by peer' in lines[-1]
|
||||||
|
|
||||||
def test_connection_closed_before_banner(self, output_spy, virtual_socket):
|
def test_connection_closed_before_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
assert 'reset by peer' in lines[-1]
|
assert 'reset by peer' in lines[-1]
|
||||||
|
|
||||||
def test_connection_closed_after_header(self, output_spy, virtual_socket):
|
def test_connection_closed_after_header(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'header line 1\n')
|
vsocket.rdata.append(b'header line 1\n')
|
||||||
vsocket.rdata.append(b'\n')
|
vsocket.rdata.append(b'\n')
|
||||||
vsocket.rdata.append(b'header line 2\n')
|
vsocket.rdata.append(b'header line 2\n')
|
||||||
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
vsocket.rdata.append(socket.error(errno.ECONNRESET, 'Connection reset by peer'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 3
|
assert len(lines) == 3
|
||||||
assert 'did not receive banner' in lines[-1]
|
assert 'did not receive banner' in lines[-1]
|
||||||
assert 'reset by peer' in lines[-1]
|
assert 'reset by peer' in lines[-1]
|
||||||
|
|
||||||
def test_connection_closed_after_banner(self, output_spy, virtual_socket):
|
def test_connection_closed_after_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
||||||
vsocket.rdata.append(socket.error(54, 'Connection reset by peer'))
|
vsocket.rdata.append(socket.error(54, 'Connection reset by peer'))
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 2
|
assert len(lines) == 2
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert 'reset by peer' in lines[-1]
|
assert 'reset by peer' in lines[-1]
|
||||||
|
|
||||||
def test_empty_data_after_banner(self, output_spy, virtual_socket):
|
def test_empty_data_after_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 2
|
assert len(lines) == 2
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert 'empty' in lines[-1]
|
assert 'empty' in lines[-1]
|
||||||
|
|
||||||
def test_wrong_data_after_banner(self, output_spy, virtual_socket):
|
def test_wrong_data_after_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
||||||
vsocket.rdata.append(b'xxx\n')
|
vsocket.rdata.append(b'xxx\n')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 2
|
assert len(lines) == 2
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert 'xxx' in lines[-1]
|
assert 'xxx' in lines[-1]
|
||||||
|
|
||||||
def test_non_ascii_banner(self, output_spy, virtual_socket):
|
def test_non_ascii_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\xc3\xbc\r\n')
|
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\xc3\xbc\r\n')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 3
|
assert len(lines) == 3
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert 'ASCII' in lines[-2]
|
assert 'ASCII' in lines[-2]
|
||||||
assert lines[-3].endswith('SSH-2.0-ssh-audit-test?')
|
assert lines[-3].endswith('SSH-2.0-ssh-audit-test?')
|
||||||
|
|
||||||
def test_nonutf8_data_after_banner(self, output_spy, virtual_socket):
|
def test_nonutf8_data_after_banner(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
vsocket.rdata.append(b'SSH-2.0-ssh-audit-test\r\n')
|
||||||
vsocket.rdata.append(b'\x81\xff\n')
|
vsocket.rdata.append(b'\x81\xff\n')
|
||||||
lines = self._audit(output_spy)
|
lines = self._audit(output_spy)
|
||||||
assert len(lines) == 2
|
assert len(lines) == 2
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert '\\x81\\xff' in lines[-1]
|
assert '\\x81\\xff' in lines[-1]
|
||||||
|
|
||||||
def test_protocol_mismatch_by_conf(self, output_spy, virtual_socket):
|
def test_protocol_mismatch_by_conf(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.rdata.append(b'SSH-1.3-ssh-audit-test\r\n')
|
vsocket.rdata.append(b'SSH-1.3-ssh-audit-test\r\n')
|
||||||
vsocket.rdata.append(b'Protocol major versions differ.\n')
|
vsocket.rdata.append(b'Protocol major versions differ.\n')
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
conf.ssh1, conf.ssh2 = True, False
|
conf.ssh1, conf.ssh2 = True, False
|
||||||
lines = self._audit(output_spy, conf)
|
lines = self._audit(output_spy, conf)
|
||||||
assert len(lines) == 3
|
assert len(lines) == 3
|
||||||
assert 'error reading packet' in lines[-1]
|
assert 'error reading packet' in lines[-1]
|
||||||
assert 'major versions differ' in lines[-1]
|
assert 'major versions differ' in lines[-1]
|
||||||
|
@ -6,170 +6,170 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestOutput(object):
|
class TestOutput(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.Output = ssh_audit.Output
|
self.Output = ssh_audit.Output
|
||||||
self.OutputBuffer = ssh_audit.OutputBuffer
|
self.OutputBuffer = ssh_audit.OutputBuffer
|
||||||
|
|
||||||
def test_output_buffer_no_lines(self, output_spy):
|
def test_output_buffer_no_lines(self, output_spy):
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with self.OutputBuffer() as obuf:
|
with self.OutputBuffer() as obuf:
|
||||||
pass
|
pass
|
||||||
assert output_spy.flush() == []
|
assert output_spy.flush() == []
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with self.OutputBuffer() as obuf:
|
with self.OutputBuffer() as obuf:
|
||||||
pass
|
pass
|
||||||
obuf.flush()
|
obuf.flush()
|
||||||
assert output_spy.flush() == []
|
assert output_spy.flush() == []
|
||||||
|
|
||||||
def test_output_buffer_no_flush(self, output_spy):
|
def test_output_buffer_no_flush(self, output_spy):
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with self.OutputBuffer():
|
with self.OutputBuffer():
|
||||||
print(u'abc')
|
print(u'abc')
|
||||||
assert output_spy.flush() == []
|
assert output_spy.flush() == []
|
||||||
|
|
||||||
def test_output_buffer_flush(self, output_spy):
|
def test_output_buffer_flush(self, output_spy):
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with self.OutputBuffer() as obuf:
|
with self.OutputBuffer() as obuf:
|
||||||
print(u'abc')
|
print(u'abc')
|
||||||
print()
|
print()
|
||||||
print(u'def')
|
print(u'def')
|
||||||
obuf.flush()
|
obuf.flush()
|
||||||
assert output_spy.flush() == [u'abc', u'', u'def']
|
assert output_spy.flush() == [u'abc', u'', u'def']
|
||||||
|
|
||||||
def test_output_defaults(self):
|
def test_output_defaults(self):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
# default: on
|
# default: on
|
||||||
assert out.batch is False
|
assert out.batch is False
|
||||||
assert out.use_colors is True
|
assert out.use_colors is True
|
||||||
assert out.level == 'info'
|
assert out.level == 'info'
|
||||||
|
|
||||||
def test_output_colors(self, output_spy):
|
def test_output_colors(self, output_spy):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
# test without colors
|
# test without colors
|
||||||
out.use_colors = False
|
out.use_colors = False
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
assert output_spy.flush() == [u'info color']
|
assert output_spy.flush() == [u'info color']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
assert output_spy.flush() == [u'head color']
|
assert output_spy.flush() == [u'head color']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
assert output_spy.flush() == [u'good color']
|
assert output_spy.flush() == [u'good color']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
assert output_spy.flush() == [u'warn color']
|
assert output_spy.flush() == [u'warn color']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert output_spy.flush() == [u'fail color']
|
assert output_spy.flush() == [u'fail color']
|
||||||
if not out.colors_supported:
|
if not out.colors_supported:
|
||||||
return
|
return
|
||||||
# test with colors
|
# test with colors
|
||||||
out.use_colors = True
|
out.use_colors = True
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
assert output_spy.flush() == [u'info color']
|
assert output_spy.flush() == [u'info color']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
assert output_spy.flush() == [u'\x1b[0;36mhead color\x1b[0m']
|
assert output_spy.flush() == [u'\x1b[0;36mhead color\x1b[0m']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
assert output_spy.flush() == [u'\x1b[0;32mgood color\x1b[0m']
|
assert output_spy.flush() == [u'\x1b[0;32mgood color\x1b[0m']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
assert output_spy.flush() == [u'\x1b[0;33mwarn color\x1b[0m']
|
assert output_spy.flush() == [u'\x1b[0;33mwarn color\x1b[0m']
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert output_spy.flush() == [u'\x1b[0;31mfail color\x1b[0m']
|
assert output_spy.flush() == [u'\x1b[0;31mfail color\x1b[0m']
|
||||||
|
|
||||||
def test_output_sep(self, output_spy):
|
def test_output_sep(self, output_spy):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.sep()
|
out.sep()
|
||||||
out.sep()
|
out.sep()
|
||||||
out.sep()
|
out.sep()
|
||||||
assert output_spy.flush() == [u'', u'', u'']
|
assert output_spy.flush() == [u'', u'', u'']
|
||||||
|
|
||||||
def test_output_levels(self):
|
def test_output_levels(self):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
assert out.get_level('info') == 0
|
assert out.get_level('info') == 0
|
||||||
assert out.get_level('good') == 0
|
assert out.get_level('good') == 0
|
||||||
assert out.get_level('warn') == 1
|
assert out.get_level('warn') == 1
|
||||||
assert out.get_level('fail') == 2
|
assert out.get_level('fail') == 2
|
||||||
assert out.get_level('unknown') > 2
|
assert out.get_level('unknown') > 2
|
||||||
|
|
||||||
def test_output_level_property(self):
|
def test_output_level_property(self):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
out.level = 'info'
|
out.level = 'info'
|
||||||
assert out.level == 'info'
|
assert out.level == 'info'
|
||||||
out.level = 'good'
|
out.level = 'good'
|
||||||
assert out.level == 'info'
|
assert out.level == 'info'
|
||||||
out.level = 'warn'
|
out.level = 'warn'
|
||||||
assert out.level == 'warn'
|
assert out.level == 'warn'
|
||||||
out.level = 'fail'
|
out.level = 'fail'
|
||||||
assert out.level == 'fail'
|
assert out.level == 'fail'
|
||||||
out.level = 'invalid level'
|
out.level = 'invalid level'
|
||||||
assert out.level == 'unknown'
|
assert out.level == 'unknown'
|
||||||
|
|
||||||
def test_output_level(self, output_spy):
|
def test_output_level(self, output_spy):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
# visible: all
|
# visible: all
|
||||||
out.level = 'info'
|
out.level = 'info'
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 5
|
assert len(output_spy.flush()) == 5
|
||||||
# visible: head, warn, fail
|
# visible: head, warn, fail
|
||||||
out.level = 'warn'
|
out.level = 'warn'
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 3
|
assert len(output_spy.flush()) == 3
|
||||||
# visible: head, fail
|
# visible: head, fail
|
||||||
out.level = 'fail'
|
out.level = 'fail'
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 2
|
assert len(output_spy.flush()) == 2
|
||||||
# visible: head
|
# visible: head
|
||||||
out.level = 'invalid level'
|
out.level = 'invalid level'
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 1
|
assert len(output_spy.flush()) == 1
|
||||||
|
|
||||||
def test_output_batch(self, output_spy):
|
def test_output_batch(self, output_spy):
|
||||||
out = self.Output()
|
out = self.Output()
|
||||||
# visible: all
|
# visible: all
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.level = 'info'
|
out.level = 'info'
|
||||||
out.batch = False
|
out.batch = False
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 5
|
assert len(output_spy.flush()) == 5
|
||||||
# visible: all except head
|
# visible: all except head
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
out.level = 'info'
|
out.level = 'info'
|
||||||
out.batch = True
|
out.batch = True
|
||||||
out.info('info color')
|
out.info('info color')
|
||||||
out.head('head color')
|
out.head('head color')
|
||||||
out.good('good color')
|
out.good('good color')
|
||||||
out.warn('warn color')
|
out.warn('warn color')
|
||||||
out.fail('fail color')
|
out.fail('fail color')
|
||||||
assert len(output_spy.flush()) == 4
|
assert len(output_spy.flush()) == 4
|
||||||
|
@ -6,76 +6,76 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init,protected-access
|
# pylint: disable=attribute-defined-outside-init,protected-access
|
||||||
class TestResolve(object):
|
class TestResolve(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
self.audit = ssh_audit.audit
|
self.audit = ssh_audit.audit
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def _conf(self):
|
def _conf(self):
|
||||||
conf = self.AuditConf('localhost', 22)
|
conf = self.AuditConf('localhost', 22)
|
||||||
conf.colors = False
|
conf.colors = False
|
||||||
conf.batch = True
|
conf.batch = True
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
def test_resolve_error(self, output_spy, virtual_socket):
|
def test_resolve_error(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.gsock.addrinfodata['localhost#22'] = socket.gaierror(8, 'hostname nor servname provided, or not known')
|
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()
|
conf = self._conf()
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
list(s._resolve(conf.ipvo))
|
list(s._resolve(conf.ipvo))
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'hostname nor servname provided' in lines[-1]
|
assert 'hostname nor servname provided' in lines[-1]
|
||||||
|
|
||||||
def test_resolve_hostname_without_records(self, output_spy, virtual_socket):
|
def test_resolve_hostname_without_records(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
vsocket.gsock.addrinfodata['localhost#22'] = []
|
vsocket.gsock.addrinfodata['localhost#22'] = []
|
||||||
s = self.ssh.Socket('localhost', 22)
|
s = self.ssh.Socket('localhost', 22)
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 0
|
assert len(r) == 0
|
||||||
|
|
||||||
def test_resolve_ipv4(self, virtual_socket):
|
def test_resolve_ipv4(self, virtual_socket):
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
s = self.ssh.Socket('localhost', 22)
|
s = self.ssh.Socket('localhost', 22)
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 1
|
assert len(r) == 1
|
||||||
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
||||||
|
|
||||||
def test_resolve_ipv6(self, virtual_socket):
|
def test_resolve_ipv6(self, virtual_socket):
|
||||||
s = self.ssh.Socket('localhost', 22)
|
s = self.ssh.Socket('localhost', 22)
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 1
|
assert len(r) == 1
|
||||||
assert r[0] == (socket.AF_INET6, ('::1', 22))
|
assert r[0] == (socket.AF_INET6, ('::1', 22))
|
||||||
|
|
||||||
def test_resolve_ipv46_both(self, virtual_socket):
|
def test_resolve_ipv46_both(self, virtual_socket):
|
||||||
s = self.ssh.Socket('localhost', 22)
|
s = self.ssh.Socket('localhost', 22)
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 2
|
assert len(r) == 2
|
||||||
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
||||||
assert r[1] == (socket.AF_INET6, ('::1', 22))
|
assert r[1] == (socket.AF_INET6, ('::1', 22))
|
||||||
|
|
||||||
def test_resolve_ipv46_order(self, virtual_socket):
|
def test_resolve_ipv46_order(self, virtual_socket):
|
||||||
s = self.ssh.Socket('localhost', 22)
|
s = self.ssh.Socket('localhost', 22)
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 2
|
assert len(r) == 2
|
||||||
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
assert r[0] == (socket.AF_INET, ('127.0.0.1', 22))
|
||||||
assert r[1] == (socket.AF_INET6, ('::1', 22))
|
assert r[1] == (socket.AF_INET6, ('::1', 22))
|
||||||
conf = self._conf()
|
conf = self._conf()
|
||||||
conf.ipv6 = True
|
conf.ipv6 = True
|
||||||
conf.ipv4 = True
|
conf.ipv4 = True
|
||||||
r = list(s._resolve(conf.ipvo))
|
r = list(s._resolve(conf.ipvo))
|
||||||
assert len(r) == 2
|
assert len(r) == 2
|
||||||
assert r[0] == (socket.AF_INET6, ('::1', 22))
|
assert r[0] == (socket.AF_INET6, ('::1', 22))
|
||||||
assert r[1] == (socket.AF_INET, ('127.0.0.1', 22))
|
assert r[1] == (socket.AF_INET, ('127.0.0.1', 22))
|
||||||
|
@ -5,36 +5,36 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestSocket(object):
|
class TestSocket(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def test_invalid_host(self, virtual_socket):
|
def test_invalid_host(self, virtual_socket):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.ssh.Socket(None, 22)
|
self.ssh.Socket(None, 22)
|
||||||
|
|
||||||
def test_invalid_port(self, virtual_socket):
|
def test_invalid_port(self, virtual_socket):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.ssh.Socket('localhost', 'abc')
|
self.ssh.Socket('localhost', 'abc')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.ssh.Socket('localhost', -1)
|
self.ssh.Socket('localhost', -1)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.ssh.Socket('localhost', 0)
|
self.ssh.Socket('localhost', 0)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
self.ssh.Socket('localhost', 65536)
|
self.ssh.Socket('localhost', 65536)
|
||||||
|
|
||||||
def test_not_connected_socket(self, virtual_socket):
|
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()
|
banner, header, err = sock.get_banner()
|
||||||
assert banner is None
|
assert banner is None
|
||||||
assert len(header) == 0
|
assert len(header) == 0
|
||||||
assert err == 'not connected'
|
assert err == 'not connected'
|
||||||
s, e = sock.recv()
|
s, e = sock.recv()
|
||||||
assert s == -1
|
assert s == -1
|
||||||
assert e == 'not connected'
|
assert e == 'not connected'
|
||||||
s, e = sock.send('nothing')
|
s, e = sock.send('nothing')
|
||||||
assert s == -1
|
assert s == -1
|
||||||
assert e == 'not connected'
|
assert e == 'not connected'
|
||||||
s, e = sock.send_packet()
|
s, e = sock.send_packet()
|
||||||
assert s == -1
|
assert s == -1
|
||||||
assert e == 'not connected'
|
assert e == 'not connected'
|
||||||
|
@ -5,283 +5,283 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=line-too-long,attribute-defined-outside-init
|
# pylint: disable=line-too-long,attribute-defined-outside-init
|
||||||
class TestSoftware(object):
|
class TestSoftware(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def test_unknown_software(self):
|
def test_unknown_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
assert ps('SSH-1.5') is None
|
assert ps('SSH-1.5') is None
|
||||||
assert ps('SSH-1.99-AlfaMegaServer') is None
|
assert ps('SSH-1.99-AlfaMegaServer') is None
|
||||||
assert ps('SSH-2.0-BetaMegaServer 0.0.1') is None
|
assert ps('SSH-2.0-BetaMegaServer 0.0.1') is None
|
||||||
|
|
||||||
def test_openssh_software(self):
|
def test_openssh_software(self):
|
||||||
# pylint: disable=too-many-statements
|
# pylint: disable=too-many-statements
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-2.0-OpenSSH_7.3')
|
s = ps('SSH-2.0-OpenSSH_7.3')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '7.3'
|
assert s.version == '7.3'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 7.3'
|
assert str(s) == 'OpenSSH 7.3'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=7.3)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=7.3)>'
|
||||||
# common, portable
|
# common, portable
|
||||||
s = ps('SSH-2.0-OpenSSH_7.2p1')
|
s = ps('SSH-2.0-OpenSSH_7.2p1')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '7.2'
|
assert s.version == '7.2'
|
||||||
assert s.patch == 'p1'
|
assert s.patch == 'p1'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 7.2p1'
|
assert str(s) == 'OpenSSH 7.2p1'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'OpenSSH 7.2'
|
assert s.display(False) == 'OpenSSH 7.2'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=p1)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=p1)>'
|
||||||
# dot instead of underline
|
# dot instead of underline
|
||||||
s = ps('SSH-2.0-OpenSSH.6.6')
|
s = ps('SSH-2.0-OpenSSH.6.6')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '6.6'
|
assert s.version == '6.6'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 6.6'
|
assert str(s) == 'OpenSSH 6.6'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=6.6)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=6.6)>'
|
||||||
# dash instead of underline
|
# dash instead of underline
|
||||||
s = ps('SSH-2.0-OpenSSH-3.9p1')
|
s = ps('SSH-2.0-OpenSSH-3.9p1')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '3.9'
|
assert s.version == '3.9'
|
||||||
assert s.patch == 'p1'
|
assert s.patch == 'p1'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 3.9p1'
|
assert str(s) == 'OpenSSH 3.9p1'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'OpenSSH 3.9'
|
assert s.display(False) == 'OpenSSH 3.9'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=3.9, patch=p1)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=3.9, patch=p1)>'
|
||||||
# patch prefix with dash
|
# patch prefix with dash
|
||||||
s = ps('SSH-2.0-OpenSSH_7.2-hpn14v5')
|
s = ps('SSH-2.0-OpenSSH_7.2-hpn14v5')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '7.2'
|
assert s.version == '7.2'
|
||||||
assert s.patch == 'hpn14v5'
|
assert s.patch == 'hpn14v5'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 7.2 (hpn14v5)'
|
assert str(s) == 'OpenSSH 7.2 (hpn14v5)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'OpenSSH 7.2'
|
assert s.display(False) == 'OpenSSH 7.2'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=hpn14v5)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=hpn14v5)>'
|
||||||
# patch prefix with underline
|
# patch prefix with underline
|
||||||
s = ps('SSH-1.5-OpenSSH_6.6.1_hpn13v11')
|
s = ps('SSH-1.5-OpenSSH_6.6.1_hpn13v11')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '6.6.1'
|
assert s.version == '6.6.1'
|
||||||
assert s.patch == 'hpn13v11'
|
assert s.patch == 'hpn13v11'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 6.6.1 (hpn13v11)'
|
assert str(s) == 'OpenSSH 6.6.1 (hpn13v11)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'OpenSSH 6.6.1'
|
assert s.display(False) == 'OpenSSH 6.6.1'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=6.6.1, patch=hpn13v11)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=6.6.1, patch=hpn13v11)>'
|
||||||
# patch prefix with dot
|
# patch prefix with dot
|
||||||
s = ps('SSH-2.0-OpenSSH_5.9.CASPUR')
|
s = ps('SSH-2.0-OpenSSH_5.9.CASPUR')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'OpenSSH'
|
assert s.product == 'OpenSSH'
|
||||||
assert s.version == '5.9'
|
assert s.version == '5.9'
|
||||||
assert s.patch == 'CASPUR'
|
assert s.patch == 'CASPUR'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'OpenSSH 5.9 (CASPUR)'
|
assert str(s) == 'OpenSSH 5.9 (CASPUR)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'OpenSSH 5.9'
|
assert s.display(False) == 'OpenSSH 5.9'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=5.9, patch=CASPUR)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=5.9, patch=CASPUR)>'
|
||||||
|
|
||||||
def test_dropbear_software(self):
|
def test_dropbear_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-2.0-dropbear_2016.74')
|
s = ps('SSH-2.0-dropbear_2016.74')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'Dropbear SSH'
|
assert s.product == 'Dropbear SSH'
|
||||||
assert s.version == '2016.74'
|
assert s.version == '2016.74'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Dropbear SSH 2016.74'
|
assert str(s) == 'Dropbear SSH 2016.74'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(product=Dropbear SSH, version=2016.74)>'
|
assert repr(s) == '<Software(product=Dropbear SSH, version=2016.74)>'
|
||||||
# common, patch
|
# common, patch
|
||||||
s = ps('SSH-2.0-dropbear_0.44test4')
|
s = ps('SSH-2.0-dropbear_0.44test4')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'Dropbear SSH'
|
assert s.product == 'Dropbear SSH'
|
||||||
assert s.version == '0.44'
|
assert s.version == '0.44'
|
||||||
assert s.patch == 'test4'
|
assert s.patch == 'test4'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Dropbear SSH 0.44 (test4)'
|
assert str(s) == 'Dropbear SSH 0.44 (test4)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'Dropbear SSH 0.44'
|
assert s.display(False) == 'Dropbear SSH 0.44'
|
||||||
assert repr(s) == '<Software(product=Dropbear SSH, version=0.44, patch=test4)>'
|
assert repr(s) == '<Software(product=Dropbear SSH, version=0.44, patch=test4)>'
|
||||||
# patch prefix with dash
|
# patch prefix with dash
|
||||||
s = ps('SSH-2.0-dropbear_0.44-Freesco-p49')
|
s = ps('SSH-2.0-dropbear_0.44-Freesco-p49')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'Dropbear SSH'
|
assert s.product == 'Dropbear SSH'
|
||||||
assert s.version == '0.44'
|
assert s.version == '0.44'
|
||||||
assert s.patch == 'Freesco-p49'
|
assert s.patch == 'Freesco-p49'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Dropbear SSH 0.44 (Freesco-p49)'
|
assert str(s) == 'Dropbear SSH 0.44 (Freesco-p49)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'Dropbear SSH 0.44'
|
assert s.display(False) == 'Dropbear SSH 0.44'
|
||||||
assert repr(s) == '<Software(product=Dropbear SSH, version=0.44, patch=Freesco-p49)>'
|
assert repr(s) == '<Software(product=Dropbear SSH, version=0.44, patch=Freesco-p49)>'
|
||||||
# patch prefix with underline
|
# patch prefix with underline
|
||||||
s = ps('SSH-2.0-dropbear_2014.66_agbn_1')
|
s = ps('SSH-2.0-dropbear_2014.66_agbn_1')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'Dropbear SSH'
|
assert s.product == 'Dropbear SSH'
|
||||||
assert s.version == '2014.66'
|
assert s.version == '2014.66'
|
||||||
assert s.patch == 'agbn_1'
|
assert s.patch == 'agbn_1'
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Dropbear SSH 2014.66 (agbn_1)'
|
assert str(s) == 'Dropbear SSH 2014.66 (agbn_1)'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == 'Dropbear SSH 2014.66'
|
assert s.display(False) == 'Dropbear SSH 2014.66'
|
||||||
assert repr(s) == '<Software(product=Dropbear SSH, version=2014.66, patch=agbn_1)>'
|
assert repr(s) == '<Software(product=Dropbear SSH, version=2014.66, patch=agbn_1)>'
|
||||||
|
|
||||||
def test_libssh_software(self):
|
def test_libssh_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-2.0-libssh-0.2')
|
s = ps('SSH-2.0-libssh-0.2')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'libssh'
|
assert s.product == 'libssh'
|
||||||
assert s.version == '0.2'
|
assert s.version == '0.2'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'libssh 0.2'
|
assert str(s) == 'libssh 0.2'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(product=libssh, version=0.2)>'
|
assert repr(s) == '<Software(product=libssh, version=0.2)>'
|
||||||
s = ps('SSH-2.0-libssh-0.7.4')
|
s = ps('SSH-2.0-libssh-0.7.4')
|
||||||
assert s.vendor is None
|
assert s.vendor is None
|
||||||
assert s.product == 'libssh'
|
assert s.product == 'libssh'
|
||||||
assert s.version == '0.7.4'
|
assert s.version == '0.7.4'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'libssh 0.7.4'
|
assert str(s) == 'libssh 0.7.4'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(product=libssh, version=0.7.4)>'
|
assert repr(s) == '<Software(product=libssh, version=0.7.4)>'
|
||||||
|
|
||||||
def test_romsshell_software(self):
|
def test_romsshell_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-2.0-RomSShell_5.40')
|
s = ps('SSH-2.0-RomSShell_5.40')
|
||||||
assert s.vendor == 'Allegro Software'
|
assert s.vendor == 'Allegro Software'
|
||||||
assert s.product == 'RomSShell'
|
assert s.product == 'RomSShell'
|
||||||
assert s.version == '5.40'
|
assert s.version == '5.40'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Allegro Software RomSShell 5.40'
|
assert str(s) == 'Allegro Software RomSShell 5.40'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(vendor=Allegro Software, product=RomSShell, version=5.40)>'
|
assert repr(s) == '<Software(vendor=Allegro Software, product=RomSShell, version=5.40)>'
|
||||||
|
|
||||||
def test_hp_ilo_software(self):
|
def test_hp_ilo_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-2.0-mpSSH_0.2.1')
|
s = ps('SSH-2.0-mpSSH_0.2.1')
|
||||||
assert s.vendor == 'HP'
|
assert s.vendor == 'HP'
|
||||||
assert s.product == 'iLO (Integrated Lights-Out) sshd'
|
assert s.product == 'iLO (Integrated Lights-Out) sshd'
|
||||||
assert s.version == '0.2.1'
|
assert s.version == '0.2.1'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'HP iLO (Integrated Lights-Out) sshd 0.2.1'
|
assert str(s) == 'HP iLO (Integrated Lights-Out) sshd 0.2.1'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(vendor=HP, product=iLO (Integrated Lights-Out) sshd, version=0.2.1)>'
|
assert repr(s) == '<Software(vendor=HP, product=iLO (Integrated Lights-Out) sshd, version=0.2.1)>'
|
||||||
|
|
||||||
def test_cisco_software(self):
|
def test_cisco_software(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# common
|
# common
|
||||||
s = ps('SSH-1.5-Cisco-1.25')
|
s = ps('SSH-1.5-Cisco-1.25')
|
||||||
assert s.vendor == 'Cisco'
|
assert s.vendor == 'Cisco'
|
||||||
assert s.product == 'IOS/PIX sshd'
|
assert s.product == 'IOS/PIX sshd'
|
||||||
assert s.version == '1.25'
|
assert s.version == '1.25'
|
||||||
assert s.patch is None
|
assert s.patch is None
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
assert str(s) == 'Cisco IOS/PIX sshd 1.25'
|
assert str(s) == 'Cisco IOS/PIX sshd 1.25'
|
||||||
assert str(s) == s.display()
|
assert str(s) == s.display()
|
||||||
assert s.display(True) == str(s)
|
assert s.display(True) == str(s)
|
||||||
assert s.display(False) == str(s)
|
assert s.display(False) == str(s)
|
||||||
assert repr(s) == '<Software(vendor=Cisco, product=IOS/PIX sshd, version=1.25)>'
|
assert repr(s) == '<Software(vendor=Cisco, product=IOS/PIX sshd, version=1.25)>'
|
||||||
|
|
||||||
def test_software_os(self):
|
def test_software_os(self):
|
||||||
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
ps = lambda x: self.ssh.Software.parse(self.ssh.Banner.parse(x)) # noqa
|
||||||
# unknown
|
# unknown
|
||||||
s = ps('SSH-2.0-OpenSSH_3.7.1 MegaOperatingSystem 123')
|
s = ps('SSH-2.0-OpenSSH_3.7.1 MegaOperatingSystem 123')
|
||||||
assert s.os is None
|
assert s.os is None
|
||||||
# NetBSD
|
# NetBSD
|
||||||
s = ps('SSH-1.99-OpenSSH_2.5.1 NetBSD_Secure_Shell-20010614')
|
s = ps('SSH-1.99-OpenSSH_2.5.1 NetBSD_Secure_Shell-20010614')
|
||||||
assert s.os == 'NetBSD (2001-06-14)'
|
assert s.os == 'NetBSD (2001-06-14)'
|
||||||
assert str(s) == 'OpenSSH 2.5.1 running on NetBSD (2001-06-14)'
|
assert str(s) == 'OpenSSH 2.5.1 running on NetBSD (2001-06-14)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=2.5.1, os=NetBSD (2001-06-14))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=2.5.1, os=NetBSD (2001-06-14))>'
|
||||||
s = ps('SSH-1.99-OpenSSH_5.0 NetBSD_Secure_Shell-20080403+-hpn13v1')
|
s = ps('SSH-1.99-OpenSSH_5.0 NetBSD_Secure_Shell-20080403+-hpn13v1')
|
||||||
assert s.os == 'NetBSD (2008-04-03)'
|
assert s.os == 'NetBSD (2008-04-03)'
|
||||||
assert str(s) == 'OpenSSH 5.0 running on NetBSD (2008-04-03)'
|
assert str(s) == 'OpenSSH 5.0 running on NetBSD (2008-04-03)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=5.0, os=NetBSD (2008-04-03))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=5.0, os=NetBSD (2008-04-03))>'
|
||||||
s = ps('SSH-2.0-OpenSSH_6.6.1_hpn13v11 NetBSD-20100308')
|
s = ps('SSH-2.0-OpenSSH_6.6.1_hpn13v11 NetBSD-20100308')
|
||||||
assert s.os == 'NetBSD (2010-03-08)'
|
assert s.os == 'NetBSD (2010-03-08)'
|
||||||
assert str(s) == 'OpenSSH 6.6.1 (hpn13v11) running on NetBSD (2010-03-08)'
|
assert str(s) == 'OpenSSH 6.6.1 (hpn13v11) running on NetBSD (2010-03-08)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=6.6.1, patch=hpn13v11, os=NetBSD (2010-03-08))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=6.6.1, patch=hpn13v11, os=NetBSD (2010-03-08))>'
|
||||||
s = ps('SSH-2.0-OpenSSH_4.4 NetBSD')
|
s = ps('SSH-2.0-OpenSSH_4.4 NetBSD')
|
||||||
assert s.os == 'NetBSD'
|
assert s.os == 'NetBSD'
|
||||||
assert str(s) == 'OpenSSH 4.4 running on NetBSD'
|
assert str(s) == 'OpenSSH 4.4 running on NetBSD'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=4.4, os=NetBSD)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=4.4, os=NetBSD)>'
|
||||||
s = ps('SSH-2.0-OpenSSH_3.0.2 NetBSD Secure Shell')
|
s = ps('SSH-2.0-OpenSSH_3.0.2 NetBSD Secure Shell')
|
||||||
assert s.os == 'NetBSD'
|
assert s.os == 'NetBSD'
|
||||||
assert str(s) == 'OpenSSH 3.0.2 running on NetBSD'
|
assert str(s) == 'OpenSSH 3.0.2 running on NetBSD'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=3.0.2, os=NetBSD)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=3.0.2, os=NetBSD)>'
|
||||||
# FreeBSD
|
# FreeBSD
|
||||||
s = ps('SSH-2.0-OpenSSH_7.2 FreeBSD-20160310')
|
s = ps('SSH-2.0-OpenSSH_7.2 FreeBSD-20160310')
|
||||||
assert s.os == 'FreeBSD (2016-03-10)'
|
assert s.os == 'FreeBSD (2016-03-10)'
|
||||||
assert str(s) == 'OpenSSH 7.2 running on FreeBSD (2016-03-10)'
|
assert str(s) == 'OpenSSH 7.2 running on FreeBSD (2016-03-10)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=7.2, os=FreeBSD (2016-03-10))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=7.2, os=FreeBSD (2016-03-10))>'
|
||||||
s = ps('SSH-1.99-OpenSSH_2.9 FreeBSD localisations 20020307')
|
s = ps('SSH-1.99-OpenSSH_2.9 FreeBSD localisations 20020307')
|
||||||
assert s.os == 'FreeBSD (2002-03-07)'
|
assert s.os == 'FreeBSD (2002-03-07)'
|
||||||
assert str(s) == 'OpenSSH 2.9 running on FreeBSD (2002-03-07)'
|
assert str(s) == 'OpenSSH 2.9 running on FreeBSD (2002-03-07)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=2.9, os=FreeBSD (2002-03-07))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=2.9, os=FreeBSD (2002-03-07))>'
|
||||||
s = ps('SSH-2.0-OpenSSH_2.3.0 green@FreeBSD.org 20010321')
|
s = ps('SSH-2.0-OpenSSH_2.3.0 green@FreeBSD.org 20010321')
|
||||||
assert s.os == 'FreeBSD (2001-03-21)'
|
assert s.os == 'FreeBSD (2001-03-21)'
|
||||||
assert str(s) == 'OpenSSH 2.3.0 running on FreeBSD (2001-03-21)'
|
assert str(s) == 'OpenSSH 2.3.0 running on FreeBSD (2001-03-21)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=2.3.0, os=FreeBSD (2001-03-21))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=2.3.0, os=FreeBSD (2001-03-21))>'
|
||||||
s = ps('SSH-1.99-OpenSSH_4.4p1 FreeBSD-openssh-portable-overwrite-base-4.4.p1_1,1')
|
s = ps('SSH-1.99-OpenSSH_4.4p1 FreeBSD-openssh-portable-overwrite-base-4.4.p1_1,1')
|
||||||
assert s.os == 'FreeBSD'
|
assert s.os == 'FreeBSD'
|
||||||
assert str(s) == 'OpenSSH 4.4p1 running on FreeBSD'
|
assert str(s) == 'OpenSSH 4.4p1 running on FreeBSD'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=4.4, patch=p1, os=FreeBSD)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=4.4, patch=p1, os=FreeBSD)>'
|
||||||
s = ps('SSH-2.0-OpenSSH_7.2-OVH-rescue FreeBSD')
|
s = ps('SSH-2.0-OpenSSH_7.2-OVH-rescue FreeBSD')
|
||||||
assert s.os == 'FreeBSD'
|
assert s.os == 'FreeBSD'
|
||||||
assert str(s) == 'OpenSSH 7.2 (OVH-rescue) running on FreeBSD'
|
assert str(s) == 'OpenSSH 7.2 (OVH-rescue) running on FreeBSD'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=OVH-rescue, os=FreeBSD)>'
|
assert repr(s) == '<Software(product=OpenSSH, version=7.2, patch=OVH-rescue, os=FreeBSD)>'
|
||||||
# Windows
|
# Windows
|
||||||
s = ps('SSH-2.0-OpenSSH_3.7.1 in RemotelyAnywhere 5.21.422')
|
s = ps('SSH-2.0-OpenSSH_3.7.1 in RemotelyAnywhere 5.21.422')
|
||||||
assert s.os == 'Microsoft Windows (RemotelyAnywhere 5.21.422)'
|
assert s.os == 'Microsoft Windows (RemotelyAnywhere 5.21.422)'
|
||||||
assert str(s) == 'OpenSSH 3.7.1 running on Microsoft Windows (RemotelyAnywhere 5.21.422)'
|
assert str(s) == 'OpenSSH 3.7.1 running on Microsoft Windows (RemotelyAnywhere 5.21.422)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=3.7.1, os=Microsoft Windows (RemotelyAnywhere 5.21.422))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=3.7.1, os=Microsoft Windows (RemotelyAnywhere 5.21.422))>'
|
||||||
s = ps('SSH-2.0-OpenSSH_3.8 in DesktopAuthority 7.1.091')
|
s = ps('SSH-2.0-OpenSSH_3.8 in DesktopAuthority 7.1.091')
|
||||||
assert s.os == 'Microsoft Windows (DesktopAuthority 7.1.091)'
|
assert s.os == 'Microsoft Windows (DesktopAuthority 7.1.091)'
|
||||||
assert str(s) == 'OpenSSH 3.8 running on Microsoft Windows (DesktopAuthority 7.1.091)'
|
assert str(s) == 'OpenSSH 3.8 running on Microsoft Windows (DesktopAuthority 7.1.091)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=3.8, os=Microsoft Windows (DesktopAuthority 7.1.091))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=3.8, os=Microsoft Windows (DesktopAuthority 7.1.091))>'
|
||||||
s = ps('SSH-2.0-OpenSSH_3.8 in RemoteSupportManager 1.0.023')
|
s = ps('SSH-2.0-OpenSSH_3.8 in RemoteSupportManager 1.0.023')
|
||||||
assert s.os == 'Microsoft Windows (RemoteSupportManager 1.0.023)'
|
assert s.os == 'Microsoft Windows (RemoteSupportManager 1.0.023)'
|
||||||
assert str(s) == 'OpenSSH 3.8 running on Microsoft Windows (RemoteSupportManager 1.0.023)'
|
assert str(s) == 'OpenSSH 3.8 running on Microsoft Windows (RemoteSupportManager 1.0.023)'
|
||||||
assert repr(s) == '<Software(product=OpenSSH, version=3.8, os=Microsoft Windows (RemoteSupportManager 1.0.023))>'
|
assert repr(s) == '<Software(product=OpenSSH, version=3.8, os=Microsoft Windows (RemoteSupportManager 1.0.023))>'
|
||||||
|
@ -6,151 +6,151 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=line-too-long,attribute-defined-outside-init
|
# pylint: disable=line-too-long,attribute-defined-outside-init
|
||||||
class TestSSH1(object):
|
class TestSSH1(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
self.ssh1 = ssh_audit.SSH1
|
self.ssh1 = ssh_audit.SSH1
|
||||||
self.rbuf = ssh_audit.ReadBuf
|
self.rbuf = ssh_audit.ReadBuf
|
||||||
self.wbuf = ssh_audit.WriteBuf
|
self.wbuf = ssh_audit.WriteBuf
|
||||||
self.audit = ssh_audit.audit
|
self.audit = ssh_audit.audit
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
|
|
||||||
def _conf(self):
|
def _conf(self):
|
||||||
conf = self.AuditConf('localhost', 22)
|
conf = self.AuditConf('localhost', 22)
|
||||||
conf.colors = False
|
conf.colors = False
|
||||||
conf.batch = True
|
conf.batch = True
|
||||||
conf.verbose = True
|
conf.verbose = True
|
||||||
conf.ssh1 = True
|
conf.ssh1 = True
|
||||||
conf.ssh2 = False
|
conf.ssh2 = False
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
def _create_ssh1_packet(self, payload, valid_crc=True):
|
def _create_ssh1_packet(self, payload, valid_crc=True):
|
||||||
padding = -(len(payload) + 4) % 8
|
padding = -(len(payload) + 4) % 8
|
||||||
plen = len(payload) + 4
|
plen = len(payload) + 4
|
||||||
pad_bytes = b'\x00' * padding
|
pad_bytes = b'\x00' * padding
|
||||||
cksum = self.ssh1.crc32(pad_bytes + payload) if valid_crc else 0
|
cksum = self.ssh1.crc32(pad_bytes + payload) if valid_crc else 0
|
||||||
data = struct.pack('>I', plen) + pad_bytes + payload + struct.pack('>I', cksum)
|
data = struct.pack('>I', plen) + pad_bytes + payload + struct.pack('>I', cksum)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _server_key(cls):
|
def _server_key(cls):
|
||||||
return (1024, 0x10001, 0xee6552da432e0ac2c422df1a51287507748bfe3b5e3e4fa989a8f49fdc163a17754939ef18ef8a667ea3b71036a151fcd7f5e01ceef1e4439864baf3ac569047582c69d6c128212e0980dcb3168f00d371004039983f6033cd785b8b8f85096c7d9405cbfdc664e27c966356a6b4eb6ee20ad43414b50de18b22829c1880b551)
|
return (1024, 0x10001, 0xee6552da432e0ac2c422df1a51287507748bfe3b5e3e4fa989a8f49fdc163a17754939ef18ef8a667ea3b71036a151fcd7f5e01ceef1e4439864baf3ac569047582c69d6c128212e0980dcb3168f00d371004039983f6033cd785b8b8f85096c7d9405cbfdc664e27c966356a6b4eb6ee20ad43414b50de18b22829c1880b551)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _host_key(cls):
|
def _host_key(cls):
|
||||||
return (2048, 0x10001, 0xdfa20cd2a530ccc8c870aa60d9feb3b35deeab81c3215a96557abbd683d21f4600f38e475d87100da9a4404220eeb3bb5584e5a2b5b48ffda58530ea19104a32577d7459d91e76aa711b241050f4cc6d5327ccce254f371acad3be56d46eb5919b73f20dbdb1177b700f00891c5bf4ed128bb90ed541b778288285bcfa28432ab5cbcb8321b6e24760e998e0daa519f093a631e44276d7dd252ce0c08c75e2ab28a7349ead779f97d0f20a6d413bf3623cd216dc35375f6366690bcc41e3b2d5465840ec7ee0dc7e3f1c101d674a0c7dbccbc3942788b111396add2f8153b46a0e4b50d66e57ee92958f1c860dd97cc0e40e32febff915343ed53573142bdf4b)
|
return (2048, 0x10001, 0xdfa20cd2a530ccc8c870aa60d9feb3b35deeab81c3215a96557abbd683d21f4600f38e475d87100da9a4404220eeb3bb5584e5a2b5b48ffda58530ea19104a32577d7459d91e76aa711b241050f4cc6d5327ccce254f371acad3be56d46eb5919b73f20dbdb1177b700f00891c5bf4ed128bb90ed541b778288285bcfa28432ab5cbcb8321b6e24760e998e0daa519f093a631e44276d7dd252ce0c08c75e2ab28a7349ead779f97d0f20a6d413bf3623cd216dc35375f6366690bcc41e3b2d5465840ec7ee0dc7e3f1c101d674a0c7dbccbc3942788b111396add2f8153b46a0e4b50d66e57ee92958f1c860dd97cc0e40e32febff915343ed53573142bdf4b)
|
||||||
|
|
||||||
def _pkm_payload(self):
|
def _pkm_payload(self):
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write(b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
|
w.write(b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
|
||||||
b, e, m = self._server_key()
|
b, e, m = self._server_key()
|
||||||
w.write_int(b).write_mpint1(e).write_mpint1(m)
|
w.write_int(b).write_mpint1(e).write_mpint1(m)
|
||||||
b, e, m = self._host_key()
|
b, e, m = self._host_key()
|
||||||
w.write_int(b).write_mpint1(e).write_mpint1(m)
|
w.write_int(b).write_mpint1(e).write_mpint1(m)
|
||||||
w.write_int(2)
|
w.write_int(2)
|
||||||
w.write_int(72)
|
w.write_int(72)
|
||||||
w.write_int(36)
|
w.write_int(36)
|
||||||
return w.write_flush()
|
return w.write_flush()
|
||||||
|
|
||||||
def test_crc32(self):
|
def test_crc32(self):
|
||||||
assert self.ssh1.crc32(b'') == 0x00
|
assert self.ssh1.crc32(b'') == 0x00
|
||||||
assert self.ssh1.crc32(b'The quick brown fox jumps over the lazy dog') == 0xb9c60808
|
assert self.ssh1.crc32(b'The quick brown fox jumps over the lazy dog') == 0xb9c60808
|
||||||
|
|
||||||
def test_fingerprint(self):
|
def test_fingerprint(self):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
b, e, m = self._host_key()
|
b, e, m = self._host_key()
|
||||||
fpd = self.wbuf._create_mpint(m, False)
|
fpd = self.wbuf._create_mpint(m, False)
|
||||||
fpd += self.wbuf._create_mpint(e, False)
|
fpd += self.wbuf._create_mpint(e, False)
|
||||||
fp = self.ssh.Fingerprint(fpd)
|
fp = self.ssh.Fingerprint(fpd)
|
||||||
assert b == 2048
|
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.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'
|
assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs'
|
||||||
|
|
||||||
def _assert_pkm_keys(self, pkm, skey, hkey):
|
def _assert_pkm_keys(self, pkm, skey, hkey):
|
||||||
b, e, m = skey
|
b, e, m = skey
|
||||||
assert pkm.server_key_bits == b
|
assert pkm.server_key_bits == b
|
||||||
assert pkm.server_key_public_exponent == e
|
assert pkm.server_key_public_exponent == e
|
||||||
assert pkm.server_key_public_modulus == m
|
assert pkm.server_key_public_modulus == m
|
||||||
b, e, m = hkey
|
b, e, m = hkey
|
||||||
assert pkm.host_key_bits == b
|
assert pkm.host_key_bits == b
|
||||||
assert pkm.host_key_public_exponent == e
|
assert pkm.host_key_public_exponent == e
|
||||||
assert pkm.host_key_public_modulus == m
|
assert pkm.host_key_public_modulus == m
|
||||||
|
|
||||||
def _assert_pkm_fields(self, pkm, skey, hkey):
|
def _assert_pkm_fields(self, pkm, skey, hkey):
|
||||||
assert pkm is not None
|
assert pkm is not None
|
||||||
assert pkm.cookie == b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
assert pkm.cookie == b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
self._assert_pkm_keys(pkm, skey, hkey)
|
self._assert_pkm_keys(pkm, skey, hkey)
|
||||||
assert pkm.protocol_flags == 2
|
assert pkm.protocol_flags == 2
|
||||||
assert pkm.supported_ciphers_mask == 72
|
assert pkm.supported_ciphers_mask == 72
|
||||||
assert pkm.supported_ciphers == ['3des', 'blowfish']
|
assert pkm.supported_ciphers == ['3des', 'blowfish']
|
||||||
assert pkm.supported_authentications_mask == 36
|
assert pkm.supported_authentications_mask == 36
|
||||||
assert pkm.supported_authentications == ['rsa', 'tis']
|
assert pkm.supported_authentications == ['rsa', 'tis']
|
||||||
fp = self.ssh.Fingerprint(pkm.host_key_fingerprint_data)
|
fp = self.ssh.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.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'
|
assert fp.sha256 == 'SHA256:vZdx3mhzbvVJmn08t/ruv8WDhJ9jfKYsCTuSzot+QIs'
|
||||||
|
|
||||||
def test_pkm_init(self):
|
def test_pkm_init(self):
|
||||||
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
pflags, cmask, amask = 2, 72, 36
|
pflags, cmask, amask = 2, 72, 36
|
||||||
skey, hkey = self._server_key(), self._host_key()
|
skey, hkey = self._server_key(), self._host_key()
|
||||||
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
|
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
|
||||||
self._assert_pkm_fields(pkm, skey, hkey)
|
self._assert_pkm_fields(pkm, skey, hkey)
|
||||||
for skey2 in ([], [0], [0, 1], [0, 1, 2, 3]):
|
for skey2 in ([], [0], [0, 1], [0, 1, 2, 3]):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
pkm = self.ssh1.PublicKeyMessage(cookie, skey2, hkey, pflags, cmask, amask)
|
pkm = self.ssh1.PublicKeyMessage(cookie, skey2, hkey, pflags, cmask, amask)
|
||||||
for hkey2 in ([], [0], [0, 1], [0, 1, 2, 3]):
|
for hkey2 in ([], [0], [0, 1], [0, 1, 2, 3]):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
print(hkey2)
|
print(hkey2)
|
||||||
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask)
|
pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask)
|
||||||
|
|
||||||
def test_pkm_read(self):
|
def test_pkm_read(self):
|
||||||
pkm = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
|
pkm = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
|
||||||
self._assert_pkm_fields(pkm, self._server_key(), self._host_key())
|
self._assert_pkm_fields(pkm, self._server_key(), self._host_key())
|
||||||
|
|
||||||
def test_pkm_payload(self):
|
def test_pkm_payload(self):
|
||||||
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
cookie = b'\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
skey, hkey = self._server_key(), self._host_key()
|
skey, hkey = self._server_key(), self._host_key()
|
||||||
pflags, cmask, amask = 2, 72, 36
|
pflags, cmask, amask = 2, 72, 36
|
||||||
pkm1 = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
|
pkm1 = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask)
|
||||||
pkm2 = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
|
pkm2 = self.ssh1.PublicKeyMessage.parse(self._pkm_payload())
|
||||||
assert pkm1.payload == pkm2.payload
|
assert pkm1.payload == pkm2.payload
|
||||||
|
|
||||||
def test_ssh1_server_simple(self, output_spy, virtual_socket):
|
def test_ssh1_server_simple(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY)
|
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY)
|
||||||
w.write(self._pkm_payload())
|
w.write(self._pkm_payload())
|
||||||
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
|
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()))
|
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush()))
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
self.audit(self._conf())
|
self.audit(self._conf())
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 13
|
assert len(lines) == 13
|
||||||
|
|
||||||
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
|
def test_ssh1_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
|
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
|
||||||
w.write(self._pkm_payload())
|
w.write(self._pkm_payload())
|
||||||
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
|
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()))
|
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush()))
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
self.audit(self._conf())
|
self.audit(self._conf())
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 7
|
assert len(lines) == 7
|
||||||
assert 'unknown message' in lines[-1]
|
assert 'unknown message' in lines[-1]
|
||||||
|
|
||||||
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
|
def test_ssh1_server_invalid_checksum(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
|
w.write_byte(self.ssh.Protocol.SMSG_PUBLIC_KEY + 1)
|
||||||
w.write(self._pkm_payload())
|
w.write(self._pkm_payload())
|
||||||
vsocket.rdata.append(b'SSH-1.5-OpenSSH_7.2 ssh-audit-test\r\n')
|
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))
|
vsocket.rdata.append(self._create_ssh1_packet(w.write_flush(), False))
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
self.audit(self._conf())
|
self.audit(self._conf())
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 1
|
assert len(lines) == 1
|
||||||
assert 'checksum' in lines[-1]
|
assert 'checksum' in lines[-1]
|
||||||
|
@ -7,151 +7,151 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=line-too-long,attribute-defined-outside-init
|
# pylint: disable=line-too-long,attribute-defined-outside-init
|
||||||
class TestSSH2(object):
|
class TestSSH2(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
self.ssh2 = ssh_audit.SSH2
|
self.ssh2 = ssh_audit.SSH2
|
||||||
self.rbuf = ssh_audit.ReadBuf
|
self.rbuf = ssh_audit.ReadBuf
|
||||||
self.wbuf = ssh_audit.WriteBuf
|
self.wbuf = ssh_audit.WriteBuf
|
||||||
self.audit = ssh_audit.audit
|
self.audit = ssh_audit.audit
|
||||||
self.AuditConf = ssh_audit.AuditConf
|
self.AuditConf = ssh_audit.AuditConf
|
||||||
|
|
||||||
def _conf(self):
|
def _conf(self):
|
||||||
conf = self.AuditConf('localhost', 22)
|
conf = self.AuditConf('localhost', 22)
|
||||||
conf.colors = False
|
conf.colors = False
|
||||||
conf.batch = True
|
conf.batch = True
|
||||||
conf.verbose = True
|
conf.verbose = True
|
||||||
conf.ssh1 = False
|
conf.ssh1 = False
|
||||||
conf.ssh2 = True
|
conf.ssh2 = True
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_ssh2_packet(cls, payload):
|
def _create_ssh2_packet(cls, payload):
|
||||||
padding = -(len(payload) + 5) % 8
|
padding = -(len(payload) + 5) % 8
|
||||||
if padding < 4:
|
if padding < 4:
|
||||||
padding += 8
|
padding += 8
|
||||||
plen = len(payload) + padding + 1
|
plen = len(payload) + padding + 1
|
||||||
pad_bytes = b'\x00' * padding
|
pad_bytes = b'\x00' * padding
|
||||||
data = struct.pack('>Ib', plen, padding) + payload + pad_bytes
|
data = struct.pack('>Ib', plen, padding) + payload + pad_bytes
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _kex_payload(self):
|
def _kex_payload(self):
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write(b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
|
w.write(b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
|
||||||
w.write_list([u'curve25519-sha256@libssh.org', u'ecdh-sha2-nistp256', u'ecdh-sha2-nistp384', u'ecdh-sha2-nistp521', u'diffie-hellman-group-exchange-sha256', u'diffie-hellman-group14-sha1'])
|
w.write_list([u'curve25519-sha256@libssh.org', u'ecdh-sha2-nistp256', u'ecdh-sha2-nistp384', u'ecdh-sha2-nistp521', u'diffie-hellman-group-exchange-sha256', u'diffie-hellman-group14-sha1'])
|
||||||
w.write_list([u'ssh-rsa', u'rsa-sha2-512', u'rsa-sha2-256', u'ssh-ed25519'])
|
w.write_list([u'ssh-rsa', u'rsa-sha2-512', u'rsa-sha2-256', u'ssh-ed25519'])
|
||||||
w.write_list([u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc'])
|
w.write_list([u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc'])
|
||||||
w.write_list([u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc'])
|
w.write_list([u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc'])
|
||||||
w.write_list([u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1'])
|
w.write_list([u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1'])
|
||||||
w.write_list([u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1'])
|
w.write_list([u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1'])
|
||||||
w.write_list([u'none', u'zlib@openssh.com'])
|
w.write_list([u'none', u'zlib@openssh.com'])
|
||||||
w.write_list([u'none', u'zlib@openssh.com'])
|
w.write_list([u'none', u'zlib@openssh.com'])
|
||||||
w.write_list([u''])
|
w.write_list([u''])
|
||||||
w.write_list([u''])
|
w.write_list([u''])
|
||||||
w.write_byte(False)
|
w.write_byte(False)
|
||||||
w.write_int(0)
|
w.write_int(0)
|
||||||
return w.write_flush()
|
return w.write_flush()
|
||||||
|
|
||||||
def test_kex_read(self):
|
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 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.cookie == b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
assert kex.kex_algorithms == [u'curve25519-sha256@libssh.org', u'ecdh-sha2-nistp256', u'ecdh-sha2-nistp384', u'ecdh-sha2-nistp521', u'diffie-hellman-group-exchange-sha256', u'diffie-hellman-group14-sha1']
|
assert kex.kex_algorithms == [u'curve25519-sha256@libssh.org', u'ecdh-sha2-nistp256', u'ecdh-sha2-nistp384', u'ecdh-sha2-nistp521', u'diffie-hellman-group-exchange-sha256', u'diffie-hellman-group14-sha1']
|
||||||
assert kex.key_algorithms == [u'ssh-rsa', u'rsa-sha2-512', u'rsa-sha2-256', u'ssh-ed25519']
|
assert kex.key_algorithms == [u'ssh-rsa', u'rsa-sha2-512', u'rsa-sha2-256', u'ssh-ed25519']
|
||||||
assert kex.client is not None
|
assert kex.client is not None
|
||||||
assert kex.server is not None
|
assert kex.server is not None
|
||||||
assert kex.client.encryption == [u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc']
|
assert kex.client.encryption == [u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc']
|
||||||
assert kex.server.encryption == [u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc']
|
assert kex.server.encryption == [u'chacha20-poly1305@openssh.com', u'aes128-ctr', u'aes192-ctr', u'aes256-ctr', u'aes128-gcm@openssh.com', u'aes256-gcm@openssh.com', u'aes128-cbc', u'aes192-cbc', u'aes256-cbc']
|
||||||
assert kex.client.mac == [u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1']
|
assert kex.client.mac == [u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1']
|
||||||
assert kex.server.mac == [u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1']
|
assert kex.server.mac == [u'umac-64-etm@openssh.com', u'umac-128-etm@openssh.com', u'hmac-sha2-256-etm@openssh.com', u'hmac-sha2-512-etm@openssh.com', u'hmac-sha1-etm@openssh.com', u'umac-64@openssh.com', u'umac-128@openssh.com', u'hmac-sha2-256', u'hmac-sha2-512', u'hmac-sha1']
|
||||||
assert kex.client.compression == [u'none', u'zlib@openssh.com']
|
assert kex.client.compression == [u'none', u'zlib@openssh.com']
|
||||||
assert kex.server.compression == [u'none', u'zlib@openssh.com']
|
assert kex.server.compression == [u'none', u'zlib@openssh.com']
|
||||||
assert kex.client.languages == [u'']
|
assert kex.client.languages == [u'']
|
||||||
assert kex.server.languages == [u'']
|
assert kex.server.languages == [u'']
|
||||||
assert kex.follows is False
|
assert kex.follows is False
|
||||||
assert kex.unused == 0
|
assert kex.unused == 0
|
||||||
|
|
||||||
def _get_empty_kex(self, cookie=None):
|
def _get_empty_kex(self, cookie=None):
|
||||||
kex_algs, key_algs = [], []
|
kex_algs, key_algs = [], []
|
||||||
enc, mac, compression, languages = [], [], ['none'], []
|
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'], []
|
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:
|
if cookie is None:
|
||||||
cookie = os.urandom(16)
|
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
|
return kex
|
||||||
|
|
||||||
def _get_kex_variat1(self):
|
def _get_kex_variat1(self):
|
||||||
cookie = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
cookie = b'\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
|
||||||
kex = self._get_empty_kex(cookie)
|
kex = self._get_empty_kex(cookie)
|
||||||
kex.kex_algorithms.append('curve25519-sha256@libssh.org')
|
kex.kex_algorithms.append('curve25519-sha256@libssh.org')
|
||||||
kex.kex_algorithms.append('ecdh-sha2-nistp256')
|
kex.kex_algorithms.append('ecdh-sha2-nistp256')
|
||||||
kex.kex_algorithms.append('ecdh-sha2-nistp384')
|
kex.kex_algorithms.append('ecdh-sha2-nistp384')
|
||||||
kex.kex_algorithms.append('ecdh-sha2-nistp521')
|
kex.kex_algorithms.append('ecdh-sha2-nistp521')
|
||||||
kex.kex_algorithms.append('diffie-hellman-group-exchange-sha256')
|
kex.kex_algorithms.append('diffie-hellman-group-exchange-sha256')
|
||||||
kex.kex_algorithms.append('diffie-hellman-group14-sha1')
|
kex.kex_algorithms.append('diffie-hellman-group14-sha1')
|
||||||
kex.key_algorithms.append('ssh-rsa')
|
kex.key_algorithms.append('ssh-rsa')
|
||||||
kex.key_algorithms.append('rsa-sha2-512')
|
kex.key_algorithms.append('rsa-sha2-512')
|
||||||
kex.key_algorithms.append('rsa-sha2-256')
|
kex.key_algorithms.append('rsa-sha2-256')
|
||||||
kex.key_algorithms.append('ssh-ed25519')
|
kex.key_algorithms.append('ssh-ed25519')
|
||||||
kex.server.encryption.append('chacha20-poly1305@openssh.com')
|
kex.server.encryption.append('chacha20-poly1305@openssh.com')
|
||||||
kex.server.encryption.append('aes128-ctr')
|
kex.server.encryption.append('aes128-ctr')
|
||||||
kex.server.encryption.append('aes192-ctr')
|
kex.server.encryption.append('aes192-ctr')
|
||||||
kex.server.encryption.append('aes256-ctr')
|
kex.server.encryption.append('aes256-ctr')
|
||||||
kex.server.encryption.append('aes128-gcm@openssh.com')
|
kex.server.encryption.append('aes128-gcm@openssh.com')
|
||||||
kex.server.encryption.append('aes256-gcm@openssh.com')
|
kex.server.encryption.append('aes256-gcm@openssh.com')
|
||||||
kex.server.encryption.append('aes128-cbc')
|
kex.server.encryption.append('aes128-cbc')
|
||||||
kex.server.encryption.append('aes192-cbc')
|
kex.server.encryption.append('aes192-cbc')
|
||||||
kex.server.encryption.append('aes256-cbc')
|
kex.server.encryption.append('aes256-cbc')
|
||||||
kex.server.mac.append('umac-64-etm@openssh.com')
|
kex.server.mac.append('umac-64-etm@openssh.com')
|
||||||
kex.server.mac.append('umac-128-etm@openssh.com')
|
kex.server.mac.append('umac-128-etm@openssh.com')
|
||||||
kex.server.mac.append('hmac-sha2-256-etm@openssh.com')
|
kex.server.mac.append('hmac-sha2-256-etm@openssh.com')
|
||||||
kex.server.mac.append('hmac-sha2-512-etm@openssh.com')
|
kex.server.mac.append('hmac-sha2-512-etm@openssh.com')
|
||||||
kex.server.mac.append('hmac-sha1-etm@openssh.com')
|
kex.server.mac.append('hmac-sha1-etm@openssh.com')
|
||||||
kex.server.mac.append('umac-64@openssh.com')
|
kex.server.mac.append('umac-64@openssh.com')
|
||||||
kex.server.mac.append('umac-128@openssh.com')
|
kex.server.mac.append('umac-128@openssh.com')
|
||||||
kex.server.mac.append('hmac-sha2-256')
|
kex.server.mac.append('hmac-sha2-256')
|
||||||
kex.server.mac.append('hmac-sha2-512')
|
kex.server.mac.append('hmac-sha2-512')
|
||||||
kex.server.mac.append('hmac-sha1')
|
kex.server.mac.append('hmac-sha1')
|
||||||
kex.server.compression.append('zlib@openssh.com')
|
kex.server.compression.append('zlib@openssh.com')
|
||||||
for a in kex.server.encryption:
|
for a in kex.server.encryption:
|
||||||
kex.client.encryption.append(a)
|
kex.client.encryption.append(a)
|
||||||
for a in kex.server.mac:
|
for a in kex.server.mac:
|
||||||
kex.client.mac.append(a)
|
kex.client.mac.append(a)
|
||||||
for a in kex.server.compression:
|
for a in kex.server.compression:
|
||||||
if a == 'none':
|
if a == 'none':
|
||||||
continue
|
continue
|
||||||
kex.client.compression.append(a)
|
kex.client.compression.append(a)
|
||||||
return kex
|
return kex
|
||||||
|
|
||||||
def test_key_payload(self):
|
def test_key_payload(self):
|
||||||
kex1 = self._get_kex_variat1()
|
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
|
assert kex1.payload == kex2.payload
|
||||||
|
|
||||||
@pytest.mark.skip(reason="Temporarily skip this test to have a working test suite!")
|
@pytest.mark.skip(reason="Temporarily skip this test to have a working test suite!")
|
||||||
def test_ssh2_server_simple(self, output_spy, virtual_socket):
|
def test_ssh2_server_simple(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write_byte(self.ssh.Protocol.MSG_KEXINIT)
|
w.write_byte(self.ssh.Protocol.MSG_KEXINIT)
|
||||||
w.write(self._kex_payload())
|
w.write(self._kex_payload())
|
||||||
vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n')
|
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()))
|
vsocket.rdata.append(self._create_ssh2_packet(w.write_flush()))
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
self.audit(self._conf())
|
self.audit(self._conf())
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 72
|
assert len(lines) == 72
|
||||||
|
|
||||||
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
|
def test_ssh2_server_invalid_first_packet(self, output_spy, virtual_socket):
|
||||||
vsocket = virtual_socket
|
vsocket = virtual_socket
|
||||||
w = self.wbuf()
|
w = self.wbuf()
|
||||||
w.write_byte(self.ssh.Protocol.MSG_KEXINIT + 1)
|
w.write_byte(self.ssh.Protocol.MSG_KEXINIT + 1)
|
||||||
vsocket.rdata.append(b'SSH-2.0-OpenSSH_7.3 ssh-audit-test\r\n')
|
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()))
|
vsocket.rdata.append(self._create_ssh2_packet(w.write_flush()))
|
||||||
output_spy.begin()
|
output_spy.begin()
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
self.audit(self._conf())
|
self.audit(self._conf())
|
||||||
lines = output_spy.flush()
|
lines = output_spy.flush()
|
||||||
assert len(lines) == 3
|
assert len(lines) == 3
|
||||||
assert 'unknown message' in lines[-1]
|
assert 'unknown message' in lines[-1]
|
||||||
|
@ -5,160 +5,160 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestSSHAlgorithm(object):
|
class TestSSHAlgorithm(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def _tf(self, v, s=None):
|
def _tf(self, v, s=None):
|
||||||
return self.ssh.Algorithm.Timeframe().update(v, s)
|
return self.ssh.Algorithm.Timeframe().update(v, s)
|
||||||
|
|
||||||
def test_get_ssh_version(self):
|
def test_get_ssh_version(self):
|
||||||
def ver(v):
|
def ver(v):
|
||||||
return self.ssh.Algorithm.get_ssh_version(v)
|
return self.ssh.Algorithm.get_ssh_version(v)
|
||||||
|
|
||||||
assert ver('7.5') == ('OpenSSH', '7.5', False)
|
assert ver('7.5') == ('OpenSSH', '7.5', False)
|
||||||
assert ver('7.5C') == ('OpenSSH', '7.5', True)
|
assert ver('7.5C') == ('OpenSSH', '7.5', True)
|
||||||
assert ver('d2016.74') == ('Dropbear SSH', '2016.74', False)
|
assert ver('d2016.74') == ('Dropbear SSH', '2016.74', False)
|
||||||
assert ver('l10.7.4') == ('libssh', '0.7.4', False)
|
assert ver('l10.7.4') == ('libssh', '0.7.4', False)
|
||||||
assert ver('')[1] == ''
|
assert ver('')[1] == ''
|
||||||
|
|
||||||
def test_get_since_text(self):
|
def test_get_since_text(self):
|
||||||
def gst(v):
|
def gst(v):
|
||||||
return self.ssh.Algorithm.get_since_text(v)
|
return self.ssh.Algorithm.get_since_text(v)
|
||||||
|
|
||||||
assert gst(['7.5']) == 'available since OpenSSH 7.5'
|
assert gst(['7.5']) == 'available since OpenSSH 7.5'
|
||||||
assert gst(['7.5C']) == 'available since OpenSSH 7.5 (client only)'
|
assert gst(['7.5C']) == 'available since OpenSSH 7.5 (client only)'
|
||||||
assert gst(['7.5,']) == 'available since OpenSSH 7.5'
|
assert gst(['7.5,']) == 'available since OpenSSH 7.5'
|
||||||
assert gst(['d2016.73']) == 'available since Dropbear SSH 2016.73'
|
assert gst(['d2016.73']) == 'available since Dropbear SSH 2016.73'
|
||||||
assert gst(['7.5,d2016.73']) == 'available since OpenSSH 7.5, Dropbear SSH 2016.73'
|
assert gst(['7.5,d2016.73']) == 'available since OpenSSH 7.5, Dropbear SSH 2016.73'
|
||||||
assert gst(['l10.7.4']) is None
|
assert gst(['l10.7.4']) is None
|
||||||
assert gst([]) is None
|
assert gst([]) is None
|
||||||
|
|
||||||
def test_timeframe_creation(self):
|
def test_timeframe_creation(self):
|
||||||
# pylint: disable=line-too-long,too-many-statements
|
# pylint: disable=line-too-long,too-many-statements
|
||||||
def cmp_tf(v, s, r):
|
def cmp_tf(v, s, r):
|
||||||
assert str(self._tf(v, s)) == str(r)
|
assert str(self._tf(v, s)) == str(r)
|
||||||
|
|
||||||
cmp_tf(['6.2'], None, {'OpenSSH': ['6.2', None, '6.2', None]})
|
cmp_tf(['6.2'], None, {'OpenSSH': ['6.2', None, '6.2', None]})
|
||||||
cmp_tf(['6.2'], True, {'OpenSSH': ['6.2', None, None, None]})
|
cmp_tf(['6.2'], True, {'OpenSSH': ['6.2', None, None, None]})
|
||||||
cmp_tf(['6.2'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C'], None, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C'], None, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C'], True, {})
|
cmp_tf(['6.2C'], True, {})
|
||||||
cmp_tf(['6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.1,6.2C'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
|
cmp_tf(['6.1,6.2C'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
|
||||||
cmp_tf(['6.1,6.2C'], True, {'OpenSSH': ['6.1', None, None, None]})
|
cmp_tf(['6.1,6.2C'], True, {'OpenSSH': ['6.1', None, None, None]})
|
||||||
cmp_tf(['6.1,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.1,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.1'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
|
cmp_tf(['6.2C,6.1'], None, {'OpenSSH': ['6.1', None, '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.1'], True, {'OpenSSH': ['6.1', None, None, None]})
|
cmp_tf(['6.2C,6.1'], True, {'OpenSSH': ['6.1', None, None, None]})
|
||||||
cmp_tf(['6.2C,6.1'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C,6.1'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.3,6.2C'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
|
cmp_tf(['6.3,6.2C'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
|
||||||
cmp_tf(['6.3,6.2C'], True, {'OpenSSH': ['6.3', None, None, None]})
|
cmp_tf(['6.3,6.2C'], True, {'OpenSSH': ['6.3', None, None, None]})
|
||||||
cmp_tf(['6.3,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.3,6.2C'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.3'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
|
cmp_tf(['6.2C,6.3'], None, {'OpenSSH': ['6.3', None, '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.3'], True, {'OpenSSH': ['6.3', None, None, None]})
|
cmp_tf(['6.2C,6.3'], True, {'OpenSSH': ['6.3', None, None, None]})
|
||||||
cmp_tf(['6.2C,6.3'], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C,6.3'], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
|
|
||||||
cmp_tf(['6.2', '6.6'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '6.6']})
|
cmp_tf(['6.2', '6.6'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.2', '6.6'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.2', '6.6'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.2', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.2', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C', '6.6'], None, {'OpenSSH': [None, '6.6', '6.2', '6.6']})
|
cmp_tf(['6.2C', '6.6'], None, {'OpenSSH': [None, '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C', '6.6'], True, {'OpenSSH': [None, '6.6', None, None]})
|
cmp_tf(['6.2C', '6.6'], True, {'OpenSSH': [None, '6.6', None, None]})
|
||||||
cmp_tf(['6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
cmp_tf(['6.1,6.2C', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
|
cmp_tf(['6.1,6.2C', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.1,6.2C', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.1,6.2C', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.1,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.1,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C,6.1', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
|
cmp_tf(['6.2C,6.1', '6.6'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C,6.1', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.2C,6.1', '6.6'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.2C,6.1', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.2C,6.1', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
cmp_tf(['6.3,6.2C', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
|
cmp_tf(['6.3,6.2C', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.3,6.2C', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
|
cmp_tf(['6.3,6.2C', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
|
||||||
cmp_tf(['6.3,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.3,6.2C', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C,6.3', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
|
cmp_tf(['6.2C,6.3', '6.6'], None, {'OpenSSH': ['6.3', '6.6', '6.2', '6.6']})
|
||||||
cmp_tf(['6.2C,6.3', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
|
cmp_tf(['6.2C,6.3', '6.6'], True, {'OpenSSH': ['6.3', '6.6', None, None]})
|
||||||
cmp_tf(['6.2C,6.3', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
cmp_tf(['6.2C,6.3', '6.6'], False, {'OpenSSH': [None, None, '6.2', '6.6']})
|
||||||
|
|
||||||
cmp_tf(['6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.2', None]})
|
cmp_tf(['6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.2', None]})
|
||||||
cmp_tf(['6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C', '6.6', None], None, {'OpenSSH': [None, '6.6', '6.2', None]})
|
cmp_tf(['6.2C', '6.6', None], None, {'OpenSSH': [None, '6.6', '6.2', None]})
|
||||||
cmp_tf(['6.2C', '6.6', None], True, {'OpenSSH': [None, '6.6', None, None]})
|
cmp_tf(['6.2C', '6.6', None], True, {'OpenSSH': [None, '6.6', None, None]})
|
||||||
cmp_tf(['6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
|
cmp_tf(['6.1,6.2C', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.1,6.2C', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.1,6.2C', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
|
cmp_tf(['6.2C,6.1', '6.6', None], None, {'OpenSSH': ['6.1', '6.6', '6.2', None]})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.2C,6.1', '6.6', None], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
cmp_tf(['6.2C,6.1', '6.6', None], False, {'OpenSSH': [None, None, '6.2', None]})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
|
cmp_tf(['6.2,6.3C', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.2,6.3C', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
|
cmp_tf(['6.2,6.3C', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
|
cmp_tf(['6.3C,6.2', '6.6', None], None, {'OpenSSH': ['6.2', '6.6', '6.3', None]})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.3C,6.2', '6.6', None], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
|
cmp_tf(['6.3C,6.2', '6.6', None], False, {'OpenSSH': [None, None, '6.3', None]})
|
||||||
|
|
||||||
cmp_tf(['6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '7.1']})
|
cmp_tf(['6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.2', '7.1']})
|
||||||
cmp_tf(['6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
cmp_tf(['6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
|
cmp_tf(['6.1,6.2C', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.1,6.2C', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.1,6.2C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
cmp_tf(['6.1,6.2C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
|
cmp_tf(['6.2C,6.1', '6.6', '7.1'], None, {'OpenSSH': ['6.1', '6.6', '6.2', '7.1']})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
cmp_tf(['6.2C,6.1', '6.6', '7.1'], True, {'OpenSSH': ['6.1', '6.6', None, None]})
|
||||||
cmp_tf(['6.2C,6.1', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
cmp_tf(['6.2C,6.1', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.2', '7.1']})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
|
cmp_tf(['6.2,6.3C', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.2,6.3C', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.2,6.3C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
|
cmp_tf(['6.2,6.3C', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
|
cmp_tf(['6.3C,6.2', '6.6', '7.1'], None, {'OpenSSH': ['6.2', '6.6', '6.3', '7.1']})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
cmp_tf(['6.3C,6.2', '6.6', '7.1'], True, {'OpenSSH': ['6.2', '6.6', None, None]})
|
||||||
cmp_tf(['6.3C,6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
|
cmp_tf(['6.3C,6.2', '6.6', '7.1'], False, {'OpenSSH': [None, None, '6.3', '7.1']})
|
||||||
|
|
||||||
tf1 = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
|
tf1 = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
|
||||||
tf2 = self._tf(['d2016.72,6.2C,6.1', 'd2016.73,6.6', 'd2016.74,7.1'])
|
tf2 = self._tf(['d2016.72,6.2C,6.1', 'd2016.73,6.6', 'd2016.74,7.1'])
|
||||||
tf3 = self._tf(['d2016.72,6.2C,6.1', '6.6,d2016.73', '7.1,d2016.74'])
|
tf3 = self._tf(['d2016.72,6.2C,6.1', '6.6,d2016.73', '7.1,d2016.74'])
|
||||||
# check without caring for output order
|
# check without caring for output order
|
||||||
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
|
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
|
||||||
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
|
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
|
||||||
assert len(str(tf1)) == len(str(tf2)) == len(str(tf3))
|
assert len(str(tf1)) == len(str(tf2)) == len(str(tf3))
|
||||||
assert ov in str(tf1) and ov in str(tf2) and ov in str(tf3)
|
assert ov in str(tf1) and ov in str(tf2) and ov in str(tf3)
|
||||||
assert dv in str(tf1) and dv in str(tf2) and dv in str(tf3)
|
assert dv in str(tf1) and dv in str(tf2) and dv in str(tf3)
|
||||||
assert ov in repr(tf1) and ov in repr(tf2) and ov in repr(tf3)
|
assert ov in repr(tf1) and ov in repr(tf2) and ov in repr(tf3)
|
||||||
assert dv in repr(tf1) and dv in repr(tf2) and dv in repr(tf3)
|
assert dv in repr(tf1) and dv in repr(tf2) and dv in repr(tf3)
|
||||||
|
|
||||||
def test_timeframe_object(self):
|
def test_timeframe_object(self):
|
||||||
tf = self._tf(['6.1,6.2C', '6.6', '7.1'])
|
tf = self._tf(['6.1,6.2C', '6.6', '7.1'])
|
||||||
assert 'OpenSSH' in tf
|
assert 'OpenSSH' in tf
|
||||||
assert 'Dropbear SSH' not in tf
|
assert 'Dropbear SSH' not in tf
|
||||||
assert 'libssh' not in tf
|
assert 'libssh' not in tf
|
||||||
assert 'unknown' not in tf
|
assert 'unknown' not in tf
|
||||||
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
|
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
|
||||||
assert tf['Dropbear SSH'] == (None, None, None, None)
|
assert tf['Dropbear SSH'] == (None, None, None, None)
|
||||||
assert tf['libssh'] == (None, None, None, None)
|
assert tf['libssh'] == (None, None, None, None)
|
||||||
assert tf['unknown'] == (None, None, None, None)
|
assert tf['unknown'] == (None, None, None, None)
|
||||||
assert tf.get_from('OpenSSH', True) == '6.1'
|
assert tf.get_from('OpenSSH', True) == '6.1'
|
||||||
assert tf.get_till('OpenSSH', True) == '6.6'
|
assert tf.get_till('OpenSSH', True) == '6.6'
|
||||||
assert tf.get_from('OpenSSH', False) == '6.2'
|
assert tf.get_from('OpenSSH', False) == '6.2'
|
||||||
assert tf.get_till('OpenSSH', False) == '7.1'
|
assert tf.get_till('OpenSSH', False) == '7.1'
|
||||||
|
|
||||||
tf = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
|
tf = self._tf(['6.1,d2016.72,6.2C', '6.6,d2016.73', '7.1,d2016.74'])
|
||||||
assert 'OpenSSH' in tf
|
assert 'OpenSSH' in tf
|
||||||
assert 'Dropbear SSH' in tf
|
assert 'Dropbear SSH' in tf
|
||||||
assert 'libssh' not in tf
|
assert 'libssh' not in tf
|
||||||
assert 'unknown' not in tf
|
assert 'unknown' not in tf
|
||||||
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
|
assert tf['OpenSSH'] == ('6.1', '6.6', '6.2', '7.1')
|
||||||
assert tf['Dropbear SSH'] == ('2016.72', '2016.73', '2016.72', '2016.74')
|
assert tf['Dropbear SSH'] == ('2016.72', '2016.73', '2016.72', '2016.74')
|
||||||
assert tf['libssh'] == (None, None, None, None)
|
assert tf['libssh'] == (None, None, None, None)
|
||||||
assert tf['unknown'] == (None, None, None, None)
|
assert tf['unknown'] == (None, None, None, None)
|
||||||
assert tf.get_from('OpenSSH', True) == '6.1'
|
assert tf.get_from('OpenSSH', True) == '6.1'
|
||||||
assert tf.get_till('OpenSSH', True) == '6.6'
|
assert tf.get_till('OpenSSH', True) == '6.6'
|
||||||
assert tf.get_from('OpenSSH', False) == '6.2'
|
assert tf.get_from('OpenSSH', False) == '6.2'
|
||||||
assert tf.get_till('OpenSSH', False) == '7.1'
|
assert tf.get_till('OpenSSH', False) == '7.1'
|
||||||
assert tf.get_from('Dropbear SSH', True) == '2016.72'
|
assert tf.get_from('Dropbear SSH', True) == '2016.72'
|
||||||
assert tf.get_till('Dropbear SSH', True) == '2016.73'
|
assert tf.get_till('Dropbear SSH', True) == '2016.73'
|
||||||
assert tf.get_from('Dropbear SSH', False) == '2016.72'
|
assert tf.get_from('Dropbear SSH', False) == '2016.72'
|
||||||
assert tf.get_till('Dropbear SSH', False) == '2016.74'
|
assert tf.get_till('Dropbear SSH', False) == '2016.74'
|
||||||
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
|
ov = "'OpenSSH': ['6.1', '6.6', '6.2', '7.1']"
|
||||||
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
|
dv = "'Dropbear SSH': ['2016.72', '2016.73', '2016.72', '2016.74']"
|
||||||
assert ov in str(tf)
|
assert ov in str(tf)
|
||||||
assert dv in str(tf)
|
assert dv in str(tf)
|
||||||
assert ov in repr(tf)
|
assert ov in repr(tf)
|
||||||
assert dv in repr(tf)
|
assert dv in repr(tf)
|
||||||
|
@ -6,213 +6,213 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestUtils(object):
|
class TestUtils(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.utils = ssh_audit.Utils
|
self.utils = ssh_audit.Utils
|
||||||
self.PY3 = sys.version_info >= (3,)
|
self.PY3 = sys.version_info >= (3,)
|
||||||
|
|
||||||
def test_to_bytes_py2(self):
|
def test_to_bytes_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# binary_type (native str, bytes as str)
|
# binary_type (native str, bytes as str)
|
||||||
assert self.utils.to_bytes('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_bytes('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
||||||
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.to_bytes(u'fran\xe7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_bytes(u'fran\xe7ais') == 'fran\xc3\xa7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_bytes(123)
|
self.utils.to_bytes(123)
|
||||||
|
|
||||||
def test_to_bytes_py3(self):
|
def test_to_bytes_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# binary_type (bytes)
|
# binary_type (bytes)
|
||||||
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == b'fran\xc3\xa7ais'
|
assert self.utils.to_bytes(b'fran\xc3\xa7ais') == b'fran\xc3\xa7ais'
|
||||||
# text_type (native str as unicode, unicode)
|
# text_type (native str as unicode, unicode)
|
||||||
assert self.utils.to_bytes('fran\xe7ais') == b'fran\xc3\xa7ais'
|
assert self.utils.to_bytes('fran\xe7ais') == b'fran\xc3\xa7ais'
|
||||||
assert self.utils.to_bytes(u'fran\xe7ais') == b'fran\xc3\xa7ais'
|
assert self.utils.to_bytes(u'fran\xe7ais') == b'fran\xc3\xa7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_bytes(123)
|
self.utils.to_bytes(123)
|
||||||
|
|
||||||
def test_to_utext_py2(self):
|
def test_to_utext_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# binary_type (native str, bytes as str)
|
# binary_type (native str, bytes as str)
|
||||||
assert self.utils.to_utext('fran\xc3\xa7ais') == u'fran\xe7ais'
|
assert self.utils.to_utext('fran\xc3\xa7ais') == u'fran\xe7ais'
|
||||||
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
|
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
|
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_utext(123)
|
self.utils.to_utext(123)
|
||||||
|
|
||||||
def test_to_utext_py3(self):
|
def test_to_utext_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# binary_type (bytes)
|
# binary_type (bytes)
|
||||||
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
|
assert self.utils.to_utext(b'fran\xc3\xa7ais') == u'fran\xe7ais'
|
||||||
# text_type (native str as unicode, unicode)
|
# text_type (native str as unicode, unicode)
|
||||||
assert self.utils.to_utext('fran\xe7ais') == 'fran\xe7ais'
|
assert self.utils.to_utext('fran\xe7ais') == 'fran\xe7ais'
|
||||||
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
|
assert self.utils.to_utext(u'fran\xe7ais') == u'fran\xe7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_utext(123)
|
self.utils.to_utext(123)
|
||||||
|
|
||||||
def test_to_ntext_py2(self):
|
def test_to_ntext_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# str (native str, bytes as str)
|
# str (native str, bytes as str)
|
||||||
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
||||||
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xc3\xa7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_ntext(123)
|
self.utils.to_ntext(123)
|
||||||
|
|
||||||
def test_to_ntext_py3(self):
|
def test_to_ntext_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# str (native str)
|
# str (native str)
|
||||||
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
assert self.utils.to_ntext('fran\xc3\xa7ais') == 'fran\xc3\xa7ais'
|
||||||
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xe7ais'
|
assert self.utils.to_ntext(u'fran\xe7ais') == 'fran\xe7ais'
|
||||||
# binary_type (bytes)
|
# binary_type (bytes)
|
||||||
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xe7ais'
|
assert self.utils.to_ntext(b'fran\xc3\xa7ais') == 'fran\xe7ais'
|
||||||
# other
|
# other
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_ntext(123)
|
self.utils.to_ntext(123)
|
||||||
|
|
||||||
def test_is_ascii_py2(self):
|
def test_is_ascii_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.is_ascii(u'francais') is True
|
assert self.utils.is_ascii(u'francais') is True
|
||||||
assert self.utils.is_ascii(u'fran\xe7ais') is False
|
assert self.utils.is_ascii(u'fran\xe7ais') is False
|
||||||
# str
|
# str
|
||||||
assert self.utils.is_ascii('francais') is True
|
assert self.utils.is_ascii('francais') is True
|
||||||
assert self.utils.is_ascii('fran\xc3\xa7ais') is False
|
assert self.utils.is_ascii('fran\xc3\xa7ais') is False
|
||||||
# other
|
# other
|
||||||
assert self.utils.is_ascii(123) is False
|
assert self.utils.is_ascii(123) is False
|
||||||
|
|
||||||
def test_is_ascii_py3(self):
|
def test_is_ascii_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (str)
|
# text_type (str)
|
||||||
assert self.utils.is_ascii('francais') is True
|
assert self.utils.is_ascii('francais') is True
|
||||||
assert self.utils.is_ascii(u'francais') is True
|
assert self.utils.is_ascii(u'francais') is True
|
||||||
assert self.utils.is_ascii('fran\xe7ais') is False
|
assert self.utils.is_ascii('fran\xe7ais') is False
|
||||||
assert self.utils.is_ascii(u'fran\xe7ais') is False
|
assert self.utils.is_ascii(u'fran\xe7ais') is False
|
||||||
# other
|
# other
|
||||||
assert self.utils.is_ascii(123) is False
|
assert self.utils.is_ascii(123) is False
|
||||||
|
|
||||||
def test_to_ascii_py2(self):
|
def test_to_ascii_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.to_ascii(u'francais') == 'francais'
|
assert self.utils.to_ascii(u'francais') == 'francais'
|
||||||
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
||||||
# str
|
# str
|
||||||
assert self.utils.to_ascii('francais') == 'francais'
|
assert self.utils.to_ascii('francais') == 'francais'
|
||||||
assert self.utils.to_ascii('fran\xc3\xa7ais') == 'fran??ais'
|
assert self.utils.to_ascii('fran\xc3\xa7ais') == 'fran??ais'
|
||||||
assert self.utils.to_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
|
assert self.utils.to_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_ascii(123)
|
self.utils.to_ascii(123)
|
||||||
|
|
||||||
def test_to_ascii_py3(self):
|
def test_to_ascii_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (str)
|
# text_type (str)
|
||||||
assert self.utils.to_ascii('francais') == 'francais'
|
assert self.utils.to_ascii('francais') == 'francais'
|
||||||
assert self.utils.to_ascii(u'francais') == 'francais'
|
assert self.utils.to_ascii(u'francais') == 'francais'
|
||||||
assert self.utils.to_ascii('fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_ascii('fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_ascii('fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_ascii('fran\xe7ais', 'ignore') == 'franais'
|
||||||
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_ascii(u'fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_ascii(123)
|
self.utils.to_ascii(123)
|
||||||
|
|
||||||
def test_is_print_ascii_py2(self):
|
def test_is_print_ascii_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.is_print_ascii(u'francais') is True
|
assert self.utils.is_print_ascii(u'francais') is True
|
||||||
assert self.utils.is_print_ascii(u'francais\n') is False
|
assert self.utils.is_print_ascii(u'francais\n') is False
|
||||||
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
|
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
|
||||||
assert self.utils.is_print_ascii(u'fran\xe7ais\n') is False
|
assert self.utils.is_print_ascii(u'fran\xe7ais\n') is False
|
||||||
# str
|
# str
|
||||||
assert self.utils.is_print_ascii('francais') is True
|
assert self.utils.is_print_ascii('francais') is True
|
||||||
assert self.utils.is_print_ascii('francais\n') is False
|
assert self.utils.is_print_ascii('francais\n') is False
|
||||||
assert self.utils.is_print_ascii('fran\xc3\xa7ais') is False
|
assert self.utils.is_print_ascii('fran\xc3\xa7ais') is False
|
||||||
# other
|
# other
|
||||||
assert self.utils.is_print_ascii(123) is False
|
assert self.utils.is_print_ascii(123) is False
|
||||||
|
|
||||||
def test_is_print_ascii_py3(self):
|
def test_is_print_ascii_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (str)
|
# text_type (str)
|
||||||
assert self.utils.is_print_ascii('francais') is True
|
assert self.utils.is_print_ascii('francais') is True
|
||||||
assert self.utils.is_print_ascii('francais\n') is False
|
assert self.utils.is_print_ascii('francais\n') is False
|
||||||
assert self.utils.is_print_ascii(u'francais') is True
|
assert self.utils.is_print_ascii(u'francais') is True
|
||||||
assert self.utils.is_print_ascii(u'francais\n') is False
|
assert self.utils.is_print_ascii(u'francais\n') is False
|
||||||
assert self.utils.is_print_ascii('fran\xe7ais') is False
|
assert self.utils.is_print_ascii('fran\xe7ais') is False
|
||||||
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
|
assert self.utils.is_print_ascii(u'fran\xe7ais') is False
|
||||||
# other
|
# other
|
||||||
assert self.utils.is_print_ascii(123) is False
|
assert self.utils.is_print_ascii(123) is False
|
||||||
|
|
||||||
def test_to_print_ascii_py2(self):
|
def test_to_print_ascii_py2(self):
|
||||||
if self.PY3:
|
if self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (unicode)
|
# text_type (unicode)
|
||||||
assert self.utils.to_print_ascii(u'francais') == 'francais'
|
assert self.utils.to_print_ascii(u'francais') == 'francais'
|
||||||
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
|
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
|
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
|
||||||
# str
|
# str
|
||||||
assert self.utils.to_print_ascii('francais') == 'francais'
|
assert self.utils.to_print_ascii('francais') == 'francais'
|
||||||
assert self.utils.to_print_ascii('francais\n') == 'francais?'
|
assert self.utils.to_print_ascii('francais\n') == 'francais?'
|
||||||
assert self.utils.to_print_ascii('fran\xc3\xa7ais') == 'fran??ais'
|
assert self.utils.to_print_ascii('fran\xc3\xa7ais') == 'fran??ais'
|
||||||
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n') == 'fran??ais?'
|
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n') == 'fran??ais?'
|
||||||
assert self.utils.to_print_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii('fran\xc3\xa7ais', 'ignore') == 'franais'
|
||||||
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii('fran\xc3\xa7ais\n', 'ignore') == 'franais'
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_print_ascii(123)
|
self.utils.to_print_ascii(123)
|
||||||
|
|
||||||
def test_to_print_ascii_py3(self):
|
def test_to_print_ascii_py3(self):
|
||||||
if not self.PY3:
|
if not self.PY3:
|
||||||
return
|
return
|
||||||
# text_type (str)
|
# text_type (str)
|
||||||
assert self.utils.to_print_ascii('francais') == 'francais'
|
assert self.utils.to_print_ascii('francais') == 'francais'
|
||||||
assert self.utils.to_print_ascii('francais\n') == 'francais?'
|
assert self.utils.to_print_ascii('francais\n') == 'francais?'
|
||||||
assert self.utils.to_print_ascii(u'francais') == 'francais'
|
assert self.utils.to_print_ascii(u'francais') == 'francais'
|
||||||
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
|
assert self.utils.to_print_ascii(u'francais\n') == 'francais?'
|
||||||
assert self.utils.to_print_ascii('fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_print_ascii('fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_print_ascii('fran\xe7ais\n') == 'fran?ais?'
|
assert self.utils.to_print_ascii('fran\xe7ais\n') == 'fran?ais?'
|
||||||
assert self.utils.to_print_ascii('fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii('fran\xe7ais', 'ignore') == 'franais'
|
||||||
assert self.utils.to_print_ascii('fran\xe7ais\n', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii('fran\xe7ais\n', 'ignore') == 'franais'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais') == 'fran?ais'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
|
assert self.utils.to_print_ascii(u'fran\xe7ais\n') == 'fran?ais?'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais', 'ignore') == 'franais'
|
||||||
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
|
assert self.utils.to_print_ascii(u'fran\xe7ais\n', 'ignore') == 'franais'
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
self.utils.to_print_ascii(123)
|
self.utils.to_print_ascii(123)
|
||||||
|
|
||||||
def test_ctoi(self):
|
def test_ctoi(self):
|
||||||
assert self.utils.ctoi(123) == 123
|
assert self.utils.ctoi(123) == 123
|
||||||
assert self.utils.ctoi('ABC') == 65
|
assert self.utils.ctoi('ABC') == 65
|
||||||
|
|
||||||
def test_parse_int(self):
|
def test_parse_int(self):
|
||||||
assert self.utils.parse_int(123) == 123
|
assert self.utils.parse_int(123) == 123
|
||||||
assert self.utils.parse_int('123') == 123
|
assert self.utils.parse_int('123') == 123
|
||||||
assert self.utils.parse_int(-123) == -123
|
assert self.utils.parse_int(-123) == -123
|
||||||
assert self.utils.parse_int('-123') == -123
|
assert self.utils.parse_int('-123') == -123
|
||||||
assert self.utils.parse_int('abc') == 0
|
assert self.utils.parse_int('abc') == 0
|
||||||
|
|
||||||
def test_unique_seq(self):
|
def test_unique_seq(self):
|
||||||
assert self.utils.unique_seq((1, 2, 2, 3, 3, 3)) == (1, 2, 3)
|
assert self.utils.unique_seq((1, 2, 2, 3, 3, 3)) == (1, 2, 3)
|
||||||
assert self.utils.unique_seq((3, 3, 3, 2, 2, 1)) == (3, 2, 1)
|
assert self.utils.unique_seq((3, 3, 3, 2, 2, 1)) == (3, 2, 1)
|
||||||
assert self.utils.unique_seq([1, 2, 2, 3, 3, 3]) == [1, 2, 3]
|
assert self.utils.unique_seq([1, 2, 2, 3, 3, 3]) == [1, 2, 3]
|
||||||
assert self.utils.unique_seq([3, 3, 3, 2, 2, 1]) == [3, 2, 1]
|
assert self.utils.unique_seq([3, 3, 3, 2, 2, 1]) == [3, 2, 1]
|
||||||
|
@ -5,211 +5,211 @@ import pytest
|
|||||||
|
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
class TestVersionCompare(object):
|
class TestVersionCompare(object):
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init(self, ssh_audit):
|
def init(self, ssh_audit):
|
||||||
self.ssh = ssh_audit.SSH
|
self.ssh = ssh_audit.SSH
|
||||||
|
|
||||||
def get_dropbear_software(self, v):
|
def get_dropbear_software(self, v):
|
||||||
b = self.ssh.Banner.parse('SSH-2.0-dropbear_{0}'.format(v))
|
b = self.ssh.Banner.parse('SSH-2.0-dropbear_{0}'.format(v))
|
||||||
return self.ssh.Software.parse(b)
|
return self.ssh.Software.parse(b)
|
||||||
|
|
||||||
def get_openssh_software(self, v):
|
def get_openssh_software(self, v):
|
||||||
b = self.ssh.Banner.parse('SSH-2.0-OpenSSH_{0}'.format(v))
|
b = self.ssh.Banner.parse('SSH-2.0-OpenSSH_{0}'.format(v))
|
||||||
return self.ssh.Software.parse(b)
|
return self.ssh.Software.parse(b)
|
||||||
|
|
||||||
def get_libssh_software(self, v):
|
def get_libssh_software(self, v):
|
||||||
b = self.ssh.Banner.parse('SSH-2.0-libssh-{0}'.format(v))
|
b = self.ssh.Banner.parse('SSH-2.0-libssh-{0}'.format(v))
|
||||||
return self.ssh.Software.parse(b)
|
return self.ssh.Software.parse(b)
|
||||||
|
|
||||||
def test_dropbear_compare_version_pre_years(self):
|
def test_dropbear_compare_version_pre_years(self):
|
||||||
s = self.get_dropbear_software('0.44')
|
s = self.get_dropbear_software('0.44')
|
||||||
assert s.compare_version(None) == 1
|
assert s.compare_version(None) == 1
|
||||||
assert s.compare_version('') == 1
|
assert s.compare_version('') == 1
|
||||||
assert s.compare_version('0.43') > 0
|
assert s.compare_version('0.43') > 0
|
||||||
assert s.compare_version('0.44') == 0
|
assert s.compare_version('0.44') == 0
|
||||||
assert s.compare_version(s) == 0
|
assert s.compare_version(s) == 0
|
||||||
assert s.compare_version('0.45') < 0
|
assert s.compare_version('0.45') < 0
|
||||||
assert s.between_versions('0.43', '0.45')
|
assert s.between_versions('0.43', '0.45')
|
||||||
assert s.between_versions('0.43', '0.43') is False
|
assert s.between_versions('0.43', '0.43') is False
|
||||||
assert s.between_versions('0.45', '0.43') is False
|
assert s.between_versions('0.45', '0.43') is False
|
||||||
|
|
||||||
def test_dropbear_compare_version_with_years(self):
|
def test_dropbear_compare_version_with_years(self):
|
||||||
s = self.get_dropbear_software('2015.71')
|
s = self.get_dropbear_software('2015.71')
|
||||||
assert s.compare_version(None) == 1
|
assert s.compare_version(None) == 1
|
||||||
assert s.compare_version('') == 1
|
assert s.compare_version('') == 1
|
||||||
assert s.compare_version('2014.66') > 0
|
assert s.compare_version('2014.66') > 0
|
||||||
assert s.compare_version('2015.71') == 0
|
assert s.compare_version('2015.71') == 0
|
||||||
assert s.compare_version(s) == 0
|
assert s.compare_version(s) == 0
|
||||||
assert s.compare_version('2016.74') < 0
|
assert s.compare_version('2016.74') < 0
|
||||||
assert s.between_versions('2014.66', '2016.74')
|
assert s.between_versions('2014.66', '2016.74')
|
||||||
assert s.between_versions('2014.66', '2015.69') is False
|
assert s.between_versions('2014.66', '2015.69') is False
|
||||||
assert s.between_versions('2016.74', '2014.66') is False
|
assert s.between_versions('2016.74', '2014.66') is False
|
||||||
|
|
||||||
def test_dropbear_compare_version_mixed(self):
|
def test_dropbear_compare_version_mixed(self):
|
||||||
s = self.get_dropbear_software('0.53.1')
|
s = self.get_dropbear_software('0.53.1')
|
||||||
assert s.compare_version(None) == 1
|
assert s.compare_version(None) == 1
|
||||||
assert s.compare_version('') == 1
|
assert s.compare_version('') == 1
|
||||||
assert s.compare_version('0.53') > 0
|
assert s.compare_version('0.53') > 0
|
||||||
assert s.compare_version('0.53.1') == 0
|
assert s.compare_version('0.53.1') == 0
|
||||||
assert s.compare_version(s) == 0
|
assert s.compare_version(s) == 0
|
||||||
assert s.compare_version('2011.54') < 0
|
assert s.compare_version('2011.54') < 0
|
||||||
assert s.between_versions('0.53', '2011.54')
|
assert s.between_versions('0.53', '2011.54')
|
||||||
assert s.between_versions('0.53', '0.53') is False
|
assert s.between_versions('0.53', '0.53') is False
|
||||||
assert s.between_versions('2011.54', '0.53') is False
|
assert s.between_versions('2011.54', '0.53') is False
|
||||||
|
|
||||||
def test_dropbear_compare_version_patchlevel(self):
|
def test_dropbear_compare_version_patchlevel(self):
|
||||||
s1 = self.get_dropbear_software('0.44')
|
s1 = self.get_dropbear_software('0.44')
|
||||||
s2 = self.get_dropbear_software('0.44test3')
|
s2 = self.get_dropbear_software('0.44test3')
|
||||||
assert s1.compare_version(None) == 1
|
assert s1.compare_version(None) == 1
|
||||||
assert s1.compare_version('') == 1
|
assert s1.compare_version('') == 1
|
||||||
assert s1.compare_version('0.44') == 0
|
assert s1.compare_version('0.44') == 0
|
||||||
assert s1.compare_version(s1) == 0
|
assert s1.compare_version(s1) == 0
|
||||||
assert s1.compare_version('0.43') > 0
|
assert s1.compare_version('0.43') > 0
|
||||||
assert s1.compare_version('0.44test4') > 0
|
assert s1.compare_version('0.44test4') > 0
|
||||||
assert s1.between_versions('0.44test4', '0.45')
|
assert s1.between_versions('0.44test4', '0.45')
|
||||||
assert s1.between_versions('0.43', '0.44test4') is False
|
assert s1.between_versions('0.43', '0.44test4') is False
|
||||||
assert s1.between_versions('0.45', '0.44test4') is False
|
assert s1.between_versions('0.45', '0.44test4') is False
|
||||||
assert s2.compare_version(None) == 1
|
assert s2.compare_version(None) == 1
|
||||||
assert s2.compare_version('') == 1
|
assert s2.compare_version('') == 1
|
||||||
assert s2.compare_version('0.44test3') == 0
|
assert s2.compare_version('0.44test3') == 0
|
||||||
assert s2.compare_version(s2) == 0
|
assert s2.compare_version(s2) == 0
|
||||||
assert s2.compare_version('0.44') < 0
|
assert s2.compare_version('0.44') < 0
|
||||||
assert s2.compare_version('0.44test4') < 0
|
assert s2.compare_version('0.44test4') < 0
|
||||||
assert s2.between_versions('0.43', '0.44')
|
assert s2.between_versions('0.43', '0.44')
|
||||||
assert s2.between_versions('0.43', '0.44test2') is False
|
assert s2.between_versions('0.43', '0.44test2') is False
|
||||||
assert s2.between_versions('0.44', '0.43') is False
|
assert s2.between_versions('0.44', '0.43') is False
|
||||||
assert s1.compare_version(s2) > 0
|
assert s1.compare_version(s2) > 0
|
||||||
assert s2.compare_version(s1) < 0
|
assert s2.compare_version(s1) < 0
|
||||||
|
|
||||||
def test_dropbear_compare_version_sequential(self):
|
def test_dropbear_compare_version_sequential(self):
|
||||||
versions = []
|
versions = []
|
||||||
for i in range(28, 44):
|
for i in range(28, 44):
|
||||||
versions.append('0.{0}'.format(i))
|
versions.append('0.{0}'.format(i))
|
||||||
for i in range(1, 5):
|
for i in range(1, 5):
|
||||||
versions.append('0.44test{0}'.format(i))
|
versions.append('0.44test{0}'.format(i))
|
||||||
for i in range(44, 49):
|
for i in range(44, 49):
|
||||||
versions.append('0.{0}'.format(i))
|
versions.append('0.{0}'.format(i))
|
||||||
versions.append('0.48.1')
|
versions.append('0.48.1')
|
||||||
for i in range(49, 54):
|
for i in range(49, 54):
|
||||||
versions.append('0.{0}'.format(i))
|
versions.append('0.{0}'.format(i))
|
||||||
versions.append('0.53.1')
|
versions.append('0.53.1')
|
||||||
for v in ['2011.54', '2012.55']:
|
for v in ['2011.54', '2012.55']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for i in range(56, 61):
|
for i in range(56, 61):
|
||||||
versions.append('2013.{0}'.format(i))
|
versions.append('2013.{0}'.format(i))
|
||||||
for v in ['2013.61test', '2013.62']:
|
for v in ['2013.61test', '2013.62']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for i in range(63, 67):
|
for i in range(63, 67):
|
||||||
versions.append('2014.{0}'.format(i))
|
versions.append('2014.{0}'.format(i))
|
||||||
for i in range(67, 72):
|
for i in range(67, 72):
|
||||||
versions.append('2015.{0}'.format(i))
|
versions.append('2015.{0}'.format(i))
|
||||||
for i in range(72, 75):
|
for i in range(72, 75):
|
||||||
versions.append('2016.{0}'.format(i))
|
versions.append('2016.{0}'.format(i))
|
||||||
length = len(versions)
|
length = len(versions)
|
||||||
for i in range(length):
|
for i in range(length):
|
||||||
v = versions[i]
|
v = versions[i]
|
||||||
s = self.get_dropbear_software(v)
|
s = self.get_dropbear_software(v)
|
||||||
assert s.compare_version(v) == 0
|
assert s.compare_version(v) == 0
|
||||||
if i - 1 >= 0:
|
if i - 1 >= 0:
|
||||||
vbefore = versions[i - 1]
|
vbefore = versions[i - 1]
|
||||||
assert s.compare_version(vbefore) > 0
|
assert s.compare_version(vbefore) > 0
|
||||||
if i + 1 < length:
|
if i + 1 < length:
|
||||||
vnext = versions[i + 1]
|
vnext = versions[i + 1]
|
||||||
assert s.compare_version(vnext) < 0
|
assert s.compare_version(vnext) < 0
|
||||||
|
|
||||||
def test_openssh_compare_version_simple(self):
|
def test_openssh_compare_version_simple(self):
|
||||||
s = self.get_openssh_software('3.7.1')
|
s = self.get_openssh_software('3.7.1')
|
||||||
assert s.compare_version(None) == 1
|
assert s.compare_version(None) == 1
|
||||||
assert s.compare_version('') == 1
|
assert s.compare_version('') == 1
|
||||||
assert s.compare_version('3.7') > 0
|
assert s.compare_version('3.7') > 0
|
||||||
assert s.compare_version('3.7.1') == 0
|
assert s.compare_version('3.7.1') == 0
|
||||||
assert s.compare_version(s) == 0
|
assert s.compare_version(s) == 0
|
||||||
assert s.compare_version('3.8') < 0
|
assert s.compare_version('3.8') < 0
|
||||||
assert s.between_versions('3.7', '3.8')
|
assert s.between_versions('3.7', '3.8')
|
||||||
assert s.between_versions('3.6', '3.7') is False
|
assert s.between_versions('3.6', '3.7') is False
|
||||||
assert s.between_versions('3.8', '3.7') is False
|
assert s.between_versions('3.8', '3.7') is False
|
||||||
|
|
||||||
def test_openssh_compare_version_patchlevel(self):
|
def test_openssh_compare_version_patchlevel(self):
|
||||||
s1 = self.get_openssh_software('2.1.1')
|
s1 = self.get_openssh_software('2.1.1')
|
||||||
s2 = self.get_openssh_software('2.1.1p2')
|
s2 = self.get_openssh_software('2.1.1p2')
|
||||||
assert s1.compare_version(s1) == 0
|
assert s1.compare_version(s1) == 0
|
||||||
assert s2.compare_version(s2) == 0
|
assert s2.compare_version(s2) == 0
|
||||||
assert s1.compare_version('2.1.1p1') == 0
|
assert s1.compare_version('2.1.1p1') == 0
|
||||||
assert s1.compare_version('2.1.1p2') == 0
|
assert s1.compare_version('2.1.1p2') == 0
|
||||||
assert s2.compare_version('2.1.1') == 0
|
assert s2.compare_version('2.1.1') == 0
|
||||||
assert s2.compare_version('2.1.1p1') > 0
|
assert s2.compare_version('2.1.1p1') > 0
|
||||||
assert s2.compare_version('2.1.1p3') < 0
|
assert s2.compare_version('2.1.1p3') < 0
|
||||||
assert s1.compare_version(s2) == 0
|
assert s1.compare_version(s2) == 0
|
||||||
assert s2.compare_version(s1) == 0
|
assert s2.compare_version(s1) == 0
|
||||||
|
|
||||||
def test_openbsd_compare_version_sequential(self):
|
def test_openbsd_compare_version_sequential(self):
|
||||||
versions = []
|
versions = []
|
||||||
for v in ['1.2.3', '2.1.0', '2.1.1', '2.2.0', '2.3.0']:
|
for v in ['1.2.3', '2.1.0', '2.1.1', '2.2.0', '2.3.0']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for v in ['2.5.0', '2.5.1', '2.5.2', '2.9', '2.9.9']:
|
for v in ['2.5.0', '2.5.1', '2.5.2', '2.9', '2.9.9']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for v in ['3.0', '3.0.1', '3.0.2', '3.1', '3.2.2', '3.2.3']:
|
for v in ['3.0', '3.0.1', '3.0.2', '3.1', '3.2.2', '3.2.3']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for i in range(3, 7):
|
for i in range(3, 7):
|
||||||
versions.append('3.{0}'.format(i))
|
versions.append('3.{0}'.format(i))
|
||||||
for v in ['3.6.1', '3.7.0', '3.7.1']:
|
for v in ['3.6.1', '3.7.0', '3.7.1']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for i in range(8, 10):
|
for i in range(8, 10):
|
||||||
versions.append('3.{0}'.format(i))
|
versions.append('3.{0}'.format(i))
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
versions.append('4.{0}'.format(i))
|
versions.append('4.{0}'.format(i))
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
versions.append('5.{0}'.format(i))
|
versions.append('5.{0}'.format(i))
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
versions.append('6.{0}'.format(i))
|
versions.append('6.{0}'.format(i))
|
||||||
for i in range(0, 4):
|
for i in range(0, 4):
|
||||||
versions.append('7.{0}'.format(i))
|
versions.append('7.{0}'.format(i))
|
||||||
length = len(versions)
|
length = len(versions)
|
||||||
for i in range(length):
|
for i in range(length):
|
||||||
v = versions[i]
|
v = versions[i]
|
||||||
s = self.get_openssh_software(v)
|
s = self.get_openssh_software(v)
|
||||||
assert s.compare_version(v) == 0
|
assert s.compare_version(v) == 0
|
||||||
if i - 1 >= 0:
|
if i - 1 >= 0:
|
||||||
vbefore = versions[i - 1]
|
vbefore = versions[i - 1]
|
||||||
assert s.compare_version(vbefore) > 0
|
assert s.compare_version(vbefore) > 0
|
||||||
if i + 1 < length:
|
if i + 1 < length:
|
||||||
vnext = versions[i + 1]
|
vnext = versions[i + 1]
|
||||||
assert s.compare_version(vnext) < 0
|
assert s.compare_version(vnext) < 0
|
||||||
|
|
||||||
def test_libssh_compare_version_simple(self):
|
def test_libssh_compare_version_simple(self):
|
||||||
s = self.get_libssh_software('0.3')
|
s = self.get_libssh_software('0.3')
|
||||||
assert s.compare_version(None) == 1
|
assert s.compare_version(None) == 1
|
||||||
assert s.compare_version('') == 1
|
assert s.compare_version('') == 1
|
||||||
assert s.compare_version('0.2') > 0
|
assert s.compare_version('0.2') > 0
|
||||||
assert s.compare_version('0.3') == 0
|
assert s.compare_version('0.3') == 0
|
||||||
assert s.compare_version(s) == 0
|
assert s.compare_version(s) == 0
|
||||||
assert s.compare_version('0.3.1') < 0
|
assert s.compare_version('0.3.1') < 0
|
||||||
assert s.between_versions('0.2', '0.3.1')
|
assert s.between_versions('0.2', '0.3.1')
|
||||||
assert s.between_versions('0.1', '0.2') is False
|
assert s.between_versions('0.1', '0.2') is False
|
||||||
assert s.between_versions('0.3.1', '0.2') is False
|
assert s.between_versions('0.3.1', '0.2') is False
|
||||||
|
|
||||||
def test_libssh_compare_version_sequential(self):
|
def test_libssh_compare_version_sequential(self):
|
||||||
versions = []
|
versions = []
|
||||||
for v in ['0.2', '0.3']:
|
for v in ['0.2', '0.3']:
|
||||||
versions.append(v)
|
versions.append(v)
|
||||||
for i in range(1, 5):
|
for i in range(1, 5):
|
||||||
versions.append('0.3.{0}'.format(i))
|
versions.append('0.3.{0}'.format(i))
|
||||||
for i in range(0, 9):
|
for i in range(0, 9):
|
||||||
versions.append('0.4.{0}'.format(i))
|
versions.append('0.4.{0}'.format(i))
|
||||||
for i in range(0, 6):
|
for i in range(0, 6):
|
||||||
versions.append('0.5.{0}'.format(i))
|
versions.append('0.5.{0}'.format(i))
|
||||||
for i in range(0, 6):
|
for i in range(0, 6):
|
||||||
versions.append('0.6.{0}'.format(i))
|
versions.append('0.6.{0}'.format(i))
|
||||||
for i in range(0, 5):
|
for i in range(0, 5):
|
||||||
versions.append('0.7.{0}'.format(i))
|
versions.append('0.7.{0}'.format(i))
|
||||||
length = len(versions)
|
length = len(versions)
|
||||||
for i in range(length):
|
for i in range(length):
|
||||||
v = versions[i]
|
v = versions[i]
|
||||||
s = self.get_libssh_software(v)
|
s = self.get_libssh_software(v)
|
||||||
assert s.compare_version(v) == 0
|
assert s.compare_version(v) == 0
|
||||||
if i - 1 >= 0:
|
if i - 1 >= 0:
|
||||||
vbefore = versions[i - 1]
|
vbefore = versions[i - 1]
|
||||||
assert s.compare_version(vbefore) > 0
|
assert s.compare_version(vbefore) > 0
|
||||||
if i + 1 < length:
|
if i + 1 < length:
|
||||||
vnext = versions[i + 1]
|
vnext = versions[i + 1]
|
||||||
assert s.compare_version(vnext) < 0
|
assert s.compare_version(vnext) < 0
|
||||||
|
8
tox.ini
8
tox.ini
@ -137,13 +137,5 @@ max-module-lines = 2500
|
|||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore =
|
ignore =
|
||||||
W191, # indentation contains tabs
|
|
||||||
E101, # indentation contains mixed spaces and tabs
|
|
||||||
E241, # multiple spaces after operator; should be kept for tabular data
|
E241, # multiple spaces after operator; should be kept for tabular data
|
||||||
E501, # line too long
|
E501, # line too long
|
||||||
E117, # over-indented
|
|
||||||
E126, # continuation line over-indented for hanging indent
|
|
||||||
E128, # continuation line under-indented for visual indent
|
|
||||||
E722, # do not use bare 'except'
|
|
||||||
F601, # dictionary key 'ecdsa-sha2-1.3.132.0.10' repeated with different values
|
|
||||||
W504, # line break after binary operator; this (or W503) has to stay
|
|
||||||
|
Loading…
Reference in New Issue
Block a user