import subprocess, sys, threading
from queue import Queue
from math import ceil

def get_auth_methods(hostname, port=22, timeout=5.0, verbose=False):
    try:
        if sys.version_info.minor < 3:
            success_output = subprocess.check_output([
                'ssh',
                # prevents ominous error on changed host key
                '-o', 'StrictHostKeyChecking=no',
                # the point - prevents attempted authentication
                '-o', 'PreferredAuthentications=none',
                # prevents warning associated with unrecognized host key
                '-o', 'LogLevel=ERROR',
                # maximum time per connections
                # NOTE: there can be multiple connections if a domain
                # resolves to multiple IPs
                '-o', 'ConnectTimeout=%d' % ceil(timeout),
                '-p', str(port),
                'root@' + hostname,    # use root user to prevent leaking username
                'exit'],    # the command to be executed upon successful auth
                stderr=subprocess.STDOUT)
        else:
            success_output = subprocess.check_output([
                'ssh',
                '-o', 'StrictHostKeyChecking=no',
                '-o', 'PreferredAuthentications=none',
                '-o', 'LogLevel=ERROR',
                '-p', str(port),
                'root@' + hostname,
                'exit'],
                stderr=subprocess.STDOUT,
                # only available in Python 3.3+ (reason for condition_
                timeout=timeout)
        # If we make it here, the server allowed us shell access without
        # authentication. Thankfully, the 'exit' command should have
        # left immediately.
        if verbose:
            print('Eek! Server allowed unauthenticated login! Exiting.')
        return ['none']
    # This is in fact the expected case, as we expect the SSH server to
    # reject the unauthenticated connection, and therefore expect exit code
    # 255, OpenSSH's sole error code.
    except subprocess.CalledProcessError as e:
        # ssh's result to stderr
        result = str(e.output.strip(), 'utf-8')

        if e.returncode != 255:
            if verbose:
                print('Eek! Server allowed unauthenticated login! '
                'Also, the command passed had a non-zero exit status.')
            return ['none']

        elif result.startswith('ssh: Could not resolve hostname'):
            if verbose:
                print('hostname resolution failed - '
                'maybe the server is down, '
                'the SSH server is on another port, '
                'or your IP is blacklisted?')
            raise Exception('resolution of hostname ' +  hostname + ' failed')

        elif result.endswith('Connection timed out'):
            raise Exception('connection to ' + hostname + ' timed out')

        elif result.startswith('Permission denied (') \
                and result.endswith(').'):
            # assume the format specified in the above condition with
            # comma-delimited auth methods
            return result[19:-2].split(',')

        else:
            raise Exception('unexpected SSH error response: ' + result)
    # we leave subprocess.TimeoutExpired uncaught, so it will propagate


def _ssh_worker(host_queue, response_queue, timeout, ssh_args):
    
    hostname = host_queue.get()
    # TODO: add port
    ssh_args = {'timeout': timeout, 'verbose': verbose}

    try:
        resp = get_auth_methods(hostname, **ssh_args)
    except:
        resp = None

    response_queue.put((hostname, resp))
    host_queue.task_done()


def _threaded_auth_methods(host_file, delay=0.1, timeout=5, verbose=False):
    # All get_auth_methods() args aside from hostname are optional,
    # and are the same across all calls.
    # We therefore use a dict of args that is unpacked in calls.
    ssh_args = {'verbose': verbose}
    host_queue, response_queue = Queue(), Queue()

    num_hosts = 0

    for line in host_file:
        num_hosts += 1
        host_queue.put(line.strip())
        t = threading.Thread(
                target=_ssh_worker,
                args=[host_queue, response_queue, timeout, ssh_args])
        t.start()

    host_queue.join()

    return [response_queue.get() for _ in range(num_hosts)]


def main():
    if sys.version_info.major != 3:
        print('this script only runs on Python 3, which should be '
                'available on your platform',
                file=sys.stderr)
        sys.exit(1)
    # the only two currently acceptable argument situations
    # a more complex argument system (using argparse, for example) may
    # be added later if needed.
    if len(sys.argv) == 1 or \
            len(sys.argv) == 2 and sys.argv[1] == '--verbose':
        verbose = len(sys.argv) == 2

        '''
        # loop through newline-delimited hostnames
        for line in sys.stdin:
            hostname = line.strip()
            try:
                auth_methods = get_auth_methods(hostname, verbose=verbose)
            except:
                # could probably use a verbose print option there
                auth_methods = []

            print('\t'.join([hostname] + auth_methods))
        '''

        response_tups = _threaded_auth_methods(sys.stdin, verbose=verbose)

        for hostname, methods in response_tups:
            print('\t'.join([hostname] + methods))

    else:
        print('ERROR: input must be line-delimited hostnames from stdin',
                file=sys.stdin)
        print('usage: python3 ssh_password.py [-v]',
                file=sys.stdin)
        sys.exit(1)


if __name__ == '__main__':
    main()

@@ -3324,33 +3324,24 @@
 ponse_queue,
- timeout,
  ssh_args):%0A
@@ -3340,16 +3340,16 @@
 _args):%0A
+
     %0A   
@@ -3380,85 +3380,8 @@
 et()
-%0A    # TODO: add port%0A    ssh_args = %7B'timeout': timeout, 'verbose': verbose%7D
 %0A%0A  
@@ -3602,16 +3602,18 @@
 imeout=5
+.0
 , verbos
@@ -3792,24 +3792,45 @@
 d in calls.%0A
+    # TODO: add port%0A
     ssh_args
@@ -3851,16 +3851,33 @@
  verbose
+, timeout=timeout
 %7D%0A    ho
@@ -4093,16 +4093,16 @@
 worker,%0A
+
         
@@ -4146,17 +4146,8 @@
 eue,
- timeout,
  ssh

change arg format