[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-36]

add common.py for commonly used constants and globals
common.py now stores the constants and globals.
lots of renaming because of this.
This commit is contained in:
Robey Pointer 2004-04-05 10:12:59 +00:00
parent d757f90ac5
commit 8fafd1aa17
6 changed files with 88 additions and 102 deletions

View File

@ -23,16 +23,12 @@ L{Transport} is a subclass of L{BaseTransport} that handles authentication.
This separation keeps either class file from being too unwieldy. This separation keeps either class file from being too unwieldy.
""" """
from common import *
from transport import BaseTransport from transport import BaseTransport
from transport import _MSG_SERVICE_REQUEST, _MSG_SERVICE_ACCEPT, _MSG_USERAUTH_REQUEST, _MSG_USERAUTH_FAILURE, \
_MSG_USERAUTH_SUCCESS, _MSG_USERAUTH_BANNER
from message import Message from message import Message
from ssh_exception import SSHException from ssh_exception import SSHException
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
_DISCONNECT_SERVICE_NOT_AVAILABLE, _DISCONNECT_AUTH_CANCELLED_BY_USER, \
_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 7, 13, 14
class Transport (BaseTransport): class Transport (BaseTransport):
""" """
@ -244,14 +240,14 @@ class Transport (BaseTransport):
def _request_auth(self): def _request_auth(self):
m = Message() m = Message()
m.add_byte(chr(_MSG_SERVICE_REQUEST)) m.add_byte(chr(MSG_SERVICE_REQUEST))
m.add_string('ssh-userauth') m.add_string('ssh-userauth')
self._send_message(m) self._send_message(m)
def _disconnect_service_not_available(self): def _disconnect_service_not_available(self):
m = Message() m = Message()
m.add_byte(chr(_MSG_DISCONNECT)) m.add_byte(chr(MSG_DISCONNECT))
m.add_int(_DISCONNECT_SERVICE_NOT_AVAILABLE) m.add_int(DISCONNECT_SERVICE_NOT_AVAILABLE)
m.add_string('Service not available') m.add_string('Service not available')
m.add_string('en') m.add_string('en')
self._send_message(m) self._send_message(m)
@ -259,8 +255,8 @@ class Transport (BaseTransport):
def _disconnect_no_more_auth(self): def _disconnect_no_more_auth(self):
m = Message() m = Message()
m.add_byte(chr(_MSG_DISCONNECT)) m.add_byte(chr(MSG_DISCONNECT))
m.add_int(_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) m.add_int(DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
m.add_string('No more auth methods available') m.add_string('No more auth methods available')
m.add_string('en') m.add_string('en')
self._send_message(m) self._send_message(m)
@ -269,7 +265,7 @@ class Transport (BaseTransport):
def _get_session_blob(self, key, service, username): def _get_session_blob(self, key, service, username):
m = Message() m = Message()
m.add_string(self.session_id) m.add_string(self.session_id)
m.add_byte(chr(_MSG_USERAUTH_REQUEST)) m.add_byte(chr(MSG_USERAUTH_REQUEST))
m.add_string(username) m.add_string(username)
m.add_string(service) m.add_string(service)
m.add_string('publickey') m.add_string('publickey')
@ -283,7 +279,7 @@ class Transport (BaseTransport):
if self.server_mode and (service == 'ssh-userauth'): if self.server_mode and (service == 'ssh-userauth'):
# accepted # accepted
m = Message() m = Message()
m.add_byte(chr(_MSG_SERVICE_ACCEPT)) m.add_byte(chr(MSG_SERVICE_ACCEPT))
m.add_string(service) m.add_string(service)
self._send_message(m) self._send_message(m)
return return
@ -295,7 +291,7 @@ class Transport (BaseTransport):
if service == 'ssh-userauth': if service == 'ssh-userauth':
self._log(DEBUG, 'userauth is OK') self._log(DEBUG, 'userauth is OK')
m = Message() m = Message()
m.add_byte(chr(_MSG_USERAUTH_REQUEST)) m.add_byte(chr(MSG_USERAUTH_REQUEST))
m.add_string(self.username) m.add_string(self.username)
m.add_string('ssh-connection') m.add_string('ssh-connection')
m.add_string(self.auth_method) m.add_string(self.auth_method)
@ -319,7 +315,7 @@ class Transport (BaseTransport):
if not self.server_mode: if not self.server_mode:
# er, uh... what? # er, uh... what?
m = Message() m = Message()
m.add_byte(chr(_MSG_USERAUTH_FAILURE)) m.add_byte(chr(MSG_USERAUTH_FAILURE))
m.add_string('none') m.add_string('none')
m.add_boolean(0) m.add_boolean(0)
self._send_message(m) self._send_message(m)
@ -368,7 +364,7 @@ class Transport (BaseTransport):
# client wants to know if this key is acceptable, before it # client wants to know if this key is acceptable, before it
# signs anything... send special "ok" message # signs anything... send special "ok" message
m = Message() m = Message()
m.add_byte(chr(_MSG_USERAUTH_PK_OK)) m.add_byte(chr(MSG_USERAUTH_PK_OK))
m.add_string(keytype) m.add_string(keytype)
m.add_string(keyblob) m.add_string(keyblob)
self._send_message(m) self._send_message(m)
@ -384,11 +380,11 @@ class Transport (BaseTransport):
m = Message() m = Message()
if result == self.AUTH_SUCCESSFUL: if result == self.AUTH_SUCCESSFUL:
self._log(DEBUG, 'Auth granted.') self._log(DEBUG, 'Auth granted.')
m.add_byte(chr(_MSG_USERAUTH_SUCCESS)) m.add_byte(chr(MSG_USERAUTH_SUCCESS))
self.auth_complete = 1 self.auth_complete = 1
else: else:
self._log(DEBUG, 'Auth rejected.') self._log(DEBUG, 'Auth rejected.')
m.add_byte(chr(_MSG_USERAUTH_FAILURE)) m.add_byte(chr(MSG_USERAUTH_FAILURE))
m.add_string(self.get_allowed_auths(username)) m.add_string(self.get_allowed_auths(username))
if result == self.AUTH_PARTIALLY_SUCCESSFUL: if result == self.AUTH_PARTIALLY_SUCCESSFUL:
m.add_boolean(1) m.add_boolean(1)
@ -427,11 +423,11 @@ class Transport (BaseTransport):
_handler_table = BaseTransport._handler_table.copy() _handler_table = BaseTransport._handler_table.copy()
_handler_table.update({ _handler_table.update({
_MSG_SERVICE_REQUEST: _parse_service_request, MSG_SERVICE_REQUEST: _parse_service_request,
_MSG_SERVICE_ACCEPT: _parse_service_accept, MSG_SERVICE_ACCEPT: _parse_service_accept,
_MSG_USERAUTH_REQUEST: _parse_userauth_request, MSG_USERAUTH_REQUEST: _parse_userauth_request,
_MSG_USERAUTH_SUCCESS: _parse_userauth_success, MSG_USERAUTH_SUCCESS: _parse_userauth_success,
_MSG_USERAUTH_FAILURE: _parse_userauth_failure, MSG_USERAUTH_FAILURE: _parse_userauth_failure,
_MSG_USERAUTH_BANNER: _parse_userauth_banner, MSG_USERAUTH_BANNER: _parse_userauth_banner,
}) })

View File

@ -22,10 +22,9 @@
Abstraction for an SSH2 channel. Abstraction for an SSH2 channel.
""" """
from common import *
from message import Message from message import Message
from ssh_exception import SSHException from ssh_exception import SSHException
from transport import _MSG_CHANNEL_REQUEST, _MSG_CHANNEL_CLOSE, _MSG_CHANNEL_WINDOW_ADJUST, _MSG_CHANNEL_DATA, \
_MSG_CHANNEL_EOF, _MSG_CHANNEL_SUCCESS, _MSG_CHANNEL_FAILURE
from file import BufferedFile from file import BufferedFile
import time, threading, logging, socket, os import time, threading, logging, socket, os
@ -116,7 +115,7 @@ class Channel (object):
if self.closed or self.eof_received or self.eof_sent or not self.active: if self.closed or self.eof_received or self.eof_sent or not self.active:
raise SSHException('Channel is not open') raise SSHException('Channel is not open')
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('pty-req') m.add_string('pty-req')
m.add_boolean(0) m.add_boolean(0)
@ -137,7 +136,7 @@ class Channel (object):
if self.closed or self.eof_received or self.eof_sent or not self.active: if self.closed or self.eof_received or self.eof_sent or not self.active:
raise SSHException('Channel is not open') raise SSHException('Channel is not open')
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('shell') m.add_string('shell')
m.add_boolean(1) m.add_boolean(1)
@ -155,7 +154,7 @@ class Channel (object):
if self.closed or self.eof_received or self.eof_sent or not self.active: if self.closed or self.eof_received or self.eof_sent or not self.active:
raise SSHException('Channel is not open') raise SSHException('Channel is not open')
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('exec') m.add_string('exec')
m.add_boolean(1) m.add_boolean(1)
@ -174,7 +173,7 @@ class Channel (object):
if self.closed or self.eof_received or self.eof_sent or not self.active: if self.closed or self.eof_received or self.eof_sent or not self.active:
raise SSHException('Channel is not open') raise SSHException('Channel is not open')
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('subsystem') m.add_string('subsystem')
m.add_boolean(1) m.add_boolean(1)
@ -194,7 +193,7 @@ class Channel (object):
if self.closed or self.eof_received or self.eof_sent or not self.active: if self.closed or self.eof_received or self.eof_sent or not self.active:
raise SSHException('Channel is not open') raise SSHException('Channel is not open')
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('window-change') m.add_string('window-change')
m.add_boolean(0) m.add_boolean(0)
@ -300,7 +299,7 @@ class Channel (object):
if self.active and not self.closed: if self.active and not self.closed:
self._send_eof() self._send_eof()
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_CLOSE)) m.add_byte(chr(MSG_CHANNEL_CLOSE))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
self.transport._send_message(m) self.transport._send_message(m)
self.closed = 1 self.closed = 1
@ -417,7 +416,7 @@ class Channel (object):
if self.out_max_packet_size < size: if self.out_max_packet_size < size:
size = self.out_max_packet_size size = self.out_max_packet_size
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_DATA)) m.add_byte(chr(MSG_CHANNEL_DATA))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string(s[:size]) m.add_string(s[:size])
self.transport._send_message(m) self.transport._send_message(m)
@ -686,9 +685,9 @@ class Channel (object):
if want_reply: if want_reply:
m = Message() m = Message()
if ok: if ok:
m.add_byte(chr(_MSG_CHANNEL_SUCCESS)) m.add_byte(chr(MSG_CHANNEL_SUCCESS))
else: else:
m.add_byte(chr(_MSG_CHANNEL_FAILURE)) m.add_byte(chr(MSG_CHANNEL_FAILURE))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
self.transport._send_message(m) self.transport._send_message(m)
@ -728,7 +727,7 @@ class Channel (object):
if self.eof_sent: if self.eof_sent:
return return
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_EOF)) m.add_byte(chr(MSG_CHANNEL_EOF))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
self.transport._send_message(m) self.transport._send_message(m)
self.eof_sent = 1 self.eof_sent = 1
@ -828,7 +827,7 @@ class Channel (object):
if self.in_window_sofar > self.in_window_threshold: if self.in_window_sofar > self.in_window_threshold:
self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar) self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_WINDOW_ADJUST)) m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_int(self.in_window_sofar) m.add_int(self.in_window_sofar)
self.transport._send_message(m) self.transport._send_message(m)

