Search code examples
pythonsshparamiko

In Paramiko, how can I determine if a successful connection was via the SSH key or the password?


This code excerpt connects properly if the private ssh key OR the password is correct (it tries the key first). After a successful connection, how can I tell which one was used? Is this even possible without first trying to connect with the key only (no password)? I cannot find this in the Paramiko documention.

self.client = paramiko.SSHClient()
hostkey = self.ssh_hostkey.split(' ')
self.client.get_host_keys().add(self.ip, hostkey[0], paramiko.RSAKey(data=base64.b64decode(hostkey[1])))
privkey_file = io.StringIO()
privkey_file.write(self.ssh_privkey)
privkey_file.seek(0)
privkey = paramiko.RSAKey.from_private_key(privkey_file)
try:
    self.client.connect(
        hostname=self.ip,
        username='root',
        pkey=privkey,
        password=self.router_password, # will try private key first, then password
        allow_agent=False,
        look_for_keys=False,
    )
    self.last_connect = time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime())
    print_msg(1, "Connected to {}".format(self.nickname))
except paramiko.ssh_exception.AuthenticationException:
    self.client = None

Solution

  • I do not think that SSHClient gives you that information (apart from you parsing a log file).

    You would have to resort to low-level Transport class.

    With it, you can do Transport.auth_publickey and fallback to Transport.auth_password, without having to reopen a session.

    transport = paramiko.Transport(host)
    transport.connect(hostkey)
    
    try:
        print("Trying key")
        transport.auth_publickey(username, key)
    except:
        print("Trying password")
        transport.auth_password(username, password)
    
    print("Authenticated")