fix a bunch of pychecker warnings, some of which were actual (but unlikely) bugs
This commit is contained in:
Robey Pointer 2006-01-14 22:30:08 -08:00
parent 26397bff47
commit cb3008b402
19 changed files with 182 additions and 134 deletions

3
README
View File

@ -255,3 +255,6 @@ v1.0 JIGGLYPUFF
key files, etc)
local and remote port forwarding
* SFTPClient.set_size
* remove @since that predate 1.0
* put examples in examples/ folder

View File

@ -16,7 +16,7 @@
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
import struct
import util
@ -91,8 +91,9 @@ class BER(object):
while True:
x = b.decode_next()
if x is None:
return out
break
out.append(x)
return out
decode_sequence = staticmethod(decode_sequence)
def encode_tlv(self, ident, val):

View File

@ -148,12 +148,7 @@ class Channel (object):
m.add_string('')
self.event.clear()
self.transport._send_user_message(m)
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
return True
return self._wait_for_event()
def invoke_shell(self):
"""
@ -180,12 +175,7 @@ class Channel (object):
m.add_boolean(1)
self.event.clear()
self.transport._send_user_message(m)
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
return True
return self._wait_for_event()
def exec_command(self, command):
"""
@ -212,12 +202,7 @@ class Channel (object):
m.add_string(command)
self.event.clear()
self.transport._send_user_message(m)
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
return True
return self._wait_for_event()
def invoke_subsystem(self, subsystem):
"""
@ -243,12 +228,7 @@ class Channel (object):
m.add_string(subsystem)
self.event.clear()
self.transport._send_user_message(m)
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
return True
return self._wait_for_event()
def resize_pty(self, width=80, height=24):
"""
@ -274,12 +254,7 @@ class Channel (object):
m.add_int(0).add_int(0)
self.event.clear()
self.transport._send_user_message(m)
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
return True
self._wait_for_event()
def recv_exit_status(self):
"""
@ -296,8 +271,9 @@ class Channel (object):
"""
while True:
if self.closed or self.status_event.isSet():
return self.exit_status
break
self.status_event.wait(0.1)
return self.exit_status
def send_exit_status(self, status):
"""
@ -1027,6 +1003,15 @@ class Channel (object):
def _log(self, level, msg):
self.logger.log(level, msg)
def _wait_for_event(self):
while True:
self.event.wait(0.1)
if self.closed:
return False
if self.event.isSet():
break
return True
def _set_closed(self):
# you are holding the lock.
self.closed = True
@ -1155,8 +1140,6 @@ class ChannelFile (BufferedFile):
def _write(self, data):
self.channel.sendall(data)
return len(data)
seek = BufferedFile.seek
class ChannelStderrFile (ChannelFile):

View File

@ -36,6 +36,12 @@ class DSSKey (PKey):
Representation of a DSS key which can be used to sign an verify SSH2
data.
"""
p = None
q = None
g = None
y = None
x = None
def __init__(self, msg=None, data=None, filename=None, password=None, vals=None):
if filename is not None:
@ -81,7 +87,7 @@ class DSSKey (PKey):
return self.size
def can_sign(self):
return hasattr(self, 'x')
return self.x is not None
def sign_ssh_data(self, rpool, data):
digest = SHA.new(data).digest()
@ -124,6 +130,8 @@ class DSSKey (PKey):
return dss.verify(sigM, (sigR, sigS))
def write_private_key_file(self, filename, password=None):
if self.x is None:
raise SSHException('Not enough key information')
keylist = [ 0, self.p, self.q, self.g, self.y, self.x ]
try:
b = BER()

View File

@ -45,6 +45,7 @@ class BufferedFile (object):
SEEK_END = 2
def __init__(self):
self.newlines = None
self._flags = 0
self._bufsize = self._DEFAULT_BUFSIZE
self._wbuffer = StringIO()
@ -55,6 +56,8 @@ class BufferedFile (object):
# realpos - position according the OS
# (these may be different because we buffer for line reading)
self._pos = self._realpos = 0
# size only matters for seekable files
self._size = 0
def __del__(self):
self.close()

View File

@ -43,6 +43,12 @@ class KexGex (object):
def __init__(self, transport):
self.transport = transport
self.p = None
self.q = None
self.g = None
self.x = None
self.e = None
self.f = None
def start_kex(self):
if self.transport.server_mode:

View File

@ -285,7 +285,7 @@ class Message (object):
elif type(i) is list:
return self.add_list(i)
else:
raise exception('Unknown type')
raise Exception('Unknown type')
def add(self, *seq):
"""

View File

@ -219,7 +219,7 @@ class Packetizer (object):
if n < 0:
raise EOFError()
if n == len(out):
return
break
out = out[n:]
return
@ -398,23 +398,24 @@ class Packetizer (object):
x = self.__socket.recv(1)
if len(x) == 0:
raise EOFError()
return x
break
if self.__closed:
raise EOFError()
now = time.time()
if now - start >= timeout:
raise socket.timeout()
return x
def _read_timeout(self, timeout):
if PY22:
return self._py22_read_timeout(n)
return self._py22_read_timeout(timeout)
start = time.time()
while True:
try:
x = self.__socket.recv(1)
if len(x) == 0:
raise EOFError()
return x
break
except socket.timeout:
pass
if self.__closed:
@ -422,6 +423,7 @@ class Packetizer (object):
now = time.time()
if now - start >= timeout:
raise socket.timeout()
return x
def _build_packet(self, payload):
# pad up at least 4 bytes, to nearest block-size (usually 8)

View File

@ -28,8 +28,10 @@ import socket
def make_pipe ():
if sys.platform[:3] != 'win':
return PosixPipe()
return WindowsPipe()
p = PosixPipe()
else:
p = WindowsPipe()
return p
class PosixPipe (object):

View File

@ -173,7 +173,7 @@ class PKey (object):
"""
return False
def from_private_key_file(cl, filename, password=None):
def from_private_key_file(cls, filename, password=None):
"""
Create a key object by reading a private key file. If the private
key is encrypted and C{password} is not C{None}, the given password
@ -197,7 +197,7 @@ class PKey (object):
@since: fearow
"""
key = cl(filename=filename, password=password)
key = cls(filename=filename, password=password)
return key
from_private_key_file = classmethod(from_private_key_file)
@ -216,7 +216,7 @@ class PKey (object):
@since: fearow
"""
raise exception('Not implemented in PKey')
raise Exception('Not implemented in PKey')
def _read_private_key_file(self, tag, filename, password=None):
"""
@ -265,7 +265,7 @@ class PKey (object):
# if we trudged to the end of the file, just try to cope.
try:
data = base64.decodestring(''.join(lines[start:end]))
except binascii.Error, e:
except base64.binascii.Error, e:
raise SSHException('base64 decoding error: ' + str(e))
if not headers.has_key('proc-type'):
# unencryped: done

View File

@ -23,6 +23,7 @@ Utility functions for dealing with primes.
from Crypto.Util import number
from paramiko import util
from paramiko.ssh_exception import SSHException
def _generate_prime(bits, randpool):
@ -39,7 +40,8 @@ def _generate_prime(bits, randpool):
while not number.isPrime(n):
n += 2
if util.bit_length(n) == bits:
return n
break
return n
def _roll_random(rpool, n):
"returns a random # from 0 to N-1"
@ -59,7 +61,8 @@ def _roll_random(rpool, n):
x = chr(ord(x[0]) & hbyte_mask) + x[1:]
num = util.inflate_long(x, 1)
if num < n:
return num
break
return num
class ModulusPack (object):
@ -75,8 +78,8 @@ class ModulusPack (object):
self.randpool = rpool
def _parse_modulus(self, line):
timestamp, type, tests, tries, size, generator, modulus = line.split()
type = int(type)
timestamp, mod_type, tests, tries, size, generator, modulus = line.split()
mod_type = int(mod_type)
tests = int(tests)
tries = int(tries)
size = int(size)
@ -87,7 +90,7 @@ class ModulusPack (object):
# type 2 (meets basic structural requirements)
# test 4 (more than just a small-prime sieve)
# tries < 100 if test & 4 (at least 100 tries of miller-rabin)
if (type < 2) or (tests < 4) or ((tests & 4) and (tests < 8) and (tries < 100)):
if (mod_type < 2) or (tests < 4) or ((tests & 4) and (tests < 8) and (tries < 100)):
self.discarded.append((modulus, 'does not meet basic requirements'))
return
if generator == 0:

View File

@ -38,6 +38,12 @@ class RSAKey (PKey):
data.
"""
n = None
e = None
d = None
p = None
q = None
def __init__(self, msg=None, data=None, filename=None, password=None, vals=None):
if filename is not None:
self._from_private_key_file(filename, password)
@ -75,7 +81,7 @@ class RSAKey (PKey):
return self.size
def can_sign(self):
return hasattr(self, 'd')
return self.d is not None
def sign_ssh_data(self, rpool, data):
digest = SHA.new(data).digest()
@ -93,11 +99,13 @@ class RSAKey (PKey):
# verify the signature by SHA'ing the data and encrypting it using the
# public key. some wackiness ensues where we "pkcs1imify" the 20-byte
# hash into a string as long as the RSA key.
hash = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()), True)
hash_obj = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()), True)
rsa = RSA.construct((long(self.n), long(self.e)))
return rsa.verify(hash, (sig,))
return rsa.verify(hash_obj, (sig,))
def write_private_key_file(self, filename, password=None):
if (self.p is None) or (self.q is None):
raise SSHException('Not enough key info to write private key file')
keylist = [ 0, self.n, self.e, self.d, self.p, self.q,
self.d % (self.p - 1), self.d % (self.q - 1),
util.mod_inverse(self.q, self.p) ]

View File

@ -51,6 +51,12 @@ class SFTPAttributes (object):
Create a new (empty) SFTPAttributes object. All fields will be empty.
"""
self._flags = 0
self.st_size = -1
self.st_uid = -1
self.st_gid = -1
self.st_mode = 0
self.st_atime = 0
self.st_mtime = 0
self.attr = {}
def from_stat(cls, obj, filename=None):
@ -114,13 +120,13 @@ class SFTPAttributes (object):
def _pack(self, msg):
self._flags = 0
if hasattr(self, 'st_size'):
if self.st_size >= 0:
self._flags |= self.FLAG_SIZE
if hasattr(self, 'st_uid') or hasattr(self, 'st_gid'):
if (self.st_uid >= 0) or (self.st_gid >= 0):
self._flags |= self.FLAG_UIDGID
if hasattr(self, 'st_mode'):
if self.st_mode != 0:
self._flags |= self.FLAG_PERMISSIONS
if hasattr(self, 'st_atime') or hasattr(self, 'st_mtime'):
if (self.st_atime > 0) or (self.st_mtime > 0):
self._flags |= self.FLAG_AMTIME
if len(self.attr) > 0:
self._flags |= self.FLAG_EXTENDED
@ -128,13 +134,13 @@ class SFTPAttributes (object):
if self._flags & self.FLAG_SIZE:
msg.add_int64(self.st_size)
if self._flags & self.FLAG_UIDGID:
msg.add_int(getattr(self, 'st_uid', 0))
msg.add_int(getattr(self, 'st_gid', 0))
msg.add_int(self.st_uid)
msg.add_int(self.st_gid)
if self._flags & self.FLAG_PERMISSIONS:
msg.add_int(self.st_mode)
if self._flags & self.FLAG_AMTIME:
msg.add_int(getattr(self, 'st_atime', 0))
msg.add_int(getattr(self, 'st_mtime', 0))
msg.add_int(self.st_atime)
msg.add_int(self.st_mtime)
if self._flags & self.FLAG_EXTENDED:
msg.add_int(len(self.attr))
for key, val in self.attr.iteritems():
@ -144,15 +150,14 @@ class SFTPAttributes (object):
def _debug_str(self):
out = '[ '
if hasattr(self, 'st_size'):
if self.st_size >= 0:
out += 'size=%d ' % self.st_size
if hasattr(self, 'st_uid') or hasattr(self, 'st_gid'):
out += 'uid=%d gid=%d ' % (getattr(self, 'st_uid', 0), getattr(self, 'st_gid', 0))
if hasattr(self, 'st_mode'):
if (self.st_uid >= 0) or (self.st_gid >= 0):
out += 'uid=%d gid=%d ' % (self.st_uid, self.st_gid)
if self.st_mode != 0:
out += 'mode=' + oct(self.st_mode) + ' '
if hasattr(self, 'st_atime') or hasattr(self, 'st_mtime'):
out += 'atime=%d mtime=%d ' % (getattr(self, 'st_atime', 0),
getattr(self, 'st_mtime', 0))
if (self.st_atime > 0) or (self.st_mtime > 0):
out += 'atime=%d mtime=%d ' % (self.st_atime, self.st_mtime)
for k, v in self.attr.iteritems():
out += '"%s"=%r ' % (str(k), v)
out += ']'
@ -171,7 +176,7 @@ class SFTPAttributes (object):
def __str__(self):
"create a unix-style long description of the file (like ls -l)"
if hasattr(self, 'st_mode'):
if self.st_mode != 0:
kind = stat.S_IFMT(self.st_mode)
if kind == stat.S_IFIFO:
ks = 'p'
@ -194,15 +199,12 @@ class SFTPAttributes (object):
ks += self._rwx(self.st_mode & 7, self.st_mode & stat.S_ISVTX, True)
else:
ks = '?---------'
uid = getattr(self, 'st_uid', -1)
gid = getattr(self, 'st_gid', -1)
size = getattr(self, 'st_size', -1)
mtime = getattr(self, 'st_mtime', 0)
# compute display date
if abs(time.time() - mtime) > 15552000:
if abs(time.time() - self.st_mtime) > 15552000:
# (15552000 = 6 months)
datestr = time.strftime('%d %b %Y', time.localtime(mtime))
datestr = time.strftime('%d %b %Y', time.localtime(self.st_mtime))
else:
datestr = time.strftime('%d %b %H:%M', time.localtime(mtime))
datestr = time.strftime('%d %b %H:%M', time.localtime(self.st_mtime))
filename = getattr(self, 'filename', '?')
return '%s 1 %-8d %-8d %8d %-12s %s' % (ks, uid, gid, size, datestr, filename)
return '%s 1 %-8d %-8d %8d %-12s %s' % (ks, self.st_uid, self.st_gid,
self.st_size, datestr, filename)

View File

@ -23,6 +23,7 @@ Client-mode SFTP support.
import errno
import os
import threading
import time
import weakref
from paramiko.sftp import *
from paramiko.sftp_attr import SFTPAttributes
@ -74,7 +75,7 @@ class SFTPClient (BaseSFTP):
def __del__(self):
self.close()
def from_transport(selfclass, t):
def from_transport(cls, t):
"""
Create an SFTP client channel from an open L{Transport}.
@ -89,7 +90,7 @@ class SFTPClient (BaseSFTP):
return None
if not chan.invoke_subsystem('sftp'):
raise SFTPError('Failed to invoke sftp subsystem')
return selfclass(chan)
return cls(chan)
from_transport = classmethod(from_transport)
def close(self):
@ -560,7 +561,7 @@ class SFTPClient (BaseSFTP):
self._log(DEBUG, 'Unexpected response #%d' % (num,))
if waitfor is None:
# just doing a single check
return
break
continue
fileobj = self._expecting[num]
del self._expecting[num]
@ -573,7 +574,8 @@ class SFTPClient (BaseSFTP):
fileobj._async_response(t, msg)
if waitfor is None:
# just doing a single check
return
break
return (None, None)
def _finish_responses(self, fileobj):
while fileobj in self._expecting.values():

View File

@ -43,12 +43,18 @@ class SFTPFile (BufferedFile):
BufferedFile._set_mode(self, mode, bufsize)
self.pipelined = False
self._prefetching = False
self._prefetch_so_far = 0
self._prefetch_size = 0
self._prefetch_data = {}
self._saved_exception = None
def __del__(self):
self.close(_async=True)
self._close(async=True)
def close(self):
self._close(async=False)
def close(self, _async=False):
def _close(self, async=False):
# We allow double-close without signaling an error, because real
# Python file objects do. However, we must protect against actually
# sending multiple CMD_CLOSE packets, because after we close our
@ -62,7 +68,7 @@ class SFTPFile (BufferedFile):
self.sftp._finish_responses(self)
BufferedFile.close(self)
try:
if _async:
if async:
# GC'd file handle could be called from an arbitrary thread -- don't wait for a response
self.sftp._async_request(type(None), CMD_CLOSE, self.handle)
else:

View File

@ -81,15 +81,16 @@ class SFTPHandle (object):
@return: data read from the file, or an SFTP error code.
@rtype: str
"""
if not hasattr(self, 'readfile') or (self.readfile is None):
readfile = getattr(self, 'readfile', None)
if readfile is None:
return SFTP_OP_UNSUPPORTED
try:
if self.__tell is None:
self.__tell = self.readfile.tell()
self.__tell = readfile.tell()
if offset != self.__tell:
self.readfile.seek(offset)
readfile.seek(offset)
self.__tell = offset
data = self.readfile.read(length)
data = readfile.read(length)
except IOError, e:
self.__tell = None
return SFTPServer.convert_errno(e.errno)
@ -116,16 +117,17 @@ class SFTPHandle (object):
@type data: str
@return: an SFTP error code like L{SFTP_OK}.
"""
if not hasattr(self, 'writefile') or (self.writefile is None):
writefile = getattr(self, 'writefile', None)
if writefile is None:
return SFTP_OP_UNSUPPORTED
try:
if self.__tell is None:
self.__tell = self.writefile.tell()
self.__tell = writefile.tell()
if offset != self.__tell:
self.writefile.seek(offset)
writefile.seek(offset)
self.__tell = offset
self.writefile.write(data)
self.writefile.flush()
writefile.write(data)
writefile.flush()
except IOError, e:
self.__tell = None
return SFTPServer.convert_errno(e.errno)

View File

@ -246,29 +246,29 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
self._send_status(request_number, SFTP_FAILURE, 'Block size too small')
return
sum = ''
sum_out = ''
offset = start
while offset < start + length:
blocklen = min(block_size, start + length - offset)
# don't try to read more than about 64KB at a time
chunklen = min(blocklen, 65536)
count = 0
hash = alg.new()
hash_obj = alg.new()
while count < blocklen:
data = f.read(offset, chunklen)
if not type(data) is str:
self._send_status(request_number, data, 'Unable to hash file')
return
hash.update(data)
hash_obj.update(data)
count += len(data)
offset += count
sum += hash.digest()
sum_out += hash_obj.digest()
msg = Message()
msg.add_int(request_number)
msg.add_string('check-file')
msg.add_string(algname)
msg.add_bytes(sum)
msg.add_bytes(sum_out)
self._send_packet(CMD_EXTENDED_REPLY, str(msg))
def _convert_pflags(self, pflags):
@ -412,7 +412,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
if tag == 'check-file':
self._check_file(request_number, msg)
else:
send._send_status(request_number, SFTP_OP_UNSUPPORTED)
self._send_status(request_number, SFTP_OP_UNSUPPORTED)
else:
self._send_status(request_number, SFTP_OP_UNSUPPORTED)

View File

@ -30,19 +30,20 @@ import time
import weakref
from paramiko import util
from paramiko.auth_handler import AuthHandler
from paramiko.channel import Channel
from paramiko.common import *
from paramiko.compress import ZlibCompressor, ZlibDecompressor
from paramiko.ssh_exception import SSHException, BadAuthenticationType
from paramiko.message import Message
from paramiko.channel import Channel
from paramiko.sftp_client import SFTPClient
from paramiko.packet import Packetizer, NeedRekeyException
from paramiko.rsakey import RSAKey
from paramiko.dsskey import DSSKey
from paramiko.kex_group1 import KexGroup1
from paramiko.kex_gex import KexGex
from paramiko.kex_group1 import KexGroup1
from paramiko.message import Message
from paramiko.packet import Packetizer, NeedRekeyException
from paramiko.primes import ModulusPack
from paramiko.auth_handler import AuthHandler
from paramiko.rsakey import RSAKey
from paramiko.server import ServerInterface
from paramiko.sftp_client import SFTPClient
from paramiko.ssh_exception import SSHException, BadAuthenticationType
# these come from PyCrypt
# http://www.amk.ca/python/writing/pycrypt/
@ -110,7 +111,8 @@ class SecurityOptions (object):
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:
forbidden = filter(lambda n: n not in possible, x)
if len(forbidden) > 0:
raise ValueError('unknown cipher')
setattr(self._transport, name, x)
@ -245,25 +247,39 @@ class Transport (threading.Thread):
self.sock.settimeout(0.1)
except AttributeError:
pass
# negotiated crypto parameters
self.packetizer = Packetizer(sock)
self.local_version = 'SSH-' + self._PROTO_ID + '-' + self._CLIENT_ID
self.remote_version = ''
self.local_cipher = self.remote_cipher = ''
self.local_kex_init = self.remote_kex_init = None
self.local_mac = self.remote_mac = None
self.local_compression = self.remote_compression = None
self.session_id = None
# /negotiated crypto parameters
self.expected_packet = 0
self.host_key_type = None
self.host_key = None
# state used during negotiation
self.kex_engine = None
self.H = None
self.K = None
self.active = False
self.initial_kex_done = False
self.in_kex = False
self.authenticated = False
self.expected_packet = 0
self.lock = threading.Lock() # synchronization (always higher level than write_lock)
# tracking open channels
self.channels = weakref.WeakValueDictionary() # (id -> Channel)
self.channel_events = { } # (id -> Event)
self.channels_seen = { } # (id -> True)
self.channel_counter = 1
self.window_size = 65536
self.max_packet_size = 34816
self.saved_exception = None
self.clear_to_send = threading.Event()
self.clear_to_send_lock = threading.Lock()
@ -271,9 +287,9 @@ class Transport (threading.Thread):
self.logger = util.get_logger(self.log_name)
self.packetizer.set_log(self.logger)
self.auth_handler = None
self.authenticated = False
# user-defined event callbacks:
self.completion_event = None
self.global_response = None # response Message from an arbitrary global request
self.completion_event = None # user-defined event callbacks
# server mode:
self.server_mode = False
self.server_object = None
@ -993,7 +1009,7 @@ class Transport (threading.Thread):
return self.auth_handler.wait_for_response(my_event)
except BadAuthenticationType, x:
# if password auth isn't allowed, but keyboard-interactive *is*, try to fudge it
if not fallback or not 'keyboard-interactive' in x.allowed_types:
if not fallback or ('keyboard-interactive' not in x.allowed_types):
raise
try:
def handler(title, instructions, fields):
@ -1010,6 +1026,7 @@ class Transport (threading.Thread):
except SSHException, ignored:
# attempt failed; just raise the original exception
raise x
return None
def auth_publickey(self, username, key, event=None):
"""
@ -1262,9 +1279,9 @@ class Transport (threading.Thread):
m.add_mpint(self.K)
m.add_bytes(self.H)
m.add_bytes(sofar)
hash = SHA.new(str(m)).digest()
out += hash
sofar += hash
digest = SHA.new(str(m)).digest()
out += digest
sofar += digest
return out[:nbytes]
def _get_cipher(self, name, key, iv):
@ -1394,24 +1411,24 @@ class Transport (threading.Thread):
else:
timeout = 2
try:
buffer = self.packetizer.readline(timeout)
buf = self.packetizer.readline(timeout)
except Exception, x:
raise SSHException('Error reading SSH protocol banner' + str(x))
if buffer[:4] == 'SSH-':
if buf[:4] == 'SSH-':
break
self._log(DEBUG, 'Banner: ' + buffer)
if buffer[:4] != 'SSH-':
raise SSHException('Indecipherable protocol version "' + buffer + '"')
self._log(DEBUG, 'Banner: ' + buf)
if buf[:4] != 'SSH-':
raise SSHException('Indecipherable protocol version "' + buf + '"')
# save this server version string for later
self.remote_version = buffer
self.remote_version = buf
# pull off any attached comment
comment = ''
i = string.find(buffer, ' ')
i = string.find(buf, ' ')
if i >= 0:
comment = buffer[i+1:]
buffer = buffer[:i]
comment = buf[i+1:]
buf = buf[:i]
# parse out version string and make sure it matches
segs = buffer.split('-', 2)
segs = buf.split('-', 2)
if len(segs) < 3:
raise SSHException('Invalid SSH banner')
version = segs[1]

View File

@ -168,12 +168,12 @@ def generate_key_bytes(hashclass, salt, key, nbytes):
if len(salt) > 8:
salt = salt[:8]
while nbytes > 0:
hash = hashclass.new()
hash_obj = hashclass.new()
if len(digest) > 0:
hash.update(digest)
hash.update(key)
hash.update(salt)
digest = hash.digest()
hash_obj.update(digest)
hash_obj.update(key)
hash_obj.update(salt)
digest = hash_obj.digest()
size = min(nbytes, len(digest))
keydata += digest[:size]
nbytes -= size