View File

@ -24,14 +24,16 @@ generator "g" are provided by the server. A bit more work is required on the
client side, and a B{lot} more on the server side. client side, and a B{lot} more on the server side.
""" """
from message import Message
from util import inflate_long, deflate_long, bit_length
from ssh_exception import SSHException
from transport import _MSG_NEWKEYS
from Crypto.Hash import SHA from Crypto.Hash import SHA
from Crypto.Util import number from Crypto.Util import number
from logging import DEBUG from logging import DEBUG
from common import *
from message import Message
from util import inflate_long, deflate_long, bit_length
from ssh_exception import SSHException
_MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, _MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(31, 35) _MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, _MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(31, 35)

View File

@ -23,12 +23,13 @@ Standard SSH key exchange ("kex" if you wanna sound cool). Diffie-Hellman of
1024 bit key halves, using a known "p" prime and "g" generator. 1024 bit key halves, using a known "p" prime and "g" generator.
""" """
from message import Message, inflate_long
from ssh_exception import SSHException
from transport import _MSG_NEWKEYS
from Crypto.Hash import SHA from Crypto.Hash import SHA
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
from common import *
from message import Message, inflate_long
from ssh_exception import SSHException
_MSG_KEXDH_INIT, _MSG_KEXDH_REPLY = range(30, 32) _MSG_KEXDH_INIT, _MSG_KEXDH_REPLY = range(30, 32)
# draft-ietf-secsh-transport-09.txt, page 17 # draft-ietf-secsh-transport-09.txt, page 17

