From: Ralf Jung Date: Mon, 21 Jul 2014 08:53:37 +0000 (+0200) Subject: Check a host, print the progress X-Git-Url: https://git.ralfj.de/tls-check.git/commitdiff_plain/936487652a78a7504696b44baedc23a6f5026cc3?hp=441c452d1b744deec84c47f08e15f47676c5f003 Check a host, print the progress --- diff --git a/ssl-check b/ssl-check index a93a4bf..ae3d26f 100755 --- a/ssl-check +++ b/ssl-check @@ -1 +1,79 @@ #!/usr/bin/python3 +import subprocess, sys +from collections import OrderedDict +from enum import Enum + +# progress bar +def terminal_size(): + import fcntl, termios, struct + try: + result = fcntl.ioctl(1, termios.TIOCGWINSZ, struct.pack('HHHH', 0, 0, 0, 0)) + except OSError: + # this is not a terminal + return 0, 0 + h, w, hp, wp = struct.unpack('HHHH', result) + assert w > 0 and h > 0, "Empty terminal...??" + return w, h + +def compute_frac(fracs): + frac = 0.0 + last_frac = 1.0 + for complete, total in fracs: + frac += (complete*last_frac/total) + last_frac *= 1/total + return frac + +def print_progress(state, fracs): + STATE_WIDTH = 30 + w, h = terminal_size() + if w < STATE_WIDTH+10: return # not a (wide enough) terminal + bar_width = w-STATE_WIDTH-3 + hashes = int(bar_width*compute_frac(fracs)) + sys.stdout.write('\r{0} [{1}{2}]'.format(state[:STATE_WIDTH].ljust(STATE_WIDTH), '#'*hashes, ' '*(bar_width-hashes))) + sys.stdout.flush() +def finish_progress(): + w, h = terminal_size() + sys.stdout.write('\r'+(' '*w)+'\r') + sys.stdout.flush() + +# cipher check +def list_ciphers(): + ciphers = subprocess.check_output(["openssl", "ciphers", "ALL:COMPLEMENTOFALL"]).decode('UTF-8').strip() + return ciphers.split(':') + +def test_cipher(host, port, protocol, cipher = None, options=[]): + try: + if cipher is not None: + options = ["-cipher", cipher]+options + subprocess.check_call(["openssl", "s_client", "-"+protocol, "-connect", host+":"+str(port)]+options, + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except subprocess.CalledProcessError: + return False + else: + return True + +def test_protocol(host, port, protocol, ciphers, base_frac, options=[]): + if test_cipher(host, port, protocol, options=options): + # the protocol is supported + results = OrderedDict() + for i in range(len(ciphers)): + cipher = ciphers[i] + print_progress(protocol+" "+cipher, base_frac+[(i, len(ciphers))]) + results[cipher] = test_cipher(host, port, protocol, cipher, options) + return results + else: + # it is not supported + return None + +def test_host(host, port, options=[]): + ciphers = list_ciphers() + results = OrderedDict() + protocols = ('ssl2', 'ssl3', 'tls1', 'tls1_1', 'tls1_2') + for i in range(len(protocols)): + protocol = protocols[i] + print_progress(protocol, [(i, len(protocols))]) + results[protocol] = test_protocol(host, port, protocol, ciphers, [(i, len(protocols))], options) + finish_progress() + return results + +print(test_host('ralfj.de', 443))