summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--paramiko/transport.py73
1 files changed, 47 insertions, 26 deletions
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 11531c53..90de98cc 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -56,37 +56,61 @@ atexit.register(_join_lingering_threads)
class SecurityOptions (object):
"""
Simple object containing the security preferences of an ssh transport.
- These are lists of acceptable ciphers, digests, key types, and key
+ These are tuples of acceptable ciphers, digests, key types, and key
exchange algorithms, listed in order of preference.
+
+ Changing the contents and/or order of these fields affects the underlying
+ L{Transport} (but only if you change them before starting the session).
+ If you try to add an algorithm that paramiko doesn't recognize,
+ C{ValueError} will be raised. If you try to assign something besides a
+ tuple to one of the fields, L{TypeError} will be raised.
"""
__slots__ = [ 'ciphers', 'digests', 'key_types', 'kex', '_transport' ]
def __init__(self, transport):
self._transport = transport
+ def __repr__(self):
+ """
+ Returns a string representation of this object, for debugging.
+
+ @rtype: string
+ """
+ return '<paramiko.SecurityOptions for %s>' % repr(self._transport)
+
def _get_ciphers(self):
return self._transport._preferred_ciphers
- def _set_ciphers(self, x):
- self._transport._preferred_ciphers = x
-
def _get_digests(self):
return self._transport._preferred_macs
- def _set_digests(self, x):
- self._transport._preferred_macs = x
-
def _get_key_types(self):
return self._transport._preferred_keys
- def _set_key_types(self, x):
- self._transport._preferred_keys = x
-
def _get_kex(self):
return self._transport._preferred_kex
+ def _set(self, name, orig, x):
+ if type(x) is list:
+ x = tuple(x)
+ if type(x) is not tuple:
+ raise TypeError('expected tuple or list')
+ possible = getattr(self._transport, orig).keys()
+ if len(filter(lambda n: n not in possible, x)) > 0:
+ raise ValueError('unknown cipher')
+ setattr(self._transport, name, x)
+
+ def _set_ciphers(self, x):
+ self._set('_preferred_ciphers', '_cipher_info', x)
+
+ def _set_digests(self, x):
+ self._set('_preferred_macs', '_mac_info', x)
+
+ def _set_key_types(self, x):
+ self._set('_preferred_keys', '_key_info', x)
+
def _set_kex(self, x):
- self._transport._preferred_kex = x
+ self._set('_preferred_kex', '_kex_info', x)
ciphers = property(_get_ciphers, _set_ciphers, None,
"Symmetric encryption ciphers")
@@ -106,10 +130,10 @@ class BaseTransport (threading.Thread):
_PROTO_ID = '2.0'
_CLIENT_ID = 'pyssh_1.1'
- _preferred_ciphers = [ 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc' ]
- _preferred_macs = [ 'hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96' ]
- _preferred_keys = [ 'ssh-rsa', 'ssh-dss' ]
- _preferred_kex = [ 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' ]
+ _preferred_ciphers = ( 'aes128-cbc', 'blowfish-cbc', 'aes256-cbc', '3des-cbc' )
+ _preferred_macs = ( 'hmac-sha1', 'hmac-md5', 'hmac-sha1-96', 'hmac-md5-96' )
+ _preferred_keys = ( 'ssh-rsa', 'ssh-dss' )
+ _preferred_kex = ( 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' )
_cipher_info = {
'blowfish-cbc': { 'class': Blowfish, 'mode': Blowfish.MODE_CBC, 'block-size': 8, 'key-size': 16 },
@@ -125,6 +149,11 @@ class BaseTransport (threading.Thread):
'hmac-md5-96': { 'class': MD5, 'size': 12 },
}
+ _key_info = {
+ 'ssh-rsa': RSAKey,
+ 'ssh-dss': DSSKey,
+ }
+
_kex_info = {
'diffie-hellman-group1-sha1': KexGroup1,
'diffie-hellman-group-exchange-sha1': KexGex,
@@ -225,7 +254,7 @@ class BaseTransport (threading.Thread):
self.keepalive_interval = 0
self.keepalive_last = time.time()
# server mode:
- self.server_mode = 0
+ self.server_mode = False
self.server_object = None
self.server_key_dict = { }
self.server_accepts = [ ]
@@ -321,7 +350,7 @@ class BaseTransport (threading.Thread):
"""
if server is None:
server = ServerInterface()
- self.server_mode = 1
+ self.server_mode = True
self.server_object = server
self.completion_event = event
self.start()
@@ -947,16 +976,8 @@ class BaseTransport (threading.Thread):
"used by a kex object to register the next packet type it expects to see"
self.expected_packet = type
- def _key_from_blob(self, keytype, keyblob):
- if keytype == 'ssh-rsa':
- return RSAKey(Message(keyblob))
- elif keytype == 'ssh-dss':
- return DSSKey(Message(keyblob))
- else:
- return None
-
def _verify_key(self, host_key, sig):
- key = self._key_from_blob(self.host_key_type, host_key)
+ key = self._key_info[self.host_key_type](Message(host_key))
if (key == None) or not key.valid:
raise SSHException('Unknown host key type')
if not key.verify_ssh_sig(self.H, Message(sig)):