View File

@ -22,18 +22,9 @@
L{BaseTransport} handles the core SSH2 protocol. L{BaseTransport} handles the core SSH2 protocol.
""" """
_MSG_DISCONNECT, _MSG_IGNORE, _MSG_UNIMPLEMENTED, _MSG_DEBUG, _MSG_SERVICE_REQUEST, \
_MSG_SERVICE_ACCEPT = range(1, 7)
_MSG_KEXINIT, _MSG_NEWKEYS = range(20, 22)
_MSG_USERAUTH_REQUEST, _MSG_USERAUTH_FAILURE, _MSG_USERAUTH_SUCCESS, \
_MSG_USERAUTH_BANNER = range(50, 54)
_MSG_USERAUTH_PK_OK = 60
_MSG_CHANNEL_OPEN, _MSG_CHANNEL_OPEN_SUCCESS, _MSG_CHANNEL_OPEN_FAILURE, \
_MSG_CHANNEL_WINDOW_ADJUST, _MSG_CHANNEL_DATA, _MSG_CHANNEL_EXTENDED_DATA, \
_MSG_CHANNEL_EOF, _MSG_CHANNEL_CLOSE, _MSG_CHANNEL_REQUEST, \
_MSG_CHANNEL_SUCCESS, _MSG_CHANNEL_FAILURE = range(90, 101)
import sys, os, string, threading, socket, logging, struct import sys, os, string, threading, socket, logging, struct
from common import *
from ssh_exception import SSHException from ssh_exception import SSHException
from message import Message from message import Message
from channel import Channel from channel import Channel
@ -49,33 +40,12 @@ from primes import ModulusPack
# i believe this on the standards track. # i believe this on the standards track.
# PyCrypt compiled for Win32 can be downloaded from the HashTar homepage: # PyCrypt compiled for Win32 can be downloaded from the HashTar homepage:
# http://nitace.bsd.uchicago.edu:8080/hashtar # http://nitace.bsd.uchicago.edu:8080/hashtar
from Crypto.Util.randpool import PersistentRandomPool, RandomPool
from Crypto.Cipher import Blowfish, AES, DES3 from Crypto.Cipher import Blowfish, AES, DES3
from Crypto.Hash import SHA, MD5, HMAC from Crypto.Hash import SHA, MD5, HMAC
from Crypto.PublicKey import RSA
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
# channel request failed reasons:
_CONNECTION_FAILED_CODE = {
1: 'Administratively prohibited',
2: 'Connect failed',
3: 'Unknown channel type',
4: 'Resource shortage'
}
# keep a crypto-strong PRNG nearby
try:
randpool = PersistentRandomPool(os.getenv('HOME') + '/.randpool')
except:
# the above will likely fail on Windows - fall back to non-persistent random pool
randpool = RandomPool()
randpool.randomize()
# for thread cleanup # for thread cleanup
_active_threads = [] _active_threads = []
def _join_lingering_threads(): def _join_lingering_threads():
@ -428,7 +398,7 @@ class BaseTransport (threading.Thread):
chanid = self.channel_counter chanid = self.channel_counter
self.channel_counter += 1 self.channel_counter += 1
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_OPEN)) m.add_byte(chr(MSG_CHANNEL_OPEN))
m.add_string(kind) m.add_string(kind)
m.add_int(chanid) m.add_int(chanid)
m.add_int(self.window_size) m.add_int(self.window_size)
@ -466,7 +436,7 @@ class BaseTransport (threading.Thread):
@type bytes: int @type bytes: int
""" """
m = Message() m = Message()
m.add_byte(chr(_MSG_IGNORE)) m.add_byte(chr(MSG_IGNORE))
if bytes is None: if bytes is None:
bytes = (ord(randpool.get_bytes(1)) % 32) + 10 bytes = (ord(randpool.get_bytes(1)) % 32) + 10
m.add_bytes(randpool.get_bytes(bytes)) m.add_bytes(randpool.get_bytes(bytes))
@ -821,17 +791,17 @@ class BaseTransport (threading.Thread):
self._write_all(self.local_version + '\r\n') self._write_all(self.local_version + '\r\n')
self._check_banner() self._check_banner()
self._send_kex_init() self._send_kex_init()
self.expected_packet = _MSG_KEXINIT self.expected_packet = MSG_KEXINIT
while self.active: while self.active:
ptype, m = self._read_message() ptype, m = self._read_message()
if ptype == _MSG_IGNORE: if ptype == MSG_IGNORE:
continue continue
elif ptype == _MSG_DISCONNECT: elif ptype == MSG_DISCONNECT:
self._parse_disconnect(m) self._parse_disconnect(m)
self.active = False self.active = False
break break
elif ptype == _MSG_DEBUG: elif ptype == MSG_DEBUG:
self._parse_debug(m) self._parse_debug(m)
continue continue
if self.expected_packet != 0: if self.expected_packet != 0:
@ -851,7 +821,7 @@ class BaseTransport (threading.Thread):
else: else:
self._log(WARNING, 'Oops, unhandled type %d' % ptype) self._log(WARNING, 'Oops, unhandled type %d' % ptype)
msg = Message() msg = Message()
msg.add_byte(chr(_MSG_UNIMPLEMENTED)) msg.add_byte(chr(MSG_UNIMPLEMENTED))
msg.add_int(m.seqno) msg.add_int(m.seqno)
self._send_message(msg) self._send_message(msg)
except SSHException, e: except SSHException, e:
@ -936,7 +906,7 @@ class BaseTransport (threading.Thread):
available_server_keys = self.preferred_keys available_server_keys = self.preferred_keys
m = Message() m = Message()
m.add_byte(chr(_MSG_KEXINIT)) m.add_byte(chr(MSG_KEXINIT))
m.add_bytes(randpool.get_bytes(16)) m.add_bytes(randpool.get_bytes(16))
m.add(','.join(self.preferred_kex)) m.add(','.join(self.preferred_kex))
m.add(','.join(available_server_keys)) m.add(','.join(available_server_keys))
@ -1047,7 +1017,7 @@ class BaseTransport (threading.Thread):
# actually some extra bytes (one NUL byte in openssh's case) added to # actually some extra bytes (one NUL byte in openssh's case) added to
# the end of the packet but not parsed. turns out we need to throw # the end of the packet but not parsed. turns out we need to throw
# away those bytes because they aren't part of the hash. # away those bytes because they aren't part of the hash.
self.remote_kex_init = chr(_MSG_KEXINIT) + m.get_so_far() self.remote_kex_init = chr(MSG_KEXINIT) + m.get_so_far()
def _activate_inbound(self): def _activate_inbound(self):
"switch on newly negotiated encryption parameters for inbound traffic" "switch on newly negotiated encryption parameters for inbound traffic"
@ -1071,7 +1041,7 @@ class BaseTransport (threading.Thread):
def _activate_outbound(self): def _activate_outbound(self):
"switch on newly negotiated encryption parameters for outbound traffic" "switch on newly negotiated encryption parameters for outbound traffic"
m = Message() m = Message()
m.add_byte(chr(_MSG_NEWKEYS)) m.add_byte(chr(MSG_NEWKEYS))
self._send_message(m) self._send_message(m)
self.block_size_out = self._cipher_info[self.local_cipher]['block-size'] self.block_size_out = self._cipher_info[self.local_cipher]['block-size']
if self.server_mode: if self.server_mode:
@ -1090,7 +1060,7 @@ class BaseTransport (threading.Thread):
else: else:
self.mac_key_out = self._compute_key('E', self.local_mac_engine.digest_size) self.mac_key_out = self._compute_key('E', self.local_mac_engine.digest_size)
# we always expect to receive NEWKEYS now # we always expect to receive NEWKEYS now
self.expected_packet = _MSG_NEWKEYS self.expected_packet = MSG_NEWKEYS
def _parse_newkeys(self, m): def _parse_newkeys(self, m):
self._log(DEBUG, 'Switch to new keys ...') self._log(DEBUG, 'Switch to new keys ...')
@ -1179,7 +1149,7 @@ class BaseTransport (threading.Thread):
reason = self.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED reason = self.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
if reject: if reject:
msg = Message() msg = Message()
msg.add_byte(chr(_MSG_CHANNEL_OPEN_FAILURE)) msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
msg.add_int(chanid) msg.add_int(chanid)
msg.add_int(reason) msg.add_int(reason)
msg.add_string('') msg.add_string('')
@ -1195,7 +1165,7 @@ class BaseTransport (threading.Thread):
finally: finally:
self.lock.release() self.lock.release()
m = Message() m = Message()
m.add_byte(chr(_MSG_CHANNEL_OPEN_SUCCESS)) m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
m.add_int(chanid) m.add_int(chanid)
m.add_int(my_chanid) m.add_int(my_chanid)
m.add_int(self.window_size) m.add_int(self.window_size)
@ -1216,19 +1186,19 @@ class BaseTransport (threading.Thread):
self._log(DEBUG, 'Debug msg: ' + safe_string(msg)) self._log(DEBUG, 'Debug msg: ' + safe_string(msg))
_handler_table = { _handler_table = {
_MSG_NEWKEYS: _parse_newkeys, MSG_NEWKEYS: _parse_newkeys,
_MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success, MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
_MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure, MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
_MSG_CHANNEL_OPEN: _parse_channel_open, MSG_CHANNEL_OPEN: _parse_channel_open,
_MSG_KEXINIT: _negotiate_keys, MSG_KEXINIT: _negotiate_keys,
} }
_channel_handler_table = { _channel_handler_table = {
_MSG_CHANNEL_SUCCESS: Channel._request_success, MSG_CHANNEL_SUCCESS: Channel._request_success,
_MSG_CHANNEL_FAILURE: Channel._request_failed, MSG_CHANNEL_FAILURE: Channel._request_failed,
_MSG_CHANNEL_DATA: Channel._feed, MSG_CHANNEL_DATA: Channel._feed,
_MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust, MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
_MSG_CHANNEL_REQUEST: Channel._handle_request, MSG_CHANNEL_REQUEST: Channel._handle_request,
_MSG_CHANNEL_EOF: Channel._handle_eof, MSG_CHANNEL_EOF: Channel._handle_eof,
_MSG_CHANNEL_CLOSE: Channel._handle_close, MSG_CHANNEL_CLOSE: Channel._handle_close,
} }

