mirror of
				https://github.com/jtesta/ssh-audit.git
				synced 2025-10-31 05:25:28 +01:00 
			
		
		
		
	Flake8 fixes (#35)
* Apply Flake8 also on `setup.py` modified: tox.ini * Fix W605 - invalid escape syntax modified: packages/setup.py modified: tox.ini * Update comment about Flake8: W504 W503 and W504 are mutual exclusive - so we have to keep one of them. modified: tox.ini * Fix F841 - variable assigned but never used modified: ssh-audit.py modified: tox.ini * Fix E741 - ambiguous variable name 'l' modified: ssh-audit.py modified: tox.ini * Fix E712 - comparison to False should be 'if cond is False' ... and not 'if conf == False'. modified: ssh-audit.py modified: tox.ini * Fix E711 - comparison to None should be 'if cond is not None' ... and not 'if cond != None'. modified: ssh-audit.py modified: tox.ini * Fix E305 - expected 2 blank lines ... after class or function definition, found 1. modified: ssh-audit.py modified: tox.ini * Fix E303 - too many blank lines modified: ssh-audit.py modified: tox.ini * Fix E303 - too many blank lines modified: ssh-audit.py modified: tox.ini * Fix E301 - expected 1 blank line, found 0 No code change necessary, probably fixed by another commit. modified: tox.ini * Fix E265 - block comment should start with '# ' There is lots of commented out code, which usually should be just deleted. I will keep it for now, as I am not yet very familiar with the code base. modified: ssh-audit.py modified: tox.ini * Fix E261 - at least two spaces before inline comment modified: ssh-audit.py modified: tox.ini * Fix E251 - unexpected spaces around keyword / parameter equals modified: packages/setup.py modified: tox.ini * Fix E231 - missing whitespace after ',' No code change necessary, probably fixed by previous commit. modified: tox.ini * Fix E226 - missing whitespace around arithmetic operator modified: ssh-audit.py modified: tox.ini * Fix W293 - blank line contains whitespace modified: ssh-audit.py modified: tox.ini * Fix E221 - multiple spaces before operator modified: ssh-audit.py modified: tox.ini * Update comment about Flake 8 E241 Lots of data is formatted as tables, so this warning is disabled for a good reason. modified: tox.ini * Fix E401 - multiple imports on one line modified: ssh-audit.py modified: tox.ini * Do not ignore Flake8 warning F401 ... as there were no errors in source code anyway. modified: tox.ini * Fix F821 - undefined name modified: ssh-audit.py modified: tox.ini * Reformat ignore section for Flake8 modified: tox.ini * Flake8 test suite modified: test/conftest.py modified: test/test_auditconf.py modified: test/test_banner.py modified: test/test_buffer.py modified: test/test_errors.py modified: test/test_output.py modified: test/test_resolve.py modified: test/test_socket.py modified: test/test_software.py modified: test/test_ssh1.py modified: test/test_ssh2.py modified: test/test_ssh_algorithm.py modified: test/test_utils.py modified: test/test_version_compare.py modified: tox.ini
This commit is contained in:
		| @@ -5,7 +5,7 @@ import re | ||||
| from setuptools import setup | ||||
|  | ||||
|  | ||||
| version = re.search('^VERSION\s*=\s*\'v(\d\.\d\.\d)\'', open('sshaudit/sshaudit.py').read(), re.M).group(1) | ||||
| version = re.search(r'^VERSION\s*=\s*\'v(\d\.\d\.\d)\'', open('sshaudit/sshaudit.py').read(), re.M).group(1) | ||||
| print("\n\nPackaging ssh-audit v%s...\n\n" % version) | ||||
|  | ||||
| with open("sshaudit/README.md", "rb") as f: | ||||
| @@ -13,20 +13,20 @@ with open("sshaudit/README.md", "rb") as f: | ||||
|  | ||||
|  | ||||
| setup( | ||||
|     name = "ssh-audit", | ||||
|     packages = ["sshaudit"], | ||||
|     license = 'MIT', | ||||
|     entry_points = { | ||||
|     name="ssh-audit", | ||||
|     packages=["sshaudit"], | ||||
|     license='MIT', | ||||
|     entry_points={ | ||||
|         "console_scripts": ['ssh-audit = sshaudit.sshaudit:main'] | ||||
|     }, | ||||
|     version = version, | ||||
|     description = "An SSH server & client configuration security auditing tool", | ||||
|     long_description = long_descr, | ||||
|     long_description_content_type = "text/markdown", | ||||
|     author = "Joe Testa", | ||||
|     author_email = "jtesta@positronsecurity.com", | ||||
|     url = "https://github.com/jtesta/ssh-audit", | ||||
|     classifiers = [ | ||||
|     version=version, | ||||
|     description="An SSH server & client configuration security auditing tool", | ||||
|     long_description=long_descr, | ||||
|     long_description_content_type="text/markdown", | ||||
|     author="Joe Testa", | ||||
|     author_email="jtesta@positronsecurity.com", | ||||
|     url="https://github.com/jtesta/ssh-audit", | ||||
|     classifiers=[ | ||||
|         "Development Status :: 5 - Production/Stable", | ||||
|         "Intended Audience :: Information Technology", | ||||
|         "Intended Audience :: System Administrators", | ||||
|   | ||||
							
								
								
									
										104
									
								
								ssh-audit.py
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								ssh-audit.py
									
									
									
									
									
								
							| @@ -25,7 +25,20 @@ | ||||
|    THE SOFTWARE. | ||||
| """ | ||||
| from __future__ import print_function | ||||
| import base64, binascii, errno, hashlib, getopt, io, os, random, re, select, socket, struct, sys, json | ||||
| import base64 | ||||
| import binascii | ||||
| import errno | ||||
| import getopt | ||||
| import hashlib | ||||
| import io | ||||
| import json | ||||
| import os | ||||
| import random | ||||
| import re | ||||
| import select | ||||
| import socket | ||||
| import struct | ||||
| import sys | ||||
|  | ||||
|  | ||||
| VERSION = 'v2.2.1-dev' | ||||
| @@ -41,7 +54,7 @@ if sys.version_info >= (3,):  # pragma: nocover | ||||
| else:  # pragma: nocover | ||||
| 	import StringIO as _StringIO  # pylint: disable=import-error | ||||
| 	StringIO = BytesIO = _StringIO.StringIO | ||||
| 	text_type = unicode  # pylint: disable=undefined-variable | ||||
| 	text_type = unicode  # pylint: disable=undefined-variable  # noqa: F821 | ||||
| 	binary_type = str | ||||
| try:  # pragma: nocover | ||||
| 	# pylint: disable=unused-import | ||||
| @@ -190,9 +203,9 @@ class AuditConf(object): | ||||
| 			elif o in ('-t', '--timeout'): | ||||
| 				aconf.timeout = float(a) | ||||
| 				aconf.timeout_set = True | ||||
| 		if len(args) == 0 and aconf.client_audit == False: | ||||
| 		if len(args) == 0 and aconf.client_audit is False: | ||||
| 			usage_cb() | ||||
| 		if aconf.client_audit == False: | ||||
| 		if aconf.client_audit is False: | ||||
| 			if oport is not None: | ||||
| 				host = args[0] | ||||
| 			else: | ||||
| @@ -700,7 +713,7 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 				'ecdh-sha2-nistp256': KexNISTP256, | ||||
| 				'ecdh-sha2-nistp384': KexNISTP384, | ||||
| 				'ecdh-sha2-nistp521': KexNISTP521, | ||||
| 				#'kexguess2@matt.ucc.asn.au': ??? | ||||
| 				# 'kexguess2@matt.ucc.asn.au': ??? | ||||
| 			} | ||||
|  | ||||
| 			# Pick the first kex algorithm that the server supports, which we | ||||
| @@ -798,7 +811,6 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 					else: | ||||
| 						host_key_types[host_key_type]['parsed'] = True | ||||
|  | ||||
|  | ||||
| 	# Performs DH group exchanges to find what moduli are supported, and checks | ||||
| 	# their size. | ||||
| 	class GEXTest(object): | ||||
| @@ -865,7 +877,7 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 						# got here, doesn't mean the server is vulnerable... | ||||
| 						smallest_modulus = kex_group.get_dh_modulus_size() | ||||
|  | ||||
| 					except Exception as e: # pylint: disable=bare-except | ||||
| 					except Exception:  # pylint: disable=bare-except | ||||
| 						pass | ||||
| 					finally: | ||||
| 						s.close() | ||||
| @@ -887,9 +899,9 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 							kex_group.send_init_gex(s, bits, bits, bits) | ||||
| 							kex_group.recv_reply(s, False) | ||||
| 							smallest_modulus = kex_group.get_dh_modulus_size() | ||||
| 						except Exception as e: # pylint: disable=bare-except | ||||
| 							#import traceback | ||||
| 							#print(traceback.format_exc()) | ||||
| 						except Exception:  # pylint: disable=bare-except | ||||
| 							# import traceback | ||||
| 							# print(traceback.format_exc()) | ||||
| 							pass | ||||
| 						finally: | ||||
| 							# The server is in a state that is not re-testable, | ||||
| @@ -897,7 +909,6 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 							# connection. | ||||
| 							s.close() | ||||
|  | ||||
|  | ||||
| 					if smallest_modulus > 0: | ||||
| 						kex.set_dh_modulus_size(gex_alg, smallest_modulus) | ||||
|  | ||||
| @@ -919,6 +930,7 @@ class SSH2(object):  # pylint: disable=too-few-public-methods | ||||
| 					if reconnect_failed: | ||||
| 						break | ||||
|  | ||||
|  | ||||
| class SSH1(object): | ||||
| 	class CRC32(object): | ||||
| 		def __init__(self): | ||||
| @@ -935,8 +947,8 @@ class SSH1(object): | ||||
|  | ||||
| 		def calc(self, v): | ||||
| 			# type: (binary_type) -> int | ||||
| 			crc, l = 0, len(v) | ||||
| 			for i in range(l): | ||||
| 			crc, length = 0, len(v) | ||||
| 			for i in range(length): | ||||
| 				n = ord(v[i:i + 1]) | ||||
| 				n = n ^ (crc & 0xff) | ||||
| 				crc = (crc >> 8) ^ self._table[n] | ||||
| @@ -1189,6 +1201,7 @@ class ReadBuf(object): | ||||
| 		self._len = 0 | ||||
| 		super(ReadBuf, self).reset() | ||||
|  | ||||
|  | ||||
| class WriteBuf(object): | ||||
| 	def __init__(self, data=None): | ||||
| 		# type: (Optional[binary_type]) -> None | ||||
| @@ -1609,7 +1622,7 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
|  | ||||
| 			def __getitem__(self, product): | ||||
| 				# type: (str) -> Sequence[Optional[str]] | ||||
| 				return tuple(self.__storage.get(product, [None]*4)) | ||||
| 				return tuple(self.__storage.get(product, [None] * 4)) | ||||
|  | ||||
| 			def __str__(self): | ||||
| 				# type: () -> str | ||||
| @@ -1640,7 +1653,7 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 					ssh_versions[ssh_prod] = ssh_ver | ||||
| 				for ssh_product, ssh_version in ssh_versions.items(): | ||||
| 					if ssh_product not in self.__storage: | ||||
| 						self.__storage[ssh_product] = [None]*4 | ||||
| 						self.__storage[ssh_product] = [None] * 4 | ||||
| 					prev = self[ssh_product][pos] | ||||
| 					if (prev is None or | ||||
| 					   (prev < ssh_version and pos % 2 == 0) or | ||||
| @@ -1783,19 +1796,18 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 			if software is not None: | ||||
| 				if software.product not in vproducts: | ||||
| 					unknown_software = True | ||||
| # | ||||
| # The code below is commented out because it would try to guess what the server is, | ||||
| # usually resulting in wild & incorrect recommendations. | ||||
| # | ||||
| #			if software is None: | ||||
| #				ssh_timeframe = self.get_ssh_timeframe(for_server) | ||||
| #				for product in vproducts: | ||||
| #					if product not in ssh_timeframe: | ||||
| #						continue | ||||
| #					version = ssh_timeframe.get_from(product, for_server) | ||||
| #					if version is not None: | ||||
| #						software = SSH.Software(None, product, version, None, None) | ||||
| #						break | ||||
|  | ||||
| 			# The code below is commented out because it would try to guess what the server is, | ||||
| 			# usually resulting in wild & incorrect recommendations. | ||||
| 			# if software is None: | ||||
| 			# 	ssh_timeframe = self.get_ssh_timeframe(for_server) | ||||
| 			# 	for product in vproducts: | ||||
| 			# 		if product not in ssh_timeframe: | ||||
| 			# 			continue | ||||
| 			# 		version = ssh_timeframe.get_from(product, for_server) | ||||
| 			# 		if version is not None: | ||||
| 			# 			software = SSH.Software(None, product, version, None, None) | ||||
| 			# 			break | ||||
| 			rec = {}  # type: Dict[int, Dict[str, Dict[str, Dict[str, int]]]] | ||||
| 			if software is None: | ||||
| 				unknown_software = True | ||||
| @@ -2057,7 +2069,6 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 			self.client_host = None | ||||
| 			self.client_port = None | ||||
|  | ||||
| 		 | ||||
| 		def _resolve(self, ipvo): | ||||
| 			# type: (Sequence[int]) -> Iterable[Tuple[int, Tuple[Any, ...]]] | ||||
| 			ipvo = tuple([x for x in utils.unique_seq(ipvo) if x in (4, 6)]) | ||||
| @@ -2081,7 +2092,6 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 				out.fail('[exception] {0}'.format(e)) | ||||
| 				sys.exit(1) | ||||
|  | ||||
|  | ||||
| 		# Listens on a server socket and accepts one connection (used for | ||||
| 		# auditing client connections). | ||||
| 		def listen_and_accept(self): | ||||
| @@ -2093,7 +2103,7 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 				s.bind(('0.0.0.0', self.__port)) | ||||
| 				s.listen() | ||||
| 				self.__sock_map[s.fileno()] = s | ||||
| 			except Exception as e: | ||||
| 			except Exception: | ||||
| 				print("Warning: failed to listen on any IPv4 interfaces.") | ||||
| 				pass | ||||
|  | ||||
| @@ -2105,7 +2115,7 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 				s.bind(('::', self.__port)) | ||||
| 				s.listen() | ||||
| 				self.__sock_map[s.fileno()] = s | ||||
| 			except Exception as e: | ||||
| 			except Exception: | ||||
| 				print("Warning: failed to listen on any IPv6 interfaces.") | ||||
| 				pass | ||||
|  | ||||
| @@ -2139,7 +2149,6 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 			c.settimeout(self.__timeout) | ||||
| 			self.__sock = c | ||||
|  | ||||
|  | ||||
| 		def connect(self): | ||||
| 			# type: () -> None | ||||
| 			err = None | ||||
| @@ -2169,10 +2178,10 @@ class SSH(object):  # pylint: disable=too-few-public-methods | ||||
| 			banner = SSH_HEADER.format('1.5' if sshv == 1 else '2.0') | ||||
| 			if self.__state < self.SM_BANNER_SENT: | ||||
| 				self.send_banner(banner) | ||||
| #			rto = self.__sock.gettimeout() | ||||
| #			self.__sock.settimeout(0.7) | ||||
| 			# rto = self.__sock.gettimeout() | ||||
| 			# self.__sock.settimeout(0.7) | ||||
| 			s, e = self.recv() | ||||
| #			self.__sock.settimeout(rto) | ||||
| 			# self.__sock.settimeout(rto) | ||||
| 			if s < 0: | ||||
| 				return self.__banner, self.__header, e | ||||
| 			e = None | ||||
| @@ -2357,7 +2366,6 @@ class KexDH(object):  # pragma: nocover | ||||
| 		self.__f = 0 | ||||
| 		self.__h_sig = 0 | ||||
|  | ||||
|  | ||||
| 	def set_params(self, g, p): | ||||
| 		self.__g = g | ||||
| 		self.__p = p | ||||
| @@ -2365,7 +2373,6 @@ class KexDH(object):  # pragma: nocover | ||||
| 		self.__x = 0 | ||||
| 		self.__e = 0 | ||||
|  | ||||
|  | ||||
| 	def send_init(self, s, init_msg=SSH.Protocol.MSG_KEXDH_INIT): | ||||
| 		# type: (SSH.Socket) -> None | ||||
| 		r = random.SystemRandom() | ||||
| @@ -2403,7 +2410,6 @@ class KexDH(object):  # pragma: nocover | ||||
|  | ||||
| 		key_id = principles = None  # pylint: disable=unused-variable | ||||
| 		critical_options = extensions = None  # pylint: disable=unused-variable | ||||
| 		valid_after = valid_before = None    # pylint: disable=unused-variable | ||||
| 		nonce = ca_key = ca_key_type = None  # pylint: disable=unused-variable | ||||
| 		ca_key_e = ca_key_n = None  # pylint: disable=unused-variable | ||||
|  | ||||
| @@ -2455,12 +2461,10 @@ class KexDH(object):  # pragma: nocover | ||||
| 				# The principles, which are... I don't know what. | ||||
| 				principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr) | ||||
|  | ||||
| 				# The timestamp that this certificate is valid after. | ||||
| 				valid_after = hostkey[ptr:ptr + 8] | ||||
| 				# Skip over the timestamp that this certificate is valid after. | ||||
| 				ptr += 8 | ||||
|  | ||||
| 				# The timestamp that this certificate is valid before. | ||||
| 				valid_before = hostkey[ptr:ptr + 8] | ||||
| 				# Skip over the timestamp that this certificate is valid before. | ||||
| 				ptr += 8 | ||||
|  | ||||
| 				# TODO: validate the principles, and time range. | ||||
| @@ -2895,7 +2899,7 @@ def output_fingerprints(algs, sha256=True): | ||||
| 		if algs.ssh1kex is not None: | ||||
| 			name = 'ssh-rsa1' | ||||
| 			fp = SSH.Fingerprint(algs.ssh1kex.host_key_fingerprint_data) | ||||
| 			#bits = algs.ssh1kex.host_key_bits | ||||
| 			# bits = algs.ssh1kex.host_key_bits | ||||
| 			fps.append((name, fp)) | ||||
| 		if algs.ssh2kex is not None: | ||||
| 			host_keys = algs.ssh2kex.host_keys() | ||||
| @@ -2917,8 +2921,8 @@ def output_fingerprints(algs, sha256=True): | ||||
| 		for fpp in fps: | ||||
| 			name, fp = fpp | ||||
| 			fpo = fp.sha256 if sha256 else fp.md5 | ||||
| 			#p = '' if out.batch else ' ' * (padlen - len(name)) | ||||
| 			#out.good('(fin) {0}{1} -- {2} {3}'.format(name, p, bits, fpo)) | ||||
| 			# p = '' if out.batch else ' ' * (padlen - len(name)) | ||||
| 			# out.good('(fin) {0}{1} -- {2} {3}'.format(name, p, bits, fpo)) | ||||
| 			out.good('(fin) {0}: {1}'.format(name, fpo)) | ||||
| 	if len(obuf) > 0: | ||||
| 		out.head('# fingerprints') | ||||
| @@ -3018,7 +3022,7 @@ def output_info(algs, software, client_audit, any_problems, padlen=0): | ||||
|  | ||||
| def output(banner, header, client_host=None, kex=None, pkm=None): | ||||
| 	# type: (Optional[SSH.Banner], List[text_type], Optional[SSH2.Kex], Optional[SSH1.PublicKeyMessage]) -> None | ||||
| 	client_audit = (client_host != None) # If set, this is a client audit. | ||||
| 	client_audit = client_host is not None  # If set, this is a client audit. | ||||
| 	sshv = 1 if pkm is not None else 2 | ||||
| 	algs = SSH.Algorithms(pkm, kex) | ||||
| 	with OutputBuffer() as obuf: | ||||
| @@ -3077,11 +3081,11 @@ def output(banner, header, client_host=None, kex=None, pkm=None): | ||||
| 	perfect_config = output_recommendations(algs, software, maxlen) | ||||
| 	output_info(algs, software, client_audit, not perfect_config) | ||||
|  | ||||
|  | ||||
| 	# If we encountered any unknown algorithms, ask the user to report them. | ||||
| 	if len(unknown_algorithms) > 0: | ||||
| 		out.warn("\n\n!!! WARNING: unknown algorithm(s) found!: %s.  Please email the full output above to the maintainer (jtesta@positronsecurity.com), or create a Github issue at <https://github.com/jtesta/ssh-audit/issues>.\n" % ','.join(unknown_algorithms)) | ||||
|  | ||||
|  | ||||
| class Utils(object): | ||||
| 	@classmethod | ||||
| 	def _type_err(cls, v, target): | ||||
| @@ -3204,6 +3208,7 @@ class Utils(object): | ||||
| 		except:  # pylint: disable=bare-except | ||||
| 			return -1.0 | ||||
|  | ||||
|  | ||||
| def build_struct(banner, kex=None, pkm=None, client_host=None): | ||||
| 	res = { | ||||
| 		"banner": { | ||||
| @@ -3281,6 +3286,7 @@ def build_struct(banner, kex=None, pkm=None, client_host=None): | ||||
|  | ||||
| 	return res | ||||
|  | ||||
|  | ||||
| def audit(aconf, sshv=None): | ||||
| 	# type: (AuditConf, Optional[int]) -> None | ||||
| 	out.batch = aconf.batch | ||||
| @@ -3350,9 +3356,11 @@ def audit(aconf, sshv=None): | ||||
| utils = Utils() | ||||
| out = Output() | ||||
|  | ||||
|  | ||||
| def main(): | ||||
| 	conf = AuditConf.from_cmdline(sys.argv[1:], usage) | ||||
| 	audit(conf) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__':  # pragma: nocover | ||||
| 	main() | ||||
|   | ||||
| @@ -52,7 +52,6 @@ class TestErrors(object): | ||||
| 		assert 'timed out' in lines[-1] | ||||
|  | ||||
| 	def test_recv_empty(self, output_spy, virtual_socket): | ||||
| 		vsocket = virtual_socket | ||||
| 		lines = self._audit(output_spy) | ||||
| 		assert len(lines) == 1 | ||||
| 		assert 'did not receive banner' in lines[-1] | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class TestResolve(object): | ||||
| 		conf = self._conf() | ||||
| 		output_spy.begin() | ||||
| 		with pytest.raises(SystemExit): | ||||
| 			r = list(s._resolve(conf.ipvo)) | ||||
| 			list(s._resolve(conf.ipvo)) | ||||
| 		lines = output_spy.flush() | ||||
| 		assert len(lines) == 1 | ||||
| 		assert 'hostname nor servname provided' in lines[-1] | ||||
| @@ -40,7 +40,6 @@ class TestResolve(object): | ||||
| 		assert len(r) == 0 | ||||
|  | ||||
| 	def test_resolve_ipv4(self, virtual_socket): | ||||
| 		vsocket = virtual_socket | ||||
| 		conf = self._conf() | ||||
| 		conf.ipv4 = True | ||||
| 		s = self.ssh.Socket('localhost', 22) | ||||
| @@ -49,7 +48,6 @@ class TestResolve(object): | ||||
| 		assert r[0] == (socket.AF_INET, ('127.0.0.1', 22)) | ||||
|  | ||||
| 	def test_resolve_ipv6(self, virtual_socket): | ||||
| 		vsocket = virtual_socket | ||||
| 		s = self.ssh.Socket('localhost', 22) | ||||
| 		conf = self._conf() | ||||
| 		conf.ipv6 = True | ||||
| @@ -58,7 +56,6 @@ class TestResolve(object): | ||||
| 		assert r[0] == (socket.AF_INET6, ('::1', 22)) | ||||
|  | ||||
| 	def test_resolve_ipv46_both(self, virtual_socket): | ||||
| 		vsocket = virtual_socket | ||||
| 		s = self.ssh.Socket('localhost', 22) | ||||
| 		conf = self._conf() | ||||
| 		r = list(s._resolve(conf.ipvo)) | ||||
| @@ -67,7 +64,6 @@ class TestResolve(object): | ||||
| 		assert r[1] == (socket.AF_INET6, ('::1', 22)) | ||||
|  | ||||
| 	def test_resolve_ipv46_order(self, virtual_socket): | ||||
| 		vsocket = virtual_socket | ||||
| 		s = self.ssh.Socket('localhost', 22) | ||||
| 		conf = self._conf() | ||||
| 		conf.ipv4 = True | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
| import socket | ||||
| import pytest | ||||
|  | ||||
|  | ||||
| @@ -12,17 +11,17 @@ class TestSocket(object): | ||||
|  | ||||
| 	def test_invalid_host(self, virtual_socket): | ||||
| 		with pytest.raises(ValueError): | ||||
| 			s = self.ssh.Socket(None, 22) | ||||
| 			self.ssh.Socket(None, 22) | ||||
|  | ||||
| 	def test_invalid_port(self, virtual_socket): | ||||
| 		with pytest.raises(ValueError): | ||||
| 			s = self.ssh.Socket('localhost', 'abc') | ||||
| 			self.ssh.Socket('localhost', 'abc') | ||||
| 		with pytest.raises(ValueError): | ||||
| 			s = self.ssh.Socket('localhost', -1) | ||||
| 			self.ssh.Socket('localhost', -1) | ||||
| 		with pytest.raises(ValueError): | ||||
| 			s = self.ssh.Socket('localhost', 0) | ||||
| 			self.ssh.Socket('localhost', 0) | ||||
| 		with pytest.raises(ValueError): | ||||
| 			s = self.ssh.Socket('localhost', 65536) | ||||
| 			self.ssh.Socket('localhost', 65536) | ||||
|  | ||||
| 	def test_not_connected_socket(self, virtual_socket): | ||||
| 		sock = self.ssh.Socket('localhost', 22) | ||||
|   | ||||
| @@ -95,10 +95,10 @@ class TestSSH1(object): | ||||
| 		skey, hkey = self._server_key(), self._host_key() | ||||
| 		pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey, pflags, cmask, amask) | ||||
| 		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): | ||||
| 				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): | ||||
| 				print(hkey2) | ||||
| 				pkm = self.ssh1.PublicKeyMessage(cookie, skey, hkey2, pflags, cmask, amask) | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
| import struct, os | ||||
| import os | ||||
| import struct | ||||
| import pytest | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -105,15 +105,15 @@ class TestVersionCompare(object): | ||||
| 			versions.append('2015.{0}'.format(i)) | ||||
| 		for i in range(72, 75): | ||||
| 			versions.append('2016.{0}'.format(i)) | ||||
| 		l = len(versions) | ||||
| 		for i in range(l): | ||||
| 		length = len(versions) | ||||
| 		for i in range(length): | ||||
| 			v = versions[i] | ||||
| 			s = self.get_dropbear_software(v) | ||||
| 			assert s.compare_version(v) == 0 | ||||
| 			if i - 1 >= 0: | ||||
| 				vbefore = versions[i - 1] | ||||
| 				assert s.compare_version(vbefore) > 0 | ||||
| 			if i + 1 < l: | ||||
| 			if i + 1 < length: | ||||
| 				vnext = versions[i + 1] | ||||
| 				assert s.compare_version(vnext) < 0 | ||||
|  | ||||
| @@ -164,15 +164,15 @@ class TestVersionCompare(object): | ||||
| 			versions.append('6.{0}'.format(i)) | ||||
| 		for i in range(0, 4): | ||||
| 			versions.append('7.{0}'.format(i)) | ||||
| 		l = len(versions) | ||||
| 		for i in range(l): | ||||
| 		length = len(versions) | ||||
| 		for i in range(length): | ||||
| 			v = versions[i] | ||||
| 			s = self.get_openssh_software(v) | ||||
| 			assert s.compare_version(v) == 0 | ||||
| 			if i - 1 >= 0: | ||||
| 				vbefore = versions[i - 1] | ||||
| 				assert s.compare_version(vbefore) > 0 | ||||
| 			if i + 1 < l: | ||||
| 			if i + 1 < length: | ||||
| 				vnext = versions[i + 1] | ||||
| 				assert s.compare_version(vnext) < 0 | ||||
|  | ||||
| @@ -202,14 +202,14 @@ class TestVersionCompare(object): | ||||
| 			versions.append('0.6.{0}'.format(i)) | ||||
| 		for i in range(0, 5): | ||||
| 			versions.append('0.7.{0}'.format(i)) | ||||
| 		l = len(versions) | ||||
| 		for i in range(l): | ||||
| 		length = len(versions) | ||||
| 		for i in range(length): | ||||
| 			v = versions[i] | ||||
| 			s = self.get_libssh_software(v) | ||||
| 			assert s.compare_version(v) == 0 | ||||
| 			if i - 1 >= 0: | ||||
| 				vbefore = versions[i - 1] | ||||
| 				assert s.compare_version(vbefore) > 0 | ||||
| 			if i + 1 < l: | ||||
| 			if i + 1 < length: | ||||
| 				vnext = versions[i + 1] | ||||
| 				assert s.compare_version(vnext) < 0 | ||||
|   | ||||
							
								
								
									
										41
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								tox.ini
									
									
									
									
									
								
							| @@ -80,7 +80,7 @@ commands = | ||||
| deps = | ||||
| 	flake8 | ||||
| commands = | ||||
| 	flake8 {posargs:{env:SSHAUDIT}} | ||||
| 	flake8 {posargs:{env:SSHAUDIT} {toxinidir}/packages/setup.py {toxinidir}/test}  --statistics | ||||
|  | ||||
| [testenv:vulture] | ||||
| deps = | ||||
| @@ -137,42 +137,13 @@ max-module-lines = 2500 | ||||
|  | ||||
| [flake8] | ||||
| ignore = | ||||
| 	# indentation contains tabs | ||||
| 	W191, | ||||
| 	# blank line contains whitespace | ||||
| 	W293, | ||||
| 	# indentation contains mixed spaces and tabs | ||||
| 	E101, | ||||
| 	# multiple spaces before operator | ||||
| 	E221, | ||||
| 	# multiple spaces after operator | ||||
| 	E241, | ||||
| 	# multiple imports on one line | ||||
| 	E401, | ||||
| 	# line too long | ||||
| 	E501, | ||||
| 	# module imported but unused | ||||
| 	F401, | ||||
| 	# undefined name | ||||
| 	F821, | ||||
| 	# these exceptions should be handled one by one | ||||
| 	W191,  # indentation contains tabs | ||||
| 	E101,  # indentation contains mixed spaces and tabs | ||||
| 	E241,  # multiple spaces after operator; should be kept for tabular data | ||||
| 	E501,  # line too long | ||||
| 	E117,  # over-indented | ||||
| 	E126,  # continuation line over-indented for hanging indent | ||||
| 	E128,  # continuation line under-indented for visual indent | ||||
| 	E226, # missing whitespace around arithmetic operator | ||||
| 	E231, # missing whitespace after ',' | ||||
| 	E251, # unexpected spaces around keyword / parameter equals | ||||
| 	E261, # at least two spaces before inline comment | ||||
| 	E265, # block comment should start with '# ' | ||||
| 	E301, # expected 1 blank line, found 0 | ||||
| 	E302, # expected 2 blank lines, found 1 | ||||
| 	E303, # too many blank lines (2) | ||||
| 	E305, # expected 2 blank lines after class or function definition, found 1 | ||||
| 	E711, # comparison to None should be 'if cond is not None:' | ||||
| 	E712, # comparison to False should be 'if cond is False:' or 'if not cond:' | ||||
| 	E722,  # do not use bare 'except' | ||||
| 	E741, # ambiguous variable name 'l' | ||||
| 	F601,  # dictionary key 'ecdsa-sha2-1.3.132.0.10' repeated with different values | ||||
| 	F841, # local variable 'e' is assigned to but never used | ||||
| 	W504, # line break after binary operator | ||||
| 	W605, # invalid escape sequence '\s' | ||||
| 	W504,  # line break after binary operator; this (or W503) has to stay | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jürgen Gmach
					Jürgen Gmach