brittspace.
This commit is contained in:
parent
71e872e23a
commit
e0a9f91c14
|
@ -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 '<HostKeyEntry %r: %r>' % (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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 <Transport.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 <rsakey.RSAKey>} or
|
||||
L{DSSKey <dsskey.DSSKey>}.
|
||||
@type key: L{PKey <pkey.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 <pkey.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<pkey.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:
|
||||
|
|
Loading…
Reference in New Issue