[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-36]
add common.py for commonly used constants and globals common.py now stores the constants and globals. lots of renaming because of this.
This commit is contained in:
parent
d757f90ac5
commit
8fafd1aa17
|
@ -23,16 +23,12 @@ L{Transport} is a subclass of L{BaseTransport} that handles authentication.
|
||||||
This separation keeps either class file from being too unwieldy.
|
This separation keeps either class file from being too unwieldy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from common import *
|
||||||
from transport import BaseTransport
|
from transport import BaseTransport
|
||||||
from transport import _MSG_SERVICE_REQUEST, _MSG_SERVICE_ACCEPT, _MSG_USERAUTH_REQUEST, _MSG_USERAUTH_FAILURE, \
|
|
||||||
_MSG_USERAUTH_SUCCESS, _MSG_USERAUTH_BANNER
|
|
||||||
from message import Message
|
from message import Message
|
||||||
from ssh_exception import SSHException
|
from ssh_exception import SSHException
|
||||||
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
|
||||||
_DISCONNECT_SERVICE_NOT_AVAILABLE, _DISCONNECT_AUTH_CANCELLED_BY_USER, \
|
|
||||||
_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 7, 13, 14
|
|
||||||
|
|
||||||
|
|
||||||
class Transport (BaseTransport):
|
class Transport (BaseTransport):
|
||||||
"""
|
"""
|
||||||
|
@ -244,14 +240,14 @@ class Transport (BaseTransport):
|
||||||
|
|
||||||
def _request_auth(self):
|
def _request_auth(self):
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_SERVICE_REQUEST))
|
m.add_byte(chr(MSG_SERVICE_REQUEST))
|
||||||
m.add_string('ssh-userauth')
|
m.add_string('ssh-userauth')
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
|
|
||||||
def _disconnect_service_not_available(self):
|
def _disconnect_service_not_available(self):
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_DISCONNECT))
|
m.add_byte(chr(MSG_DISCONNECT))
|
||||||
m.add_int(_DISCONNECT_SERVICE_NOT_AVAILABLE)
|
m.add_int(DISCONNECT_SERVICE_NOT_AVAILABLE)
|
||||||
m.add_string('Service not available')
|
m.add_string('Service not available')
|
||||||
m.add_string('en')
|
m.add_string('en')
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
|
@ -259,8 +255,8 @@ class Transport (BaseTransport):
|
||||||
|
|
||||||
def _disconnect_no_more_auth(self):
|
def _disconnect_no_more_auth(self):
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_DISCONNECT))
|
m.add_byte(chr(MSG_DISCONNECT))
|
||||||
m.add_int(_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
|
m.add_int(DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
|
||||||
m.add_string('No more auth methods available')
|
m.add_string('No more auth methods available')
|
||||||
m.add_string('en')
|
m.add_string('en')
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
|
@ -269,7 +265,7 @@ class Transport (BaseTransport):
|
||||||
def _get_session_blob(self, key, service, username):
|
def _get_session_blob(self, key, service, username):
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_string(self.session_id)
|
m.add_string(self.session_id)
|
||||||
m.add_byte(chr(_MSG_USERAUTH_REQUEST))
|
m.add_byte(chr(MSG_USERAUTH_REQUEST))
|
||||||
m.add_string(username)
|
m.add_string(username)
|
||||||
m.add_string(service)
|
m.add_string(service)
|
||||||
m.add_string('publickey')
|
m.add_string('publickey')
|
||||||
|
@ -283,7 +279,7 @@ class Transport (BaseTransport):
|
||||||
if self.server_mode and (service == 'ssh-userauth'):
|
if self.server_mode and (service == 'ssh-userauth'):
|
||||||
# accepted
|
# accepted
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_SERVICE_ACCEPT))
|
m.add_byte(chr(MSG_SERVICE_ACCEPT))
|
||||||
m.add_string(service)
|
m.add_string(service)
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
return
|
return
|
||||||
|
@ -295,7 +291,7 @@ class Transport (BaseTransport):
|
||||||
if service == 'ssh-userauth':
|
if service == 'ssh-userauth':
|
||||||
self._log(DEBUG, 'userauth is OK')
|
self._log(DEBUG, 'userauth is OK')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_USERAUTH_REQUEST))
|
m.add_byte(chr(MSG_USERAUTH_REQUEST))
|
||||||
m.add_string(self.username)
|
m.add_string(self.username)
|
||||||
m.add_string('ssh-connection')
|
m.add_string('ssh-connection')
|
||||||
m.add_string(self.auth_method)
|
m.add_string(self.auth_method)
|
||||||
|
@ -319,7 +315,7 @@ class Transport (BaseTransport):
|
||||||
if not self.server_mode:
|
if not self.server_mode:
|
||||||
# er, uh... what?
|
# er, uh... what?
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_USERAUTH_FAILURE))
|
m.add_byte(chr(MSG_USERAUTH_FAILURE))
|
||||||
m.add_string('none')
|
m.add_string('none')
|
||||||
m.add_boolean(0)
|
m.add_boolean(0)
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
|
@ -368,7 +364,7 @@ class Transport (BaseTransport):
|
||||||
# client wants to know if this key is acceptable, before it
|
# client wants to know if this key is acceptable, before it
|
||||||
# signs anything... send special "ok" message
|
# signs anything... send special "ok" message
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_USERAUTH_PK_OK))
|
m.add_byte(chr(MSG_USERAUTH_PK_OK))
|
||||||
m.add_string(keytype)
|
m.add_string(keytype)
|
||||||
m.add_string(keyblob)
|
m.add_string(keyblob)
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
|
@ -384,11 +380,11 @@ class Transport (BaseTransport):
|
||||||
m = Message()
|
m = Message()
|
||||||
if result == self.AUTH_SUCCESSFUL:
|
if result == self.AUTH_SUCCESSFUL:
|
||||||
self._log(DEBUG, 'Auth granted.')
|
self._log(DEBUG, 'Auth granted.')
|
||||||
m.add_byte(chr(_MSG_USERAUTH_SUCCESS))
|
m.add_byte(chr(MSG_USERAUTH_SUCCESS))
|
||||||
self.auth_complete = 1
|
self.auth_complete = 1
|
||||||
else:
|
else:
|
||||||
self._log(DEBUG, 'Auth rejected.')
|
self._log(DEBUG, 'Auth rejected.')
|
||||||
m.add_byte(chr(_MSG_USERAUTH_FAILURE))
|
m.add_byte(chr(MSG_USERAUTH_FAILURE))
|
||||||
m.add_string(self.get_allowed_auths(username))
|
m.add_string(self.get_allowed_auths(username))
|
||||||
if result == self.AUTH_PARTIALLY_SUCCESSFUL:
|
if result == self.AUTH_PARTIALLY_SUCCESSFUL:
|
||||||
m.add_boolean(1)
|
m.add_boolean(1)
|
||||||
|
@ -427,11 +423,11 @@ class Transport (BaseTransport):
|
||||||
|
|
||||||
_handler_table = BaseTransport._handler_table.copy()
|
_handler_table = BaseTransport._handler_table.copy()
|
||||||
_handler_table.update({
|
_handler_table.update({
|
||||||
_MSG_SERVICE_REQUEST: _parse_service_request,
|
MSG_SERVICE_REQUEST: _parse_service_request,
|
||||||
_MSG_SERVICE_ACCEPT: _parse_service_accept,
|
MSG_SERVICE_ACCEPT: _parse_service_accept,
|
||||||
_MSG_USERAUTH_REQUEST: _parse_userauth_request,
|
MSG_USERAUTH_REQUEST: _parse_userauth_request,
|
||||||
_MSG_USERAUTH_SUCCESS: _parse_userauth_success,
|
MSG_USERAUTH_SUCCESS: _parse_userauth_success,
|
||||||
_MSG_USERAUTH_FAILURE: _parse_userauth_failure,
|
MSG_USERAUTH_FAILURE: _parse_userauth_failure,
|
||||||
_MSG_USERAUTH_BANNER: _parse_userauth_banner,
|
MSG_USERAUTH_BANNER: _parse_userauth_banner,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,9 @@
|
||||||
Abstraction for an SSH2 channel.
|
Abstraction for an SSH2 channel.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from common import *
|
||||||
from message import Message
|
from message import Message
|
||||||
from ssh_exception import SSHException
|
from ssh_exception import SSHException
|
||||||
from transport import _MSG_CHANNEL_REQUEST, _MSG_CHANNEL_CLOSE, _MSG_CHANNEL_WINDOW_ADJUST, _MSG_CHANNEL_DATA, \
|
|
||||||
_MSG_CHANNEL_EOF, _MSG_CHANNEL_SUCCESS, _MSG_CHANNEL_FAILURE
|
|
||||||
from file import BufferedFile
|
from file import BufferedFile
|
||||||
|
|
||||||
import time, threading, logging, socket, os
|
import time, threading, logging, socket, os
|
||||||
|
@ -116,7 +115,7 @@ class Channel (object):
|
||||||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||||
raise SSHException('Channel is not open')
|
raise SSHException('Channel is not open')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_REQUEST))
|
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string('pty-req')
|
m.add_string('pty-req')
|
||||||
m.add_boolean(0)
|
m.add_boolean(0)
|
||||||
|
@ -137,7 +136,7 @@ class Channel (object):
|
||||||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||||
raise SSHException('Channel is not open')
|
raise SSHException('Channel is not open')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_REQUEST))
|
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string('shell')
|
m.add_string('shell')
|
||||||
m.add_boolean(1)
|
m.add_boolean(1)
|
||||||
|
@ -155,7 +154,7 @@ class Channel (object):
|
||||||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||||
raise SSHException('Channel is not open')
|
raise SSHException('Channel is not open')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_REQUEST))
|
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string('exec')
|
m.add_string('exec')
|
||||||
m.add_boolean(1)
|
m.add_boolean(1)
|
||||||
|
@ -174,7 +173,7 @@ class Channel (object):
|
||||||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||||
raise SSHException('Channel is not open')
|
raise SSHException('Channel is not open')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_REQUEST))
|
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string('subsystem')
|
m.add_string('subsystem')
|
||||||
m.add_boolean(1)
|
m.add_boolean(1)
|
||||||
|
@ -194,7 +193,7 @@ class Channel (object):
|
||||||
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
if self.closed or self.eof_received or self.eof_sent or not self.active:
|
||||||
raise SSHException('Channel is not open')
|
raise SSHException('Channel is not open')
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_REQUEST))
|
m.add_byte(chr(MSG_CHANNEL_REQUEST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string('window-change')
|
m.add_string('window-change')
|
||||||
m.add_boolean(0)
|
m.add_boolean(0)
|
||||||
|
@ -300,7 +299,7 @@ class Channel (object):
|
||||||
if self.active and not self.closed:
|
if self.active and not self.closed:
|
||||||
self._send_eof()
|
self._send_eof()
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_CLOSE))
|
m.add_byte(chr(MSG_CHANNEL_CLOSE))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
self.transport._send_message(m)
|
self.transport._send_message(m)
|
||||||
self.closed = 1
|
self.closed = 1
|
||||||
|
@ -417,7 +416,7 @@ class Channel (object):
|
||||||
if self.out_max_packet_size < size:
|
if self.out_max_packet_size < size:
|
||||||
size = self.out_max_packet_size
|
size = self.out_max_packet_size
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_DATA))
|
m.add_byte(chr(MSG_CHANNEL_DATA))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_string(s[:size])
|
m.add_string(s[:size])
|
||||||
self.transport._send_message(m)
|
self.transport._send_message(m)
|
||||||
|
@ -686,9 +685,9 @@ class Channel (object):
|
||||||
if want_reply:
|
if want_reply:
|
||||||
m = Message()
|
m = Message()
|
||||||
if ok:
|
if ok:
|
||||||
m.add_byte(chr(_MSG_CHANNEL_SUCCESS))
|
m.add_byte(chr(MSG_CHANNEL_SUCCESS))
|
||||||
else:
|
else:
|
||||||
m.add_byte(chr(_MSG_CHANNEL_FAILURE))
|
m.add_byte(chr(MSG_CHANNEL_FAILURE))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
self.transport._send_message(m)
|
self.transport._send_message(m)
|
||||||
|
|
||||||
|
@ -728,7 +727,7 @@ class Channel (object):
|
||||||
if self.eof_sent:
|
if self.eof_sent:
|
||||||
return
|
return
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_EOF))
|
m.add_byte(chr(MSG_CHANNEL_EOF))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
self.transport._send_message(m)
|
self.transport._send_message(m)
|
||||||
self.eof_sent = 1
|
self.eof_sent = 1
|
||||||
|
@ -828,7 +827,7 @@ class Channel (object):
|
||||||
if self.in_window_sofar > self.in_window_threshold:
|
if self.in_window_sofar > self.in_window_threshold:
|
||||||
self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
|
self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_WINDOW_ADJUST))
|
m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
m.add_int(self.in_window_sofar)
|
m.add_int(self.in_window_sofar)
|
||||||
self.transport._send_message(m)
|
self.transport._send_message(m)
|
||||||
|
|
|
@ -24,14 +24,16 @@ generator "g" are provided by the server. A bit more work is required on the
|
||||||
client side, and a B{lot} more on the server side.
|
client side, and a B{lot} more on the server side.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from message import Message
|
|
||||||
from util import inflate_long, deflate_long, bit_length
|
|
||||||
from ssh_exception import SSHException
|
|
||||||
from transport import _MSG_NEWKEYS
|
|
||||||
from Crypto.Hash import SHA
|
from Crypto.Hash import SHA
|
||||||
from Crypto.Util import number
|
from Crypto.Util import number
|
||||||
from logging import DEBUG
|
from logging import DEBUG
|
||||||
|
|
||||||
|
from common import *
|
||||||
|
from message import Message
|
||||||
|
from util import inflate_long, deflate_long, bit_length
|
||||||
|
from ssh_exception import SSHException
|
||||||
|
|
||||||
|
|
||||||
_MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, _MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(31, 35)
|
_MSG_KEXDH_GEX_GROUP, _MSG_KEXDH_GEX_INIT, _MSG_KEXDH_GEX_REPLY, _MSG_KEXDH_GEX_REQUEST = range(31, 35)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,13 @@ Standard SSH key exchange ("kex" if you wanna sound cool). Diffie-Hellman of
|
||||||
1024 bit key halves, using a known "p" prime and "g" generator.
|
1024 bit key halves, using a known "p" prime and "g" generator.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from message import Message, inflate_long
|
|
||||||
from ssh_exception import SSHException
|
|
||||||
from transport import _MSG_NEWKEYS
|
|
||||||
from Crypto.Hash import SHA
|
from Crypto.Hash import SHA
|
||||||
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
|
||||||
|
from common import *
|
||||||
|
from message import Message, inflate_long
|
||||||
|
from ssh_exception import SSHException
|
||||||
|
|
||||||
_MSG_KEXDH_INIT, _MSG_KEXDH_REPLY = range(30, 32)
|
_MSG_KEXDH_INIT, _MSG_KEXDH_REPLY = range(30, 32)
|
||||||
|
|
||||||
# draft-ietf-secsh-transport-09.txt, page 17
|
# draft-ietf-secsh-transport-09.txt, page 17
|
||||||
|
|
|
@ -22,18 +22,9 @@
|
||||||
L{BaseTransport} handles the core SSH2 protocol.
|
L{BaseTransport} handles the core SSH2 protocol.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_MSG_DISCONNECT, _MSG_IGNORE, _MSG_UNIMPLEMENTED, _MSG_DEBUG, _MSG_SERVICE_REQUEST, \
|
|
||||||
_MSG_SERVICE_ACCEPT = range(1, 7)
|
|
||||||
_MSG_KEXINIT, _MSG_NEWKEYS = range(20, 22)
|
|
||||||
_MSG_USERAUTH_REQUEST, _MSG_USERAUTH_FAILURE, _MSG_USERAUTH_SUCCESS, \
|
|
||||||
_MSG_USERAUTH_BANNER = range(50, 54)
|
|
||||||
_MSG_USERAUTH_PK_OK = 60
|
|
||||||
_MSG_CHANNEL_OPEN, _MSG_CHANNEL_OPEN_SUCCESS, _MSG_CHANNEL_OPEN_FAILURE, \
|
|
||||||
_MSG_CHANNEL_WINDOW_ADJUST, _MSG_CHANNEL_DATA, _MSG_CHANNEL_EXTENDED_DATA, \
|
|
||||||
_MSG_CHANNEL_EOF, _MSG_CHANNEL_CLOSE, _MSG_CHANNEL_REQUEST, \
|
|
||||||
_MSG_CHANNEL_SUCCESS, _MSG_CHANNEL_FAILURE = range(90, 101)
|
|
||||||
|
|
||||||
import sys, os, string, threading, socket, logging, struct
|
import sys, os, string, threading, socket, logging, struct
|
||||||
|
|
||||||
|
from common import *
|
||||||
from ssh_exception import SSHException
|
from ssh_exception import SSHException
|
||||||
from message import Message
|
from message import Message
|
||||||
from channel import Channel
|
from channel import Channel
|
||||||
|
@ -49,33 +40,12 @@ from primes import ModulusPack
|
||||||
# i believe this on the standards track.
|
# i believe this on the standards track.
|
||||||
# PyCrypt compiled for Win32 can be downloaded from the HashTar homepage:
|
# PyCrypt compiled for Win32 can be downloaded from the HashTar homepage:
|
||||||
# http://nitace.bsd.uchicago.edu:8080/hashtar
|
# http://nitace.bsd.uchicago.edu:8080/hashtar
|
||||||
from Crypto.Util.randpool import PersistentRandomPool, RandomPool
|
|
||||||
from Crypto.Cipher import Blowfish, AES, DES3
|
from Crypto.Cipher import Blowfish, AES, DES3
|
||||||
from Crypto.Hash import SHA, MD5, HMAC
|
from Crypto.Hash import SHA, MD5, HMAC
|
||||||
from Crypto.PublicKey import RSA
|
|
||||||
|
|
||||||
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
|
||||||
|
|
||||||
# channel request failed reasons:
|
|
||||||
_CONNECTION_FAILED_CODE = {
|
|
||||||
1: 'Administratively prohibited',
|
|
||||||
2: 'Connect failed',
|
|
||||||
3: 'Unknown channel type',
|
|
||||||
4: 'Resource shortage'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# keep a crypto-strong PRNG nearby
|
|
||||||
try:
|
|
||||||
randpool = PersistentRandomPool(os.getenv('HOME') + '/.randpool')
|
|
||||||
except:
|
|
||||||
# the above will likely fail on Windows - fall back to non-persistent random pool
|
|
||||||
randpool = RandomPool()
|
|
||||||
|
|
||||||
randpool.randomize()
|
|
||||||
|
|
||||||
|
|
||||||
# for thread cleanup
|
# for thread cleanup
|
||||||
_active_threads = []
|
_active_threads = []
|
||||||
def _join_lingering_threads():
|
def _join_lingering_threads():
|
||||||
|
@ -428,7 +398,7 @@ class BaseTransport (threading.Thread):
|
||||||
chanid = self.channel_counter
|
chanid = self.channel_counter
|
||||||
self.channel_counter += 1
|
self.channel_counter += 1
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_OPEN))
|
m.add_byte(chr(MSG_CHANNEL_OPEN))
|
||||||
m.add_string(kind)
|
m.add_string(kind)
|
||||||
m.add_int(chanid)
|
m.add_int(chanid)
|
||||||
m.add_int(self.window_size)
|
m.add_int(self.window_size)
|
||||||
|
@ -466,7 +436,7 @@ class BaseTransport (threading.Thread):
|
||||||
@type bytes: int
|
@type bytes: int
|
||||||
"""
|
"""
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_IGNORE))
|
m.add_byte(chr(MSG_IGNORE))
|
||||||
if bytes is None:
|
if bytes is None:
|
||||||
bytes = (ord(randpool.get_bytes(1)) % 32) + 10
|
bytes = (ord(randpool.get_bytes(1)) % 32) + 10
|
||||||
m.add_bytes(randpool.get_bytes(bytes))
|
m.add_bytes(randpool.get_bytes(bytes))
|
||||||
|
@ -821,17 +791,17 @@ class BaseTransport (threading.Thread):
|
||||||
self._write_all(self.local_version + '\r\n')
|
self._write_all(self.local_version + '\r\n')
|
||||||
self._check_banner()
|
self._check_banner()
|
||||||
self._send_kex_init()
|
self._send_kex_init()
|
||||||
self.expected_packet = _MSG_KEXINIT
|
self.expected_packet = MSG_KEXINIT
|
||||||
|
|
||||||
while self.active:
|
while self.active:
|
||||||
ptype, m = self._read_message()
|
ptype, m = self._read_message()
|
||||||
if ptype == _MSG_IGNORE:
|
if ptype == MSG_IGNORE:
|
||||||
continue
|
continue
|
||||||
elif ptype == _MSG_DISCONNECT:
|
elif ptype == MSG_DISCONNECT:
|
||||||
self._parse_disconnect(m)
|
self._parse_disconnect(m)
|
||||||
self.active = False
|
self.active = False
|
||||||
break
|
break
|
||||||
elif ptype == _MSG_DEBUG:
|
elif ptype == MSG_DEBUG:
|
||||||
self._parse_debug(m)
|
self._parse_debug(m)
|
||||||
continue
|
continue
|
||||||
if self.expected_packet != 0:
|
if self.expected_packet != 0:
|
||||||
|
@ -851,7 +821,7 @@ class BaseTransport (threading.Thread):
|
||||||
else:
|
else:
|
||||||
self._log(WARNING, 'Oops, unhandled type %d' % ptype)
|
self._log(WARNING, 'Oops, unhandled type %d' % ptype)
|
||||||
msg = Message()
|
msg = Message()
|
||||||
msg.add_byte(chr(_MSG_UNIMPLEMENTED))
|
msg.add_byte(chr(MSG_UNIMPLEMENTED))
|
||||||
msg.add_int(m.seqno)
|
msg.add_int(m.seqno)
|
||||||
self._send_message(msg)
|
self._send_message(msg)
|
||||||
except SSHException, e:
|
except SSHException, e:
|
||||||
|
@ -936,7 +906,7 @@ class BaseTransport (threading.Thread):
|
||||||
available_server_keys = self.preferred_keys
|
available_server_keys = self.preferred_keys
|
||||||
|
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_KEXINIT))
|
m.add_byte(chr(MSG_KEXINIT))
|
||||||
m.add_bytes(randpool.get_bytes(16))
|
m.add_bytes(randpool.get_bytes(16))
|
||||||
m.add(','.join(self.preferred_kex))
|
m.add(','.join(self.preferred_kex))
|
||||||
m.add(','.join(available_server_keys))
|
m.add(','.join(available_server_keys))
|
||||||
|
@ -1047,7 +1017,7 @@ class BaseTransport (threading.Thread):
|
||||||
# actually some extra bytes (one NUL byte in openssh's case) added to
|
# actually some extra bytes (one NUL byte in openssh's case) added to
|
||||||
# the end of the packet but not parsed. turns out we need to throw
|
# the end of the packet but not parsed. turns out we need to throw
|
||||||
# away those bytes because they aren't part of the hash.
|
# away those bytes because they aren't part of the hash.
|
||||||
self.remote_kex_init = chr(_MSG_KEXINIT) + m.get_so_far()
|
self.remote_kex_init = chr(MSG_KEXINIT) + m.get_so_far()
|
||||||
|
|
||||||
def _activate_inbound(self):
|
def _activate_inbound(self):
|
||||||
"switch on newly negotiated encryption parameters for inbound traffic"
|
"switch on newly negotiated encryption parameters for inbound traffic"
|
||||||
|
@ -1071,7 +1041,7 @@ class BaseTransport (threading.Thread):
|
||||||
def _activate_outbound(self):
|
def _activate_outbound(self):
|
||||||
"switch on newly negotiated encryption parameters for outbound traffic"
|
"switch on newly negotiated encryption parameters for outbound traffic"
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_NEWKEYS))
|
m.add_byte(chr(MSG_NEWKEYS))
|
||||||
self._send_message(m)
|
self._send_message(m)
|
||||||
self.block_size_out = self._cipher_info[self.local_cipher]['block-size']
|
self.block_size_out = self._cipher_info[self.local_cipher]['block-size']
|
||||||
if self.server_mode:
|
if self.server_mode:
|
||||||
|
@ -1090,7 +1060,7 @@ class BaseTransport (threading.Thread):
|
||||||
else:
|
else:
|
||||||
self.mac_key_out = self._compute_key('E', self.local_mac_engine.digest_size)
|
self.mac_key_out = self._compute_key('E', self.local_mac_engine.digest_size)
|
||||||
# we always expect to receive NEWKEYS now
|
# we always expect to receive NEWKEYS now
|
||||||
self.expected_packet = _MSG_NEWKEYS
|
self.expected_packet = MSG_NEWKEYS
|
||||||
|
|
||||||
def _parse_newkeys(self, m):
|
def _parse_newkeys(self, m):
|
||||||
self._log(DEBUG, 'Switch to new keys ...')
|
self._log(DEBUG, 'Switch to new keys ...')
|
||||||
|
@ -1179,7 +1149,7 @@ class BaseTransport (threading.Thread):
|
||||||
reason = self.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
|
reason = self.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
|
||||||
if reject:
|
if reject:
|
||||||
msg = Message()
|
msg = Message()
|
||||||
msg.add_byte(chr(_MSG_CHANNEL_OPEN_FAILURE))
|
msg.add_byte(chr(MSG_CHANNEL_OPEN_FAILURE))
|
||||||
msg.add_int(chanid)
|
msg.add_int(chanid)
|
||||||
msg.add_int(reason)
|
msg.add_int(reason)
|
||||||
msg.add_string('')
|
msg.add_string('')
|
||||||
|
@ -1195,7 +1165,7 @@ class BaseTransport (threading.Thread):
|
||||||
finally:
|
finally:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(_MSG_CHANNEL_OPEN_SUCCESS))
|
m.add_byte(chr(MSG_CHANNEL_OPEN_SUCCESS))
|
||||||
m.add_int(chanid)
|
m.add_int(chanid)
|
||||||
m.add_int(my_chanid)
|
m.add_int(my_chanid)
|
||||||
m.add_int(self.window_size)
|
m.add_int(self.window_size)
|
||||||
|
@ -1216,19 +1186,19 @@ class BaseTransport (threading.Thread):
|
||||||
self._log(DEBUG, 'Debug msg: ' + safe_string(msg))
|
self._log(DEBUG, 'Debug msg: ' + safe_string(msg))
|
||||||
|
|
||||||
_handler_table = {
|
_handler_table = {
|
||||||
_MSG_NEWKEYS: _parse_newkeys,
|
MSG_NEWKEYS: _parse_newkeys,
|
||||||
_MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
|
MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
|
||||||
_MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
|
MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
|
||||||
_MSG_CHANNEL_OPEN: _parse_channel_open,
|
MSG_CHANNEL_OPEN: _parse_channel_open,
|
||||||
_MSG_KEXINIT: _negotiate_keys,
|
MSG_KEXINIT: _negotiate_keys,
|
||||||
}
|
}
|
||||||
|
|
||||||
_channel_handler_table = {
|
_channel_handler_table = {
|
||||||
_MSG_CHANNEL_SUCCESS: Channel._request_success,
|
MSG_CHANNEL_SUCCESS: Channel._request_success,
|
||||||
_MSG_CHANNEL_FAILURE: Channel._request_failed,
|
MSG_CHANNEL_FAILURE: Channel._request_failed,
|
||||||
_MSG_CHANNEL_DATA: Channel._feed,
|
MSG_CHANNEL_DATA: Channel._feed,
|
||||||
_MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
|
MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
|
||||||
_MSG_CHANNEL_REQUEST: Channel._handle_request,
|
MSG_CHANNEL_REQUEST: Channel._handle_request,
|
||||||
_MSG_CHANNEL_EOF: Channel._handle_eof,
|
MSG_CHANNEL_EOF: Channel._handle_eof,
|
||||||
_MSG_CHANNEL_CLOSE: Channel._handle_close,
|
MSG_CHANNEL_CLOSE: Channel._handle_close,
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ Useful functions used by the rest of paramiko.
|
||||||
|
|
||||||
import sys, struct, traceback
|
import sys, struct, traceback
|
||||||
|
|
||||||
def inflate_long(s, always_positive=0):
|
def inflate_long(s, always_positive=False):
|
||||||
"turns a normalized byte string into a long-int (adapted from Crypto.Util.number)"
|
"turns a normalized byte string into a long-int (adapted from Crypto.Util.number)"
|
||||||
out = 0L
|
out = 0L
|
||||||
negative = 0
|
negative = 0
|
||||||
|
@ -41,7 +41,7 @@ def inflate_long(s, always_positive=0):
|
||||||
out -= (1L << (8 * len(s)))
|
out -= (1L << (8 * len(s)))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def deflate_long(n, add_sign_padding=1):
|
def deflate_long(n, add_sign_padding=True):
|
||||||
"turns a long-int into a normalized byte string (adapted from Crypto.Util.number)"
|
"turns a long-int into a normalized byte string (adapted from Crypto.Util.number)"
|
||||||
# after much testing, this algorithm was deemed to be the fastest
|
# after much testing, this algorithm was deemed to be the fastest
|
||||||
s = ''
|
s = ''
|
||||||
|
@ -99,6 +99,10 @@ def hexify(s):
|
||||||
"turn a string into a hex sequence"
|
"turn a string into a hex sequence"
|
||||||
return ''.join(['%02X' % ord(c) for c in s])
|
return ''.join(['%02X' % ord(c) for c in s])
|
||||||
|
|
||||||
|
def unhexify(s):
|
||||||
|
"turn a hex sequence back into a string"
|
||||||
|
return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)])
|
||||||
|
|
||||||
def safe_string(s):
|
def safe_string(s):
|
||||||
out = ''
|
out = ''
|
||||||
for c in s:
|
for c in s:
|
||||||
|
@ -155,3 +159,17 @@ def generate_key_bytes(hashclass, salt, key, nbytes):
|
||||||
keydata += digest[:size]
|
keydata += digest[:size]
|
||||||
nbytes -= size
|
nbytes -= size
|
||||||
return keydata
|
return keydata
|
||||||
|
|
||||||
|
def mod_inverse(x, m):
|
||||||
|
# it's crazy how small python can make this function.
|
||||||
|
u1, u2, u3 = 1, 0, m
|
||||||
|
v1, v2, v3 = 0, 1, x
|
||||||
|
|
||||||
|
while v3 > 0:
|
||||||
|
q = u3 // v3
|
||||||
|
u1, v1 = v1, u1 - v1 * q
|
||||||
|
u2, v2 = v2, u2 - v2 * q
|
||||||
|
u3, v3 = v3, u3 - v3 * q
|
||||||
|
if u2 < 0:
|
||||||
|
u2 += m
|
||||||
|
return u2
|
||||||
|
|
Loading…
Reference in New Issue