summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2004-04-05 10:12:59 +0000
committerRobey Pointer <robey@lag.net>2004-04-05 10:12:59 +0000
commit8fafd1aa1716bdf50575c4c3f98e46a2c7e73f8c (patch)
treedc9ee4413d5d1038978613e1ec08d97f8e425d14
parentd757f90ac52d5a98b8b7db98297a50f6e53a81d0 (diff)
[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.
-rw-r--r--paramiko/auth_transport.py42
-rw-r--r--paramiko/channel.py25
-rw-r--r--paramiko/kex_gex.py10
-rw-r--r--paramiko/kex_group1.py7
-rw-r--r--paramiko/transport.py84
-rw-r--r--paramiko/util.py22
6 files changed, 88 insertions, 102 deletions
diff --git a/paramiko/auth_transport.py b/paramiko/auth_transport.py
index 7ef77a8c..ccb71499 100644
--- a/paramiko/auth_transport.py
+++ b/paramiko/auth_transport.py
@@ -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.
"""
+from common import *
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 ssh_exception import SSHException
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):
"""
@@ -244,14 +240,14 @@ class Transport (BaseTransport):
def _request_auth(self):
m = Message()
- m.add_byte(chr(_MSG_SERVICE_REQUEST))
+ m.add_byte(chr(MSG_SERVICE_REQUEST))
m.add_string('ssh-userauth')
self._send_message(m)
def _disconnect_service_not_available(self):
m = Message()
- m.add_byte(chr(_MSG_DISCONNECT))
- m.add_int(_DISCONNECT_SERVICE_NOT_AVAILABLE)
+ m.add_byte(chr(MSG_DISCONNECT))
+ m.add_int(DISCONNECT_SERVICE_NOT_AVAILABLE)
m.add_string('Service not available')
m.add_string('en')
self._send_message(m)
@@ -259,8 +255,8 @@ class Transport (BaseTransport):
def _disconnect_no_more_auth(self):
m = Message()
- m.add_byte(chr(_MSG_DISCONNECT))
- m.add_int(_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
+ m.add_byte(chr(MSG_DISCONNECT))
+ m.add_int(DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
m.add_string('No more auth methods available')
m.add_string('en')
self._send_message(m)
@@ -269,7 +265,7 @@ class Transport (BaseTransport):
def _get_session_blob(self, key, service, username):
m = Message()
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(service)
m.add_string('publickey')
@@ -283,7 +279,7 @@ class Transport (BaseTransport):
if self.server_mode and (service == 'ssh-userauth'):
# accepted
m = Message()
- m.add_byte(chr(_MSG_SERVICE_ACCEPT))
+ m.add_byte(chr(MSG_SERVICE_ACCEPT))
m.add_string(service)
self._send_message(m)
return
@@ -295,7 +291,7 @@ class Transport (BaseTransport):
if service == 'ssh-userauth':
self._log(DEBUG, 'userauth is OK')
m = Message()
- m.add_byte(chr(_MSG_USERAUTH_REQUEST))
+ m.add_byte(chr(MSG_USERAUTH_REQUEST))
m.add_string(self.username)
m.add_string('ssh-connection')
m.add_string(self.auth_method)
@@ -319,7 +315,7 @@ class Transport (BaseTransport):
if not self.server_mode:
# er, uh... what?
m = Message()
- m.add_byte(chr(_MSG_USERAUTH_FAILURE))
+ m.add_byte(chr(MSG_USERAUTH_FAILURE))
m.add_string('none')
m.add_boolean(0)
self._send_message(m)
@@ -368,7 +364,7 @@ class Transport (BaseTransport):
# 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(chr(MSG_USERAUTH_PK_OK))
m.add_string(keytype)
m.add_string(keyblob)
self._send_message(m)
@@ -384,11 +380,11 @@ class Transport (BaseTransport):
m = Message()
if result == self.AUTH_SUCCESSFUL:
self._log(DEBUG, 'Auth granted.')
- m.add_byte(chr(_MSG_USERAUTH_SUCCESS))
+ m.add_byte(chr(MSG_USERAUTH_SUCCESS))
self.auth_complete = 1
else:
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))
if result == self.AUTH_PARTIALLY_SUCCESSFUL:
m.add_boolean(1)
@@ -427,11 +423,11 @@ class Transport (BaseTransport):
_handler_table = BaseTransport._handler_table.copy()
_handler_table.update({
- _MSG_SERVICE_REQUEST: _parse_service_request,
- _MSG_SERVICE_ACCEPT: _parse_service_accept,
- _MSG_USERAUTH_REQUEST: _parse_userauth_request,
- _MSG_USERAUTH_SUCCESS: _parse_userauth_success,
- _MSG_USERAUTH_FAILURE: _parse_userauth_failure,
- _MSG_USERAUTH_BANNER: _parse_userauth_banner,
+ MSG_SERVICE_REQUEST: _parse_service_request,
+ MSG_SERVICE_ACCEPT: _parse_service_accept,
+ MSG_USERAUTH_REQUEST: _parse_userauth_request,
+ MSG_USERAUTH_SUCCESS: _parse_userauth_success,
+ MSG_USERAUTH_FAILURE: _parse_userauth_failure,
+ MSG_USERAUTH_BANNER: _parse_userauth_banner,
})
diff --git a/paramiko/channel.py b/paramiko/channel.py
index c634f93a..cf2ff633 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -22,10 +22,9 @@
Abstraction for an SSH2 channel.
"""
+from common import *
from message import Message
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
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:
raise SSHException('Channel is not open')
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_REQUEST))
+ m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
m.add_string('pty-req')
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:
raise SSHException('Channel is not open')
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_REQUEST))
+ m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
m.add_string('shell')
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:
raise SSHException('Channel is not open')
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_REQUEST))
+ m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
m.add_string('exec')
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:
raise SSHException('Channel is not open')
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_REQUEST))
+ m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
m.add_string('subsystem')
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:
raise SSHException('Channel is not open')
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_REQUEST))
+ m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
m.add_string('window-change')
m.add_boolean(0)
@@ -300,7 +299,7 @@ class Channel (object):
if self.active and not self.closed:
self._send_eof()
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_CLOSE))
+ m.add_byte(chr(MSG_CHANNEL_CLOSE))
m.add_int(self.remote_chanid)
self.transport._send_message(m)
self.closed = 1
@@ -417,7 +416,7 @@ class Channel (object):
if self.out_max_packet_size < size:
size = self.out_max_packet_size
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_DATA))
+ m.add_byte(chr(MSG_CHANNEL_DATA))
m.add_int(self.remote_chanid)
m.add_string(s[:size])
self.transport._send_message(m)
@@ -686,9 +685,9 @@ class Channel (object):
if want_reply:
m = Message()
if ok:
- m.add_byte(chr(_MSG_CHANNEL_SUCCESS))
+ m.add_byte(chr(MSG_CHANNEL_SUCCESS))
else:
- m.add_byte(chr(_MSG_CHANNEL_FAILURE))
+ m.add_byte(chr(MSG_CHANNEL_FAILURE))
m.add_int(self.remote_chanid)
self.transport._send_message(m)
@@ -728,7 +727,7 @@ class Channel (object):
if self.eof_sent:
return
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_EOF))
+ m.add_byte(chr(MSG_CHANNEL_EOF))
m.add_int(self.remote_chanid)
self.transport._send_message(m)
self.eof_sent = 1
@@ -828,7 +827,7 @@ class Channel (object):
if self.in_window_sofar > self.in_window_threshold:
self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
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.in_window_sofar)
self.transport._send_message(m)
diff --git a/paramiko/kex_gex.py b/paramiko/kex_gex.py
index a83c84b7..c7b07a3e 100644
--- a/paramiko/kex_gex.py
+++ b/paramiko/kex_gex.py
@@ -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.
"""
-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.Util import number
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)
diff --git a/paramiko/kex_group1.py b/paramiko/kex_group1.py
index 94e6bea3..77857f8c 100644
--- a/paramiko/kex_group1.py
+++ b/paramiko/kex_group1.py
@@ -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.
"""
-from message import Message, inflate_long
-from ssh_exception import SSHException
-from transport import _MSG_NEWKEYS
from Crypto.Hash import SHA
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)
# draft-ietf-secsh-transport-09.txt, page 17
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 1ec63ebd..58508c08 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -22,18 +22,9 @@
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
+
+from common import *
from ssh_exception import SSHException
from message import Message
from channel import Channel
@@ -49,33 +40,12 @@ from primes import ModulusPack
# i believe this on the standards track.
# PyCrypt compiled for Win32 can be downloaded from the HashTar homepage:
# http://nitace.bsd.uchicago.edu:8080/hashtar
-from Crypto.Util.randpool import PersistentRandomPool, RandomPool
from Crypto.Cipher import Blowfish, AES, DES3
from Crypto.Hash import SHA, MD5, HMAC
-from Crypto.PublicKey import RSA
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
_active_threads = []
def _join_lingering_threads():
@@ -428,7 +398,7 @@ class BaseTransport (threading.Thread):
chanid = self.channel_counter
self.channel_counter += 1
m = Message()
- m.add_byte(chr(_MSG_CHANNEL_OPEN))
+ m.add_byte(chr(MSG_CHANNEL_OPEN))
m.add_string(kind)
m.add_int(chanid)
m.add_int(self.window_size)
@@ -466,7 +436,7 @@ class BaseTransport (threading.Thread):
@type bytes: int
"""
m = Message()
- m.add_byte(chr(_MSG_IGNORE))
+ m.add_byte(chr(MSG_IGNORE))
if bytes is None:
bytes = (ord(randpool.get_bytes(1)) % 32) + 10
m.add_bytes(randpool.get_bytes(bytes))
@@ -821,17 +791,17 @@ class BaseTransport (threading.Thread):
self._write_all(self.local_version + '\r\n')
self._check_banner()
self._send_kex_init()
- self.expected_packet = _MSG_KEXINIT
+ self.expected_packet = MSG_KEXINIT
while self.active:
ptype, m = self._read_message()
- if ptype == _MSG_IGNORE:
+ if ptype == MSG_IGNORE:
continue
- elif ptype == _MSG_DISCONNECT:
+ elif ptype == MSG_DISCONNECT:
self._parse_disconnect(m)
self.active = False
break
- elif ptype == _MSG_DEBUG:
+ elif ptype == MSG_DEBUG:
self._parse_debug(m)
continue
if self.expected_packet != 0:
@@ -851,7 +821,7 @@ class BaseTransport (threading.Thread):
else:
self._log(WARNING, 'Oops, unhandled type %d' % ptype)
msg = Message()
- msg.add_byte(chr(_MSG_UNIMPLEMENTED))
+ msg.add_byte(chr(MSG_UNIMPLEMENTED))
msg.add_int(m.seqno)
self._send_message(msg)
except SSHException, e:
@@ -936,7 +906,7 @@ class BaseTransport (threading.Thread):
available_server_keys = self.preferred_keys
m = Message()
- m.add_byte(chr(_MSG_KEXINIT))
+ m.add_byte(chr(MSG_KEXINIT))
m.add_bytes(randpool.get_bytes(16))
m.add(','.join(self.preferred_kex))
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
# 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 = chr(MSG_KEXINIT) + m.get_so_far()
def _activate_inbound(self):
"switch on newly negotiated encryption parameters for inbound traffic"
@@ -1071,7 +1041,7 @@ class BaseTransport (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(chr(MSG_NEWKEYS))
self._send_message(m)
self.block_size_out = self._cipher_info[self.local_cipher]['block-size']
if self.server_mode:
@@ -1090,7 +1060,7 @@ class BaseTransport (threading.Thread):
else:
self.mac_key_out = self._compute_key('E', self.local_mac_engine.digest_size)
# we always expect to receive NEWKEYS now
- self.expected_packet = _MSG_NEWKEYS
+ self.expected_packet = MSG_NEWKEYS
def _parse_newkeys(self, m):
self._log(DEBUG, 'Switch to new keys ...')
@@ -1179,7 +1149,7 @@ class BaseTransport (threading.Thread):
reason = self.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
if reject:
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(reason)
msg.add_string('')
@@ -1195,7 +1165,7 @@ class BaseTransport (threading.Thread):
finally:
self.lock.release()
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(my_chanid)
m.add_int(self.window_size)
@@ -1216,19 +1186,19 @@ class BaseTransport (threading.Thread):
self._log(DEBUG, 'Debug msg: ' + safe_string(msg))
_handler_table = {
- _MSG_NEWKEYS: _parse_newkeys,
- _MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
- _MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
- _MSG_CHANNEL_OPEN: _parse_channel_open,
- _MSG_KEXINIT: _negotiate_keys,
+ MSG_NEWKEYS: _parse_newkeys,
+ MSG_CHANNEL_OPEN_SUCCESS: _parse_channel_open_success,
+ MSG_CHANNEL_OPEN_FAILURE: _parse_channel_open_failure,
+ MSG_CHANNEL_OPEN: _parse_channel_open,
+ MSG_KEXINIT: _negotiate_keys,
}
_channel_handler_table = {
- _MSG_CHANNEL_SUCCESS: Channel._request_success,
- _MSG_CHANNEL_FAILURE: Channel._request_failed,
- _MSG_CHANNEL_DATA: Channel._feed,
- _MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
- _MSG_CHANNEL_REQUEST: Channel._handle_request,
- _MSG_CHANNEL_EOF: Channel._handle_eof,
- _MSG_CHANNEL_CLOSE: Channel._handle_close,
+ MSG_CHANNEL_SUCCESS: Channel._request_success,
+ MSG_CHANNEL_FAILURE: Channel._request_failed,
+ MSG_CHANNEL_DATA: Channel._feed,
+ MSG_CHANNEL_WINDOW_ADJUST: Channel._window_adjust,
+ MSG_CHANNEL_REQUEST: Channel._handle_request,
+ MSG_CHANNEL_EOF: Channel._handle_eof,
+ MSG_CHANNEL_CLOSE: Channel._handle_close,
}
diff --git a/paramiko/util.py b/paramiko/util.py
index cc71c6c8..4fa4ec83 100644
--- a/paramiko/util.py
+++ b/paramiko/util.py
@@ -24,7 +24,7 @@ Useful functions used by the rest of paramiko.
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)"
out = 0L
negative = 0
@@ -41,7 +41,7 @@ def inflate_long(s, always_positive=0):
out -= (1L << (8 * len(s)))
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)"
# after much testing, this algorithm was deemed to be the fastest
s = ''
@@ -99,6 +99,10 @@ def hexify(s):
"turn a string into a hex sequence"
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):
out = ''
for c in s:
@@ -155,3 +159,17 @@ def generate_key_bytes(hashclass, salt, key, nbytes):
keydata += digest[:size]
nbytes -= size
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