diff options
author | Robey Pointer <robey@lag.net> | 2003-11-10 04:54:02 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2003-11-10 04:54:02 +0000 |
commit | aad7b859f194451a0529c4d8aa20cdc724ae33a2 (patch) | |
tree | 24b19c05626e547f3f3bc4a12c7a8c64578dbed5 /transport.py | |
parent | 0e1ef2c65c80bd76eb62f5dfd953cb987d36ce3a (diff) |
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-7]
cleaned up server code, renamed some files & classes
renamed demo-server.py and demo-host-key to demo_server.py and
demo_host_key, just to be consistent.
renamed SSHException -> SecshException.
generalized the mechanism where Channel decides whether to allow
different channel requests: 4 of the main ones (pty, window-change,
shell, and subsystem) go through easily override-able methods now.
you could probably make an actual ssh shell server.
gave ChannelFile a repr().
turned off ultra debugging in the demos. demo_server creates a
subclass of Channel to allow pty/shell and sets an event when the
shell request is made, so that it knows when it can start sending
the fake bbs.
renamed to charmander and updated some of the distutils files.
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] |