View File

@ -24,7 +24,7 @@ Useful functions used by the rest of paramiko.
import sys, struct, traceback import sys, struct, traceback
def inflate_long(s, always_positive=0): def inflate_long(s, always_positive=False):
"turns a normalized byte string into a long-int (adapted from Crypto.Util.number)" "turns a normalized byte string into a long-int (adapted from Crypto.Util.number)"
out = 0L out = 0L
negative = 0 negative = 0
@ -41,7 +41,7 @@ def inflate_long(s, always_positive=0):
out -= (1L << (8 * len(s))) out -= (1L << (8 * len(s)))
return out return out
def deflate_long(n, add_sign_padding=1): def deflate_long(n, add_sign_padding=True):
"turns a long-int into a normalized byte string (adapted from Crypto.Util.number)" "turns a long-int into a normalized byte string (adapted from Crypto.Util.number)"
# after much testing, this algorithm was deemed to be the fastest # after much testing, this algorithm was deemed to be the fastest
s = '' s = ''
@ -99,6 +99,10 @@ def hexify(s):
"turn a string into a hex sequence" "turn a string into a hex sequence"
return ''.join(['%02X' % ord(c) for c in s]) return ''.join(['%02X' % ord(c) for c in s])
def unhexify(s):
"turn a hex sequence back into a string"
return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)])
def safe_string(s): def safe_string(s):
out = '' out = ''
for c in s: for c in s:
@ -155,3 +159,17 @@ def generate_key_bytes(hashclass, salt, key, nbytes):
keydata += digest[:size] keydata += digest[:size]
nbytes -= size nbytes -= size
return keydata return keydata
def mod_inverse(x, m):
# it's crazy how small python can make this function.
u1, u2, u3 = 1, 0, m
v1, v2, v3 = 0, 1, x
while v3 > 0:
q = u3 // v3
u1, v1 = v1, u1 - v1 * q
u2, v2 = v2, u2 - v2 * q
u3, v3 = v3, u3 - v3 * q
if u2 < 0:
u2 += m
return u2