def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.isSet():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
python类message()的实例源码
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.') # noqa
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation') # noqa
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.') # noqa
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation') # noqa
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _parse_kexgss_continue(self, m):
"""
Parse the SSH2_MSG_KEXGSS_CONTINUE message.
:param `.Message` m: The content of the SSH2_MSG_KEXGSS_CONTINUE
message
"""
if not self.transport.server_mode:
srv_token = m.get_string()
m = Message()
m.add_byte(c_MSG_KEXGSS_CONTINUE)
m.add_string(self.kexgss.ssh_init_sec_context(
target=self.gss_host, recv_token=srv_token))
self.transport.send_message(m)
self.transport._expect_packet(
MSG_KEXGSS_CONTINUE,
MSG_KEXGSS_COMPLETE,
MSG_KEXGSS_ERROR
)
else:
pass
def _parse_kexgss_error(self, m):
"""
Parse the SSH2_MSG_KEXGSS_ERROR message (client mode).
The server may send a GSS-API error message. if it does, we display
the error by throwing an exception (client mode).
:param `.Message` m: The content of the SSH2_MSG_KEXGSS_ERROR message
:raise SSHException: Contains GSS-API major and minor status as well as
the error message and the language tag of the
message
"""
maj_status = m.get_int()
min_status = m.get_int()
err_msg = m.get_string()
m.get_string() # we don't care about the language!
raise SSHException("GSS-API Error:\nMajor Status: %s\nMinor Status: %s\
\nError Message: %s\n") % (str(maj_status),
str(min_status),
err_msg)
def _parse_kexgss_error(self, m):
"""
Parse the SSH2_MSG_KEXGSS_ERROR message (client mode).
The server may send a GSS-API error message. if it does, we display
the error by throwing an exception (client mode).
:param `Message` m: The content of the SSH2_MSG_KEXGSS_ERROR message
:raise SSHException: Contains GSS-API major and minor status as well as
the error message and the language tag of the
message
"""
maj_status = m.get_int()
min_status = m.get_int()
err_msg = m.get_string()
m.get_string() # we don't care about the language (lang_tag)!
raise SSHException("GSS-API Error:\nMajor Status: %s\nMinor Status: %s\
\nError Message: %s\n") % (str(maj_status),
str(min_status),
err_msg)
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def _send_user_message(self, data):
"""
send a message, but block if we're in key negotiation. this is used
for user-initiated requests.
"""
start = time.time()
while True:
self.clear_to_send.wait(0.1)
if not self.active:
self._log(DEBUG, 'Dropping user packet because connection is dead.')
return
self.clear_to_send_lock.acquire()
if self.clear_to_send.is_set():
break
self.clear_to_send_lock.release()
if time.time() > start + self.clear_to_send_timeout:
raise SSHException('Key-exchange timed out waiting for key negotiation')
try:
self._send_message(data)
finally:
self.clear_to_send_lock.release()
def compute_hmac(key, message, digest_class):
return HMAC(key, message, digest_class).digest()
def _parse_kexgss_hostkey(self, m):
"""
Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode).
:param `.Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message
"""
# client mode
host_key = m.get_string()
self.transport.host_key = host_key
sig = m.get_string()
self.transport._verify_key(host_key, sig)
self.transport._expect_packet(MSG_KEXGSS_CONTINUE,
MSG_KEXGSS_COMPLETE)
def _parse_kexgss_complete(self, m):
"""
Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).
:param `.Message` m: The content of the
SSH2_MSG_KEXGSS_COMPLETE message
"""
# client mode
if self.transport.host_key is None:
self.transport.host_key = NullHostKey()
self.f = m.get_mpint()
if (self.f < 1) or (self.f > self.P - 1):
raise SSHException('Server kex "f" is out of range')
mic_token = m.get_string()
# This must be TRUE, if there is a GSS-API token in this message.
bool = m.get_boolean()
srv_token = None
if bool:
srv_token = m.get_string()
K = pow(self.f, self.x, self.P)
# 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.local_version, self.transport.remote_version,
self.transport.local_kex_init, self.transport.remote_kex_init)
hm.add_string(self.transport.host_key.__str__())
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
self.transport._set_K_H(K, sha1(str(hm)).digest())
if srv_token is not None:
self.kexgss.ssh_init_sec_context(target=self.gss_host,
recv_token=srv_token)
self.kexgss.ssh_check_mic(mic_token,
self.transport.session_id)
else:
self.kexgss.ssh_check_mic(mic_token,
self.transport.session_id)
self.transport._activate_outbound()
def _parse_kexgss_group(self, m):
"""
Parse the SSH2_MSG_KEXGSS_GROUP message (client mode).
:param `Message` m: The content of the SSH2_MSG_KEXGSS_GROUP message
"""
self.p = m.get_mpint()
self.g = m.get_mpint()
# reject if p's bit length < 1024 or > 8192
bitlen = paramiko.util.bit_length(self.p)
if (bitlen < 1024) or (bitlen > 8192):
raise SSHException(
'Server-generated gex p (don\'t ask) is out of range '
'(%d bits)' % bitlen)
self.transport._log(DEBUG, 'Got server p (%d bits)' % bitlen) # noqa
self._generate_x()
# now compute e = g^x mod p
self.e = pow(self.g, self.x, self.p)
m = Message()
m.add_byte(c_MSG_KEXGSS_INIT)
m.add_string(self.kexgss.ssh_init_sec_context(target=self.gss_host))
m.add_mpint(self.e)
self.transport._send_message(m)
self.transport._expect_packet(MSG_KEXGSS_HOSTKEY,
MSG_KEXGSS_CONTINUE,
MSG_KEXGSS_COMPLETE,
MSG_KEXGSS_ERROR)
def _parse_kexgss_hostkey(self, m):
"""
Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode).
:param `Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message
"""
# client mode
host_key = m.get_string()
self.transport.host_key = host_key
sig = m.get_string()
self.transport._verify_key(host_key, sig)
self.transport._expect_packet(MSG_KEXGSS_CONTINUE,
MSG_KEXGSS_COMPLETE)
def _parse_kexgss_groupreq(self, m):
"""
Parse the SSH2_MSG_KEXGSS_GROUPREQ message (server mode).
:param `.Message` m: The content of the
SSH2_MSG_KEXGSS_GROUPREQ message
"""
minbits = m.get_int()
preferredbits = m.get_int()
maxbits = m.get_int()
# smoosh the user's preferred size into our own limits
if preferredbits > self.max_bits:
preferredbits = self.max_bits
if preferredbits < self.min_bits:
preferredbits = self.min_bits
# fix min/max if they're inconsistent. technically, we could just pout
# and hang up, but there's no harm in giving them the benefit of the
# doubt and just picking a bitsize for them.
if minbits > preferredbits:
minbits = preferredbits
if maxbits < preferredbits:
maxbits = preferredbits
# now save a copy
self.min_bits = minbits
self.preferred_bits = preferredbits
self.max_bits = maxbits
# generate prime
pack = self.transport._get_modulus_pack()
if pack is None:
raise SSHException(
'Can\'t do server-side gex with no modulus pack')
self.transport._log(
DEBUG, # noqa
'Picking p (%d <= %d <= %d bits)' % (
minbits, preferredbits, maxbits))
self.g, self.p = pack.get_modulus(minbits, preferredbits, maxbits)
m = Message()
m.add_byte(c_MSG_KEXGSS_GROUP)
m.add_mpint(self.p)
m.add_mpint(self.g)
self.transport._send_message(m)
self.transport._expect_packet(MSG_KEXGSS_INIT)
def _parse_kexgss_gex_init(self, m):
"""
Parse the SSH2_MSG_KEXGSS_INIT message (server mode).
:param `Message` m: The content of the SSH2_MSG_KEXGSS_INIT message
"""
client_token = m.get_string()
self.e = m.get_mpint()
if (self.e < 1) or (self.e > self.p - 1):
raise SSHException('Client kex "e" is out of range')
self._generate_x()
self.f = pow(self.g, self.x, self.p)
K = pow(self.e, self.x, self.p)
self.transport.host_key = NullHostKey()
key = self.transport.host_key.__str__()
# 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) # noqa
hm = Message()
hm.add(self.transport.remote_version, self.transport.local_version,
self.transport.remote_kex_init, self.transport.local_kex_init,
key)
hm.add_int(self.min_bits)
hm.add_int(self.preferred_bits)
hm.add_int(self.max_bits)
hm.add_mpint(self.p)
hm.add_mpint(self.g)
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
H = sha1(hm.asbytes()).digest()
self.transport._set_K_H(K, H)
srv_token = self.kexgss.ssh_accept_sec_context(self.gss_host,
client_token)
m = Message()
if self.kexgss._gss_srv_ctxt_status:
mic_token = self.kexgss.ssh_get_mic(self.transport.session_id,
gss_kex=True)
m.add_byte(c_MSG_KEXGSS_COMPLETE)
m.add_mpint(self.f)
m.add_string(mic_token)
if srv_token is not None:
m.add_boolean(True)
m.add_string(srv_token)
else:
m.add_boolean(False)
self.transport._send_message(m)
self.transport._activate_outbound()
else:
m.add_byte(c_MSG_KEXGSS_CONTINUE)
m.add_string(srv_token)
self.transport._send_message(m)
self.transport._expect_packet(MSG_KEXGSS_CONTINUE,
MSG_KEXGSS_COMPLETE,
MSG_KEXGSS_ERROR)
def _parse_kexgss_complete(self, m):
"""
Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).
:param `Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message
"""
if self.transport.host_key is None:
self.transport.host_key = NullHostKey()
self.f = m.get_mpint()
mic_token = m.get_string()
# This must be TRUE, if there is a GSS-API token in this message.
bool = m.get_boolean()
srv_token = None
if bool:
srv_token = m.get_string()
if (self.f < 1) or (self.f > self.p - 1):
raise SSHException('Server kex "f" is out of range')
K = pow(self.f, self.x, self.p)
# 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) # noqa
hm = Message()
hm.add(self.transport.local_version, self.transport.remote_version,
self.transport.local_kex_init, self.transport.remote_kex_init,
self.transport.host_key.__str__())
if not self.old_style:
hm.add_int(self.min_bits)
hm.add_int(self.preferred_bits)
if not self.old_style:
hm.add_int(self.max_bits)
hm.add_mpint(self.p)
hm.add_mpint(self.g)
hm.add_mpint(self.e)
hm.add_mpint(self.f)
hm.add_mpint(K)
H = sha1(hm.asbytes()).digest()
self.transport._set_K_H(K, H)
if srv_token is not None:
self.kexgss.ssh_init_sec_context(target=self.gss_host,
recv_token=srv_token)
self.kexgss.ssh_check_mic(mic_token,
self.transport.session_id)
else:
self.kexgss.ssh_check_mic(mic_token,
self.transport.session_id)
self.transport._activate_outbound()