[paramiko] Hostkeys acception Policy

Diego Jacobi jacobidiego at gmail.com
Fri Jan 4 18:14:25 PST 2008


Hello.

I was going to write a log mail to ask for help, but i have already resolved
it with lots and increible lots of hours, so i send what the problem was and
how i have solved it for any other who haves the same problem.

I have a method called tryconnect which is called from a thread in python:

self._connect_thread = DepThread( target=self.tryConnect, args=() )
self._connect_thread.start()

inside the tryconnect i call connect and manage its exceptions.
When an exception occurs i call a callback which shows the info to the user.

I got on the need to ask the user to accept a new hostkey when it is not on
the hostkeys list.
So i made my own Policy:

class HostkeyUserRejectedException(paramiko.AuthenticationException):
    """
    Exception raised when the hostkey is rejected by the user.
    """
    pass
class Policy_with_callback(paramiko.AutoAddPolicy, paramiko.RejectPolicy):
    def __init__(self,callback):
        self.callback = callback

    def missing_host_key(self, client, hostname, key):
        """
        Called when an SSHClient receives a server key for a server that
        isn't in either the system or local HostKeys object.  To accept
        the key, simply return.  To reject, raise an exception (which will
        be passed to the calling application).
        """
        if not self.callback:
            raise Exception("No callback specified. When using method -1 to
validate hostkeys you should use a callback.")

        try:
            ret = self.callback(client, hostname, key)
        except Exception, error:
            raise Exception("An error ocurred when calling the
policy_callback:  "+error)
        if ret:
            try:
                paramiko.AutoAddPolicy.missing_host_key
(self,client,hostname,key)
            except IOError,error:
                os.mkdir( os.path.expanduser('~/.ssh') )
            return
        try:
            paramiko.RejectPolicy.missing_host_key(self,client,hostname,key)
        except paramiko.SSHException,error:
            raise HostkeyUserRejectedException('The user rejected to accept
the hostkey for %s' % hostname)


This policy uses a callback to make another code ask the user in different
ways, like only in the console or with gtk.
The problem was when i reject intentionally the key, even with RejectPolicy
the raised exception goes to my tryconnect method and is wrapped there, but
the transport is still alive and waiting for a response to happen, which
never occurs becouse i have wrapped the exception.
This makes the tryconnect-thread eternal. Never ends.

To fix this i call a single method on every exception handler called
self.selfdestruct:

        except HostkeyUserRejectedException, error:
            self.selfdestruct("HostkeyUserRejectedException",error)
        except HostkeyAutoRejectedException, error:
            self.selfdestruct("HostkeyAutoRejectedException",error)
        except paramiko.PasswordRequiredException, error:
            self.selfdestruct("PasswordRequiredException",error)


    def selfdestruct(self,errtype,error):
        self.error_calls(errtype+": "+error[0])
        self.onconnect_callback(self,errtype)
        if not self._isconnected:
            self.client.close()
            del self.client
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.lag.net/pipermail/paramiko/attachments/20080105/1b801e42/attachment.htm 


More information about the paramiko mailing list