From e0a9f91c149a10758694adfe574417566c650d0d Mon Sep 17 00:00:00 2001 From: Robey Pointer Date: Sun, 1 Nov 2009 21:33:13 -0800 Subject: [PATCH] brittspace. --- paramiko/hostkeys.py | 52 +++++++-------- paramiko/rng_posix.py | 10 +-- paramiko/transport.py | 144 +++++++++++++++++++++--------------------- 3 files changed, 103 insertions(+), 103 deletions(-) diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py index 09922d4..9ceef43 100644 --- a/paramiko/hostkeys.py +++ b/paramiko/hostkeys.py @@ -33,7 +33,7 @@ class HostKeyEntry: """ Representation of a line in an OpenSSH-style "known hosts" file. """ - + def __init__(self, hostnames=None, key=None): self.valid = (hostnames is not None) and (key is not None) self.hostnames = hostnames @@ -83,7 +83,7 @@ class HostKeyEntry: return '%s %s %s\n' % (','.join(self.hostnames), self.key.get_name(), self.key.get_base64()) return None - + def __repr__(self): return '' % (self.hostnames, self.key) @@ -93,18 +93,18 @@ class HostKeys (UserDict.DictMixin): Representation of an openssh-style "known hosts" file. Host keys can be read from one or more files, and then individual hosts can be looked up to verify server keys during SSH negotiation. - + A HostKeys object can be treated like a dict; any dict lookup is equivalent to calling L{lookup}. - + @since: 1.5.3 """ - + def __init__(self, filename=None): """ Create a new HostKeys object, optionally loading keys from an openssh style host-key file. - + @param filename: filename to load host keys from, or C{None} @type filename: str """ @@ -112,12 +112,12 @@ class HostKeys (UserDict.DictMixin): self._entries = [] if filename is not None: self.load(filename) - + def add(self, hostname, keytype, key): """ Add a host key entry to the table. Any existing entry for a C{(hostname, keytype)} pair will be replaced. - + @param hostname: the hostname (or IP) to add @type hostname: str @param keytype: key type (C{"ssh-rsa"} or C{"ssh-dss"}) @@ -130,21 +130,21 @@ class HostKeys (UserDict.DictMixin): e.key = key return self._entries.append(HostKeyEntry([hostname], key)) - + def load(self, filename): """ Read a file of known SSH host keys, in the format used by openssh. This type of file unfortunately doesn't exist on Windows, but on posix, it will usually be stored in C{os.path.expanduser("~/.ssh/known_hosts")}. - + If this method is called multiple times, the host keys are merged, not cleared. So multiple calls to C{load} will just call L{add}, replacing any existing entries and adding new ones. - + @param filename: name of the file to read host keys from @type filename: str - + @raise IOError: if there was an error reading the file """ f = open(filename, 'r') @@ -156,19 +156,19 @@ class HostKeys (UserDict.DictMixin): if e is not None: self._entries.append(e) f.close() - + def save(self, filename): """ Save host keys into a file, in the format used by openssh. The order of keys in the file will be preserved when possible (if these keys were loaded from a file originally). The single exception is that combined lines will be split into individual key lines, which is arguably a bug. - + @param filename: name of the file to write @type filename: str - + @raise IOError: if there was an error writing the file - + @since: 1.6.1 """ f = open(filename, 'w') @@ -183,7 +183,7 @@ class HostKeys (UserDict.DictMixin): Find a hostkey entry for a given hostname or IP. If no entry is found, C{None} is returned. Otherwise a dictionary of keytype to key is returned. The keytype will be either C{"ssh-rsa"} or C{"ssh-dss"}. - + @param hostname: the hostname (or IP) to lookup @type hostname: str @return: keys associated with this host (or C{None}) @@ -194,13 +194,13 @@ class HostKeys (UserDict.DictMixin): self._hostname = hostname self._entries = entries self._hostkeys = hostkeys - + def __getitem__(self, key): for e in self._entries: if e.key.get_name() == key: return e.key raise KeyError(key) - + def __setitem__(self, key, val): for e in self._entries: if e.key is None: @@ -214,7 +214,7 @@ class HostKeys (UserDict.DictMixin): e = HostKeyEntry([hostname], val) self._entries.append(e) self._hostkeys._entries.append(e) - + def keys(self): return [e.key.get_name() for e in self._entries if e.key is not None] @@ -226,12 +226,12 @@ class HostKeys (UserDict.DictMixin): if len(entries) == 0: return None return SubDict(hostname, entries, self) - + def check(self, hostname, key): """ Return True if the given key is associated with the given hostname in this dictionary. - + @param hostname: hostname (or IP) of the SSH server @type hostname: str @param key: the key to check @@ -253,13 +253,13 @@ class HostKeys (UserDict.DictMixin): Remove all host keys from the dictionary. """ self._entries = [] - + def __getitem__(self, key): ret = self.lookup(key) if ret is None: raise KeyError(key) return ret - + def __setitem__(self, hostname, entry): # don't use this please. if len(entry) == 0: @@ -274,7 +274,7 @@ class HostKeys (UserDict.DictMixin): found = True if not found: self._entries.append(HostKeyEntry([hostname], entry[key_type])) - + def keys(self): # python 2.4 sets would be nice here. ret = [] @@ -294,7 +294,7 @@ class HostKeys (UserDict.DictMixin): """ Return a "hashed" form of the hostname, as used by openssh when storing hashed hostnames in the known_hosts file. - + @param hostname: the hostname to hash @type hostname: str @param salt: optional salt to use when hashing (must be 20 bytes long) diff --git a/paramiko/rng_posix.py b/paramiko/rng_posix.py index 1e6d72c..c4c9691 100644 --- a/paramiko/rng_posix.py +++ b/paramiko/rng_posix.py @@ -43,7 +43,7 @@ def open_rng_device(device_path=None): f = None g = None - + if device_path is None: device_path = "/dev/urandom" @@ -54,7 +54,7 @@ def open_rng_device(device_path=None): f = open(device_path, "rb", 0) except EnvironmentError: raise error("Unable to open /dev/urandom") - + # Open a second file descriptor for sanity checking later. try: g = open(device_path, "rb", 0) @@ -65,17 +65,17 @@ def open_rng_device(device_path=None): st = os.fstat(f.fileno()) # f if stat.S_ISREG(st.st_mode) or not stat.S_ISCHR(st.st_mode): raise error("/dev/urandom is not a character special device") - + st = os.fstat(g.fileno()) # g if stat.S_ISREG(st.st_mode) or not stat.S_ISCHR(st.st_mode): raise error("/dev/urandom is not a character special device") - + # Check that /dev/urandom always returns the number of bytes requested x = f.read(20) y = g.read(20) if len(x) != 20 or len(y) != 20: raise error("Error reading from /dev/urandom: input truncated") - + # Check that different reads return different data if x == y: raise error("/dev/urandom is broken; returning identical data: %r == %r" % (x, y)) diff --git a/paramiko/transport.py b/paramiko/transport.py index dd04206..a00b754 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -103,7 +103,7 @@ class SecurityOptions (object): def _get_kex(self): return self._transport._preferred_kex - + def _get_compression(self): return self._transport._preferred_compression @@ -129,7 +129,7 @@ class SecurityOptions (object): def _set_kex(self, x): self._set('_preferred_kex', '_kex_info', x) - + def _set_compression(self, x): self._set('_preferred_compression', '_compression_info', x) @@ -156,14 +156,14 @@ class ChannelMap (object): self._map[chanid] = chan finally: self._lock.release() - + def get(self, chanid): self._lock.acquire() try: return self._map.get(chanid, None) finally: self._lock.release() - + def delete(self, chanid): self._lock.acquire() try: @@ -173,14 +173,14 @@ class ChannelMap (object): pass finally: self._lock.release() - + def values(self): self._lock.acquire() try: return self._map.values() finally: self._lock.release() - + def __len__(self): self._lock.acquire() try: @@ -206,7 +206,7 @@ class Transport (threading.Thread): _preferred_keys = ( 'ssh-rsa', 'ssh-dss' ) _preferred_kex = ( 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' ) _preferred_compression = ( 'none', ) - + _cipher_info = { 'aes128-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 16 }, 'aes256-ctr': { 'class': AES, 'mode': AES.MODE_CTR, 'block-size': 16, 'key-size': 32 }, @@ -234,7 +234,7 @@ class Transport (threading.Thread): 'diffie-hellman-group1-sha1': KexGroup1, 'diffie-hellman-group-exchange-sha1': KexGex, } - + _compression_info = { # zlib@openssh.com is just zlib, but only turned on after a successful # authentication. openssh servers may only offer this type because @@ -319,7 +319,7 @@ class Transport (threading.Thread): self.session_id = None self.host_key_type = None self.host_key = None - + # state used during negotiation self.kex_engine = None self.H = None @@ -383,7 +383,7 @@ class Transport (threading.Thread): out += ' (connecting)' out += '>' return out - + def atfork(self): """ Terminate this Transport without closing the session. On posix @@ -391,7 +391,7 @@ class Transport (threading.Thread): and child will share the underlying socket, but only one process can use the connection (without corrupting the session). Use this method to clean up a Transport object without disrupting the other process. - + @since: 1.5.3 """ self.sock.close() @@ -414,11 +414,11 @@ class Transport (threading.Thread): Negotiate a new SSH2 session as a client. This is the first step after creating a new L{Transport}. A separate thread is created for protocol negotiation. - + If an event is passed in, this method returns immediately. When negotiation is done (successful or not), the given C{Event} will be triggered. On failure, L{is_active} will return C{False}. - + (Since 1.4) If C{event} is C{None}, this method will not return until negotation is done. On success, the method returns normally. Otherwise an SSHException is raised. @@ -428,7 +428,7 @@ class Transport (threading.Thread): L{auth_publickey }. @note: L{connect} is a simpler method for connecting as a client. - + @note: After calling this method (or L{start_server} or L{connect}), you should no longer directly read from or write to the original socket object. @@ -465,11 +465,11 @@ class Transport (threading.Thread): Negotiate a new SSH2 session as a server. This is the first step after creating a new L{Transport} and setting up your server host key(s). A separate thread is created for protocol negotiation. - + If an event is passed in, this method returns immediately. When negotiation is done (successful or not), the given C{Event} will be triggered. On failure, L{is_active} will return C{False}. - + (Since 1.4) If C{event} is C{None}, this method will not return until negotation is done. On success, the method returns normally. Otherwise an SSHException is raised. @@ -532,7 +532,7 @@ class Transport (threading.Thread): we are. Because this is used for signing, the key must contain private key info, not just the public half. Only one key of each type (RSA or DSS) is kept. - + @param key: the host key to add, usually an L{RSAKey } or L{DSSKey }. @type key: L{PKey } @@ -582,7 +582,7 @@ class Transport (threading.Thread): @return: True if a moduli file was successfully loaded; False otherwise. @rtype: bool - + @note: This has no effect when used in client mode. """ Transport._modulus_pack = ModulusPack(randpool) @@ -623,7 +623,7 @@ class Transport (threading.Thread): C{str(key)} for the key string. @raise SSHException: if no session is currently active. - + @return: public key of the remote server @rtype: L{PKey } """ @@ -648,7 +648,7 @@ class Transport (threading.Thread): @return: a new L{Channel} @rtype: L{Channel} - + @raise SSHException: if the request is rejected or the session ends prematurely """ @@ -664,25 +664,25 @@ class Transport (threading.Thread): @type src_addr: (str, int) @return: a new L{Channel} @rtype: L{Channel} - + @raise SSHException: if the request is rejected or the session ends prematurely """ return self.open_channel('x11', src_addr=src_addr) - + def open_forwarded_tcpip_channel(self, (src_addr, src_port), (dest_addr, dest_port)): """ Request a new channel back to the client, of type C{"forwarded-tcpip"}. This is used after a client has requested port forwarding, for sending incoming connections back to the client. - + @param src_addr: originator's address @param src_port: originator's port @param dest_addr: local (server) connected address @param dest_port: local (server) connected port """ return self.open_channel('forwarded-tcpip', (dest_addr, dest_port), (src_addr, src_port)) - + def open_channel(self, kind, dest_addr=None, src_addr=None): """ Request a new channel to the server. L{Channel}s are socket-like @@ -757,19 +757,19 @@ class Transport (threading.Thread): """ Ask the server to forward TCP connections from a listening port on the server, across this SSH session. - + If a handler is given, that handler is called from a different thread whenever a forwarded connection arrives. The handler parameters are:: - + handler(channel, (origin_addr, origin_port), (server_addr, server_port)) - + where C{server_addr} and C{server_port} are the address and port that the server was listening on. - + If no handler is set, the default behavior is to send new incoming forwarded connections into the accept queue, to be picked up via L{accept}. - + @param address: the address to bind when forwarding @type address: str @param port: the port to forward, or 0 to ask the server to allocate @@ -779,7 +779,7 @@ class Transport (threading.Thread): @type handler: function(Channel, (str, int), (str, int)) @return: the port # allocated by the server @rtype: int - + @raise SSHException: if the server refused the TCP forward request """ if not self.active: @@ -803,7 +803,7 @@ class Transport (threading.Thread): Ask the server to cancel a previous port-forwarding request. No more connections to the given address & port will be forwarded across this ssh connection. - + @param address: the address to stop forwarding @type address: str @param port: the port to stop forwarding @@ -813,7 +813,7 @@ class Transport (threading.Thread): return self._tcp_handler = None self.global_request('cancel-tcpip-forward', (address, port), wait=True) - + def open_sftp_client(self): """ Create an SFTP client channel from an open transport. On success, @@ -876,7 +876,7 @@ class Transport (threading.Thread): C{interval} seconds without sending any data over the connection, a "keepalive" packet will be sent (and ignored by the remote host). This can be useful to keep connections alive over a NAT, for example. - + @param interval: seconds to wait before sending a keepalive packet (or 0 to disable keepalives). @type interval: int @@ -927,7 +927,7 @@ class Transport (threading.Thread): Return the next channel opened by the client over this transport, in server mode. If no channel is opened before the given timeout, C{None} is returned. - + @param timeout: seconds to wait for a channel, or C{None} to wait forever @type timeout: int @@ -979,7 +979,7 @@ class Transport (threading.Thread): @param pkey: a private key to use for authentication, if you want to use private key authentication; otherwise C{None}. @type pkey: L{PKey} - + @raise SSHException: if the SSH2 negotiation fails, the host key supplied by the server is incorrect, or authentication fails. """ @@ -1007,17 +1007,17 @@ class Transport (threading.Thread): self.auth_publickey(username, pkey) return - + def get_exception(self): """ Return any exception that happened during the last server request. This can be used to fetch more specific error information after using calls like L{start_client}. The exception (if any) is cleared after this call. - + @return: an exception, or C{None} if there is no stored exception. @rtype: Exception - + @since: 1.1 """ self.lock.acquire() @@ -1049,7 +1049,7 @@ class Transport (threading.Thread): self.subsystem_table[name] = (handler, larg, kwarg) finally: self.lock.release() - + def is_authenticated(self): """ Return true if this session is active and authenticated. @@ -1060,7 +1060,7 @@ class Transport (threading.Thread): @rtype: bool """ return self.active and (self.auth_handler is not None) and self.auth_handler.is_authenticated() - + def get_username(self): """ Return the username this connection is authenticated for. If the @@ -1080,7 +1080,7 @@ class Transport (threading.Thread): This will almost always fail. It may be useful for determining the list of authentication types supported by the server, by catching the L{BadAuthenticationType} exception raised. - + @param username: the username to authenticate as @type username: string @return: list of auth types permissible for the next stage of @@ -1091,7 +1091,7 @@ class Transport (threading.Thread): by the server for this user @raise SSHException: if the authentication failed due to a network error - + @since: 1.5 """ if (not self.active) or (not self.initial_kex_done): @@ -1105,7 +1105,7 @@ class Transport (threading.Thread): """ Authenticate to the server using a password. The username and password are sent over an encrypted link. - + If an C{event} is passed in, this method will return immediately, and the event will be triggered once authentication succeeds or fails. On success, L{is_authenticated} will return C{True}. On failure, you may @@ -1114,7 +1114,7 @@ class Transport (threading.Thread): Since 1.1, if no event is passed, this method will block until the authentication succeeds or fails. On failure, an exception is raised. Otherwise, the method simply returns. - + Since 1.5, if no event is passed and C{fallback} is C{True} (the default), if the server doesn't support plain password authentication but does support so-called "keyboard-interactive" mode, an attempt @@ -1123,11 +1123,11 @@ class Transport (threading.Thread): made. This is useful for some recent Gentoo and Debian distributions, which turn off plain password authentication in a misguided belief that interactive authentication is "more secure". (It's not.) - + If the server requires multi-step authentication (which is very rare), this method will return a list of auth types permissible for the next step. Otherwise, in the normal case, an empty list is returned. - + @param username: the username to authenticate as @type username: str @param password: the password to authenticate with @@ -1142,7 +1142,7 @@ class Transport (threading.Thread): @return: list of auth types permissible for the next stage of authentication (normally empty) @rtype: list - + @raise BadAuthenticationType: if password authentication isn't allowed by the server for this user (and no event was passed in) @raise AuthenticationException: if the authentication failed (and no @@ -1188,12 +1188,12 @@ class Transport (threading.Thread): """ Authenticate to the server using a private key. The key is used to sign data from the server, so it must include the private part. - + If an C{event} is passed in, this method will return immediately, and the event will be triggered once authentication succeeds or fails. On success, L{is_authenticated} will return C{True}. On failure, you may use L{get_exception} to get more detailed error information. - + Since 1.1, if no event is passed, this method will block until the authentication succeeds or fails. On failure, an exception is raised. Otherwise, the method simply returns. @@ -1212,7 +1212,7 @@ class Transport (threading.Thread): @return: list of auth types permissible for the next stage of authentication (normally empty) @rtype: list - + @raise BadAuthenticationType: if public-key authentication isn't allowed by the server for this user (and no event was passed in) @raise AuthenticationException: if the authentication failed (and no @@ -1232,18 +1232,18 @@ class Transport (threading.Thread): # caller wants to wait for event themselves return [] return self.auth_handler.wait_for_response(my_event) - + def auth_interactive(self, username, handler, submethods=''): """ Authenticate to the server interactively. A handler is used to answer arbitrary questions from the server. On many servers, this is just a dumb wrapper around PAM. - + This method will block until the authentication succeeds or fails, peroidically calling the handler asynchronously to get answers to authentication questions. The handler may be called more than once if the server continues to ask questions. - + The handler is expected to be a callable that will handle calls of the form: C{handler(title, instructions, prompt_list)}. The C{title} is meant to be a dialog-window title, and the C{instructions} are user @@ -1251,13 +1251,13 @@ class Transport (threading.Thread): prompts, each prompt being a tuple of C{(str, bool)}. The string is the prompt and the boolean indicates whether the user text should be echoed. - + A sample call would thus be: C{handler('title', 'instructions', [('Password:', False)])}. - + The handler should return a list or tuple of answers to the server's questions. - + If the server requires multi-step authentication (which is very rare), this method will return a list of auth types permissible for the next step. Otherwise, in the normal case, an empty list is returned. @@ -1271,12 +1271,12 @@ class Transport (threading.Thread): @return: list of auth types permissible for the next stage of authentication (normally empty). @rtype: list - + @raise BadAuthenticationType: if public-key authentication isn't allowed by the server for this user @raise AuthenticationException: if the authentication failed @raise SSHException: if there was a network error - + @since: 1.5 """ if (not self.active) or (not self.initial_kex_done): @@ -1325,43 +1325,43 @@ class Transport (threading.Thread): @type hexdump: bool """ self.packetizer.set_hexdump(hexdump) - + def get_hexdump(self): """ Return C{True} if the transport is currently logging hex dumps of protocol traffic. - + @return: C{True} if hex dumps are being logged @rtype: bool - + @since: 1.4 """ return self.packetizer.get_hexdump() - + def use_compression(self, compress=True): """ Turn on/off compression. This will only have an affect before starting the transport (ie before calling L{connect}, etc). By default, compression is off since it negatively affects interactive sessions. - + @param compress: C{True} to ask the remote client/server to compress traffic; C{False} to refuse compression @type compress: bool - + @since: 1.5.2 """ if compress: self._preferred_compression = ( 'zlib@openssh.com', 'zlib', 'none' ) else: self._preferred_compression = ( 'none', ) - + def getpeername(self): """ Return the address of the remote side of this Transport, if possible. This is effectively a wrapper around C{'getpeername'} on the underlying socket. If the socket-like object has no C{'getpeername'} method, then C{("unknown", 0)} is returned. - + @return: the address if the remote host, if known @rtype: tuple(str, int) """ @@ -1377,7 +1377,7 @@ class Transport (threading.Thread): ### internals... - + def _log(self, level, msg, *args): if issubclass(type(msg), list): for m in msg: @@ -1498,13 +1498,13 @@ class Transport (threading.Thread): self.server_accept_cv.notify() finally: self.lock.release() - + def run(self): # (use the exposed "run" method, because if we specify a thread target # of a private method, threading.Thread will keep a reference to it # indefinitely, creating a GC cycle and not letting Transport ever be # GC'd. it's a bug in Thread.) - + # active=True occurs before the thread is launched, to avoid a race _active_threads.append(self) if self.server_mode: @@ -1929,7 +1929,7 @@ class Transport (threading.Thread): self.global_response = m if self.completion_event is not None: self.completion_event.set() - + def _parse_request_failure(self, m): self._log(DEBUG, 'Global request denied.') self.global_response = None @@ -2018,7 +2018,7 @@ class Transport (threading.Thread): origin_addr = m.get_string() origin_port = m.get_int() reason = self.server_object.check_channel_direct_tcpip_request( - my_chanid, (origin_addr, origin_port), + my_chanid, (origin_addr, origin_port), (dest_addr, dest_port)) else: reason = self.server_object.check_channel_request(kind, my_chanid) @@ -2034,7 +2034,7 @@ class Transport (threading.Thread): msg.add_string('en') self._send_message(msg) return - + chan = Channel(my_chanid) self.lock.acquire() try: