Fix message sending
Create constants for byte messages, implement asbytes so many methods can take Message and key objects directly and split get_string into get_text and get_binary. Also, change int handling to use mpint with a flag whenever the int is greater than 32 bits.
This commit is contained in:
parent
339d73cc13
commit
0e4ce3762a
|
@ -37,8 +37,11 @@ from paramiko.channel import Channel
|
|||
from paramiko.common import *
|
||||
from paramiko.util import retry_on_signal
|
||||
|
||||
SSH2_AGENTC_REQUEST_IDENTITIES, SSH2_AGENT_IDENTITIES_ANSWER, \
|
||||
SSH2_AGENTC_SIGN_REQUEST, SSH2_AGENT_SIGN_RESPONSE = range(11, 15)
|
||||
cSSH2_AGENTC_REQUEST_IDENTITIES = byte_chr(11)
|
||||
SSH2_AGENT_IDENTITIES_ANSWER = 12
|
||||
cSSH2_AGENTC_SIGN_REQUEST = byte_chr(13)
|
||||
SSH2_AGENT_SIGN_RESPONSE = 14
|
||||
|
||||
|
||||
class AgentSSH(object):
|
||||
"""
|
||||
|
@ -68,12 +71,12 @@ class AgentSSH(object):
|
|||
|
||||
def _connect(self, conn):
|
||||
self._conn = conn
|
||||
ptype, result = self._send_message(chr(SSH2_AGENTC_REQUEST_IDENTITIES))
|
||||
ptype, result = self._send_message(cSSH2_AGENTC_REQUEST_IDENTITIES)
|
||||
if ptype != SSH2_AGENT_IDENTITIES_ANSWER:
|
||||
raise SSHException('could not get keys from ssh-agent')
|
||||
keys = []
|
||||
for i in range(result.get_int()):
|
||||
keys.append(AgentKey(self, result.get_string()))
|
||||
keys.append(AgentKey(self, result.get_binary()))
|
||||
result.get_string()
|
||||
self._keys = tuple(keys)
|
||||
|
||||
|
@ -83,7 +86,7 @@ class AgentSSH(object):
|
|||
self._keys = ()
|
||||
|
||||
def _send_message(self, msg):
|
||||
msg = str(msg)
|
||||
msg = asbytes(msg)
|
||||
self._conn.send(struct.pack('>I', len(msg)) + msg)
|
||||
l = self._read_all(4)
|
||||
msg = Message(self._read_all(struct.unpack('>I', l)[0]))
|
||||
|
@ -360,21 +363,24 @@ class AgentKey(PKey):
|
|||
def __init__(self, agent, blob):
|
||||
self.agent = agent
|
||||
self.blob = blob
|
||||
self.name = Message(blob).get_string()
|
||||
self.name = Message(blob).get_text()
|
||||
|
||||
def asbytes(self):
|
||||
return self.blob
|
||||
|
||||
def __str__(self):
|
||||
return self.blob
|
||||
return self.asbytes()
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
def sign_ssh_data(self, rng, data):
|
||||
msg = Message()
|
||||
msg.add_byte(chr(SSH2_AGENTC_SIGN_REQUEST))
|
||||
msg.add_byte(cSSH2_AGENTC_SIGN_REQUEST)
|
||||
msg.add_string(self.blob)
|
||||
msg.add_string(data)
|
||||
msg.add_int(0)
|
||||
ptype, result = self.agent._send_message(msg)
|
||||
if ptype != SSH2_AGENT_SIGN_RESPONSE:
|
||||
raise SSHException('key cannot be used for signing')
|
||||
return result.get_string()
|
||||
return result.get_binary()
|
||||
|
|
|
@ -119,13 +119,13 @@ class AuthHandler (object):
|
|||
|
||||
def _request_auth(self):
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_SERVICE_REQUEST))
|
||||
m.add_byte(cMSG_SERVICE_REQUEST)
|
||||
m.add_string('ssh-userauth')
|
||||
self.transport._send_message(m)
|
||||
|
||||
def _disconnect_service_not_available(self):
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_DISCONNECT))
|
||||
m.add_byte(cMSG_DISCONNECT)
|
||||
m.add_int(DISCONNECT_SERVICE_NOT_AVAILABLE)
|
||||
m.add_string('Service not available')
|
||||
m.add_string('en')
|
||||
|
@ -134,7 +134,7 @@ class AuthHandler (object):
|
|||
|
||||
def _disconnect_no_more_auth(self):
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_DISCONNECT))
|
||||
m.add_byte(cMSG_DISCONNECT)
|
||||
m.add_int(DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
|
||||
m.add_string('No more auth methods available')
|
||||
m.add_string('en')
|
||||
|
@ -144,14 +144,14 @@ class AuthHandler (object):
|
|||
def _get_session_blob(self, key, service, username):
|
||||
m = Message()
|
||||
m.add_string(self.transport.session_id)
|
||||
m.add_byte(chr(MSG_USERAUTH_REQUEST))
|
||||
m.add_byte(cMSG_USERAUTH_REQUEST)
|
||||
m.add_string(username)
|
||||
m.add_string(service)
|
||||
m.add_string('publickey')
|
||||
m.add_boolean(1)
|
||||
m.add_string(key.get_name())
|
||||
m.add_string(str(key))
|
||||
return str(m)
|
||||
m.add_string(key)
|
||||
return m.asbytes()
|
||||
|
||||
def wait_for_response(self, event):
|
||||
while True:
|
||||
|
@ -175,11 +175,11 @@ class AuthHandler (object):
|
|||
return []
|
||||
|
||||
def _parse_service_request(self, m):
|
||||
service = m.get_string()
|
||||
service = m.get_text()
|
||||
if self.transport.server_mode and (service == 'ssh-userauth'):
|
||||
# accepted
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_SERVICE_ACCEPT))
|
||||
m.add_byte(cMSG_SERVICE_ACCEPT)
|
||||
m.add_string(service)
|
||||
self.transport._send_message(m)
|
||||
return
|
||||
|
@ -187,27 +187,25 @@ class AuthHandler (object):
|
|||
self._disconnect_service_not_available()
|
||||
|
||||
def _parse_service_accept(self, m):
|
||||
service = m.get_string()
|
||||
service = m.get_text()
|
||||
if service == 'ssh-userauth':
|
||||
self.transport._log(DEBUG, 'userauth is OK')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_USERAUTH_REQUEST))
|
||||
m.add_byte(cMSG_USERAUTH_REQUEST)
|
||||
m.add_string(self.username)
|
||||
m.add_string('ssh-connection')
|
||||
m.add_string(self.auth_method)
|
||||
if self.auth_method == 'password':
|
||||
m.add_boolean(False)
|
||||
password = self.password
|
||||
if isinstance(password, unicode):
|
||||
password = password.encode('UTF-8')
|
||||
password = bytestring(self.password)
|
||||
m.add_string(password)
|
||||
elif self.auth_method == 'publickey':
|
||||
m.add_boolean(True)
|
||||
m.add_string(self.private_key.get_name())
|
||||
m.add_string(str(self.private_key))
|
||||
m.add_string(self.private_key)
|
||||
blob = self._get_session_blob(self.private_key, 'ssh-connection', self.username)
|
||||
sig = self.private_key.sign_ssh_data(self.transport.rng, blob)
|
||||
m.add_string(str(sig))
|
||||
m.add_string(sig)
|
||||
elif self.auth_method == 'keyboard-interactive':
|
||||
m.add_string('')
|
||||
m.add_string(self.submethods)
|
||||
|
@ -224,11 +222,11 @@ class AuthHandler (object):
|
|||
m = Message()
|
||||
if result == AUTH_SUCCESSFUL:
|
||||
self.transport._log(INFO, 'Auth granted (%s).' % method)
|
||||
m.add_byte(chr(MSG_USERAUTH_SUCCESS))
|
||||
m.add_byte(cMSG_USERAUTH_SUCCESS)
|
||||
self.authenticated = True
|
||||
else:
|
||||
self.transport._log(INFO, 'Auth rejected (%s).' % method)
|
||||
m.add_byte(chr(MSG_USERAUTH_FAILURE))
|
||||
m.add_byte(cMSG_USERAUTH_FAILURE)
|
||||
m.add_string(self.transport.server_object.get_allowed_auths(username))
|
||||
if result == AUTH_PARTIALLY_SUCCESSFUL:
|
||||
m.add_boolean(1)
|
||||
|
@ -244,7 +242,7 @@ class AuthHandler (object):
|
|||
def _interactive_query(self, q):
|
||||
# make interactive query instead of response
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_USERAUTH_INFO_REQUEST))
|
||||
m.add_byte(cMSG_USERAUTH_INFO_REQUEST)
|
||||
m.add_string(q.name)
|
||||
m.add_string(q.instructions)
|
||||
m.add_string('')
|
||||
|
@ -258,7 +256,7 @@ class AuthHandler (object):
|
|||
if not self.transport.server_mode:
|
||||
# er, uh... what?
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_USERAUTH_FAILURE))
|
||||
m.add_byte(cMSG_USERAUTH_FAILURE)
|
||||
m.add_string('none')
|
||||
m.add_boolean(0)
|
||||
self.transport._send_message(m)
|
||||
|
@ -266,9 +264,9 @@ class AuthHandler (object):
|
|||
if self.authenticated:
|
||||
# ignore
|
||||
return
|
||||
username = m.get_string()
|
||||
service = m.get_string()
|
||||
method = m.get_string()
|
||||
username = m.get_text()
|
||||
service = m.get_text()
|
||||
method = m.get_text()
|
||||
self.transport._log(DEBUG, 'Auth request (type=%s) service=%s, username=%s' % (method, service, username))
|
||||
if service != 'ssh-connection':
|
||||
self._disconnect_service_not_available()
|
||||
|
@ -283,7 +281,7 @@ class AuthHandler (object):
|
|||
result = self.transport.server_object.check_auth_none(username)
|
||||
elif method == 'password':
|
||||
changereq = m.get_boolean()
|
||||
password = m.get_string()
|
||||
password = m.get_binary()
|
||||
try:
|
||||
password = password.decode('UTF-8')
|
||||
except UnicodeError:
|
||||
|
@ -294,7 +292,7 @@ class AuthHandler (object):
|
|||
# always treated as failure, since we don't support changing passwords, but collect
|
||||
# the list of valid auth types from the callback anyway
|
||||
self.transport._log(DEBUG, 'Auth request to change passwords (rejected)')
|
||||
newpassword = m.get_string()
|
||||
newpassword = m.get_binary()
|
||||
try:
|
||||
newpassword = newpassword.decode('UTF-8', 'replace')
|
||||
except UnicodeError:
|
||||
|
@ -304,8 +302,8 @@ class AuthHandler (object):
|
|||
result = self.transport.server_object.check_auth_password(username, password)
|
||||
elif method == 'publickey':
|
||||
sig_attached = m.get_boolean()
|
||||
keytype = m.get_string()
|
||||
keyblob = m.get_string()
|
||||
keytype = m.get_text()
|
||||
keyblob = m.get_binary()
|
||||
try:
|
||||
key = self.transport._key_info[keytype](Message(keyblob))
|
||||
except SSHException:
|
||||
|
@ -326,12 +324,12 @@ class AuthHandler (object):
|
|||
# client wants to know if this key is acceptable, before it
|
||||
# signs anything... send special "ok" message
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_USERAUTH_PK_OK))
|
||||
m.add_byte(cMSG_USERAUTH_PK_OK)
|
||||
m.add_string(keytype)
|
||||
m.add_string(keyblob)
|
||||
self.transport._send_message(m)
|
||||
return
|
||||
sig = Message(m.get_string())
|
||||
sig = Message(m.get_binary())
|
||||
blob = self._get_session_blob(key, service, username)
|
||||
if not key.verify_ssh_sig(blob, sig):
|
||||
self.transport._log(INFO, 'Auth rejected: invalid signature')
|
||||
|
@ -383,17 +381,17 @@ class AuthHandler (object):
|
|||
def _parse_userauth_info_request(self, m):
|
||||
if self.auth_method != 'keyboard-interactive':
|
||||
raise SSHException('Illegal info request from server')
|
||||
title = m.get_string()
|
||||
instructions = m.get_string()
|
||||
m.get_string() # lang
|
||||
title = m.get_text()
|
||||
instructions = m.get_text()
|
||||
m.get_binary() # lang
|
||||
prompts = m.get_int()
|
||||
prompt_list = []
|
||||
for i in range(prompts):
|
||||
prompt_list.append((m.get_string(), m.get_boolean()))
|
||||
prompt_list.append((m.get_text(), m.get_boolean()))
|
||||
response_list = self.interactive_handler(title, instructions, prompt_list)
|
||||
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_USERAUTH_INFO_RESPONSE))
|
||||
m.add_byte(cMSG_USERAUTH_INFO_RESPONSE)
|
||||
m.add_int(len(response_list))
|
||||
for r in response_list:
|
||||
m.add_string(r)
|
||||
|
@ -405,14 +403,14 @@ class AuthHandler (object):
|
|||
n = m.get_int()
|
||||
responses = []
|
||||
for i in range(n):
|
||||
responses.append(m.get_string())
|
||||
responses.append(m.get_text())
|
||||
result = self.transport.server_object.check_auth_interactive_response(responses)
|
||||
if isinstance(type(result), InteractiveQuery):
|
||||
# make interactive query instead of response
|
||||
self._interactive_query(result)
|
||||
return
|
||||
self._send_auth_result(self.auth_username, 'keyboard-interactive', result)
|
||||
|
||||
|
||||
|
||||
_handler_table = {
|
||||
MSG_SERVICE_REQUEST: _parse_service_request,
|
||||
|
|
|
@ -30,13 +30,16 @@ class BER(object):
|
|||
Robey's tiny little attempt at a BER decoder.
|
||||
"""
|
||||
|
||||
def __init__(self, content=''):
|
||||
self.content = content
|
||||
def __init__(self, content=bytes()):
|
||||
self.content = b(content)
|
||||
self.idx = 0
|
||||
|
||||
def __str__(self):
|
||||
def asbytes(self):
|
||||
return self.content
|
||||
|
||||
def __str__(self):
|
||||
return self.asbytes()
|
||||
|
||||
def __repr__(self):
|
||||
return 'BER(\'' + repr(self.content) + '\')'
|
||||
|
||||
|
@ -126,5 +129,5 @@ class BER(object):
|
|||
b = BER()
|
||||
for item in data:
|
||||
b.encode(item)
|
||||
return str(b)
|
||||
return b.asbytes()
|
||||
encode_sequence = staticmethod(encode_sequence)
|
||||
|
|
|
@ -148,7 +148,7 @@ class Channel (object):
|
|||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||
raise SSHException('Channel is not open')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('pty-req')
|
||||
m.add_boolean(True)
|
||||
|
@ -181,7 +181,7 @@ class Channel (object):
|
|||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||
raise SSHException('Channel is not open')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('shell')
|
||||
m.add_boolean(1)
|
||||
|
@ -208,7 +208,7 @@ class Channel (object):
|
|||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||
raise SSHException('Channel is not open')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('exec')
|
||||
m.add_boolean(True)
|
||||
|
@ -235,7 +235,7 @@ class Channel (object):
|
|||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||
raise SSHException('Channel is not open')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('subsystem')
|
||||
m.add_boolean(True)
|
||||
|
@ -264,7 +264,7 @@ class Channel (object):
|
|||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||
raise SSHException('Channel is not open')
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('window-change')
|
||||
m.add_boolean(False)
|
||||
|
@ -319,7 +319,7 @@ class Channel (object):
|
|||
# in many cases, the channel will not still be open here.
|
||||
# that's fine.
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('exit-status')
|
||||
m.add_boolean(False)
|
||||
|
@ -375,7 +375,7 @@ class Channel (object):
|
|||
auth_cookie = binascii.hexlify(self.transport.rng.read(16))
|
||||
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('x11-req')
|
||||
m.add_boolean(True)
|
||||
|
@ -406,7 +406,7 @@ class Channel (object):
|
|||
raise SSHException('Channel is not open')
|
||||
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||
m.add_byte(cMSG_CHANNEL_REQUEST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string('auth-agent-req@openssh.com')
|
||||
m.add_boolean(False)
|
||||
|
@ -491,7 +491,7 @@ class Channel (object):
|
|||
self._feed(data)
|
||||
return old
|
||||
|
||||
|
||||
|
||||
### socket API
|
||||
|
||||
|
||||
|
@ -622,7 +622,7 @@ class Channel (object):
|
|||
# no need to hold the channel lock when sending this
|
||||
if ack > 0:
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
|
||||
m.add_byte(cMSG_CHANNEL_WINDOW_ADJUST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_int(ack)
|
||||
self.transport._send_user_message(m)
|
||||
|
@ -672,7 +672,7 @@ class Channel (object):
|
|||
# no need to hold the channel lock when sending this
|
||||
if ack > 0:
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
|
||||
m.add_byte(cMSG_CHANNEL_WINDOW_ADJUST)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_int(ack)
|
||||
self.transport._send_user_message(m)
|
||||
|
@ -724,7 +724,7 @@ class Channel (object):
|
|||
# eof or similar
|
||||
return 0
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_DATA))
|
||||
m.add_byte(cMSG_CHANNEL_DATA)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_string(s[:size])
|
||||
finally:
|
||||
|
@ -761,7 +761,7 @@ class Channel (object):
|
|||
# eof or similar
|
||||
return 0
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_EXTENDED_DATA))
|
||||
m.add_byte(cMSG_CHANNEL_EXTENDED_DATA)
|
||||
m.add_int(self.remote_chanid)
|
||||
m.add_int(1)
|
||||
m.add_string(s[:size])
|
||||
|
@ -973,12 +973,12 @@ class Channel (object):
|
|||
# passed from _feed_extended
|
||||
s = m
|
||||
else:
|
||||
s = m.get_string()
|
||||
s = m.get_binary()
|
||||
self.in_buffer.feed(s)
|
||||
|
||||
def _feed_extended(self, m):
|
||||
code = m.get_int()
|
||||
s = m.get_string()
|
||||
s = m.get_text()
|
||||
if code != 1:
|
||||
self._log(ERROR, 'unknown extended_data type %d; discarding' % code)
|
||||
return
|
||||
|
@ -999,7 +999,7 @@ class Channel (object):
|
|||
self.lock.release()
|
||||
|
||||
def _handle_request(self, m):
|
||||
key = m.get_string()
|
||||
key = m.get_text()
|
||||
want_reply = m.get_boolean()
|
||||
server = self.transport.server_object
|
||||
ok = False
|
||||
|
@ -1035,13 +1035,13 @@ class Channel (object):
|
|||
else:
|
||||
ok = server.check_channel_env_request(self, name, value)
|
||||
elif key == 'exec':
|
||||
cmd = m.get_string()
|
||||
cmd = m.get_text()
|
||||
if server is None:
|
||||
ok = False
|
||||
else:
|
||||
ok = server.check_channel_exec_request(self, cmd)
|
||||
elif key == 'subsystem':
|
||||
name = m.get_string()
|
||||
name = m.get_text()
|
||||
if server is None:
|
||||
ok = False
|
||||
else:
|
||||
|
@ -1058,8 +1058,8 @@ class Channel (object):
|
|||
pixelheight)
|
||||
elif key == 'x11-req':
|
||||
single_connection = m.get_boolean()
|
||||
auth_proto = m.get_string()
|
||||
auth_cookie = m.get_string()
|
||||
auth_proto = m.get_text()
|
||||
auth_cookie = m.get_text()
|
||||
screen_number = m.get_int()
|
||||
if server is None:
|
||||
ok = False
|
||||
|
@ -1077,9 +1077,9 @@ class Channel (object):
|
|||
if want_reply:
|
||||
m = Message()
|
||||
if ok:
|
||||
m.add_byte(chr(MSG_CHANNEL_SUCCESS))
|
||||
m.add_byte(cMSG_CHANNEL_SUCCESS)
|
||||
else:
|
||||
m.add_byte(chr(MSG_CHANNEL_FAILURE))
|
||||
m.add_byte(cMSG_CHANNEL_FAILURE)
|
||||
m.add_int(self.remote_chanid)
|
||||
self.transport._send_user_message(m)
|
||||
|
||||
|
@ -1145,7 +1145,7 @@ class Channel (object):
|
|||
if self.eof_sent:
|
||||
return None
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_EOF))
|
||||
m.add_byte(cMSG_CHANNEL_EOF)
|
||||
m.add_int(self.remote_chanid)
|
||||
self.eof_sent = True
|
||||
self._log(DEBUG, 'EOF sent (%s)', self._name)
|
||||
|
@ -1157,7 +1157,7 @@ class Channel (object):
|
|||
return None, None
|
||||
m1 = self._send_eof()
|
||||
m2 = Message()
|
||||
m2.add_byte(chr(MSG_CHANNEL_CLOSE))
|
||||
m2.add_byte(cMSG_CHANNEL_CLOSE)
|
||||
m2.add_int(self.remote_chanid)
|
||||
self._set_closed()
|
||||
# can't unlink from the Transport yet -- the remote side may still
|
||||
|
|
|
@ -56,7 +56,7 @@ class DSSKey (PKey):
|
|||
else:
|
||||
if msg is None:
|
||||
raise SSHException('Key object may not be empty')
|
||||
if msg.get_string() != 'ssh-dss':
|
||||
if msg.get_text() != 'ssh-dss':
|
||||
raise SSHException('Invalid key')
|
||||
self.p = msg.get_mpint()
|
||||
self.q = msg.get_mpint()
|
||||
|
@ -64,14 +64,17 @@ class DSSKey (PKey):
|
|||
self.y = msg.get_mpint()
|
||||
self.size = util.bit_length(self.p)
|
||||
|
||||
def __str__(self):
|
||||
def asbytes(self):
|
||||
m = Message()
|
||||
m.add_string('ssh-dss')
|
||||
m.add_mpint(self.p)
|
||||
m.add_mpint(self.q)
|
||||
m.add_mpint(self.g)
|
||||
m.add_mpint(self.y)
|
||||
return str(m)
|
||||
return m.asbytes()
|
||||
|
||||
def __str__(self):
|
||||
return self.asbytes()
|
||||
|
||||
def __hash__(self):
|
||||
h = hash(self.get_name())
|
||||
|
@ -114,14 +117,14 @@ class DSSKey (PKey):
|
|||
return m
|
||||
|
||||
def verify_ssh_sig(self, data, msg):
|
||||
if len(str(msg)) == 40:
|
||||
if len(msg.asbytes()) == 40:
|
||||
# spies.com bug: signature has no header
|
||||
sig = str(msg)
|
||||
sig = msg.asbytes()
|
||||
else:
|
||||
kind = msg.get_string()
|
||||
kind = msg.get_text()
|
||||
if kind != 'ssh-dss':
|
||||
return 0
|
||||
sig = msg.get_string()
|
||||
sig = msg.get_binary()
|
||||
|
||||
# pull out (r, s) which are NOT encoded as mpints
|
||||
sigR = util.inflate_long(sig[:20], 1)
|
||||
|
@ -140,7 +143,7 @@ class DSSKey (PKey):
|
|||
b.encode(keylist)
|
||||
except BERException:
|
||||
raise SSHException('Unable to create ber encoding of key')
|
||||
return str(b)
|
||||
return b.asbytes()
|
||||
|
||||
def write_private_key_file(self, filename, password=None):
|
||||
self._write_private_key_file('DSA', filename, self._encode_key(), password)
|
||||
|
|
|
@ -56,30 +56,33 @@ class ECDSAKey (PKey):
|
|||
else:
|
||||
if msg is None:
|
||||
raise SSHException('Key object may not be empty')
|
||||
if msg.get_string() != 'ecdsa-sha2-nistp256':
|
||||
if msg.get_text() != 'ecdsa-sha2-nistp256':
|
||||
raise SSHException('Invalid key')
|
||||
curvename = msg.get_string()
|
||||
curvename = msg.get_text()
|
||||
if curvename != 'nistp256':
|
||||
raise SSHException("Can't handle curve of type %s" % curvename)
|
||||
|
||||
pointinfo = msg.get_string()
|
||||
if pointinfo[0] != "\x04":
|
||||
raise SSHException('Point compression is being used: %s'%
|
||||
pointinfo = msg.get_binary()
|
||||
if pointinfo[0] != four_byte:
|
||||
raise SSHException('Point compression is being used: %s' %
|
||||
binascii.hexlify(pointinfo))
|
||||
self.verifying_key = VerifyingKey.from_string(pointinfo[1:],
|
||||
curve=curves.NIST256p)
|
||||
curve=curves.NIST256p)
|
||||
self.size = 256
|
||||
|
||||
def __str__(self):
|
||||
def asbytes(self):
|
||||
key = self.verifying_key
|
||||
m = Message()
|
||||
m.add_string('ecdsa-sha2-nistp256')
|
||||
m.add_string('nistp256')
|
||||
|
||||
point_str = "\x04" + key.to_string()
|
||||
point_str = four_byte + key.to_string()
|
||||
|
||||
m.add_string(point_str)
|
||||
return str(m)
|
||||
return m.asbytes()
|
||||
|
||||
def __str__(self):
|
||||
return self.asbytes()
|
||||
|
||||
def __hash__(self):
|
||||
h = hash(self.get_name())
|
||||
|
@ -106,9 +109,9 @@ class ECDSAKey (PKey):
|
|||
return m
|
||||
|
||||
def verify_ssh_sig(self, data, msg):
|
||||
if msg.get_string() != 'ecdsa-sha2-nistp256':
|
||||
if msg.get_text() != 'ecdsa-sha2-nistp256':
|
||||
return False
|
||||
sig = msg.get_string()
|
||||
sig = msg.get_binary()
|
||||
|
||||
# verify the signature by SHA'ing the data and encrypting it
|
||||
# using the public key.
|
||||
|
@ -161,7 +164,7 @@ class ECDSAKey (PKey):
|
|||
s, padding = der.remove_sequence(data)
|
||||
if padding:
|
||||
if padding not in self.ALLOWED_PADDINGS:
|
||||
raise ValueError, "weird padding: %s" % (binascii.hexlify(empty))
|
||||
raise ValueError("weird padding: %s" % (binascii.hexlify(empty)))
|
||||
data = data[:-len(padding)]
|
||||
key = SigningKey.from_der(data)
|
||||
self.signing_key = key
|
||||
|
@ -172,7 +175,7 @@ class ECDSAKey (PKey):
|
|||
msg = Message()
|
||||
msg.add_mpint(r)
|
||||
msg.add_mpint(s)
|
||||
return str(msg)
|
||||
return msg.asbytes()
|
||||
|
||||
def _sigdecode(self, sig, order):
|
||||
msg = Message(sig)
|
||||
|
|
|
@ -289,7 +289,7 @@ class HostKeys (MutableMapping):
|
|||
host_key = k.get(key.get_name(), None)
|
||||
if host_key is None:
|
||||
return False
|
||||
return str(host_key) == str(key)
|
||||
return host_key.asbytes() == key.asbytes()
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
|
|
|
@ -33,6 +33,8 @@ from paramiko.ssh_exception import SSHException
|
|||
|
||||
_MSG_KEXDH_GEX_REQUEST_OLD, _MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, \
|
||||
_MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(30, 35)
|
||||
c_MSG_KEXDH_GEX_REQUEST_OLD, c_MSG_KEXDH_GEX_GROUP, c_MSG_KEXDH_GEX_INIT, \
|
||||
c_MSG_KEXDH_GEX_REPLY, c_MSG_KEXDH_GEX_REQUEST = [byte_chr(c) for c in range(30, 35)]
|
||||
|
||||
|
||||
class KexGex (object):
|
||||
|
@ -62,11 +64,11 @@ class KexGex (object):
|
|||
m = Message()
|
||||
if _test_old_style:
|
||||
# only used for unit tests: we shouldn't ever send this
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_REQUEST_OLD))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_REQUEST_OLD)
|
||||
m.add_int(self.preferred_bits)
|
||||
self.old_style = True
|
||||
else:
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_REQUEST))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_REQUEST)
|
||||
m.add_int(self.min_bits)
|
||||
m.add_int(self.preferred_bits)
|
||||
m.add_int(self.max_bits)
|
||||
|
@ -135,7 +137,7 @@ class KexGex (object):
|
|||
self.transport._log(DEBUG, 'Picking p (%d <= %d <= %d bits)' % (minbits, preferredbits, maxbits))
|
||||
self.g, self.p = pack.get_modulus(minbits, preferredbits, maxbits)
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_GROUP))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_GROUP)
|
||||
m.add_mpint(self.p)
|
||||
m.add_mpint(self.g)
|
||||
self.transport._send_message(m)
|
||||
|
@ -156,7 +158,7 @@ class KexGex (object):
|
|||
self.transport._log(DEBUG, 'Picking p (~ %d bits)' % (self.preferred_bits,))
|
||||
self.g, self.p = pack.get_modulus(self.min_bits, self.preferred_bits, self.max_bits)
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_GROUP))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_GROUP)
|
||||
m.add_mpint(self.p)
|
||||
m.add_mpint(self.g)
|
||||
self.transport._send_message(m)
|
||||
|
@ -175,7 +177,7 @@ class KexGex (object):
|
|||
# now compute e = g^x mod p
|
||||
self.e = pow(self.g, self.x, self.p)
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_INIT))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_INIT)
|
||||
m.add_mpint(self.e)
|
||||
self.transport._send_message(m)
|
||||
self.transport._expect_packet(_MSG_KEXDH_GEX_REPLY)
|
||||
|
@ -187,7 +189,7 @@ class KexGex (object):
|
|||
self._generate_x()
|
||||
self.f = pow(self.g, self.x, self.p)
|
||||
K = pow(self.e, self.x, self.p)
|
||||
key = str(self.transport.get_server_key())
|
||||
key = self.transport.get_server_key().asbytes()
|
||||
# okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)
|
||||
hm = Message()
|
||||
hm.add(self.transport.remote_version, self.transport.local_version,
|
||||
|
@ -203,16 +205,16 @@ class KexGex (object):
|
|||
hm.add_mpint(self.e)
|
||||
hm.add_mpint(self.f)
|
||||
hm.add_mpint(K)
|
||||
H = SHA.new(str(hm)).digest()
|
||||
H = SHA.new(hm.asbytes()).digest()
|
||||
self.transport._set_K_H(K, H)
|
||||
# sign it
|
||||
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
||||
# send reply
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_GEX_REPLY))
|
||||
m.add_byte(c_MSG_KEXDH_GEX_REPLY)
|
||||
m.add_string(key)
|
||||
m.add_mpint(self.f)
|
||||
m.add_string(str(sig))
|
||||
m.add_string(sig)
|
||||
self.transport._send_message(m)
|
||||
self.transport._activate_outbound()
|
||||
|
||||
|
@ -238,6 +240,6 @@ class KexGex (object):
|
|||
hm.add_mpint(self.e)
|
||||
hm.add_mpint(self.f)
|
||||
hm.add_mpint(K)
|
||||
self.transport._set_K_H(K, SHA.new(str(hm)).digest())
|
||||
self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
|
||||
self.transport._verify_key(host_key, sig)
|
||||
self.transport._activate_outbound()
|
||||
|
|
|
@ -56,7 +56,7 @@ class KexGroup1(object):
|
|||
# compute e = g^x mod p (where g=2), and send it
|
||||
self.e = pow(G, self.x, P)
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_INIT))
|
||||
m.add_byte(c_MSG_KEXDH_INIT)
|
||||
m.add_mpint(self.e)
|
||||
self.transport._send_message(m)
|
||||
self.transport._expect_packet(_MSG_KEXDH_REPLY)
|
||||
|
@ -67,7 +67,7 @@ class KexGroup1(object):
|
|||
elif not self.transport.server_mode and (ptype == _MSG_KEXDH_REPLY):
|
||||
return self._parse_kexdh_reply(m)
|
||||
raise SSHException('KexGroup1 asked to handle packet type %d' % ptype)
|
||||
|
||||
|
||||
|
||||
### internals...
|
||||
|
||||
|
@ -92,7 +92,7 @@ class KexGroup1(object):
|
|||
self.f = m.get_mpint()
|
||||
if (self.f < 1) or (self.f > P - 1):
|
||||
raise SSHException('Server kex "f" is out of range')
|
||||
sig = m.get_string()
|
||||
sig = m.get_binary()
|
||||
K = pow(self.f, self.x, P)
|
||||
# okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
|
||||
hm = Message()
|
||||
|
@ -102,7 +102,7 @@ class KexGroup1(object):
|
|||
hm.add_mpint(self.e)
|
||||
hm.add_mpint(self.f)
|
||||
hm.add_mpint(K)
|
||||
self.transport._set_K_H(K, SHA.new(str(hm)).digest())
|
||||
self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
|
||||
self.transport._verify_key(host_key, sig)
|
||||
self.transport._activate_outbound()
|
||||
|
||||
|
@ -112,7 +112,7 @@ class KexGroup1(object):
|
|||
if (self.e < 1) or (self.e > P - 1):
|
||||
raise SSHException('Client kex "e" is out of range')
|
||||
K = pow(self.e, self.x, P)
|
||||
key = str(self.transport.get_server_key())
|
||||
key = self.transport.get_server_key().asbytes()
|
||||
# okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
|
||||
hm = Message()
|
||||
hm.add(self.transport.remote_version, self.transport.local_version,
|
||||
|
@ -121,15 +121,15 @@ class KexGroup1(object):
|
|||
hm.add_mpint(self.e)
|
||||
hm.add_mpint(self.f)
|
||||
hm.add_mpint(K)
|
||||
H = SHA.new(str(hm)).digest()
|
||||
H = SHA.new(hm.asbytes()).digest()
|
||||
self.transport._set_K_H(K, H)
|
||||
# sign it
|
||||
sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
|
||||
# send reply
|
||||
m = Message()
|
||||
m.add_byte(chr(_MSG_KEXDH_REPLY))
|
||||
m.add_byte(c_MSG_KEXDH_REPLY)
|
||||
m.add_string(key)
|
||||
m.add_mpint(self.f)
|
||||
m.add_string(str(sig))
|
||||
m.add_string(sig)
|
||||
self.transport._send_message(m)
|
||||
self.transport._activate_outbound()
|
||||
|
|
|
@ -37,6 +37,8 @@ class Message (object):
|
|||
paramiko doesn't support yet.
|
||||
"""
|
||||
|
||||
big_int = long(0xff000000)
|
||||
|
||||
def __init__(self, content=None):
|
||||
"""
|
||||
Create a new SSH2 Message.
|
||||
|
@ -46,18 +48,12 @@ class Message (object):
|
|||
@type content: string
|
||||
"""
|
||||
if content != None:
|
||||
self.packet = cStringIO.StringIO(content)
|
||||
self.packet = BytesIO(content)
|
||||
else:
|
||||
self.packet = cStringIO.StringIO()
|
||||
self.packet = BytesIO()
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Return the byte stream content of this Message, as a string.
|
||||
|
||||
@return: the contents of this Message.
|
||||
@rtype: string
|
||||
"""
|
||||
return self.packet.getvalue()
|
||||
return self.asbytes()
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
|
@ -67,6 +63,15 @@ class Message (object):
|
|||
"""
|
||||
return 'paramiko.Message(' + repr(self.packet.getvalue()) + ')'
|
||||
|
||||
def asbytes(self):
|
||||
"""
|
||||
Return the byte stream content of this Message, as bytes.
|
||||
|
||||
@return: the contents of this Message.
|
||||
@rtype: bytes
|
||||
"""
|
||||
return self.packet.getvalue()
|
||||
|
||||
def rewind(self):
|
||||
"""
|
||||
Rewind the message to the beginning as if no items had been parsed
|
||||
|
@ -112,7 +117,7 @@ class Message (object):
|
|||
b = self.packet.read(n)
|
||||
max_pad_size = 1<<20 # Limit padding to 1 MB
|
||||
if len(b) < n and n < max_pad_size:
|
||||
return b + '\x00' * (n - len(b))
|
||||
return b + zero_byte * (n - len(b))
|
||||
return b
|
||||
|
||||
def get_byte(self):
|
||||
|
@ -134,12 +139,25 @@ class Message (object):
|
|||
@rtype: bool
|
||||
"""
|
||||
b = self.get_bytes(1)
|
||||
return b != '\x00'
|
||||
return b != zero_byte
|
||||
|
||||
def get_int(self):
|
||||
"""
|
||||
Fetch an int from the stream.
|
||||
|
||||
@return: a 32-bit unsigned integer.
|
||||
@rtype: int
|
||||
"""
|
||||
byte = self.get_bytes(1)
|
||||
if byte == max_byte:
|
||||
return util.inflate_long(self.get_binary())
|
||||
byte += self.get_bytes(3)
|
||||
return struct.unpack('>I', byte)[0]
|
||||
|
||||
def get_size(self):
|
||||
"""
|
||||
Fetch an int from the stream.
|
||||
|
||||
@return: a 32-bit unsigned integer.
|
||||
@rtype: int
|
||||
"""
|
||||
|
@ -152,7 +170,7 @@ class Message (object):
|
|||
@return: a 64-bit unsigned integer.
|
||||
@rtype: long
|
||||
"""
|
||||
return struct.unpack('>Q', self.get_bytes(8))[0]
|
||||
return self.get_int()
|
||||
|
||||
def get_mpint(self):
|
||||
"""
|
||||
|
@ -161,7 +179,7 @@ class Message (object):
|
|||
@return: an arbitrary-length integer.
|
||||
@rtype: long
|
||||
"""
|
||||
return util.inflate_long(self.get_string())
|
||||
return util.inflate_long(self.get_binary())
|
||||
|
||||
def get_string(self):
|
||||
"""
|
||||
|
@ -172,7 +190,30 @@ class Message (object):
|
|||
@return: a string.
|
||||
@rtype: string
|
||||
"""
|
||||
return self.get_bytes(self.get_int())
|
||||
return self.get_bytes(self.get_size())
|
||||
|
||||
def get_text(self):
|
||||
"""
|
||||
Fetch a string from the stream. This could be a byte string and may
|
||||
contain unprintable characters. (It's not unheard of for a string to
|
||||
contain another byte-stream Message.)
|
||||
|
||||
@return: a string.
|
||||
@rtype: string
|
||||
"""
|
||||
return u(self.get_bytes(self.get_size()))
|
||||
#return self.get_bytes(self.get_size())
|
||||
|
||||
def get_binary(self):
|
||||
"""
|
||||
Fetch a string from the stream. This could be a byte string and may
|
||||
contain unprintable characters. (It's not unheard of for a string to
|
||||
contain another byte-stream Message.)
|
||||
|
||||
@return: a string.
|
||||
@rtype: string
|
||||
"""
|
||||
return self.get_bytes(self.get_size())
|
||||
|
||||
def get_list(self):
|
||||
"""
|
||||
|
@ -182,7 +223,7 @@ class Message (object):
|
|||
@return: a list of strings.
|
||||
@rtype: list of strings
|
||||
"""
|
||||
return self.get_string().split(',')
|
||||
return self.get_text().split(',')
|
||||
|
||||
def add_bytes(self, b):
|
||||
"""
|
||||
|
@ -212,12 +253,12 @@ class Message (object):
|
|||
@type b: bool
|
||||
"""
|
||||
if b:
|
||||
self.add_byte('\x01')
|
||||
self.packet.write(one_byte)
|
||||
else:
|
||||
self.add_byte('\x00')
|
||||
self.packet.write(zero_byte)
|
||||
return self
|
||||
|
||||
def add_int(self, n):
|
||||
def add_size(self, n):
|
||||
"""
|
||||
Add an integer to the stream.
|
||||
|
||||
|
@ -227,6 +268,20 @@ class Message (object):
|
|||
self.packet.write(struct.pack('>I', n))
|
||||
return self
|
||||
|
||||
def add_int(self, n):
|
||||
"""
|
||||
Add an integer to the stream.
|
||||
|
||||
@param n: integer to add
|
||||
@type n: int
|
||||
"""
|
||||
if n >= Message.big_int:
|
||||
self.packet.write(max_byte)
|
||||
self.add_string(util.deflate_long(n))
|
||||
else:
|
||||
self.packet.write(struct.pack('>I', n))
|
||||
return self
|
||||
|
||||
def add_int64(self, n):
|
||||
"""
|
||||
Add a 64-bit int to the stream.
|
||||
|
@ -234,8 +289,7 @@ class Message (object):
|
|||
@param n: long int to add
|
||||
@type n: long
|
||||
"""
|
||||
self.packet.write(struct.pack('>Q', n))
|
||||
return self
|
||||
return self.add_int(n)
|
||||
|
||||
def add_mpint(self, z):
|
||||
"""
|
||||
|
@ -255,7 +309,8 @@ class Message (object):
|
|||
@param s: string to add
|
||||
@type s: str
|
||||
"""
|
||||
self.add_int(len(s))
|
||||
s = asbytes(s)
|
||||
self.add_size(len(s))
|
||||
self.packet.write(s)
|
||||
return self
|
||||
|
||||
|
@ -272,21 +327,14 @@ class Message (object):
|
|||
return self
|
||||
|
||||
def _add(self, i):
|
||||
if type(i) is str:
|
||||
return self.add_string(i)
|
||||
elif type(i) is int:
|
||||
return self.add_int(i)
|
||||
elif type(i) is long:
|
||||
if i > 0xffffffffL:
|
||||
return self.add_mpint(i)
|
||||
else:
|
||||
return self.add_int(i)
|
||||
elif type(i) is bool:
|
||||
if type(i) is bool:
|
||||
return self.add_boolean(i)
|
||||
elif isinstance(i, integer_types):
|
||||
return self.add_int(i)
|
||||
elif type(i) is list:
|
||||
return self.add_list(i)
|
||||
else:
|
||||
raise Exception('Unknown type')
|
||||
return self.add_string(i)
|
||||
|
||||
def add(self, *seq):
|
||||
"""
|
||||
|
|
|
@ -63,7 +63,7 @@ class PKey (object):
|
|||
"""
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
def asbytes(self):
|
||||
"""
|
||||
Return a string of an SSH L{Message} made up of the public part(s) of
|
||||
this key. This string is suitable for passing to L{__init__} to
|
||||
|
@ -72,7 +72,10 @@ class PKey (object):
|
|||
@return: string representation of an SSH key message.
|
||||
@rtype: str
|
||||
"""
|
||||
return ''
|
||||
return bytes()
|
||||
|
||||
def __str__(self):
|
||||
return self.asbytes()
|
||||
|
||||
def __cmp__(self, other):
|
||||
"""
|
||||
|
@ -90,7 +93,10 @@ class PKey (object):
|
|||
ho = hash(other)
|
||||
if hs != ho:
|
||||
return cmp(hs, ho)
|
||||
return cmp(str(self), str(other))
|
||||
return cmp(self.asbytes(), other.asbytes())
|
||||
|
||||
def __eq__(self, other):
|
||||
return hash(self) == hash(other)
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
|
@ -131,7 +137,7 @@ class PKey (object):
|
|||
format.
|
||||
@rtype: str
|
||||
"""
|
||||
return MD5.new(str(self)).digest()
|
||||
return MD5.new(self.asbytes()).digest()
|
||||
|
||||
def get_base64(self):
|
||||
"""
|
||||
|
@ -142,7 +148,7 @@ class PKey (object):
|
|||
@return: a base64 string containing the public part of the key.
|
||||
@rtype: str
|
||||
"""
|
||||
return base64.encodestring(str(self)).replace('\n', '')
|
||||
return base64.encodestring(self.asbytes()).replace('\n', '')
|
||||
|
||||
def sign_ssh_data(self, rng, data):
|
||||
"""
|
||||
|
@ -156,7 +162,7 @@ class PKey (object):
|
|||
@return: an SSH signature message.
|
||||
@rtype: L{Message}
|
||||
"""
|
||||
return ''
|
||||
return bytes()
|
||||
|
||||
def verify_ssh_sig(self, data, msg):
|
||||
"""
|
||||
|
@ -303,7 +309,7 @@ class PKey (object):
|
|||
end += 1
|
||||
# if we trudged to the end of the file, just try to cope.
|
||||
try:
|
||||
data = base64.decodestring(''.join(lines[start:end]))
|
||||
data = base64.decodestring(b(''.join(lines[start:end])))
|
||||
except base64.binascii.Error:
|
||||
raise SSHException('base64 decoding error: ' + str(sys.exc_info()[1]))
|
||||
if 'proc-type' not in headers:
|
||||
|
@ -356,7 +362,7 @@ class PKey (object):
|
|||
f.write('-----BEGIN %s PRIVATE KEY-----\n' % tag)
|
||||
if password is not None:
|
||||
# since we only support one cipher here, use it
|
||||
cipher_name = self._CIPHER_TABLE.keys()[0]
|
||||
cipher_name = list(self._CIPHER_TABLE.keys())[0]
|
||||
cipher = self._CIPHER_TABLE[cipher_name]['cipher']
|
||||
keysize = self._CIPHER_TABLE[cipher_name]['keysize']
|
||||
blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
|
||||
|
|
|
@ -57,18 +57,21 @@ class RSAKey (PKey):
|
|||
else:
|
||||
if msg is None:
|
||||
raise SSHException('Key object may not be empty')
|
||||
if msg.get_string() != 'ssh-rsa':
|
||||
if msg.get_text() != 'ssh-rsa':
|
||||
raise SSHException('Invalid key')
|
||||
self.e = msg.get_mpint()
|
||||
self.n = msg.get_mpint()
|
||||
self.size = util.bit_length(self.n)
|
||||
|
||||
def __str__(self):
|
||||
def asbytes(self):
|
||||
m = Message()
|
||||
m.add_string('ssh-rsa')
|
||||
m.add_mpint(self.e)
|
||||
m.add_mpint(self.n)
|
||||
return str(m)
|
||||
return m.asbytes()
|
||||
|
||||
def __str__(self):
|
||||
return self.asbytes()
|
||||
|
||||
def __hash__(self):
|
||||
h = hash(self.get_name())
|
||||
|
@ -95,9 +98,9 @@ class RSAKey (PKey):
|
|||
return m
|
||||
|
||||
def verify_ssh_sig(self, data, msg):
|
||||
if msg.get_string() != 'ssh-rsa':
|
||||
if msg.get_text() != 'ssh-rsa':
|
||||
return False
|
||||
sig = util.inflate_long(msg.get_string(), True)
|
||||
sig = util.inflate_long(msg.get_binary(), True)
|
||||
# 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.
|
||||
|
@ -116,7 +119,7 @@ class RSAKey (PKey):
|
|||
b.encode(keylist)
|
||||
except BERException:
|
||||
raise SSHException('Unable to create ber encoding of key')
|
||||
return str(b)
|
||||
return b.asbytes()
|
||||
|
||||
def write_private_key_file(self, filename, password=None):
|
||||
self._write_private_key_file('RSA', filename, self._encode_key(), password)
|
||||
|
|
|
@ -86,7 +86,7 @@ CMD_NAMES = {
|
|||
CMD_ATTRS: 'attrs',
|
||||
CMD_EXTENDED: 'extended',
|
||||
CMD_EXTENDED_REPLY: 'extended_reply'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SFTPError (Exception):
|
||||
|
@ -125,7 +125,7 @@ class BaseSFTP (object):
|
|||
msg = Message()
|
||||
msg.add_int(_VERSION)
|
||||
msg.add(*extension_pairs)
|
||||
self._send_packet(CMD_VERSION, str(msg))
|
||||
self._send_packet(CMD_VERSION, msg)
|
||||
return version
|
||||
|
||||
def _log(self, level, msg, *args):
|
||||
|
@ -167,6 +167,7 @@ class BaseSFTP (object):
|
|||
def _send_packet(self, t, packet):
|
||||
#self._log(DEBUG2, 'write: %s (len=%d)' % (CMD_NAMES.get(t, '0x%02x' % t), len(packet)))
|
||||
out = struct.pack('>I', len(packet) + 1) + chr(t) + packet
|
||||
packet = asbytes(packet)
|
||||
if self.ultra_debug:
|
||||
self._log(DEBUG, util.format_binary(out, 'OUT: '))
|
||||
self._write_all(out)
|
||||
|
|
|
@ -173,7 +173,7 @@ class SFTPClient (BaseSFTP):
|
|||
t, msg = self._request(CMD_OPENDIR, path)
|
||||
if t != CMD_HANDLE:
|
||||
raise SFTPError('Expected handle')
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
filelist = []
|
||||
while True:
|
||||
try:
|
||||
|
@ -245,7 +245,7 @@ class SFTPClient (BaseSFTP):
|
|||
t, msg = self._request(CMD_OPEN, filename, imode, attrblock)
|
||||
if t != CMD_HANDLE:
|
||||
raise SFTPError('Expected handle')
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
self._log(DEBUG, 'open(%r, %r) -> %s' % (filename, mode, hexlify(handle)))
|
||||
return SFTPFile(self, handle, mode, bufsize)
|
||||
|
||||
|
@ -369,8 +369,7 @@ class SFTPClient (BaseSFTP):
|
|||
"""
|
||||
dest = self._adjust_cwd(dest)
|
||||
self._log(DEBUG, 'symlink(%r, %r)' % (source, dest))
|
||||
if type(source) is unicode:
|
||||
source = source.encode('utf-8')
|
||||
source = bytestring(source)
|
||||
self._request(CMD_SYMLINK, source, dest)
|
||||
|
||||
def chmod(self, path, mode):
|
||||
|
@ -610,7 +609,7 @@ class SFTPClient (BaseSFTP):
|
|||
@since: 1.4
|
||||
"""
|
||||
file_size = os.stat(localpath).st_size
|
||||
fl = file(localpath, 'rb')
|
||||
fl = open(localpath, 'rb')
|
||||
try:
|
||||
return self.putfo(fl, remotepath, os.stat(localpath).st_size, callback, confirm)
|
||||
finally:
|
||||
|
@ -636,7 +635,7 @@ class SFTPClient (BaseSFTP):
|
|||
|
||||
@since: 1.4
|
||||
"""
|
||||
fr = self.file(remotepath, 'rb')
|
||||
fr = self.open(remotepath, 'rb')
|
||||
file_size = self.stat(remotepath).st_size
|
||||
fr.prefetch()
|
||||
try:
|
||||
|
@ -671,7 +670,7 @@ class SFTPClient (BaseSFTP):
|
|||
@since: 1.4
|
||||
"""
|
||||
file_size = self.stat(remotepath).st_size
|
||||
fl = file(localpath, 'wb')
|
||||
fl = open(localpath, 'wb')
|
||||
try:
|
||||
size = self.getfo(remotepath, fl, callback)
|
||||
finally:
|
||||
|
@ -707,7 +706,7 @@ class SFTPClient (BaseSFTP):
|
|||
raise Exception('unknown type for %r type %r' % (item, type(item)))
|
||||
num = self.request_number
|
||||
self._expecting[num] = fileobj
|
||||
self._send_packet(t, str(msg))
|
||||
self._send_packet(t, msg)
|
||||
self.request_number += 1
|
||||
finally:
|
||||
self._lock.release()
|
||||
|
@ -752,7 +751,7 @@ class SFTPClient (BaseSFTP):
|
|||
Raises EOFError or IOError on error status; otherwise does nothing.
|
||||
"""
|
||||
code = msg.get_int()
|
||||
text = msg.get_string()
|
||||
text = msg.get_text()
|
||||
if code == SFTP_OK:
|
||||
return
|
||||
elif code == SFTP_EOF:
|
||||
|
@ -770,8 +769,7 @@ class SFTPClient (BaseSFTP):
|
|||
Return an adjusted path if we're emulating a "current working
|
||||
directory" for the server.
|
||||
"""
|
||||
if type(path) is unicode:
|
||||
path = path.encode('utf-8')
|
||||
path = bytestring(path)
|
||||
if self._cwd is None:
|
||||
return path
|
||||
if (len(path) > 0) and (path[0] == '/'):
|
||||
|
|
|
@ -348,8 +348,8 @@ class SFTPFile (BufferedFile):
|
|||
"""
|
||||
t, msg = self.sftp._request(CMD_EXTENDED, 'check-file', self.handle,
|
||||
hash_algorithm, long(offset), long(length), block_size)
|
||||
ext = msg.get_string()
|
||||
alg = msg.get_string()
|
||||
ext = msg.get_text()
|
||||
alg = msg.get_text()
|
||||
data = msg.get_remainder()
|
||||
return data
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
item._pack(msg)
|
||||
else:
|
||||
raise Exception('unknown type for ' + repr(item) + ' type ' + repr(type(item)))
|
||||
self._send_packet(t, str(msg))
|
||||
self._send_packet(t, msg)
|
||||
|
||||
def _send_handle_response(self, request_number, handle, folder=False):
|
||||
if not issubclass(type(handle), SFTPHandle):
|
||||
|
@ -236,14 +236,14 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
msg.add_string(attr.filename)
|
||||
msg.add_string(str(attr))
|
||||
attr._pack(msg)
|
||||
self._send_packet(CMD_NAME, str(msg))
|
||||
self._send_packet(CMD_NAME, msg)
|
||||
|
||||
def _check_file(self, request_number, msg):
|
||||
# this extension actually comes from v6 protocol, but since it's an
|
||||
# extension, i feel like we can reasonably support it backported.
|
||||
# it's very useful for verifying uploaded files or checking for
|
||||
# rsync-like differences between local and remote files.
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
alg_list = msg.get_list()
|
||||
start = msg.get_int64()
|
||||
length = msg.get_int64()
|
||||
|
@ -295,7 +295,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
msg.add_string('check-file')
|
||||
msg.add_string(algname)
|
||||
msg.add_bytes(sum_out)
|
||||
self._send_packet(CMD_EXTENDED_REPLY, str(msg))
|
||||
self._send_packet(CMD_EXTENDED_REPLY, msg)
|
||||
|
||||
def _convert_pflags(self, pflags):
|
||||
"convert SFTP-style open() flags to python's os.open() flags"
|
||||
|
@ -318,12 +318,12 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
def _process(self, t, request_number, msg):
|
||||
self._log(DEBUG, 'Request: %s' % CMD_NAMES[t])
|
||||
if t == CMD_OPEN:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
flags = self._convert_pflags(msg.get_int())
|
||||
attr = SFTPAttributes._from_msg(msg)
|
||||
self._send_handle_response(request_number, self.server.open(path, flags, attr))
|
||||
elif t == CMD_CLOSE:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
if handle in self.folder_table:
|
||||
del self.folder_table[handle]
|
||||
self._send_status(request_number, SFTP_OK)
|
||||
|
@ -335,7 +335,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
return
|
||||
self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
|
||||
elif t == CMD_READ:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
offset = msg.get_int64()
|
||||
length = msg.get_int()
|
||||
if handle not in self.file_table:
|
||||
|
@ -350,54 +350,54 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
else:
|
||||
self._send_status(request_number, data)
|
||||
elif t == CMD_WRITE:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
offset = msg.get_int64()
|
||||
data = msg.get_string()
|
||||
data = msg.get_binary()
|
||||
if handle not in self.file_table:
|
||||
self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
|
||||
return
|
||||
self._send_status(request_number, self.file_table[handle].write(offset, data))
|
||||
elif t == CMD_REMOVE:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
self._send_status(request_number, self.server.remove(path))
|
||||
elif t == CMD_RENAME:
|
||||
oldpath = msg.get_string()
|
||||
newpath = msg.get_string()
|
||||
oldpath = msg.get_text()
|
||||
newpath = msg.get_text()
|
||||
self._send_status(request_number, self.server.rename(oldpath, newpath))
|
||||
elif t == CMD_MKDIR:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
attr = SFTPAttributes._from_msg(msg)
|
||||
self._send_status(request_number, self.server.mkdir(path, attr))
|
||||
elif t == CMD_RMDIR:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
self._send_status(request_number, self.server.rmdir(path))
|
||||
elif t == CMD_OPENDIR:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
self._open_folder(request_number, path)
|
||||
return
|
||||
elif t == CMD_READDIR:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
if handle not in self.folder_table:
|
||||
self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
|
||||
return
|
||||
folder = self.folder_table[handle]
|
||||
self._read_folder(request_number, folder)
|
||||
elif t == CMD_STAT:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
resp = self.server.stat(path)
|
||||
if issubclass(type(resp), SFTPAttributes):
|
||||
self._response(request_number, CMD_ATTRS, resp)
|
||||
else:
|
||||
self._send_status(request_number, resp)
|
||||
elif t == CMD_LSTAT:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
resp = self.server.lstat(path)
|
||||
if issubclass(type(resp), SFTPAttributes):
|
||||
self._response(request_number, CMD_ATTRS, resp)
|
||||
else:
|
||||
self._send_status(request_number, resp)
|
||||
elif t == CMD_FSTAT:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
if handle not in self.file_table:
|
||||
self._send_status(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
|
||||
return
|
||||
|
@ -407,18 +407,18 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
else:
|
||||
self._send_status(request_number, resp)
|
||||
elif t == CMD_SETSTAT:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
attr = SFTPAttributes._from_msg(msg)
|
||||
self._send_status(request_number, self.server.chattr(path, attr))
|
||||
elif t == CMD_FSETSTAT:
|
||||
handle = msg.get_string()
|
||||
handle = msg.get_binary()
|
||||
attr = SFTPAttributes._from_msg(msg)
|
||||
if handle not in self.file_table:
|
||||
self._response(request_number, SFTP_BAD_MESSAGE, 'Invalid handle')
|
||||
return
|
||||
self._send_status(request_number, self.file_table[handle].chattr(attr))
|
||||
elif t == CMD_READLINK:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
resp = self.server.readlink(path)
|
||||
if type(resp) is str:
|
||||
self._response(request_number, CMD_NAME, 1, resp, '', SFTPAttributes())
|
||||
|
@ -426,15 +426,15 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
|||
self._send_status(request_number, resp)
|
||||
elif t == CMD_SYMLINK:
|
||||
# the sftp 2 draft is incorrect here! path always follows target_path
|
||||
target_path = msg.get_string()
|
||||
path = msg.get_string()
|
||||
target_path = msg.get_text()
|
||||
path = msg.get_text()
|
||||
self._send_status(request_number, self.server.symlink(target_path, path))
|
||||
elif t == CMD_REALPATH:
|
||||
path = msg.get_string()
|
||||
path = msg.get_text()
|
||||
rpath = self.server.canonicalize(path)
|
||||
self._response(request_number, CMD_NAME, 1, rpath, '', SFTPAttributes())
|
||||
elif t == CMD_EXTENDED:
|
||||
tag = msg.get_string()
|
||||
tag = msg.get_text()
|
||||
if tag == 'check-file':
|
||||
self._check_file(request_number, msg)
|
||||
else:
|
||||
|
|
|
@ -112,8 +112,8 @@ class SecurityOptions (object):
|
|||
x = tuple(x)
|
||||
if type(x) is not tuple:
|
||||
raise TypeError('expected tuple or list')
|
||||
possible = getattr(self._transport, orig).keys()
|
||||
forbidden = filter(lambda n: n not in possible, x)
|
||||
possible = list(getattr(self._transport, orig).keys())
|
||||
forbidden = [n for n in x if n not in possible]
|
||||
if len(forbidden) > 0:
|
||||
raise ValueError('unknown cipher')
|
||||
setattr(self._transport, name, x)
|
||||
|
@ -276,7 +276,7 @@ class Transport (threading.Thread):
|
|||
@param sock: a socket or socket-like object to create the session over.
|
||||
@type sock: socket
|
||||
"""
|
||||
if isinstance(sock, (str, unicode)):
|
||||
if isinstance(sock, string_types):
|
||||
# convert "host:port" into (host, port)
|
||||
hl = sock.split(':', 1)
|
||||
if len(hl) == 1:
|
||||
|
@ -735,7 +735,7 @@ class Transport (threading.Thread):
|
|||
try:
|
||||
chanid = self._next_channel()
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_OPEN))
|
||||
m.add_byte(cMSG_CHANNEL_OPEN)
|
||||
m.add_string(kind)
|
||||
m.add_int(chanid)
|
||||
m.add_int(self.window_size)
|
||||
|
@ -861,7 +861,7 @@ class Transport (threading.Thread):
|
|||
@type byte_count: int
|
||||
"""
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_IGNORE))
|
||||
m.add_byte(cMSG_IGNORE)
|
||||
if byte_count is None:
|
||||
byte_count = (byte_ord(rng.read(1)) % 32) + 10
|
||||
m.add_bytes(rng.read(byte_count))
|
||||
|
@ -927,7 +927,7 @@ class Transport (threading.Thread):
|
|||
if wait:
|
||||
self.completion_event = threading.Event()
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_GLOBAL_REQUEST))
|
||||
m.add_byte(cMSG_GLOBAL_REQUEST)
|
||||
m.add_string(kind)
|
||||
m.add_boolean(wait)
|
||||
if data is not None:
|
||||
|
@ -1013,10 +1013,10 @@ class Transport (threading.Thread):
|
|||
# check host key if we were given one
|
||||
if (hostkey is not None):
|
||||
key = self.get_remote_server_key()
|
||||
if (key.get_name() != hostkey.get_name()) or (str(key) != str(hostkey)):
|
||||
if (key.get_name() != hostkey.get_name()) or (key.asbytes() != hostkey.asbytes()):
|
||||
self._log(DEBUG, 'Bad host key from server')
|
||||
self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(str(hostkey))))
|
||||
self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(str(key))))
|
||||
self._log(DEBUG, 'Expected: %s: %s' % (hostkey.get_name(), repr(hostkey.asbytes())))
|
||||
self._log(DEBUG, 'Got : %s: %s' % (key.get_name(), repr(key.asbytes())))
|
||||
raise SSHException('Bad host key from server')
|
||||
self._log(DEBUG, 'Host key verified (%s)' % hostkey.get_name())
|
||||
|
||||
|
@ -1476,15 +1476,15 @@ class Transport (threading.Thread):
|
|||
m = Message()
|
||||
m.add_mpint(self.K)
|
||||
m.add_bytes(self.H)
|
||||
m.add_byte(id)
|
||||
m.add_byte(b(id))
|
||||
m.add_bytes(self.session_id)
|
||||
out = sofar = SHA.new(str(m)).digest()
|
||||
out = sofar = SHA.new(m.asbytes()).digest()
|
||||
while len(out) < nbytes:
|
||||
m = Message()
|
||||
m.add_mpint(self.K)
|
||||
m.add_bytes(self.H)
|
||||
m.add_bytes(sofar)
|
||||
digest = SHA.new(str(m)).digest()
|
||||
digest = SHA.new(m.asbytes()).digest()
|
||||
out += digest
|
||||
sofar += digest
|
||||
return out[:nbytes]
|
||||
|
@ -1606,7 +1606,7 @@ class Transport (threading.Thread):
|
|||
else:
|
||||
self._log(WARNING, 'Oops, unhandled type %d' % ptype)
|
||||
msg = Message()
|
||||
msg.add_byte(chr(MSG_UNIMPLEMENTED))
|
||||
msg.add_byte(cMSG_UNIMPLEMENTED)
|
||||
msg.add_int(m.seqno)
|
||||
self._send_message(msg)
|
||||
except SSHException:
|
||||
|
@ -1633,7 +1633,7 @@ class Transport (threading.Thread):
|
|||
self._log(ERROR, util.tb_strings())
|
||||
self.saved_exception = e
|
||||
_active_threads.remove(self)
|
||||
for chan in self._channels.values():
|
||||
for chan in list(self._channels.values()):
|
||||
chan._unlink()
|
||||
if self.active:
|
||||
self.active = False
|
||||
|
@ -1642,7 +1642,7 @@ class Transport (threading.Thread):
|
|||
self.completion_event.set()
|
||||
if self.auth_handler is not None:
|
||||
self.auth_handler.abort()
|
||||
for event in self.channel_events.values():
|
||||
for event in list(self.channel_events.values()):
|
||||
event.set()
|
||||
try:
|
||||
self.lock.acquire()
|
||||
|
@ -1731,13 +1731,13 @@ class Transport (threading.Thread):
|
|||
pkex = list(self.get_security_options().kex)
|
||||
pkex.remove('diffie-hellman-group-exchange-sha1')
|
||||
self.get_security_options().kex = pkex
|
||||
available_server_keys = filter(self.server_key_dict.keys().__contains__,
|
||||
self._preferred_keys)
|
||||
available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
|
||||
self._preferred_keys))
|
||||
else:
|
||||
available_server_keys = self._preferred_keys
|
||||
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_KEXINIT))
|
||||
m.add_byte(cMSG_KEXINIT)
|
||||
m.add_bytes(rng.read(16))
|
||||
m.add_list(self._preferred_kex)
|
||||
m.add_list(available_server_keys)
|
||||
|
@ -1752,7 +1752,7 @@ class Transport (threading.Thread):
|
|||
m.add_boolean(False)
|
||||
m.add_int(0)
|
||||
# save a copy for later (needed to compute a hash)
|
||||
self.local_kex_init = str(m)
|
||||
self.local_kex_init = m.asbytes()
|
||||
self._send_message(m)
|
||||
|
||||
def _parse_kex_init(self, m):
|
||||
|
@ -1850,7 +1850,7 @@ class Transport (threading.Thread):
|
|||
# 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
|
||||
# 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 = cMSG_KEXINIT + m.get_so_far()
|
||||
|
||||
def _activate_inbound(self):
|
||||
"switch on newly negotiated encryption parameters for inbound traffic"
|
||||
|
@ -1879,7 +1879,7 @@ class Transport (threading.Thread):
|
|||
def _activate_outbound(self):
|
||||
"switch on newly negotiated encryption parameters for outbound traffic"
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_NEWKEYS))
|
||||
m.add_byte(cMSG_NEWKEYS)
|
||||
self._send_message(m)
|
||||
block_size = self._cipher_info[self.local_cipher]['block-size']
|
||||
if self.server_mode:
|
||||
|
@ -1952,20 +1952,20 @@ class Transport (threading.Thread):
|
|||
self._log(INFO, 'Disconnect (code %d): %s' % (code, desc))
|
||||
|
||||
def _parse_global_request(self, m):
|
||||
kind = m.get_string()
|
||||
kind = m.get_text()
|
||||
self._log(DEBUG, 'Received global request "%s"' % kind)
|
||||
want_reply = m.get_boolean()
|
||||
if not self.server_mode:
|
||||
self._log(DEBUG, 'Rejecting "%s" global request from server.' % kind)
|
||||
ok = False
|
||||
elif kind == 'tcpip-forward':
|
||||
address = m.get_string()
|
||||
address = m.get_text()
|
||||
port = m.get_int()
|
||||
ok = self.server_object.check_port_forward_request(address, port)
|
||||
if ok != False:
|
||||
ok = (ok,)
|
||||
elif kind == 'cancel-tcpip-forward':
|
||||
address = m.get_string()
|
||||
address = m.get_text()
|
||||
port = m.get_int()
|
||||
self.server_object.cancel_port_forward_request(address, port)
|
||||
ok = True
|
||||
|
@ -1978,10 +1978,10 @@ class Transport (threading.Thread):
|
|||
if want_reply:
|
||||
msg = Message()
|
||||
if ok:
|
||||
msg.add_byte(chr(MSG_REQUEST_SUCCESS))
|
||||
msg.add_byte(cMSG_REQUEST_SUCCESS)
|
||||
msg.add(*extra)
|
||||
else:
|
||||
msg.add_byte(chr(MSG_REQUEST_FAILURE))
|
||||
msg.add_byte(cMSG_REQUEST_FAILURE)
|
||||
self._send_message(msg)
|
||||
|
||||
def _parse_request_success(self, m):
|
||||
|
@ -2019,8 +2019,8 @@ class Transport (threading.Thread):
|
|||
def _parse_channel_open_failure(self, m):
|
||||
chanid = m.get_int()
|
||||
reason = m.get_int()
|
||||
reason_str = m.get_string()
|
||||
lang = m.get_string()
|
||||
reason_str = m.get_text()
|
||||
lang = m.get_text()
|
||||
reason_text = CONNECTION_FAILED_CODE.get(reason, '(unknown code)')
|
||||
self._log(INFO, 'Secsh channel %d open FAILED: %s: %s' % (chanid, reason_str, reason_text))
|
||||
self.lock.acquire()
|
||||
|
@ -2036,7 +2036,7 @@ class Transport (threading.Thread):
|
|||
return
|
||||
|
||||
def _parse_channel_open(self, m):
|
||||
kind = m.get_string()
|
||||
kind = m.get_text()
|
||||
chanid = m.get_int()
|
||||
initial_window_size = m.get_int()
|
||||
max_packet_size = m.get_int()
|
||||
|
@ -2049,7 +2049,7 @@ class Transport (threading.Thread):
|
|||
finally:
|
||||
self.lock.release()
|
||||
elif (kind == 'x11') and (self._x11_handler is not None):
|
||||
origin_addr = m.get_string()
|
||||
origin_addr = m.get_text()
|
||||
origin_port = m.get_int()
|
||||
self._log(DEBUG, 'Incoming x11 connection from %s:%d' % (origin_addr, origin_port))
|
||||
self.lock.acquire()
|
||||
|
@ -2058,9 +2058,9 @@ class Transport (threading.Thread):
|
|||
finally:
|
||||
self.lock.release()
|
||||
elif (kind == 'forwarded-tcpip') and (self._tcp_handler is not None):
|
||||
server_addr = m.get_string()
|
||||
server_addr = m.get_text()
|
||||
server_port = m.get_int()
|
||||
origin_addr = m.get_string()
|
||||
origin_addr = m.get_text()
|
||||
origin_port = m.get_int()
|
||||
self._log(DEBUG, 'Incoming tcp forwarded connection from %s:%d' % (origin_addr, origin_port))
|
||||
self.lock.acquire()
|
||||
|
@ -2080,9 +2080,9 @@ class Transport (threading.Thread):
|
|||
self.lock.release()
|
||||
if kind == 'direct-tcpip':
|
||||
# handle direct-tcpip requests comming from the client
|
||||
dest_addr = m.get_string()
|
||||
dest_addr = m.get_text()
|
||||
dest_port = m.get_int()
|
||||
origin_addr = m.get_string()
|
||||
origin_addr = m.get_text()
|
||||
origin_port = m.get_int()
|
||||
reason = self.server_object.check_channel_direct_tcpip_request(
|
||||
my_chanid, (origin_addr, origin_port),
|
||||
|
@ -2094,7 +2094,7 @@ class Transport (threading.Thread):
|
|||
reject = True
|
||||
if reject:
|
||||
msg = Message()
|
||||
msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
|
||||
msg.add_byte(cMSG_CHANNEL_OPEN_FAILURE)
|
||||
msg.add_int(chanid)
|
||||
msg.add_int(reason)
|
||||
msg.add_string('')
|
||||
|
@ -2113,7 +2113,7 @@ class Transport (threading.Thread):
|
|||
finally:
|
||||
self.lock.release()
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
|
||||
m.add_byte(cMSG_CHANNEL_OPEN_SUCCESS)
|
||||
m.add_int(chanid)
|
||||
m.add_int(my_chanid)
|
||||
m.add_int(self.window_size)
|
||||
|
|
|
@ -111,8 +111,8 @@ class AuthTest (unittest.TestCase):
|
|||
self.sockc.close()
|
||||
|
||||
def start_server(self):
|
||||
self.public_host_key = RSAKey(data=str(host_key))
|
||||
host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
self.public_host_key = RSAKey(data=host_key.asbytes())
|
||||
self.ts.add_server_key(host_key)
|
||||
self.event = threading.Event()
|
||||
self.server = NullServer()
|
||||
|
|
|
@ -86,8 +86,8 @@ class SSHClientTest (unittest.TestCase):
|
|||
"""
|
||||
verify that the SSHClient stuff works too.
|
||||
"""
|
||||
public_host_key = paramiko.RSAKey(data=str(host_key))
|
||||
host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = paramiko.RSAKey(data=host_key.asbytes())
|
||||
|
||||
self.tc = paramiko.SSHClient()
|
||||
self.tc.get_host_keys().add('[%s]:%d' % (self.addr, self.port), 'ssh-rsa', public_host_key)
|
||||
|
@ -119,8 +119,8 @@ class SSHClientTest (unittest.TestCase):
|
|||
"""
|
||||
verify that SSHClient works with a DSA key.
|
||||
"""
|
||||
public_host_key = paramiko.RSAKey(data=str(host_key))
|
||||
host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = paramiko.RSAKey(data=host_key.asbytes())
|
||||
|
||||
self.tc = paramiko.SSHClient()
|
||||
self.tc.get_host_keys().add('[%s]:%d' % (self.addr, self.port), 'ssh-rsa', public_host_key)
|
||||
|
@ -152,8 +152,8 @@ class SSHClientTest (unittest.TestCase):
|
|||
"""
|
||||
verify that SSHClient accepts and tries multiple key files.
|
||||
"""
|
||||
public_host_key = paramiko.RSAKey(data=str(host_key))
|
||||
host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = paramiko.RSAKey(data=host_key.asbytes())
|
||||
|
||||
self.tc = paramiko.SSHClient()
|
||||
self.tc.get_host_keys().add('[%s]:%d' % (self.addr, self.port), 'ssh-rsa', public_host_key)
|
||||
|
@ -169,8 +169,8 @@ class SSHClientTest (unittest.TestCase):
|
|||
"""
|
||||
verify that SSHClient's AutoAddPolicy works.
|
||||
"""
|
||||
public_host_key = paramiko.RSAKey(data=str(host_key))
|
||||
host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = paramiko.RSAKey(data=host_key.asbytes())
|
||||
|
||||
self.tc = paramiko.SSHClient()
|
||||
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
@ -190,8 +190,8 @@ class SSHClientTest (unittest.TestCase):
|
|||
verify that when an SSHClient is collected, its transport (and the
|
||||
transport's packetizer) is closed.
|
||||
"""
|
||||
public_host_key = paramiko.RSAKey(data=str(host_key))
|
||||
host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = paramiko.RSAKey(data=host_key.asbytes())
|
||||
|
||||
self.tc = paramiko.SSHClient()
|
||||
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
|
|
@ -65,8 +65,8 @@ class HostKeysTest (unittest.TestCase):
|
|||
def test_1_load(self):
|
||||
hostdict = paramiko.HostKeys('hostfile.temp')
|
||||
self.assertEquals(2, len(hostdict))
|
||||
self.assertEquals(1, len(hostdict.values()[0]))
|
||||
self.assertEquals(1, len(hostdict.values()[1]))
|
||||
self.assertEquals(1, len(list(hostdict.values())[0]))
|
||||
self.assertEquals(1, len(list(hostdict.values())[1]))
|
||||
fp = hexlify(hostdict['secure.example.com']['ssh-rsa'].get_fingerprint()).upper()
|
||||
self.assertEquals('E6684DB30E109B67B70FF1DC5C7F1363', fp)
|
||||
|
||||
|
@ -75,7 +75,7 @@ class HostKeysTest (unittest.TestCase):
|
|||
hh = '|1|BMsIC6cUIP2zBuXR3t2LRcJYjzM=|hpkJMysjTk/+zzUUzxQEa2ieq6c='
|
||||
key = paramiko.RSAKey(data=base64.decodestring(keyblob))
|
||||
hostdict.add(hh, 'ssh-rsa', key)
|
||||
self.assertEquals(3, len(hostdict))
|
||||
self.assertEquals(3, len(list(hostdict)))
|
||||
x = hostdict['foo.example.com']
|
||||
fp = hexlify(x['ssh-rsa'].get_fingerprint()).upper()
|
||||
self.assertEquals('7EC91BB336CB6D810B124B1353C32396', fp)
|
||||
|
@ -85,8 +85,8 @@ class HostKeysTest (unittest.TestCase):
|
|||
hostdict = paramiko.HostKeys('hostfile.temp')
|
||||
self.assert_('secure.example.com' in hostdict)
|
||||
self.assert_('not.example.com' not in hostdict)
|
||||
self.assert_(hostdict.has_key('secure.example.com'))
|
||||
self.assert_(not hostdict.has_key('not.example.com'))
|
||||
self.assert_('secure.example.com' in hostdict)
|
||||
self.assert_('not.example.com' not in hostdict)
|
||||
x = hostdict.get('secure.example.com', None)
|
||||
self.assert_(x is not None)
|
||||
fp = hexlify(x['ssh-rsa'].get_fingerprint()).upper()
|
||||
|
@ -108,9 +108,9 @@ class HostKeysTest (unittest.TestCase):
|
|||
hostdict['fake.example.com']['ssh-rsa'] = key
|
||||
|
||||
self.assertEquals(3, len(hostdict))
|
||||
self.assertEquals(2, len(hostdict.values()[0]))
|
||||
self.assertEquals(1, len(hostdict.values()[1]))
|
||||
self.assertEquals(1, len(hostdict.values()[2]))
|
||||
self.assertEquals(2, len(list(hostdict.values())[0]))
|
||||
self.assertEquals(1, len(list(hostdict.values())[1]))
|
||||
self.assertEquals(1, len(list(hostdict.values())[2]))
|
||||
fp = hexlify(hostdict['secure.example.com']['ssh-rsa'].get_fingerprint()).upper()
|
||||
self.assertEquals('7EC91BB336CB6D810B124B1353C32396', fp)
|
||||
fp = hexlify(hostdict['secure.example.com']['ssh-dss'].get_fingerprint()).upper()
|
||||
|
|
|
@ -37,6 +37,8 @@ class FakeRng (object):
|
|||
class FakeKey (object):
|
||||
def __str__(self):
|
||||
return 'fake-key'
|
||||
def asbytes(self):
|
||||
return b('fake-key')
|
||||
def sign_ssh_data(self, rng, H):
|
||||
return 'fake-sig'
|
||||
|
||||
|
@ -90,7 +92,7 @@ class KexTest (unittest.TestCase):
|
|||
kex = KexGroup1(transport)
|
||||
kex.start_kex()
|
||||
x = '1E000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_group1._MSG_KEXDH_REPLY,), transport._expect)
|
||||
|
||||
# fake "reply"
|
||||
|
@ -121,7 +123,7 @@ class KexTest (unittest.TestCase):
|
|||
x = '1F0000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967'
|
||||
self.assertEquals(self.K, transport._K)
|
||||
self.assertEquals(H, hexlify(transport._H).upper())
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assert_(transport._activated)
|
||||
|
||||
def test_3_gex_client(self):
|
||||
|
@ -130,7 +132,7 @@ class KexTest (unittest.TestCase):
|
|||
kex = KexGex(transport)
|
||||
kex.start_kex()
|
||||
x = '22000004000000080000002000'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_GROUP,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
|
@ -139,7 +141,7 @@ class KexTest (unittest.TestCase):
|
|||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
|
||||
x = '20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
|
@ -160,7 +162,7 @@ class KexTest (unittest.TestCase):
|
|||
kex = KexGex(transport)
|
||||
kex.start_kex(_test_old_style=True)
|
||||
x = '1E00000800'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_GROUP,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
|
@ -169,7 +171,7 @@ class KexTest (unittest.TestCase):
|
|||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_GROUP, msg)
|
||||
x = '20000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D4'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_REPLY,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
|
@ -198,19 +200,19 @@ class KexTest (unittest.TestCase):
|
|||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST, msg)
|
||||
x = '1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
msg.add_mpint(12345)
|
||||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
|
||||
K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581L
|
||||
K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
|
||||
H = 'CE754197C21BF3452863B4F44D0B3951F12516EF'
|
||||
x = '210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967'
|
||||
self.assertEquals(K, transport._K)
|
||||
self.assertEquals(H, hexlify(transport._H).upper())
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assert_(transport._activated)
|
||||
|
||||
def test_6_gex_server_with_old_client(self):
|
||||
|
@ -225,17 +227,17 @@ class KexTest (unittest.TestCase):
|
|||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_REQUEST_OLD, msg)
|
||||
x = '1F0000008100FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF0000000102'
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assertEquals((paramiko.kex_gex._MSG_KEXDH_GEX_INIT,), transport._expect)
|
||||
|
||||
msg = Message()
|
||||
msg.add_mpint(12345)
|
||||
msg.rewind()
|
||||
kex.parse_next(paramiko.kex_gex._MSG_KEXDH_GEX_INIT, msg)
|
||||
K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581L
|
||||
K = 67592995013596137876033460028393339951879041140378510871612128162185209509220726296697886624612526735888348020498716482757677848959420073720160491114319163078862905400020959196386947926388406687288901564192071077389283980347784184487280885335302632305026248574716290537036069329724382811853044654824945750581
|
||||
H = 'B41A06B2E59043CEFC1AE16EC31F1E2D12EC455B'
|
||||
x = '210000000866616B652D6B6579000000807E2DDB1743F3487D6545F04F1C8476092FB912B013626AB5BCEB764257D88BBA64243B9F348DF7B41B8C814A995E00299913503456983FFB9178D3CD79EB6D55522418A8ABF65375872E55938AB99A84A0B5FC8A1ECC66A7C3766E7E0F80B7CE2C9225FC2DD683F4764244B72963BBB383F529DCF0C5D17740B8A2ADBE9208D40000000866616B652D736967'
|
||||
self.assertEquals(K, transport._K)
|
||||
self.assertEquals(H, hexlify(transport._H).upper())
|
||||
self.assertEquals(x, hexlify(str(transport._message)).upper())
|
||||
self.assertEquals(x, hexlify(transport._message.asbytes()).upper())
|
||||
self.assert_(transport._activated)
|
||||
|
|
|
@ -27,10 +27,16 @@ from paramiko.common import *
|
|||
|
||||
class MessageTest (unittest.TestCase):
|
||||
|
||||
__a = '\x00\x00\x00\x17\x07\x60\xe0\x90\x00\x00\x00\x01q\x00\x00\x00\x05hello\x00\x00\x03\xe8' + ('x' * 1000)
|
||||
__b = '\x01\x00\xf3\x00\x3f\x00\x00\x00\x10huey,dewey,louie'
|
||||
__c = '\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x01\x11\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x06\x9a\x1b\x2c\x3d\x4e\xf7'
|
||||
__d = '\x00\x00\x00\x05\x00\x00\x00\x05\x11\x22\x33\x44\x55\x01\x00\x00\x00\x03cat\x00\x00\x00\x03a,b'
|
||||
if PY3:
|
||||
__a = b'\x00\x00\x00\x17\x07\x60\xe0\x90\x00\x00\x00\x01q\x00\x00\x00\x05hello\x00\x00\x03\xe8' + (b'x' * 1000)
|
||||
__b = b'\x01\x00\xf3\x00\x3f\x00\x00\x00\x10huey,dewey,louie'
|
||||
__c = b'\x00\x00\x00\x05\xff\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x01\x11\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x06\x9a\x1b\x2c\x3d\x4e\xf7'
|
||||
__d = b'\x00\x00\x00\x05\xff\x00\x00\x00\x05\x11\x22\x33\x44\x55\xff\x00\x00\x00\x0a\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03cat\x00\x00\x00\x03a,b'
|
||||
else:
|
||||
__a = '\x00\x00\x00\x17\x07\x60\xe0\x90\x00\x00\x00\x01q\x00\x00\x00\x05hello\x00\x00\x03\xe8' + ('x' * 1000)
|
||||
__b = '\x01\x00\xf3\x00\x3f\x00\x00\x00\x10huey,dewey,louie'
|
||||
__c = '\x00\x00\x00\x05\xff\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x01\x11\x00\x00\x00\x07\x00\xf5\xe4\xd3\xc2\xb1\x09\x00\x00\x00\x06\x9a\x1b\x2c\x3d\x4e\xf7'
|
||||
__d = '\x00\x00\x00\x05\xff\x00\x00\x00\x05\x11\x22\x33\x44\x55\xff\x00\x00\x00\x0a\x00\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03cat\x00\x00\x00\x03a,b'
|
||||
|
||||
def test_1_encode(self):
|
||||
msg = Message()
|
||||
|
@ -39,63 +45,65 @@ class MessageTest (unittest.TestCase):
|
|||
msg.add_string('q')
|
||||
msg.add_string('hello')
|
||||
msg.add_string('x' * 1000)
|
||||
self.assertEquals(str(msg), self.__a)
|
||||
self.assertEquals(msg.asbytes(), self.__a)
|
||||
|
||||
msg = Message()
|
||||
msg.add_boolean(True)
|
||||
msg.add_boolean(False)
|
||||
msg.add_byte('\xf3')
|
||||
msg.add_bytes('\x00\x3f')
|
||||
msg.add_byte(byte_chr(0xf3))
|
||||
|
||||
msg.add_bytes(zero_byte + byte_chr(0x3f))
|
||||
msg.add_list(['huey', 'dewey', 'louie'])
|
||||
self.assertEquals(str(msg), self.__b)
|
||||
self.assertEquals(msg.asbytes(), self.__b)
|
||||
|
||||
msg = Message()
|
||||
msg.add_int64(5)
|
||||
msg.add_int64(0xf5e4d3c2b109L)
|
||||
msg.add_int64(0xf5e4d3c2b109)
|
||||
msg.add_mpint(17)
|
||||
msg.add_mpint(0xf5e4d3c2b109L)
|
||||
msg.add_mpint(-0x65e4d3c2b109L)
|
||||
self.assertEquals(str(msg), self.__c)
|
||||
msg.add_mpint(0xf5e4d3c2b109)
|
||||
msg.add_mpint(-0x65e4d3c2b109)
|
||||
self.assertEquals(msg.asbytes(), self.__c)
|
||||
|
||||
def test_2_decode(self):
|
||||
msg = Message(self.__a)
|
||||
self.assertEquals(msg.get_int(), 23)
|
||||
self.assertEquals(msg.get_int(), 123789456)
|
||||
self.assertEquals(msg.get_string(), 'q')
|
||||
self.assertEquals(msg.get_string(), 'hello')
|
||||
self.assertEquals(msg.get_string(), 'x' * 1000)
|
||||
self.assertEquals(msg.get_text(), 'q')
|
||||
self.assertEquals(msg.get_text(), 'hello')
|
||||
self.assertEquals(msg.get_text(), 'x' * 1000)
|
||||
|
||||
msg = Message(self.__b)
|
||||
self.assertEquals(msg.get_boolean(), True)
|
||||
self.assertEquals(msg.get_boolean(), False)
|
||||
self.assertEquals(msg.get_byte(), '\xf3')
|
||||
self.assertEquals(msg.get_bytes(2), '\x00\x3f')
|
||||
self.assertEquals(msg.get_byte(), byte_chr(0xf3))
|
||||
self.assertEquals(msg.get_bytes(2), zero_byte + byte_chr(0x3f))
|
||||
self.assertEquals(msg.get_list(), ['huey', 'dewey', 'louie'])
|
||||
|
||||
msg = Message(self.__c)
|
||||
self.assertEquals(msg.get_int64(), 5)
|
||||
self.assertEquals(msg.get_int64(), 0xf5e4d3c2b109L)
|
||||
self.assertEquals(msg.get_int64(), 0xf5e4d3c2b109)
|
||||
self.assertEquals(msg.get_mpint(), 17)
|
||||
self.assertEquals(msg.get_mpint(), 0xf5e4d3c2b109L)
|
||||
self.assertEquals(msg.get_mpint(), -0x65e4d3c2b109L)
|
||||
self.assertEquals(msg.get_mpint(), 0xf5e4d3c2b109)
|
||||
self.assertEquals(msg.get_mpint(), -0x65e4d3c2b109)
|
||||
|
||||
def test_3_add(self):
|
||||
msg = Message()
|
||||
msg.add(5)
|
||||
msg.add(0x1122334455L)
|
||||
msg.add(0x1122334455)
|
||||
msg.add(0xf00000000000000000)
|
||||
msg.add(True)
|
||||
msg.add('cat')
|
||||
msg.add(['a', 'b'])
|
||||
self.assertEquals(str(msg), self.__d)
|
||||
self.assertEquals(msg.asbytes(), self.__d)
|
||||
|
||||
def test_4_misc(self):
|
||||
msg = Message(self.__d)
|
||||
self.assertEquals(msg.get_int(), 5)
|
||||
self.assertEquals(msg.get_mpint(), 0x1122334455L)
|
||||
self.assertEquals(msg.get_so_far(), self.__d[:13])
|
||||
self.assertEquals(msg.get_remainder(), self.__d[13:])
|
||||
self.assertEquals(msg.get_int(), 0x1122334455)
|
||||
self.assertEquals(msg.get_int(), 0xf00000000000000000)
|
||||
self.assertEquals(msg.get_so_far(), self.__d[:29])
|
||||
self.assertEquals(msg.get_remainder(), self.__d[29:])
|
||||
msg.rewind()
|
||||
self.assertEquals(msg.get_int(), 5)
|
||||
self.assertEquals(msg.get_so_far(), self.__d[:4])
|
||||
self.assertEquals(msg.get_remainder(), self.__d[4:])
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ class PacketizerTest (unittest.TestCase):
|
|||
# message has to be at least 16 bytes long, so we'll have at least one
|
||||
# block of data encrypted that contains zero random padding bytes
|
||||
m = Message()
|
||||
m.add_byte(chr(100))
|
||||
m.add_byte(byte_chr(100))
|
||||
m.add_int(100)
|
||||
m.add_int(1)
|
||||
m.add_int(900)
|
||||
|
|
|
@ -144,7 +144,7 @@ class KeyTest (unittest.TestCase):
|
|||
# verify that the private & public keys compare equal
|
||||
key = RSAKey.from_private_key_file('tests/test_rsa.key')
|
||||
self.assertEquals(key, key)
|
||||
pub = RSAKey(data=str(key))
|
||||
pub = RSAKey(data=key.asbytes())
|
||||
self.assert_(key.can_sign())
|
||||
self.assert_(not pub.can_sign())
|
||||
self.assertEquals(key, pub)
|
||||
|
@ -153,7 +153,7 @@ class KeyTest (unittest.TestCase):
|
|||
# verify that the private & public keys compare equal
|
||||
key = DSSKey.from_private_key_file('tests/test_dss.key')
|
||||
self.assertEquals(key, key)
|
||||
pub = DSSKey(data=str(key))
|
||||
pub = DSSKey(data=key.asbytes())
|
||||
self.assert_(key.can_sign())
|
||||
self.assert_(not pub.can_sign())
|
||||
self.assertEquals(key, pub)
|
||||
|
@ -164,11 +164,11 @@ class KeyTest (unittest.TestCase):
|
|||
msg = key.sign_ssh_data(rng, 'ice weasels')
|
||||
self.assert_(type(msg) is Message)
|
||||
msg.rewind()
|
||||
self.assertEquals('ssh-rsa', msg.get_string())
|
||||
sig = ''.join([chr(int(x, 16)) for x in SIGNED_RSA.split(':')])
|
||||
self.assertEquals(sig, msg.get_string())
|
||||
self.assertEquals('ssh-rsa', msg.get_text())
|
||||
sig = bytes().join([byte_chr(int(x, 16)) for x in SIGNED_RSA.split(':')])
|
||||
self.assertEquals(sig, msg.get_binary())
|
||||
msg.rewind()
|
||||
pub = RSAKey(data=str(key))
|
||||
pub = RSAKey(data=key.asbytes())
|
||||
self.assert_(pub.verify_ssh_sig('ice weasels', msg))
|
||||
|
||||
def test_9_sign_dss(self):
|
||||
|
@ -177,13 +177,13 @@ class KeyTest (unittest.TestCase):
|
|||
msg = key.sign_ssh_data(rng, 'ice weasels')
|
||||
self.assert_(type(msg) is Message)
|
||||
msg.rewind()
|
||||
self.assertEquals('ssh-dss', msg.get_string())
|
||||
self.assertEquals('ssh-dss', msg.get_text())
|
||||
# can't do the same test as we do for RSA, because DSS signatures
|
||||
# are usually different each time. but we can test verification
|
||||
# anyway so it's ok.
|
||||
self.assertEquals(40, len(msg.get_string()))
|
||||
self.assertEquals(40, len(msg.get_binary()))
|
||||
msg.rewind()
|
||||
pub = DSSKey(data=str(key))
|
||||
pub = DSSKey(data=key.asbytes())
|
||||
self.assert_(pub.verify_ssh_sig('ice weasels', msg))
|
||||
|
||||
def test_A_generate_rsa(self):
|
||||
|
@ -227,7 +227,7 @@ class KeyTest (unittest.TestCase):
|
|||
# verify that the private & public keys compare equal
|
||||
key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key')
|
||||
self.assertEquals(key, key)
|
||||
pub = ECDSAKey(data=str(key))
|
||||
pub = ECDSAKey(data=key.asbytes())
|
||||
self.assert_(key.can_sign())
|
||||
self.assert_(not pub.can_sign())
|
||||
self.assertEquals(key, pub)
|
||||
|
@ -238,12 +238,12 @@ class KeyTest (unittest.TestCase):
|
|||
msg = key.sign_ssh_data(rng, 'ice weasels')
|
||||
self.assert_(type(msg) is Message)
|
||||
msg.rewind()
|
||||
self.assertEquals('ecdsa-sha2-nistp256', msg.get_string())
|
||||
self.assertEquals('ecdsa-sha2-nistp256', msg.get_text())
|
||||
# ECDSA signatures, like DSS signatures, tend to be different
|
||||
# each time, so we can't compare against a "known correct"
|
||||
# signature.
|
||||
# Even the length of the signature can change.
|
||||
|
||||
msg.rewind()
|
||||
pub = ECDSAKey(data=str(key))
|
||||
pub = ECDSAKey(data=key.asbytes())
|
||||
self.assert_(pub.verify_ssh_sig('ice weasels', msg))
|
||||
|
|
|
@ -645,7 +645,8 @@ class SFTPTest (unittest.TestCase):
|
|||
try:
|
||||
sftp.rename(FOLDER + '/something', FOLDER + u'/\u00fcnic\u00f8de')
|
||||
sftp.open(FOLDER + '/\xc3\xbcnic\xc3\xb8\x64\x65', 'r')
|
||||
except Exception, e:
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
self.fail('exception ' + e)
|
||||
sftp.unlink(FOLDER + '/\xc3\xbcnic\xc3\xb8\x64\x65')
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class BigSFTPTest (unittest.TestCase):
|
|||
|
||||
# now make sure every file is there, by creating a list of filenmes
|
||||
# and reading them in random order.
|
||||
numlist = range(numfiles)
|
||||
numlist = list(range(numfiles))
|
||||
while len(numlist) > 0:
|
||||
r = numlist[random.randint(0, len(numlist) - 1)]
|
||||
f = sftp.open('%s/file%d.txt' % (FOLDER, r))
|
||||
|
|
|
@ -121,8 +121,8 @@ class TransportTest(ParamikoTest):
|
|||
self.sockc.close()
|
||||
|
||||
def setup_test_server(self, client_options=None, server_options=None):
|
||||
public_host_key = RSAKey(data=str(host_key))
|
||||
host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = RSAKey(data=host_key.asbytes())
|
||||
self.ts.add_server_key(host_key)
|
||||
|
||||
if client_options is not None:
|
||||
|
@ -171,8 +171,8 @@ class TransportTest(ParamikoTest):
|
|||
loopback sockets. this is hardly "simple" but it's simpler than the
|
||||
later tests. :)
|
||||
"""
|
||||
public_host_key = RSAKey(data=str(host_key))
|
||||
host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = RSAKey(data=host_key.asbytes())
|
||||
self.ts.add_server_key(host_key)
|
||||
event = threading.Event()
|
||||
server = NullServer()
|
||||
|
@ -196,8 +196,8 @@ class TransportTest(ParamikoTest):
|
|||
"""
|
||||
verify that a long banner doesn't mess up the handshake.
|
||||
"""
|
||||
public_host_key = RSAKey(data=str(host_key))
|
||||
host_key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
|
||||
public_host_key = RSAKey(data=host_key.asbytes())
|
||||
self.ts.add_server_key(host_key)
|
||||
event = threading.Event()
|
||||
server = NullServer()
|
||||
|
@ -708,7 +708,7 @@ class TransportTest(ParamikoTest):
|
|||
# Simulate in-transit MSG_CHANNEL_WINDOW_ADJUST by sending it
|
||||
# before responding to the incoming MSG_KEXINIT.
|
||||
m2 = Message()
|
||||
m2.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
|
||||
m2.add_byte(cMSG_CHANNEL_WINDOW_ADJUST)
|
||||
m2.add_int(chan.remote_chanid)
|
||||
m2.add_int(1) # bytes to add
|
||||
self._send_message(m2)
|
||||
|
|
Loading…
Reference in New Issue