diff options
Diffstat (limited to 'transport.py')
-rw-r--r-- | transport.py | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/transport.py b/transport.py index c5ff252b..611e5771 100644 --- a/transport.py +++ b/transport.py @@ -14,7 +14,7 @@ MSG_CHANNEL_OPEN, MSG_CHANNEL_OPEN_SUCCESS, MSG_CHANNEL_OPEN_FAILURE, \ import sys, os, string, threading, socket, logging, struct from message import Message from channel import Channel -from secsh import SSHException +from secsh import SecshException from util import format_binary, safe_string, inflate_long, deflate_long, tb_strings from rsakey import RSAKey from dsskey import DSSKey @@ -79,8 +79,7 @@ class BaseTransport(threading.Thread): 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' ] -# preferred_kex = [ 'diffie-hellman-group1-sha1', 'diffie-hellman-group-exchange-sha1' ] + 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 }, @@ -203,7 +202,7 @@ class BaseTransport(threading.Thread): def get_remote_server_key(self): 'returns (type, key) where type is like "ssh-rsa" and key is an opaque string' if (not self.active) or (not self.initial_kex_done): - raise SSHException('No existing session') + raise SecshException('No existing session') key_msg = Message(self.host_key) key_type = key_msg.get_string() return key_type, self.host_key @@ -324,7 +323,7 @@ class BaseTransport(threading.Thread): # leftover contains decrypted bytes from the first block (after the length field) leftover = header[4:] if (packet_size - len(leftover)) % self.block_size_in != 0: - raise SSHException('Invalid packet blocking') + raise SecshException('Invalid packet blocking') buffer = self.read_all(packet_size + self.remote_mac_len - len(leftover)) packet = buffer[:packet_size - len(leftover)] post_packet = buffer[packet_size - len(leftover):] @@ -338,7 +337,7 @@ class BaseTransport(threading.Thread): mac_payload = struct.pack('>II', self.sequence_number_in, packet_size) + packet my_mac = HMAC.HMAC(self.mac_key_in, mac_payload, self.remote_mac_engine).digest()[:self.remote_mac_len] if my_mac != mac: - raise SSHException('Mismatched MAC') + raise SecshException('Mismatched MAC') padding = ord(packet[0]) payload = packet[1:packet_size - padding + 1] randpool.add_event(packet[packet_size - padding + 1]) @@ -361,7 +360,7 @@ class BaseTransport(threading.Thread): # comply, then just drop the connection self.received_packets_overflow += 1 if self.received_packets_overflow >= 20: - raise SSHException('Remote transport is ignoring rekey requests') + raise SecshException('Remote transport is ignoring rekey requests') return ord(payload[0]), msg @@ -380,9 +379,9 @@ class BaseTransport(threading.Thread): else: key = None if (key == None) or not key.valid: - raise SSHException('Unknown host key type') + raise SecshException('Unknown host key type') if not key.verify_ssh_sig(self.H, Message(sig)): - raise SSHException('Signature verification (%s) failed. Boo. Robey should debug this.' % self.host_key_type) + raise SecshException('Signature verification (%s) failed. Boo. Robey should debug this.' % self.host_key_type) self.host_key = host_key def compute_key(self, id, nbytes): @@ -405,7 +404,7 @@ class BaseTransport(threading.Thread): def get_cipher(self, name, key, iv): if not self.cipher_info.has_key(name): - raise SSHException('Unknown client cipher ' + name) + raise SecshException('Unknown client cipher ' + name) return self.cipher_info[name]['class'].new(key, self.cipher_info[name]['mode'], iv) def run(self): @@ -430,7 +429,7 @@ class BaseTransport(threading.Thread): continue if self.expected_packet != 0: if ptype != self.expected_packet: - raise SSHException('Expecting packet %d, got %d' % (self.expected_packet, ptype)) + raise SecshException('Expecting packet %d, got %d' % (self.expected_packet, ptype)) self.expected_packet = 0 if (ptype >= 30) and (ptype <= 39): self.kex_engine.parse_next(ptype, m) @@ -448,7 +447,7 @@ class BaseTransport(threading.Thread): msg.add_byte(chr(MSG_UNIMPLEMENTED)) msg.add_int(m.seqno) self.send_message(msg) - except SSHException, e: + except SecshException, e: self.log(DEBUG, 'Exception: ' + str(e)) self.log(DEBUG, tb_strings()) except EOFError, e: @@ -480,7 +479,7 @@ class BaseTransport(threading.Thread): return 1 def negotiate_keys(self, m): - # throws SSHException on anything unusual + # throws SecshException on anything unusual if self.local_kex_init == None: # remote side wants to renegotiate self.send_kex_init() @@ -500,7 +499,7 @@ class BaseTransport(threading.Thread): break self.log(DEBUG, 'Banner: ' + buffer) if buffer[:4] != 'SSH-': - raise SSHException('Indecipherable protocol version "' + buffer + '"') + raise SecshException('Indecipherable protocol version "' + buffer + '"') # save this server version string for later self.remote_version = buffer # pull off any attached comment @@ -512,15 +511,19 @@ class BaseTransport(threading.Thread): # parse out version string and make sure it matches segs = buffer.split('-', 2) if len(segs) < 3: - raise SSHException('Invalid SSH banner') + raise SecshException('Invalid SSH banner') version = segs[1] client = segs[2] if version != '1.99' and version != '2.0': - raise SSHException('Incompatible version (%s instead of 2.0)' % (version,)) + raise SecshException('Incompatible version (%s instead of 2.0)' % (version,)) self.log(INFO, 'Connected (version %s, client %s)' % (version, client)) def send_kex_init(self): # send a really wimpy kex-init packet that says we're a bare-bones ssh client + if self.server_mode: + # FIXME: can't do group-exchange (gex) yet -- too slow + if 'diffie-hellman-group-exchange-sha1' in self.preferred_kex: + self.preferred_kex.remove('diffie-hellman-group-exchange-sha1') m = Message() m.add_byte(chr(MSG_KEXINIT)) m.add_bytes(randpool.get_bytes(16)) @@ -563,7 +566,7 @@ class BaseTransport(threading.Thread): # no compression support (yet?) if (not('none' in client_compress_algo_list) or not('none' in server_compress_algo_list)): - raise SSHException('Incompatible ssh peer.') + raise SecshException('Incompatible ssh peer.') # as a server, we pick the first item in the client's list that we support. # as a client, we pick the first item in our list that the server supports. @@ -572,7 +575,7 @@ class BaseTransport(threading.Thread): else: agreed_kex = filter(kex_algo_list.__contains__, self.preferred_kex) if len(agreed_kex) == 0: - raise SSHException('Incompatible ssh peer (no acceptable kex algorithm)') + raise SecshException('Incompatible ssh peer (no acceptable kex algorithm)') self.kex_engine = self.kex_info[agreed_kex[0]](self) if self.server_mode: @@ -580,10 +583,10 @@ class BaseTransport(threading.Thread): else: agreed_keys = filter(server_key_algo_list.__contains__, self.preferred_keys) if len(agreed_keys) == 0: - raise SSHException('Incompatible ssh peer (no acceptable host key)') + raise SecshException('Incompatible ssh peer (no acceptable host key)') self.host_key_type = agreed_keys[0] if self.server_mode and (self.get_server_key() is None): - raise SSHException('Incompatible ssh peer (can\'t match requested host key type)') + raise SecshException('Incompatible ssh peer (can\'t match requested host key type)') if self.server_mode: agreed_local_ciphers = filter(self.preferred_ciphers.__contains__, @@ -596,7 +599,7 @@ class BaseTransport(threading.Thread): agreed_remote_ciphers = filter(server_encrypt_algo_list.__contains__, self.preferred_ciphers) if (len(agreed_local_ciphers) == 0) or (len(agreed_remote_ciphers) == 0): - raise SSHException('Incompatible ssh server (no acceptable ciphers)') + raise SecshException('Incompatible ssh server (no acceptable ciphers)') self.local_cipher = agreed_local_ciphers[0] self.remote_cipher = agreed_remote_ciphers[0] self.log(DEBUG, 'Ciphers agreed: local=%s, remote=%s' % (self.local_cipher, self.remote_cipher)) @@ -608,7 +611,7 @@ class BaseTransport(threading.Thread): agreed_local_macs = filter(client_mac_algo_list.__contains__, self.preferred_macs) agreed_remote_macs = filter(server_mac_algo_list.__contains__, self.preferred_macs) if (len(agreed_local_macs) == 0) or (len(agreed_remote_macs) == 0): - raise SSHException('Incompatible ssh server (no acceptable macs)') + raise SecshException('Incompatible ssh server (no acceptable macs)') self.local_mac = agreed_local_macs[0] self.remote_mac = agreed_remote_macs[0] |