diff options
-rw-r--r-- | paramiko/agent.py | 15 | ||||
-rw-r--r-- | paramiko/pkey.py | 31 | ||||
-rw-r--r-- | paramiko/server.py | 58 |
3 files changed, 59 insertions, 45 deletions
diff --git a/paramiko/agent.py b/paramiko/agent.py index c13810bb..c950ba5e 100644 --- a/paramiko/agent.py +++ b/paramiko/agent.py @@ -109,15 +109,19 @@ class AgentProxyThread(threading.Thread): def run(self): try: (r, addr) = self.get_connection() - # Found that r should be either a socket from the socket library or None + # Found that r should be either + # a socket from the socket library or None self.__inr = r - self.__addr = addr # This should be an IP address as a string? or None + # The address should be an IP address as a string? or None + self.__addr = addr self._agent.connect() - if not isinstance(self._agent, int) and (self._agent._conn is None or not hasattr(self._agent._conn, 'fileno')): + if not isinstance(self._agent, int) and \ + (self._agent._conn is None or + not hasattr(self._agent._conn, 'fileno')): raise AuthenticationException("Unable to connect to SSH agent") self._communicate() except: - #XXX Not sure what to do here ... raise or pass ? + # XXX Not sure what to do here ... raise or pass ? raise def _communicate(self): @@ -213,7 +217,8 @@ class AgentClientProxy(object): if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'): conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: - retry_on_signal(lambda: conn.connect(os.environ['SSH_AUTH_SOCK'])) + retry_on_signal( + lambda: conn.connect(os.environ['SSH_AUTH_SOCK'])) except: # probably a dangling env var: the ssh agent is gone return diff --git a/paramiko/pkey.py b/paramiko/pkey.py index c87daaed..af9370fc 100644 --- a/paramiko/pkey.py +++ b/paramiko/pkey.py @@ -65,7 +65,8 @@ class PKey(object): :param .Message msg: an optional SSH `.Message` containing a public key of this type. - :param str data: an optional string containing a public key of this type + :param str data: an optional string containing a public key + of this type :raises SSHException: if a key cannot be created from the ``data`` or ``msg`` given, or @@ -85,6 +86,8 @@ class PKey(object): return self.asbytes() # noinspection PyUnresolvedReferences + # TODO: The comparison functions should be removed as per: + # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons def __cmp__(self, other): """ Compare this key to another. Returns 0 if this key is equivalent to @@ -97,8 +100,8 @@ class PKey(object): hs = hash(self) ho = hash(other) if hs != ho: - return cmp(hs, ho) - return cmp(self.asbytes(), other.asbytes()) + return cmp(hs, ho) # noqa + return cmp(self.asbytes(), other.asbytes()) # noqa def __eq__(self, other): return hash(self) == hash(other) @@ -249,10 +252,11 @@ class PKey(object): Read an SSH2-format private key file, looking for a string of the type ``"BEGIN xxx PRIVATE KEY"`` for some ``xxx``, base64-decode the text we find, and return it as a string. If the private key is encrypted and - ``password`` is not ``None``, the given password will be used to decrypt - the key (otherwise `.PasswordRequiredException` is thrown). + ``password`` is not ``None``, the given password will be used to + decrypt the key (otherwise `.PasswordRequiredException` is thrown). - :param str tag: ``"RSA"`` or ``"DSA"``, the tag used to mark the data block. + :param str tag: ``"RSA"`` or ``"DSA"``, the tag used to mark the + data block. :param str filename: name of the file to read. :param str password: an optional password to use to decrypt the key file, if it's @@ -271,7 +275,8 @@ class PKey(object): def _read_private_key(self, tag, f, password=None): lines = f.readlines() start = 0 - while (start < len(lines)) and (lines[start].strip() != '-----BEGIN ' + tag + ' PRIVATE KEY-----'): + beginning_of_key = '-----BEGIN ' + tag + ' PRIVATE KEY-----' + while start < len(lines) and lines[start].strip() != beginning_of_key: start += 1 if start >= len(lines): raise SSHException('not a valid ' + tag + ' private key file') @@ -286,7 +291,8 @@ class PKey(object): start += 1 # find end end = start - while end < len(lines) and lines[end].strip() != '-----END ' + tag + ' PRIVATE KEY-----': + ending_of_key = '-----END ' + tag + ' PRIVATE KEY-----' + while end < len(lines) and lines[end].strip() != ending_of_key: end += 1 # if we trudged to the end of the file, just try to cope. try: @@ -298,14 +304,17 @@ class PKey(object): return data # encrypted keyfile: will need a password if headers['proc-type'] != '4,ENCRYPTED': - raise SSHException('Unknown private key structure "%s"' % headers['proc-type']) + raise SSHException( + 'Unknown private key structure "%s"' % headers['proc-type']) try: encryption_type, saltstr = headers['dek-info'].split(',') except: raise SSHException("Can't parse DEK-info in private key file") if encryption_type not in self._CIPHER_TABLE: - raise SSHException('Unknown private key cipher "%s"' % encryption_type) - # if no password was passed in, raise an exception pointing out that we need one + raise SSHException( + 'Unknown private key cipher "%s"' % encryption_type) + # if no password was passed in, + # raise an exception pointing out that we need one if password is None: raise PasswordRequiredException('Private key file is encrypted') cipher = self._CIPHER_TABLE[encryption_type]['cipher'] diff --git a/paramiko/server.py b/paramiko/server.py index da4a1e1c..bb244efe 100644 --- a/paramiko/server.py +++ b/paramiko/server.py @@ -70,7 +70,7 @@ class ServerInterface (object): - ``OPEN_FAILED_CONNECT_FAILED`` - ``OPEN_FAILED_UNKNOWN_CHANNEL_TYPE`` - ``OPEN_FAILED_RESOURCE_SHORTAGE`` - + The default implementation always returns ``OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED``. @@ -161,7 +161,7 @@ class ServerInterface (object): Note that you don't have to actually verify any key signtature here. If you're willing to accept the key, Paramiko will do the work of verifying the client's signature. - + The default implementation always returns `.AUTH_FAILED`. :param str username: the username of the authenticating client @@ -174,21 +174,21 @@ class ServerInterface (object): :rtype: int """ return AUTH_FAILED - + def check_auth_interactive(self, username, submethods): """ Begin an interactive authentication challenge, if supported. You should override this method in server mode if you want to support the ``"keyboard-interactive"`` auth type, which requires you to send a series of questions for the client to answer. - + Return `.AUTH_FAILED` if this auth method isn't supported. Otherwise, you should return an `.InteractiveQuery` object containing the prompts and instructions for the user. The response will be sent via a call to `check_auth_interactive_response`. - + The default implementation always returns `.AUTH_FAILED`. - + :param str username: the username of the authenticating client :param str submethods: a comma-separated list of methods preferred by the client (usually @@ -199,13 +199,13 @@ class ServerInterface (object): :rtype: int or `.InteractiveQuery` """ return AUTH_FAILED - + def check_auth_interactive_response(self, responses): """ Continue or finish an interactive authentication challenge, if supported. You should override this method in server mode if you want to support the ``"keyboard-interactive"`` auth type. - + Return `.AUTH_FAILED` if the responses are not accepted, `.AUTH_SUCCESSFUL` if the responses are accepted and complete the authentication, or `.AUTH_PARTIALLY_SUCCESSFUL` if your @@ -277,7 +277,7 @@ class ServerInterface (object): `.AUTH_SUCCESSFUL` :rtype: int :note: Kerberos credential delegation is not supported. - :see: `.ssh_gss` `.kex_gss` + :see: `.ssh_gss` `.kex_gss` :note: : We are just checking in L{AuthHandler} that the given user is a valid krb5 principal! We don't check if the krb5 principal is allowed to log in on @@ -304,9 +304,8 @@ class ServerInterface (object): :see: : `.ssh_gss` """ UseGSSAPI = False - GSSAPICleanupCredentials = False return UseGSSAPI - + def check_port_forward_request(self, address, port): """ Handle a request for port forwarding. The client is asking that @@ -315,11 +314,11 @@ class ServerInterface (object): address (any address associated with this server) and a port of ``0`` indicates that no specific port is requested (usually the OS will pick a port). - + The default implementation always returns ``False``, rejecting the port forwarding request. If the request is accepted, you should return the port opened for listening. - + :param str address: the requested address :param int port: the requested port :return: @@ -327,18 +326,18 @@ class ServerInterface (object): to reject """ return False - + def cancel_port_forward_request(self, address, port): """ The client would like to cancel a previous port-forwarding request. If the given address and port is being forwarded across this ssh connection, the port should be closed. - + :param str address: the forwarded address :param int port: the forwarded port """ pass - + def check_global_request(self, kind, msg): """ Handle a global request of the given ``kind``. This method is called @@ -357,7 +356,7 @@ class ServerInterface (object): The default implementation always returns ``False``, indicating that it does not support any global requests. - + .. note:: Port forwarding requests are handled separately, in `check_port_forward_request`. @@ -415,20 +414,20 @@ class ServerInterface (object): Determine if a shell command will be executed for the client. If this method returns ``True``, the channel should be connected to the stdin, stdout, and stderr of the shell command. - + The default implementation always returns ``False``. - + :param .Channel channel: the `.Channel` the request arrived on. :param str command: the command to execute. :return: ``True`` if this channel is now hooked up to the stdin, stdout, and stderr of the executing command; ``False`` if the command will not be executed. - + .. versionadded:: 1.1 """ return False - + def check_channel_subsystem_request(self, channel, name): """ Determine if a requested subsystem will be provided to the client on @@ -477,7 +476,7 @@ class ServerInterface (object): :return: ``True`` if the terminal was resized; ``False`` if not. """ return False - + def check_channel_x11_request( self, channel, single_connection, auth_protocol, auth_cookie, screen_number): @@ -485,9 +484,9 @@ class ServerInterface (object): Determine if the client will be provided with an X11 session. If this method returns ``True``, X11 applications should be routed through new SSH channels, using `.Transport.open_x11_channel`. - + The default implementation always returns ``False``. - + :param .Channel channel: the `.Channel` the X11 request arrived on :param bool single_connection: ``True`` if only a single X11 channel should be opened, else @@ -537,7 +536,7 @@ class ServerInterface (object): - ``OPEN_FAILED_CONNECT_FAILED`` - ``OPEN_FAILED_UNKNOWN_CHANNEL_TYPE`` - ``OPEN_FAILED_RESOURCE_SHORTAGE`` - + The default implementation always returns ``OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED``. @@ -575,14 +574,14 @@ class InteractiveQuery (object): """ A query (set of prompts) for a user during interactive authentication. """ - + def __init__(self, name='', instructions='', *prompts): """ Create a new interactive query to send to the client. The name and instructions are optional, but are generally displayed to the end user. A list of prompts may be included, or they may be added via the `add_prompt` method. - + :param str name: name of this query :param str instructions: user instructions (usually short) about this query @@ -658,8 +657,9 @@ class SubsystemHandler (threading.Thread): self.start_subsystem(self.__name, self.__transport, self.__channel) except Exception as e: self.__transport._log( - ERROR, 'Exception in subsystem handler for "%s": %s' % - (self.__name, str(e))) + ERROR, + 'Exception in subsystem handler for "{}": {}'.format( + self.__name, e)) self.__transport._log(ERROR, util.tb_strings()) try: self.finish_subsystem() |