diff options
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch')
88 files changed, 0 insertions, 32553 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py deleted file mode 100755 index d7ce597c..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- test-case-name: twisted.conch.test -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - - -""" -Twisted.Conch: The Twisted Shell. Terminal emulation, SSHv2 and telnet. - -Currently this contains the SSHv2 implementation, but it may work over other -protocols in the future. (i.e. Telnet) - -Maintainer: Paul Swartz -""" - -from twisted.conch._version import version -__version__ = version.short() diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py deleted file mode 100755 index 26337c3f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/_version.py +++ /dev/null @@ -1,3 +0,0 @@ -# This is an auto-generated file. Do not edit it. -from twisted.python import versions -version = versions.Version('twisted.conch', 12, 2, 0) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py deleted file mode 100755 index a914da3e..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/avatar.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_conch -*- -from interfaces import IConchUser -from error import ConchError -from ssh.connection import OPEN_UNKNOWN_CHANNEL_TYPE -from twisted.python import log -from zope import interface - -class ConchUser: - interface.implements(IConchUser) - - def __init__(self): - self.channelLookup = {} - self.subsystemLookup = {} - - def lookupChannel(self, channelType, windowSize, maxPacket, data): - klass = self.channelLookup.get(channelType, None) - if not klass: - raise ConchError(OPEN_UNKNOWN_CHANNEL_TYPE, "unknown channel") - else: - return klass(remoteWindow = windowSize, - remoteMaxPacket = maxPacket, - data=data, avatar=self) - - def lookupSubsystem(self, subsystem, data): - log.msg(repr(self.subsystemLookup)) - klass = self.subsystemLookup.get(subsystem, None) - if not klass: - return False - return klass(data, avatar=self) - - def gotGlobalRequest(self, requestType, data): - # XXX should this use method dispatch? - requestType = requestType.replace('-','_') - f = getattr(self, "global_%s" % requestType, None) - if not f: - return 0 - return f(data) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py deleted file mode 100755 index 3cd6a0ec..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/checkers.py +++ /dev/null @@ -1,308 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_checkers -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Provide L{ICredentialsChecker} implementations to be used in Conch protocols. -""" - -import os, base64, binascii, errno -try: - import pwd -except ImportError: - pwd = None -else: - import crypt - -try: - # Python 2.5 got spwd to interface with shadow passwords - import spwd -except ImportError: - spwd = None - try: - import shadow - except ImportError: - shadow = None -else: - shadow = None - -try: - from twisted.cred import pamauth -except ImportError: - pamauth = None - -from zope.interface import implements, providedBy - -from twisted.conch import error -from twisted.conch.ssh import keys -from twisted.cred.checkers import ICredentialsChecker -from twisted.cred.credentials import IUsernamePassword, ISSHPrivateKey -from twisted.cred.error import UnauthorizedLogin, UnhandledCredentials -from twisted.internet import defer -from twisted.python import failure, reflect, log -from twisted.python.util import runAsEffectiveUser -from twisted.python.filepath import FilePath - - - -def verifyCryptedPassword(crypted, pw): - return crypt.crypt(pw, crypted) == crypted - - - -def _pwdGetByName(username): - """ - Look up a user in the /etc/passwd database using the pwd module. If the - pwd module is not available, return None. - - @param username: the username of the user to return the passwd database - information for. - """ - if pwd is None: - return None - return pwd.getpwnam(username) - - - -def _shadowGetByName(username): - """ - Look up a user in the /etc/shadow database using the spwd or shadow - modules. If neither module is available, return None. - - @param username: the username of the user to return the shadow database - information for. - """ - if spwd is not None: - f = spwd.getspnam - elif shadow is not None: - f = shadow.getspnam - else: - return None - return runAsEffectiveUser(0, 0, f, username) - - - -class UNIXPasswordDatabase: - """ - A checker which validates users out of the UNIX password databases, or - databases of a compatible format. - - @ivar _getByNameFunctions: a C{list} of functions which are called in order - to valid a user. The default value is such that the /etc/passwd - database will be tried first, followed by the /etc/shadow database. - """ - credentialInterfaces = IUsernamePassword, - implements(ICredentialsChecker) - - - def __init__(self, getByNameFunctions=None): - if getByNameFunctions is None: - getByNameFunctions = [_pwdGetByName, _shadowGetByName] - self._getByNameFunctions = getByNameFunctions - - - def requestAvatarId(self, credentials): - for func in self._getByNameFunctions: - try: - pwnam = func(credentials.username) - except KeyError: - return defer.fail(UnauthorizedLogin("invalid username")) - else: - if pwnam is not None: - crypted = pwnam[1] - if crypted == '': - continue - if verifyCryptedPassword(crypted, credentials.password): - return defer.succeed(credentials.username) - # fallback - return defer.fail(UnauthorizedLogin("unable to verify password")) - - - -class SSHPublicKeyDatabase: - """ - Checker that authenticates SSH public keys, based on public keys listed in - authorized_keys and authorized_keys2 files in user .ssh/ directories. - """ - implements(ICredentialsChecker) - - credentialInterfaces = (ISSHPrivateKey,) - - _userdb = pwd - - def requestAvatarId(self, credentials): - d = defer.maybeDeferred(self.checkKey, credentials) - d.addCallback(self._cbRequestAvatarId, credentials) - d.addErrback(self._ebRequestAvatarId) - return d - - def _cbRequestAvatarId(self, validKey, credentials): - """ - Check whether the credentials themselves are valid, now that we know - if the key matches the user. - - @param validKey: A boolean indicating whether or not the public key - matches a key in the user's authorized_keys file. - - @param credentials: The credentials offered by the user. - @type credentials: L{ISSHPrivateKey} provider - - @raise UnauthorizedLogin: (as a failure) if the key does not match the - user in C{credentials}. Also raised if the user provides an invalid - signature. - - @raise ValidPublicKey: (as a failure) if the key matches the user but - the credentials do not include a signature. See - L{error.ValidPublicKey} for more information. - - @return: The user's username, if authentication was successful. - """ - if not validKey: - return failure.Failure(UnauthorizedLogin("invalid key")) - if not credentials.signature: - return failure.Failure(error.ValidPublicKey()) - else: - try: - pubKey = keys.Key.fromString(credentials.blob) - if pubKey.verify(credentials.signature, credentials.sigData): - return credentials.username - except: # any error should be treated as a failed login - log.err() - return failure.Failure(UnauthorizedLogin('error while verifying key')) - return failure.Failure(UnauthorizedLogin("unable to verify key")) - - - def getAuthorizedKeysFiles(self, credentials): - """ - Return a list of L{FilePath} instances for I{authorized_keys} files - which might contain information about authorized keys for the given - credentials. - - On OpenSSH servers, the default location of the file containing the - list of authorized public keys is - U{$HOME/.ssh/authorized_keys<http://www.openbsd.org/cgi-bin/man.cgi?query=sshd_config>}. - - I{$HOME/.ssh/authorized_keys2} is also returned, though it has been - U{deprecated by OpenSSH since - 2001<http://marc.info/?m=100508718416162>}. - - @return: A list of L{FilePath} instances to files with the authorized keys. - """ - pwent = self._userdb.getpwnam(credentials.username) - root = FilePath(pwent.pw_dir).child('.ssh') - files = ['authorized_keys', 'authorized_keys2'] - return [root.child(f) for f in files] - - - def checkKey(self, credentials): - """ - Retrieve files containing authorized keys and check against user - credentials. - """ - uid, gid = os.geteuid(), os.getegid() - ouid, ogid = self._userdb.getpwnam(credentials.username)[2:4] - for filepath in self.getAuthorizedKeysFiles(credentials): - if not filepath.exists(): - continue - try: - lines = filepath.open() - except IOError, e: - if e.errno == errno.EACCES: - lines = runAsEffectiveUser(ouid, ogid, filepath.open) - else: - raise - for l in lines: - l2 = l.split() - if len(l2) < 2: - continue - try: - if base64.decodestring(l2[1]) == credentials.blob: - return True - except binascii.Error: - continue - return False - - def _ebRequestAvatarId(self, f): - if not f.check(UnauthorizedLogin): - log.msg(f) - return failure.Failure(UnauthorizedLogin("unable to get avatar id")) - return f - - -class SSHProtocolChecker: - """ - SSHProtocolChecker is a checker that requires multiple authentications - to succeed. To add a checker, call my registerChecker method with - the checker and the interface. - - After each successful authenticate, I call my areDone method with the - avatar id. To get a list of the successful credentials for an avatar id, - use C{SSHProcotolChecker.successfulCredentials[avatarId]}. If L{areDone} - returns True, the authentication has succeeded. - """ - - implements(ICredentialsChecker) - - def __init__(self): - self.checkers = {} - self.successfulCredentials = {} - - def get_credentialInterfaces(self): - return self.checkers.keys() - - credentialInterfaces = property(get_credentialInterfaces) - - def registerChecker(self, checker, *credentialInterfaces): - if not credentialInterfaces: - credentialInterfaces = checker.credentialInterfaces - for credentialInterface in credentialInterfaces: - self.checkers[credentialInterface] = checker - - def requestAvatarId(self, credentials): - """ - Part of the L{ICredentialsChecker} interface. Called by a portal with - some credentials to check if they'll authenticate a user. We check the - interfaces that the credentials provide against our list of acceptable - checkers. If one of them matches, we ask that checker to verify the - credentials. If they're valid, we call our L{_cbGoodAuthentication} - method to continue. - - @param credentials: the credentials the L{Portal} wants us to verify - """ - ifac = providedBy(credentials) - for i in ifac: - c = self.checkers.get(i) - if c is not None: - d = defer.maybeDeferred(c.requestAvatarId, credentials) - return d.addCallback(self._cbGoodAuthentication, - credentials) - return defer.fail(UnhandledCredentials("No checker for %s" % \ - ', '.join(map(reflect.qual, ifac)))) - - def _cbGoodAuthentication(self, avatarId, credentials): - """ - Called if a checker has verified the credentials. We call our - L{areDone} method to see if the whole of the successful authentications - are enough. If they are, we return the avatar ID returned by the first - checker. - """ - if avatarId not in self.successfulCredentials: - self.successfulCredentials[avatarId] = [] - self.successfulCredentials[avatarId].append(credentials) - if self.areDone(avatarId): - del self.successfulCredentials[avatarId] - return avatarId - else: - raise error.NotEnoughAuthentication() - - def areDone(self, avatarId): - """ - Override to determine if the authentication is finished for a given - avatarId. - - @param avatarId: the avatar returned by the first checker. For - this checker to function correctly, all the checkers must - return the same avatar ID. - """ - return True - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py deleted file mode 100755 index f55d474d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -""" -Client support code for Conch. - -Maintainer: Paul Swartz -""" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py deleted file mode 100755 index 50a8feaa..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/agent.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_default -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Accesses the key agent for user authentication. - -Maintainer: Paul Swartz -""" - -import os - -from twisted.conch.ssh import agent, channel, keys -from twisted.internet import protocol, reactor -from twisted.python import log - - - -class SSHAgentClient(agent.SSHAgentClient): - - def __init__(self): - agent.SSHAgentClient.__init__(self) - self.blobs = [] - - - def getPublicKeys(self): - return self.requestIdentities().addCallback(self._cbPublicKeys) - - - def _cbPublicKeys(self, blobcomm): - log.msg('got %i public keys' % len(blobcomm)) - self.blobs = [x[0] for x in blobcomm] - - - def getPublicKey(self): - """ - Return a L{Key} from the first blob in C{self.blobs}, if any, or - return C{None}. - """ - if self.blobs: - return keys.Key.fromString(self.blobs.pop(0)) - return None - - - -class SSHAgentForwardingChannel(channel.SSHChannel): - - def channelOpen(self, specificData): - cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal) - d = cc.connectUNIX(os.environ['SSH_AUTH_SOCK']) - d.addCallback(self._cbGotLocal) - d.addErrback(lambda x:self.loseConnection()) - self.buf = '' - - - def _cbGotLocal(self, local): - self.local = local - self.dataReceived = self.local.transport.write - self.local.dataReceived = self.write - - - def dataReceived(self, data): - self.buf += data - - - def closed(self): - if self.local: - self.local.loseConnection() - self.local = None - - -class SSHAgentForwardingLocal(protocol.Protocol): - pass diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py deleted file mode 100755 index dc5fe22d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/connect.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -import direct - -connectTypes = {"direct" : direct.connect} - -def connect(host, port, options, verifyHostKey, userAuthObject): - useConnects = ['direct'] - return _ebConnect(None, useConnects, host, port, options, verifyHostKey, - userAuthObject) - -def _ebConnect(f, useConnects, host, port, options, vhk, uao): - if not useConnects: - return f - connectType = useConnects.pop(0) - f = connectTypes[connectType] - d = f(host, port, options, vhk, uao) - d.addErrback(_ebConnect, useConnects, host, port, options, vhk, uao) - return d diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py deleted file mode 100755 index 50fe97a1..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/default.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_knownhosts,twisted.conch.test.test_default -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Various classes and functions for implementing user-interaction in the -command-line conch client. - -You probably shouldn't use anything in this module directly, since it assumes -you are sitting at an interactive terminal. For example, to programmatically -interact with a known_hosts database, use L{twisted.conch.client.knownhosts}. -""" - -from twisted.python import log -from twisted.python.filepath import FilePath - -from twisted.conch.error import ConchError -from twisted.conch.ssh import common, keys, userauth -from twisted.internet import defer, protocol, reactor - -from twisted.conch.client.knownhosts import KnownHostsFile, ConsoleUI - -from twisted.conch.client import agent - -import os, sys, base64, getpass - -# This name is bound so that the unit tests can use 'patch' to override it. -_open = open - -def verifyHostKey(transport, host, pubKey, fingerprint): - """ - Verify a host's key. - - This function is a gross vestige of some bad factoring in the client - internals. The actual implementation, and a better signature of this logic - is in L{KnownHostsFile.verifyHostKey}. This function is not deprecated yet - because the callers have not yet been rehabilitated, but they should - eventually be changed to call that method instead. - - However, this function does perform two functions not implemented by - L{KnownHostsFile.verifyHostKey}. It determines the path to the user's - known_hosts file based on the options (which should really be the options - object's job), and it provides an opener to L{ConsoleUI} which opens - '/dev/tty' so that the user will be prompted on the tty of the process even - if the input and output of the process has been redirected. This latter - part is, somewhat obviously, not portable, but I don't know of a portable - equivalent that could be used. - - @param host: Due to a bug in L{SSHClientTransport.verifyHostKey}, this is - always the dotted-quad IP address of the host being connected to. - @type host: L{str} - - @param transport: the client transport which is attempting to connect to - the given host. - @type transport: L{SSHClientTransport} - - @param fingerprint: the fingerprint of the given public key, in - xx:xx:xx:... format. This is ignored in favor of getting the fingerprint - from the key itself. - @type fingerprint: L{str} - - @param pubKey: The public key of the server being connected to. - @type pubKey: L{str} - - @return: a L{Deferred} which fires with C{1} if the key was successfully - verified, or fails if the key could not be successfully verified. Failure - types may include L{HostKeyChanged}, L{UserRejectedKey}, L{IOError} or - L{KeyboardInterrupt}. - """ - actualHost = transport.factory.options['host'] - actualKey = keys.Key.fromString(pubKey) - kh = KnownHostsFile.fromPath(FilePath( - transport.factory.options['known-hosts'] - or os.path.expanduser("~/.ssh/known_hosts") - )) - ui = ConsoleUI(lambda : _open("/dev/tty", "r+b")) - return kh.verifyHostKey(ui, actualHost, host, actualKey) - - - -def isInKnownHosts(host, pubKey, options): - """checks to see if host is in the known_hosts file for the user. - returns 0 if it isn't, 1 if it is and is the same, 2 if it's changed. - """ - keyType = common.getNS(pubKey)[0] - retVal = 0 - - if not options['known-hosts'] and not os.path.exists(os.path.expanduser('~/.ssh/')): - print 'Creating ~/.ssh directory...' - os.mkdir(os.path.expanduser('~/.ssh')) - kh_file = options['known-hosts'] or '~/.ssh/known_hosts' - try: - known_hosts = open(os.path.expanduser(kh_file)) - except IOError: - return 0 - for line in known_hosts.xreadlines(): - split = line.split() - if len(split) < 3: - continue - hosts, hostKeyType, encodedKey = split[:3] - if host not in hosts.split(','): # incorrect host - continue - if hostKeyType != keyType: # incorrect type of key - continue - try: - decodedKey = base64.decodestring(encodedKey) - except: - continue - if decodedKey == pubKey: - return 1 - else: - retVal = 2 - return retVal - - - -class SSHUserAuthClient(userauth.SSHUserAuthClient): - - def __init__(self, user, options, *args): - userauth.SSHUserAuthClient.__init__(self, user, *args) - self.keyAgent = None - self.options = options - self.usedFiles = [] - if not options.identitys: - options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa'] - - def serviceStarted(self): - if 'SSH_AUTH_SOCK' in os.environ and not self.options['noagent']: - log.msg('using agent') - cc = protocol.ClientCreator(reactor, agent.SSHAgentClient) - d = cc.connectUNIX(os.environ['SSH_AUTH_SOCK']) - d.addCallback(self._setAgent) - d.addErrback(self._ebSetAgent) - else: - userauth.SSHUserAuthClient.serviceStarted(self) - - def serviceStopped(self): - if self.keyAgent: - self.keyAgent.transport.loseConnection() - self.keyAgent = None - - def _setAgent(self, a): - self.keyAgent = a - d = self.keyAgent.getPublicKeys() - d.addBoth(self._ebSetAgent) - return d - - def _ebSetAgent(self, f): - userauth.SSHUserAuthClient.serviceStarted(self) - - def _getPassword(self, prompt): - try: - oldout, oldin = sys.stdout, sys.stdin - sys.stdin = sys.stdout = open('/dev/tty','r+') - p=getpass.getpass(prompt) - sys.stdout,sys.stdin=oldout,oldin - return p - except (KeyboardInterrupt, IOError): - print - raise ConchError('PEBKAC') - - def getPassword(self, prompt = None): - if not prompt: - prompt = "%s@%s's password: " % (self.user, self.transport.transport.getPeer().host) - try: - p = self._getPassword(prompt) - return defer.succeed(p) - except ConchError: - return defer.fail() - - - def getPublicKey(self): - """ - Get a public key from the key agent if possible, otherwise look in - the next configured identity file for one. - """ - if self.keyAgent: - key = self.keyAgent.getPublicKey() - if key is not None: - return key - files = [x for x in self.options.identitys if x not in self.usedFiles] - log.msg(str(self.options.identitys)) - log.msg(str(files)) - if not files: - return None - file = files[0] - log.msg(file) - self.usedFiles.append(file) - file = os.path.expanduser(file) - file += '.pub' - if not os.path.exists(file): - return self.getPublicKey() # try again - try: - return keys.Key.fromFile(file) - except keys.BadKeyError: - return self.getPublicKey() # try again - - - def signData(self, publicKey, signData): - """ - Extend the base signing behavior by using an SSH agent to sign the - data, if one is available. - - @type publicKey: L{Key} - @type signData: C{str} - """ - if not self.usedFiles: # agent key - return self.keyAgent.signData(publicKey.blob(), signData) - else: - return userauth.SSHUserAuthClient.signData(self, publicKey, signData) - - - def getPrivateKey(self): - """ - Try to load the private key from the last used file identified by - C{getPublicKey}, potentially asking for the passphrase if the key is - encrypted. - """ - file = os.path.expanduser(self.usedFiles[-1]) - if not os.path.exists(file): - return None - try: - return defer.succeed(keys.Key.fromFile(file)) - except keys.EncryptedKeyError: - for i in range(3): - prompt = "Enter passphrase for key '%s': " % \ - self.usedFiles[-1] - try: - p = self._getPassword(prompt) - return defer.succeed(keys.Key.fromFile(file, passphrase=p)) - except (keys.BadKeyError, ConchError): - pass - return defer.fail(ConchError('bad password')) - raise - except KeyboardInterrupt: - print - reactor.stop() - - - def getGenericAnswers(self, name, instruction, prompts): - responses = [] - try: - oldout, oldin = sys.stdout, sys.stdin - sys.stdin = sys.stdout = open('/dev/tty','r+') - if name: - print name - if instruction: - print instruction - for prompt, echo in prompts: - if echo: - responses.append(raw_input(prompt)) - else: - responses.append(getpass.getpass(prompt)) - finally: - sys.stdout,sys.stdin=oldout,oldin - return defer.succeed(responses) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py deleted file mode 100755 index f95a14ae..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/direct.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - - -from twisted.internet import defer, protocol, reactor -from twisted.conch import error -from twisted.conch.ssh import transport -from twisted.python import log - - - -class SSHClientFactory(protocol.ClientFactory): - - def __init__(self, d, options, verifyHostKey, userAuthObject): - self.d = d - self.options = options - self.verifyHostKey = verifyHostKey - self.userAuthObject = userAuthObject - - - def clientConnectionLost(self, connector, reason): - if self.options['reconnect']: - connector.connect() - - - def clientConnectionFailed(self, connector, reason): - if self.d is None: - return - d, self.d = self.d, None - d.errback(reason) - - - def buildProtocol(self, addr): - trans = SSHClientTransport(self) - if self.options['ciphers']: - trans.supportedCiphers = self.options['ciphers'] - if self.options['macs']: - trans.supportedMACs = self.options['macs'] - if self.options['compress']: - trans.supportedCompressions[0:1] = ['zlib'] - if self.options['host-key-algorithms']: - trans.supportedPublicKeys = self.options['host-key-algorithms'] - return trans - - - -class SSHClientTransport(transport.SSHClientTransport): - - def __init__(self, factory): - self.factory = factory - self.unixServer = None - - - def connectionLost(self, reason): - if self.unixServer: - d = self.unixServer.stopListening() - self.unixServer = None - else: - d = defer.succeed(None) - d.addCallback(lambda x: - transport.SSHClientTransport.connectionLost(self, reason)) - - - def receiveError(self, code, desc): - if self.factory.d is None: - return - d, self.factory.d = self.factory.d, None - d.errback(error.ConchError(desc, code)) - - - def sendDisconnect(self, code, reason): - if self.factory.d is None: - return - d, self.factory.d = self.factory.d, None - transport.SSHClientTransport.sendDisconnect(self, code, reason) - d.errback(error.ConchError(reason, code)) - - - def receiveDebug(self, alwaysDisplay, message, lang): - log.msg('Received Debug Message: %s' % message) - if alwaysDisplay: # XXX what should happen here? - print message - - - def verifyHostKey(self, pubKey, fingerprint): - return self.factory.verifyHostKey(self, self.transport.getPeer().host, pubKey, - fingerprint) - - - def setService(self, service): - log.msg('setting client server to %s' % service) - transport.SSHClientTransport.setService(self, service) - if service.name != 'ssh-userauth' and self.factory.d is not None: - d, self.factory.d = self.factory.d, None - d.callback(None) - - - def connectionSecure(self): - self.requestService(self.factory.userAuthObject) - - - -def connect(host, port, options, verifyHostKey, userAuthObject): - d = defer.Deferred() - factory = SSHClientFactory(d, options, verifyHostKey, userAuthObject) - reactor.connectTCP(host, port, factory) - return d diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py deleted file mode 100755 index 48cd89bf..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/knownhosts.py +++ /dev/null @@ -1,478 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_knownhosts -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -An implementation of the OpenSSH known_hosts database. - -@since: 8.2 -""" - -from binascii import Error as DecodeError, b2a_base64 -import hmac -import sys - -from zope.interface import implements - -from twisted.python.randbytes import secureRandom -if sys.version_info >= (2, 5): - from twisted.python.hashlib import sha1 -else: - # We need to have an object with a method named 'new'. - import sha as sha1 - -from twisted.internet import defer - -from twisted.python import log -from twisted.conch.interfaces import IKnownHostEntry -from twisted.conch.error import HostKeyChanged, UserRejectedKey, InvalidEntry -from twisted.conch.ssh.keys import Key, BadKeyError - - -def _b64encode(s): - """ - Encode a binary string as base64 with no trailing newline. - """ - return b2a_base64(s).strip() - - - -def _extractCommon(string): - """ - Extract common elements of base64 keys from an entry in a hosts file. - - @return: a 4-tuple of hostname data (L{str}), ssh key type (L{str}), key - (L{Key}), and comment (L{str} or L{None}). The hostname data is simply the - beginning of the line up to the first occurrence of whitespace. - """ - elements = string.split(None, 2) - if len(elements) != 3: - raise InvalidEntry() - hostnames, keyType, keyAndComment = elements - splitkey = keyAndComment.split(None, 1) - if len(splitkey) == 2: - keyString, comment = splitkey - comment = comment.rstrip("\n") - else: - keyString = splitkey[0] - comment = None - key = Key.fromString(keyString.decode('base64')) - return hostnames, keyType, key, comment - - - -class _BaseEntry(object): - """ - Abstract base of both hashed and non-hashed entry objects, since they - represent keys and key types the same way. - - @ivar keyType: The type of the key; either ssh-dss or ssh-rsa. - @type keyType: L{str} - - @ivar publicKey: The server public key indicated by this line. - @type publicKey: L{twisted.conch.ssh.keys.Key} - - @ivar comment: Trailing garbage after the key line. - @type comment: L{str} - """ - - def __init__(self, keyType, publicKey, comment): - self.keyType = keyType - self.publicKey = publicKey - self.comment = comment - - - def matchesKey(self, keyObject): - """ - Check to see if this entry matches a given key object. - - @type keyObject: L{Key} - - @rtype: bool - """ - return self.publicKey == keyObject - - - -class PlainEntry(_BaseEntry): - """ - A L{PlainEntry} is a representation of a plain-text entry in a known_hosts - file. - - @ivar _hostnames: the list of all host-names associated with this entry. - @type _hostnames: L{list} of L{str} - """ - - implements(IKnownHostEntry) - - def __init__(self, hostnames, keyType, publicKey, comment): - self._hostnames = hostnames - super(PlainEntry, self).__init__(keyType, publicKey, comment) - - - def fromString(cls, string): - """ - Parse a plain-text entry in a known_hosts file, and return a - corresponding L{PlainEntry}. - - @param string: a space-separated string formatted like "hostname - key-type base64-key-data comment". - - @type string: L{str} - - @raise DecodeError: if the key is not valid encoded as valid base64. - - @raise InvalidEntry: if the entry does not have the right number of - elements and is therefore invalid. - - @raise BadKeyError: if the key, once decoded from base64, is not - actually an SSH key. - - @return: an IKnownHostEntry representing the hostname and key in the - input line. - - @rtype: L{PlainEntry} - """ - hostnames, keyType, key, comment = _extractCommon(string) - self = cls(hostnames.split(","), keyType, key, comment) - return self - - fromString = classmethod(fromString) - - - def matchesHost(self, hostname): - """ - Check to see if this entry matches a given hostname. - - @type hostname: L{str} - - @rtype: bool - """ - return hostname in self._hostnames - - - def toString(self): - """ - Implement L{IKnownHostEntry.toString} by recording the comma-separated - hostnames, key type, and base-64 encoded key. - """ - fields = [','.join(self._hostnames), - self.keyType, - _b64encode(self.publicKey.blob())] - if self.comment is not None: - fields.append(self.comment) - return ' '.join(fields) - - -class UnparsedEntry(object): - """ - L{UnparsedEntry} is an entry in a L{KnownHostsFile} which can't actually be - parsed; therefore it matches no keys and no hosts. - """ - - implements(IKnownHostEntry) - - def __init__(self, string): - """ - Create an unparsed entry from a line in a known_hosts file which cannot - otherwise be parsed. - """ - self._string = string - - - def matchesHost(self, hostname): - """ - Always returns False. - """ - return False - - - def matchesKey(self, key): - """ - Always returns False. - """ - return False - - - def toString(self): - """ - Returns the input line, without its newline if one was given. - """ - return self._string.rstrip("\n") - - - -def _hmacedString(key, string): - """ - Return the SHA-1 HMAC hash of the given key and string. - """ - hash = hmac.HMAC(key, digestmod=sha1) - hash.update(string) - return hash.digest() - - - -class HashedEntry(_BaseEntry): - """ - A L{HashedEntry} is a representation of an entry in a known_hosts file - where the hostname has been hashed and salted. - - @ivar _hostSalt: the salt to combine with a hostname for hashing. - - @ivar _hostHash: the hashed representation of the hostname. - - @cvar MAGIC: the 'hash magic' string used to identify a hashed line in a - known_hosts file as opposed to a plaintext one. - """ - - implements(IKnownHostEntry) - - MAGIC = '|1|' - - def __init__(self, hostSalt, hostHash, keyType, publicKey, comment): - self._hostSalt = hostSalt - self._hostHash = hostHash - super(HashedEntry, self).__init__(keyType, publicKey, comment) - - - def fromString(cls, string): - """ - Load a hashed entry from a string representing a line in a known_hosts - file. - - @raise DecodeError: if the key, the hostname, or the is not valid - encoded as valid base64 - - @raise InvalidEntry: if the entry does not have the right number of - elements and is therefore invalid, or the host/hash portion contains - more items than just the host and hash. - - @raise BadKeyError: if the key, once decoded from base64, is not - actually an SSH key. - """ - stuff, keyType, key, comment = _extractCommon(string) - saltAndHash = stuff[len(cls.MAGIC):].split("|") - if len(saltAndHash) != 2: - raise InvalidEntry() - hostSalt, hostHash = saltAndHash - self = cls(hostSalt.decode("base64"), hostHash.decode("base64"), - keyType, key, comment) - return self - - fromString = classmethod(fromString) - - - def matchesHost(self, hostname): - """ - Implement L{IKnownHostEntry.matchesHost} to compare the hash of the - input to the stored hash. - """ - return (_hmacedString(self._hostSalt, hostname) == self._hostHash) - - - def toString(self): - """ - Implement L{IKnownHostEntry.toString} by base64-encoding the salt, host - hash, and key. - """ - fields = [self.MAGIC + '|'.join([_b64encode(self._hostSalt), - _b64encode(self._hostHash)]), - self.keyType, - _b64encode(self.publicKey.blob())] - if self.comment is not None: - fields.append(self.comment) - return ' '.join(fields) - - - -class KnownHostsFile(object): - """ - A structured representation of an OpenSSH-format ~/.ssh/known_hosts file. - - @ivar _entries: a list of L{IKnownHostEntry} providers. - - @ivar _savePath: the L{FilePath} to save new entries to. - """ - - def __init__(self, savePath): - """ - Create a new, empty KnownHostsFile. - - You want to use L{KnownHostsFile.fromPath} to parse one of these. - """ - self._entries = [] - self._savePath = savePath - - - def hasHostKey(self, hostname, key): - """ - @return: True if the given hostname and key are present in this file, - False if they are not. - - @rtype: L{bool} - - @raise HostKeyChanged: if the host key found for the given hostname - does not match the given key. - """ - for lineidx, entry in enumerate(self._entries): - if entry.matchesHost(hostname): - if entry.matchesKey(key): - return True - else: - raise HostKeyChanged(entry, self._savePath, lineidx + 1) - return False - - - def verifyHostKey(self, ui, hostname, ip, key): - """ - Verify the given host key for the given IP and host, asking for - confirmation from, and notifying, the given UI about changes to this - file. - - @param ui: The user interface to request an IP address from. - - @param hostname: The hostname that the user requested to connect to. - - @param ip: The string representation of the IP address that is actually - being connected to. - - @param key: The public key of the server. - - @return: a L{Deferred} that fires with True when the key has been - verified, or fires with an errback when the key either cannot be - verified or has changed. - - @rtype: L{Deferred} - """ - hhk = defer.maybeDeferred(self.hasHostKey, hostname, key) - def gotHasKey(result): - if result: - if not self.hasHostKey(ip, key): - ui.warn("Warning: Permanently added the %s host key for " - "IP address '%s' to the list of known hosts." % - (key.type(), ip)) - self.addHostKey(ip, key) - self.save() - return result - else: - def promptResponse(response): - if response: - self.addHostKey(hostname, key) - self.addHostKey(ip, key) - self.save() - return response - else: - raise UserRejectedKey() - return ui.prompt( - "The authenticity of host '%s (%s)' " - "can't be established.\n" - "RSA key fingerprint is %s.\n" - "Are you sure you want to continue connecting (yes/no)? " % - (hostname, ip, key.fingerprint())).addCallback(promptResponse) - return hhk.addCallback(gotHasKey) - - - def addHostKey(self, hostname, key): - """ - Add a new L{HashedEntry} to the key database. - - Note that you still need to call L{KnownHostsFile.save} if you wish - these changes to be persisted. - - @return: the L{HashedEntry} that was added. - """ - salt = secureRandom(20) - keyType = "ssh-" + key.type().lower() - entry = HashedEntry(salt, _hmacedString(salt, hostname), - keyType, key, None) - self._entries.append(entry) - return entry - - - def save(self): - """ - Save this L{KnownHostsFile} to the path it was loaded from. - """ - p = self._savePath.parent() - if not p.isdir(): - p.makedirs() - self._savePath.setContent('\n'.join( - [entry.toString() for entry in self._entries]) + "\n") - - - def fromPath(cls, path): - """ - @param path: A path object to use for both reading contents from and - later saving to. - - @type path: L{FilePath} - """ - self = cls(path) - try: - fp = path.open() - except IOError: - return self - for line in fp: - try: - if line.startswith(HashedEntry.MAGIC): - entry = HashedEntry.fromString(line) - else: - entry = PlainEntry.fromString(line) - except (DecodeError, InvalidEntry, BadKeyError): - entry = UnparsedEntry(line) - self._entries.append(entry) - return self - - fromPath = classmethod(fromPath) - - -class ConsoleUI(object): - """ - A UI object that can ask true/false questions and post notifications on the - console, to be used during key verification. - - @ivar opener: a no-argument callable which should open a console file-like - object to be used for reading and writing. - """ - - def __init__(self, opener): - self.opener = opener - - - def prompt(self, text): - """ - Write the given text as a prompt to the console output, then read a - result from the console input. - - @return: a L{Deferred} which fires with L{True} when the user answers - 'yes' and L{False} when the user answers 'no'. It may errback if there - were any I/O errors. - """ - d = defer.succeed(None) - def body(ignored): - f = self.opener() - f.write(text) - while True: - answer = f.readline().strip().lower() - if answer == 'yes': - f.close() - return True - elif answer == 'no': - f.close() - return False - else: - f.write("Please type 'yes' or 'no': ") - return d.addCallback(body) - - - def warn(self, text): - """ - Notify the user (non-interactively) of the provided text, by writing it - to the console. - """ - try: - f = self.opener() - f.write(text) - f.close() - except: - log.err() diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py deleted file mode 100755 index 8550573d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/client/options.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -from twisted.conch.ssh.transport import SSHClientTransport, SSHCiphers -from twisted.python import usage - -import sys - -class ConchOptions(usage.Options): - - optParameters = [['user', 'l', None, 'Log in using this user name.'], - ['identity', 'i', None], - ['ciphers', 'c', None], - ['macs', 'm', None], - ['port', 'p', None, 'Connect to this port. Server must be on the same port.'], - ['option', 'o', None, 'Ignored OpenSSH options'], - ['host-key-algorithms', '', None], - ['known-hosts', '', None, 'File to check for host keys'], - ['user-authentications', '', None, 'Types of user authentications to use.'], - ['logfile', '', None, 'File to log to, or - for stdout'], - ] - - optFlags = [['version', 'V', 'Display version number only.'], - ['compress', 'C', 'Enable compression.'], - ['log', 'v', 'Enable logging (defaults to stderr)'], - ['nox11', 'x', 'Disable X11 connection forwarding (default)'], - ['agent', 'A', 'Enable authentication agent forwarding'], - ['noagent', 'a', 'Disable authentication agent forwarding (default)'], - ['reconnect', 'r', 'Reconnect to the server if the connection is lost.'], - ] - - compData = usage.Completions( - mutuallyExclusive=[("agent", "noagent")], - optActions={ - "user": usage.CompleteUsernames(), - "ciphers": usage.CompleteMultiList( - SSHCiphers.cipherMap.keys(), - descr='ciphers to choose from'), - "macs": usage.CompleteMultiList( - SSHCiphers.macMap.keys(), - descr='macs to choose from'), - "host-key-algorithms": usage.CompleteMultiList( - SSHClientTransport.supportedPublicKeys, - descr='host key algorithms to choose from'), - #"user-authentications": usage.CompleteMultiList(? - # descr='user authentication types' ), - }, - extraActions=[usage.CompleteUserAtHost(), - usage.Completer(descr="command"), - usage.Completer(descr='argument', - repeat=True)] - ) - - def __init__(self, *args, **kw): - usage.Options.__init__(self, *args, **kw) - self.identitys = [] - self.conns = None - - def opt_identity(self, i): - """Identity for public-key authentication""" - self.identitys.append(i) - - def opt_ciphers(self, ciphers): - "Select encryption algorithms" - ciphers = ciphers.split(',') - for cipher in ciphers: - if not SSHCiphers.cipherMap.has_key(cipher): - sys.exit("Unknown cipher type '%s'" % cipher) - self['ciphers'] = ciphers - - - def opt_macs(self, macs): - "Specify MAC algorithms" - macs = macs.split(',') - for mac in macs: - if not SSHCiphers.macMap.has_key(mac): - sys.exit("Unknown mac type '%s'" % mac) - self['macs'] = macs - - def opt_host_key_algorithms(self, hkas): - "Select host key algorithms" - hkas = hkas.split(',') - for hka in hkas: - if hka not in SSHClientTransport.supportedPublicKeys: - sys.exit("Unknown host key type '%s'" % hka) - self['host-key-algorithms'] = hkas - - def opt_user_authentications(self, uas): - "Choose how to authenticate to the remote server" - self['user-authentications'] = uas.split(',') - -# def opt_compress(self): -# "Enable compression" -# self.enableCompression = 1 -# SSHClientTransport.supportedCompressions[0:1] = ['zlib'] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py deleted file mode 100755 index a3bcc65e..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/error.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -An error to represent bad things happening in Conch. - -Maintainer: Paul Swartz -""" - -from twisted.cred.error import UnauthorizedLogin - - - -class ConchError(Exception): - def __init__(self, value, data = None): - Exception.__init__(self, value, data) - self.value = value - self.data = data - - - -class NotEnoughAuthentication(Exception): - """ - This is thrown if the authentication is valid, but is not enough to - successfully verify the user. i.e. don't retry this type of - authentication, try another one. - """ - - - -class ValidPublicKey(UnauthorizedLogin): - """ - Raised by public key checkers when they receive public key credentials - that don't contain a signature at all, but are valid in every other way. - (e.g. the public key matches one in the user's authorized_keys file). - - Protocol code (eg - L{SSHUserAuthServer<twisted.conch.ssh.userauth.SSHUserAuthServer>}) which - attempts to log in using - L{ISSHPrivateKey<twisted.cred.credentials.ISSHPrivateKey>} credentials - should be prepared to handle a failure of this type by telling the user to - re-authenticate using the same key and to include a signature with the new - attempt. - - See U{http://www.ietf.org/rfc/rfc4252.txt} section 7 for more details. - """ - - - -class IgnoreAuthentication(Exception): - """ - This is thrown to let the UserAuthServer know it doesn't need to handle the - authentication anymore. - """ - - - -class MissingKeyStoreError(Exception): - """ - Raised if an SSHAgentServer starts receiving data without its factory - providing a keys dict on which to read/write key data. - """ - - - -class UserRejectedKey(Exception): - """ - The user interactively rejected a key. - """ - - - -class InvalidEntry(Exception): - """ - An entry in a known_hosts file could not be interpreted as a valid entry. - """ - - - -class HostKeyChanged(Exception): - """ - The host key of a remote host has changed. - - @ivar offendingEntry: The entry which contains the persistent host key that - disagrees with the given host key. - - @type offendingEntry: L{twisted.conch.interfaces.IKnownHostEntry} - - @ivar path: a reference to the known_hosts file that the offending entry - was loaded from - - @type path: L{twisted.python.filepath.FilePath} - - @ivar lineno: The line number of the offending entry in the given path. - - @type lineno: L{int} - """ - def __init__(self, offendingEntry, path, lineno): - Exception.__init__(self) - self.offendingEntry = offendingEntry - self.path = path - self.lineno = lineno diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py deleted file mode 100755 index c070d4f5..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -Insults: a replacement for Curses/S-Lang. - -Very basic at the moment.""" - -from twisted.python import deprecate, versions - -deprecate.deprecatedModuleAttribute( - versions.Version("Twisted", 10, 1, 0), - "Please use twisted.conch.insults.helper instead.", - __name__, "colors") - -deprecate.deprecatedModuleAttribute( - versions.Version("Twisted", 10, 1, 0), - "Please use twisted.conch.insults.insults instead.", - __name__, "client") diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py deleted file mode 100755 index 89c79cda..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/client.py +++ /dev/null @@ -1,138 +0,0 @@ -""" -You don't really want to use this module. Try insults.py instead. -""" - -from twisted.internet import protocol - -class InsultsClient(protocol.Protocol): - - escapeTimeout = 0.2 - - def __init__(self): - self.width = self.height = None - self.xpos = self.ypos = 0 - self.commandQueue = [] - self.inEscape = '' - - def setSize(self, width, height): - call = 0 - if self.width: - call = 1 - self.width = width - self.height = height - if call: - self.windowSizeChanged() - - def dataReceived(self, data): - from twisted.internet import reactor - for ch in data: - if ch == '\x1b': - if self.inEscape: - self.keyReceived(ch) - self.inEscape = '' - else: - self.inEscape = ch - self.escapeCall = reactor.callLater(self.escapeTimeout, - self.endEscape) - elif ch in 'ABCD' and self.inEscape: - self.inEscape = '' - self.escapeCall.cancel() - if ch == 'A': - self.keyReceived('<Up>') - elif ch == 'B': - self.keyReceived('<Down>') - elif ch == 'C': - self.keyReceived('<Right>') - elif ch == 'D': - self.keyReceived('<Left>') - elif self.inEscape: - self.inEscape += ch - else: - self.keyReceived(ch) - - def endEscape(self): - ch = self.inEscape - self.inEscape = '' - self.keyReceived(ch) - - def initScreen(self): - self.transport.write('\x1b=\x1b[?1h') - - def gotoXY(self, x, y): - """Go to a position on the screen. - """ - self.xpos = x - self.ypos = y - self.commandQueue.append(('gotoxy', x, y)) - - def writeCh(self, ch): - """Write a character to the screen. If we're at the end of the row, - ignore the write. - """ - if self.xpos < self.width - 1: - self.commandQueue.append(('write', ch)) - self.xpos += 1 - - def writeStr(self, s): - """Write a string to the screen. This does not wrap a the edge of the - screen, and stops at \\r and \\n. - """ - s = s[:self.width-self.xpos] - if '\n' in s: - s=s[:s.find('\n')] - if '\r' in s: - s=s[:s.find('\r')] - self.commandQueue.append(('write', s)) - self.xpos += len(s) - - def eraseToLine(self): - """Erase from the current position to the end of the line. - """ - self.commandQueue.append(('eraseeol',)) - - def eraseToScreen(self): - """Erase from the current position to the end of the screen. - """ - self.commandQueue.append(('eraseeos',)) - - def clearScreen(self): - """Clear the screen, and return the cursor to 0, 0. - """ - self.commandQueue = [('cls',)] - self.xpos = self.ypos = 0 - - def setAttributes(self, *attrs): - """Set the attributes for drawing on the screen. - """ - self.commandQueue.append(('attributes', attrs)) - - def refresh(self): - """Redraw the screen. - """ - redraw = '' - for command in self.commandQueue: - if command[0] == 'gotoxy': - redraw += '\x1b[%i;%iH' % (command[2]+1, command[1]+1) - elif command[0] == 'write': - redraw += command[1] - elif command[0] == 'eraseeol': - redraw += '\x1b[0K' - elif command[0] == 'eraseeos': - redraw += '\x1b[OJ' - elif command[0] == 'cls': - redraw += '\x1b[H\x1b[J' - elif command[0] == 'attributes': - redraw += '\x1b[%sm' % ';'.join(map(str, command[1])) - else: - print command - self.commandQueue = [] - self.transport.write(redraw) - - def windowSizeChanged(self): - """Called when the size of the window changes. - Might want to redraw the screen here, or something. - """ - - def keyReceived(self, key): - """Called when the user hits a key. - """ diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py deleted file mode 100755 index c12ab16f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/colors.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -You don't really want to use this module. Try helper.py instead. -""" - -CLEAR = 0 -BOLD = 1 -DIM = 2 -ITALIC = 3 -UNDERSCORE = 4 -BLINK_SLOW = 5 -BLINK_FAST = 6 -REVERSE = 7 -CONCEALED = 8 -FG_BLACK = 30 -FG_RED = 31 -FG_GREEN = 32 -FG_YELLOW = 33 -FG_BLUE = 34 -FG_MAGENTA = 35 -FG_CYAN = 36 -FG_WHITE = 37 -BG_BLACK = 40 -BG_RED = 41 -BG_GREEN = 42 -BG_YELLOW = 43 -BG_BLUE = 44 -BG_MAGENTA = 45 -BG_CYAN = 46 -BG_WHITE = 47 diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py deleted file mode 100755 index ed645c48..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/helper.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_helper -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Partial in-memory terminal emulator - -@author: Jp Calderone -""" - -import re, string - -from zope.interface import implements - -from twisted.internet import defer, protocol, reactor -from twisted.python import log - -from twisted.conch.insults import insults - -FOREGROUND = 30 -BACKGROUND = 40 -BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, N_COLORS = range(9) - -class CharacterAttribute: - """Represents the attributes of a single character. - - Character set, intensity, underlinedness, blinkitude, video - reversal, as well as foreground and background colors made up a - character's attributes. - """ - def __init__(self, charset=insults.G0, - bold=False, underline=False, - blink=False, reverseVideo=False, - foreground=WHITE, background=BLACK, - - _subtracting=False): - self.charset = charset - self.bold = bold - self.underline = underline - self.blink = blink - self.reverseVideo = reverseVideo - self.foreground = foreground - self.background = background - - self._subtracting = _subtracting - - def __eq__(self, other): - return vars(self) == vars(other) - - def __ne__(self, other): - return not self.__eq__(other) - - def copy(self): - c = self.__class__() - c.__dict__.update(vars(self)) - return c - - def wantOne(self, **kw): - k, v = kw.popitem() - if getattr(self, k) != v: - attr = self.copy() - attr._subtracting = not v - setattr(attr, k, v) - return attr - else: - return self.copy() - - def toVT102(self): - # Spit out a vt102 control sequence that will set up - # all the attributes set here. Except charset. - attrs = [] - if self._subtracting: - attrs.append(0) - if self.bold: - attrs.append(insults.BOLD) - if self.underline: - attrs.append(insults.UNDERLINE) - if self.blink: - attrs.append(insults.BLINK) - if self.reverseVideo: - attrs.append(insults.REVERSE_VIDEO) - if self.foreground != WHITE: - attrs.append(FOREGROUND + self.foreground) - if self.background != BLACK: - attrs.append(BACKGROUND + self.background) - if attrs: - return '\x1b[' + ';'.join(map(str, attrs)) + 'm' - return '' - -# XXX - need to support scroll regions and scroll history -class TerminalBuffer(protocol.Protocol): - """ - An in-memory terminal emulator. - """ - implements(insults.ITerminalTransport) - - for keyID in ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW', - 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN', - 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', - 'F10', 'F11', 'F12'): - exec '%s = object()' % (keyID,) - - TAB = '\t' - BACKSPACE = '\x7f' - - width = 80 - height = 24 - - fill = ' ' - void = object() - - def getCharacter(self, x, y): - return self.lines[y][x] - - def connectionMade(self): - self.reset() - - def write(self, bytes): - """ - Add the given printable bytes to the terminal. - - Line feeds in C{bytes} will be replaced with carriage return / line - feed pairs. - """ - for b in bytes.replace('\n', '\r\n'): - self.insertAtCursor(b) - - def _currentCharacterAttributes(self): - return CharacterAttribute(self.activeCharset, **self.graphicRendition) - - def insertAtCursor(self, b): - """ - Add one byte to the terminal at the cursor and make consequent state - updates. - - If b is a carriage return, move the cursor to the beginning of the - current row. - - If b is a line feed, move the cursor to the next row or scroll down if - the cursor is already in the last row. - - Otherwise, if b is printable, put it at the cursor position (inserting - or overwriting as dictated by the current mode) and move the cursor. - """ - if b == '\r': - self.x = 0 - elif b == '\n': - self._scrollDown() - elif b in string.printable: - if self.x >= self.width: - self.nextLine() - ch = (b, self._currentCharacterAttributes()) - if self.modes.get(insults.modes.IRM): - self.lines[self.y][self.x:self.x] = [ch] - self.lines[self.y].pop() - else: - self.lines[self.y][self.x] = ch - self.x += 1 - - def _emptyLine(self, width): - return [(self.void, self._currentCharacterAttributes()) for i in xrange(width)] - - def _scrollDown(self): - self.y += 1 - if self.y >= self.height: - self.y -= 1 - del self.lines[0] - self.lines.append(self._emptyLine(self.width)) - - def _scrollUp(self): - self.y -= 1 - if self.y < 0: - self.y = 0 - del self.lines[-1] - self.lines.insert(0, self._emptyLine(self.width)) - - def cursorUp(self, n=1): - self.y = max(0, self.y - n) - - def cursorDown(self, n=1): - self.y = min(self.height - 1, self.y + n) - - def cursorBackward(self, n=1): - self.x = max(0, self.x - n) - - def cursorForward(self, n=1): - self.x = min(self.width, self.x + n) - - def cursorPosition(self, column, line): - self.x = column - self.y = line - - def cursorHome(self): - self.x = self.home.x - self.y = self.home.y - - def index(self): - self._scrollDown() - - def reverseIndex(self): - self._scrollUp() - - def nextLine(self): - """ - Update the cursor position attributes and scroll down if appropriate. - """ - self.x = 0 - self._scrollDown() - - def saveCursor(self): - self._savedCursor = (self.x, self.y) - - def restoreCursor(self): - self.x, self.y = self._savedCursor - del self._savedCursor - - def setModes(self, modes): - for m in modes: - self.modes[m] = True - - def resetModes(self, modes): - for m in modes: - try: - del self.modes[m] - except KeyError: - pass - - - def setPrivateModes(self, modes): - """ - Enable the given modes. - - Track which modes have been enabled so that the implementations of - other L{insults.ITerminalTransport} methods can be properly implemented - to respect these settings. - - @see: L{resetPrivateModes} - @see: L{insults.ITerminalTransport.setPrivateModes} - """ - for m in modes: - self.privateModes[m] = True - - - def resetPrivateModes(self, modes): - """ - Disable the given modes. - - @see: L{setPrivateModes} - @see: L{insults.ITerminalTransport.resetPrivateModes} - """ - for m in modes: - try: - del self.privateModes[m] - except KeyError: - pass - - - def applicationKeypadMode(self): - self.keypadMode = 'app' - - def numericKeypadMode(self): - self.keypadMode = 'num' - - def selectCharacterSet(self, charSet, which): - self.charsets[which] = charSet - - def shiftIn(self): - self.activeCharset = insults.G0 - - def shiftOut(self): - self.activeCharset = insults.G1 - - def singleShift2(self): - oldActiveCharset = self.activeCharset - self.activeCharset = insults.G2 - f = self.insertAtCursor - def insertAtCursor(b): - f(b) - del self.insertAtCursor - self.activeCharset = oldActiveCharset - self.insertAtCursor = insertAtCursor - - def singleShift3(self): - oldActiveCharset = self.activeCharset - self.activeCharset = insults.G3 - f = self.insertAtCursor - def insertAtCursor(b): - f(b) - del self.insertAtCursor - self.activeCharset = oldActiveCharset - self.insertAtCursor = insertAtCursor - - def selectGraphicRendition(self, *attributes): - for a in attributes: - if a == insults.NORMAL: - self.graphicRendition = { - 'bold': False, - 'underline': False, - 'blink': False, - 'reverseVideo': False, - 'foreground': WHITE, - 'background': BLACK} - elif a == insults.BOLD: - self.graphicRendition['bold'] = True - elif a == insults.UNDERLINE: - self.graphicRendition['underline'] = True - elif a == insults.BLINK: - self.graphicRendition['blink'] = True - elif a == insults.REVERSE_VIDEO: - self.graphicRendition['reverseVideo'] = True - else: - try: - v = int(a) - except ValueError: - log.msg("Unknown graphic rendition attribute: " + repr(a)) - else: - if FOREGROUND <= v <= FOREGROUND + N_COLORS: - self.graphicRendition['foreground'] = v - FOREGROUND - elif BACKGROUND <= v <= BACKGROUND + N_COLORS: - self.graphicRendition['background'] = v - BACKGROUND - else: - log.msg("Unknown graphic rendition attribute: " + repr(a)) - - def eraseLine(self): - self.lines[self.y] = self._emptyLine(self.width) - - def eraseToLineEnd(self): - width = self.width - self.x - self.lines[self.y][self.x:] = self._emptyLine(width) - - def eraseToLineBeginning(self): - self.lines[self.y][:self.x + 1] = self._emptyLine(self.x + 1) - - def eraseDisplay(self): - self.lines = [self._emptyLine(self.width) for i in xrange(self.height)] - - def eraseToDisplayEnd(self): - self.eraseToLineEnd() - height = self.height - self.y - 1 - self.lines[self.y + 1:] = [self._emptyLine(self.width) for i in range(height)] - - def eraseToDisplayBeginning(self): - self.eraseToLineBeginning() - self.lines[:self.y] = [self._emptyLine(self.width) for i in range(self.y)] - - def deleteCharacter(self, n=1): - del self.lines[self.y][self.x:self.x+n] - self.lines[self.y].extend(self._emptyLine(min(self.width - self.x, n))) - - def insertLine(self, n=1): - self.lines[self.y:self.y] = [self._emptyLine(self.width) for i in range(n)] - del self.lines[self.height:] - - def deleteLine(self, n=1): - del self.lines[self.y:self.y+n] - self.lines.extend([self._emptyLine(self.width) for i in range(n)]) - - def reportCursorPosition(self): - return (self.x, self.y) - - def reset(self): - self.home = insults.Vector(0, 0) - self.x = self.y = 0 - self.modes = {} - self.privateModes = {} - self.setPrivateModes([insults.privateModes.AUTO_WRAP, - insults.privateModes.CURSOR_MODE]) - self.numericKeypad = 'app' - self.activeCharset = insults.G0 - self.graphicRendition = { - 'bold': False, - 'underline': False, - 'blink': False, - 'reverseVideo': False, - 'foreground': WHITE, - 'background': BLACK} - self.charsets = { - insults.G0: insults.CS_US, - insults.G1: insults.CS_US, - insults.G2: insults.CS_ALTERNATE, - insults.G3: insults.CS_ALTERNATE_SPECIAL} - self.eraseDisplay() - - def unhandledControlSequence(self, buf): - print 'Could not handle', repr(buf) - - def __str__(self): - lines = [] - for L in self.lines: - buf = [] - length = 0 - for (ch, attr) in L: - if ch is not self.void: - buf.append(ch) - length = len(buf) - else: - buf.append(self.fill) - lines.append(''.join(buf[:length])) - return '\n'.join(lines) - -class ExpectationTimeout(Exception): - pass - -class ExpectableBuffer(TerminalBuffer): - _mark = 0 - - def connectionMade(self): - TerminalBuffer.connectionMade(self) - self._expecting = [] - - def write(self, bytes): - TerminalBuffer.write(self, bytes) - self._checkExpected() - - def cursorHome(self): - TerminalBuffer.cursorHome(self) - self._mark = 0 - - def _timeoutExpected(self, d): - d.errback(ExpectationTimeout()) - self._checkExpected() - - def _checkExpected(self): - s = str(self)[self._mark:] - while self._expecting: - expr, timer, deferred = self._expecting[0] - if timer and not timer.active(): - del self._expecting[0] - continue - for match in expr.finditer(s): - if timer: - timer.cancel() - del self._expecting[0] - self._mark += match.end() - s = s[match.end():] - deferred.callback(match) - break - else: - return - - def expect(self, expression, timeout=None, scheduler=reactor): - d = defer.Deferred() - timer = None - if timeout: - timer = scheduler.callLater(timeout, self._timeoutExpected, d) - self._expecting.append((re.compile(expression), timer, d)) - self._checkExpected() - return d - -__all__ = ['CharacterAttribute', 'TerminalBuffer', 'ExpectableBuffer'] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py deleted file mode 100755 index 721551de..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/insults.py +++ /dev/null @@ -1,1087 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_insults -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -VT102 and VT220 terminal manipulation. - -@author: Jp Calderone -""" - -from zope.interface import implements, Interface - -from twisted.internet import protocol, defer, interfaces as iinternet - -class ITerminalProtocol(Interface): - def makeConnection(transport): - """Called with an L{ITerminalTransport} when a connection is established. - """ - - def keystrokeReceived(keyID, modifier): - """A keystroke was received. - - Each keystroke corresponds to one invocation of this method. - keyID is a string identifier for that key. Printable characters - are represented by themselves. Control keys, such as arrows and - function keys, are represented with symbolic constants on - L{ServerProtocol}. - """ - - def terminalSize(width, height): - """Called to indicate the size of the terminal. - - A terminal of 80x24 should be assumed if this method is not - called. This method might not be called for real terminals. - """ - - def unhandledControlSequence(seq): - """Called when an unsupported control sequence is received. - - @type seq: C{str} - @param seq: The whole control sequence which could not be interpreted. - """ - - def connectionLost(reason): - """Called when the connection has been lost. - - reason is a Failure describing why. - """ - -class TerminalProtocol(object): - implements(ITerminalProtocol) - - def makeConnection(self, terminal): - # assert ITerminalTransport.providedBy(transport), "TerminalProtocol.makeConnection must be passed an ITerminalTransport implementor" - self.terminal = terminal - self.connectionMade() - - def connectionMade(self): - """Called after a connection has been established. - """ - - def keystrokeReceived(self, keyID, modifier): - pass - - def terminalSize(self, width, height): - pass - - def unhandledControlSequence(self, seq): - pass - - def connectionLost(self, reason): - pass - -class ITerminalTransport(iinternet.ITransport): - def cursorUp(n=1): - """Move the cursor up n lines. - """ - - def cursorDown(n=1): - """Move the cursor down n lines. - """ - - def cursorForward(n=1): - """Move the cursor right n columns. - """ - - def cursorBackward(n=1): - """Move the cursor left n columns. - """ - - def cursorPosition(column, line): - """Move the cursor to the given line and column. - """ - - def cursorHome(): - """Move the cursor home. - """ - - def index(): - """Move the cursor down one line, performing scrolling if necessary. - """ - - def reverseIndex(): - """Move the cursor up one line, performing scrolling if necessary. - """ - - def nextLine(): - """Move the cursor to the first position on the next line, performing scrolling if necessary. - """ - - def saveCursor(): - """Save the cursor position, character attribute, character set, and origin mode selection. - """ - - def restoreCursor(): - """Restore the previously saved cursor position, character attribute, character set, and origin mode selection. - - If no cursor state was previously saved, move the cursor to the home position. - """ - - def setModes(modes): - """Set the given modes on the terminal. - """ - - def resetModes(mode): - """Reset the given modes on the terminal. - """ - - - def setPrivateModes(modes): - """ - Set the given DEC private modes on the terminal. - """ - - - def resetPrivateModes(modes): - """ - Reset the given DEC private modes on the terminal. - """ - - - def applicationKeypadMode(): - """Cause keypad to generate control functions. - - Cursor key mode selects the type of characters generated by cursor keys. - """ - - def numericKeypadMode(): - """Cause keypad to generate normal characters. - """ - - def selectCharacterSet(charSet, which): - """Select a character set. - - charSet should be one of CS_US, CS_UK, CS_DRAWING, CS_ALTERNATE, or - CS_ALTERNATE_SPECIAL. - - which should be one of G0 or G1. - """ - - def shiftIn(): - """Activate the G0 character set. - """ - - def shiftOut(): - """Activate the G1 character set. - """ - - def singleShift2(): - """Shift to the G2 character set for a single character. - """ - - def singleShift3(): - """Shift to the G3 character set for a single character. - """ - - def selectGraphicRendition(*attributes): - """Enabled one or more character attributes. - - Arguments should be one or more of UNDERLINE, REVERSE_VIDEO, BLINK, or BOLD. - NORMAL may also be specified to disable all character attributes. - """ - - def horizontalTabulationSet(): - """Set a tab stop at the current cursor position. - """ - - def tabulationClear(): - """Clear the tab stop at the current cursor position. - """ - - def tabulationClearAll(): - """Clear all tab stops. - """ - - def doubleHeightLine(top=True): - """Make the current line the top or bottom half of a double-height, double-width line. - - If top is True, the current line is the top half. Otherwise, it is the bottom half. - """ - - def singleWidthLine(): - """Make the current line a single-width, single-height line. - """ - - def doubleWidthLine(): - """Make the current line a double-width line. - """ - - def eraseToLineEnd(): - """Erase from the cursor to the end of line, including cursor position. - """ - - def eraseToLineBeginning(): - """Erase from the cursor to the beginning of the line, including the cursor position. - """ - - def eraseLine(): - """Erase the entire cursor line. - """ - - def eraseToDisplayEnd(): - """Erase from the cursor to the end of the display, including the cursor position. - """ - - def eraseToDisplayBeginning(): - """Erase from the cursor to the beginning of the display, including the cursor position. - """ - - def eraseDisplay(): - """Erase the entire display. - """ - - def deleteCharacter(n=1): - """Delete n characters starting at the cursor position. - - Characters to the right of deleted characters are shifted to the left. - """ - - def insertLine(n=1): - """Insert n lines at the cursor position. - - Lines below the cursor are shifted down. Lines moved past the bottom margin are lost. - This command is ignored when the cursor is outside the scroll region. - """ - - def deleteLine(n=1): - """Delete n lines starting at the cursor position. - - Lines below the cursor are shifted up. This command is ignored when the cursor is outside - the scroll region. - """ - - def reportCursorPosition(): - """Return a Deferred that fires with a two-tuple of (x, y) indicating the cursor position. - """ - - def reset(): - """Reset the terminal to its initial state. - """ - - def unhandledControlSequence(seq): - """Called when an unsupported control sequence is received. - - @type seq: C{str} - @param seq: The whole control sequence which could not be interpreted. - """ - - -CSI = '\x1b' -CST = {'~': 'tilde'} - -class modes: - """ECMA 48 standardized modes - """ - - # BREAKS YOPUR KEYBOARD MOFO - KEYBOARD_ACTION = KAM = 2 - - # When set, enables character insertion. New display characters - # move old display characters to the right. Characters moved past - # the right margin are lost. - - # When reset, enables replacement mode (disables character - # insertion). New display characters replace old display - # characters at cursor position. The old character is erased. - INSERTION_REPLACEMENT = IRM = 4 - - # Set causes a received linefeed, form feed, or vertical tab to - # move cursor to first column of next line. RETURN transmits both - # a carriage return and linefeed. This selection is also called - # new line option. - - # Reset causes a received linefeed, form feed, or vertical tab to - # move cursor to next line in current column. RETURN transmits a - # carriage return. - LINEFEED_NEWLINE = LNM = 20 - - -class privateModes: - """ANSI-Compatible Private Modes - """ - ERROR = 0 - CURSOR_KEY = 1 - ANSI_VT52 = 2 - COLUMN = 3 - SCROLL = 4 - SCREEN = 5 - ORIGIN = 6 - AUTO_WRAP = 7 - AUTO_REPEAT = 8 - PRINTER_FORM_FEED = 18 - PRINTER_EXTENT = 19 - - # Toggle cursor visibility (reset hides it) - CURSOR_MODE = 25 - - -# Character sets -CS_US = 'CS_US' -CS_UK = 'CS_UK' -CS_DRAWING = 'CS_DRAWING' -CS_ALTERNATE = 'CS_ALTERNATE' -CS_ALTERNATE_SPECIAL = 'CS_ALTERNATE_SPECIAL' - -# Groupings (or something?? These are like variables that can be bound to character sets) -G0 = 'G0' -G1 = 'G1' - -# G2 and G3 cannot be changed, but they can be shifted to. -G2 = 'G2' -G3 = 'G3' - -# Character attributes - -NORMAL = 0 -BOLD = 1 -UNDERLINE = 4 -BLINK = 5 -REVERSE_VIDEO = 7 - -class Vector: - def __init__(self, x, y): - self.x = x - self.y = y - -def log(s): - file('log', 'a').write(str(s) + '\n') - -# XXX TODO - These attributes are really part of the -# ITerminalTransport interface, I think. -_KEY_NAMES = ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW', - 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN', 'NUMPAD_MIDDLE', - 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', - 'F10', 'F11', 'F12', - - 'ALT', 'SHIFT', 'CONTROL') - -class _const(object): - """ - @ivar name: A string naming this constant - """ - def __init__(self, name): - self.name = name - - def __repr__(self): - return '[' + self.name + ']' - - -FUNCTION_KEYS = [ - _const(_name) for _name in _KEY_NAMES] - -class ServerProtocol(protocol.Protocol): - implements(ITerminalTransport) - - protocolFactory = None - terminalProtocol = None - - TAB = '\t' - BACKSPACE = '\x7f' - ## - - lastWrite = '' - - state = 'data' - - termSize = Vector(80, 24) - cursorPos = Vector(0, 0) - scrollRegion = None - - # Factory who instantiated me - factory = None - - def __init__(self, protocolFactory=None, *a, **kw): - """ - @param protocolFactory: A callable which will be invoked with - *a, **kw and should return an ITerminalProtocol implementor. - This will be invoked when a connection to this ServerProtocol - is established. - - @param a: Any positional arguments to pass to protocolFactory. - @param kw: Any keyword arguments to pass to protocolFactory. - """ - # assert protocolFactory is None or ITerminalProtocol.implementedBy(protocolFactory), "ServerProtocol.__init__ must be passed an ITerminalProtocol implementor" - if protocolFactory is not None: - self.protocolFactory = protocolFactory - self.protocolArgs = a - self.protocolKwArgs = kw - - self._cursorReports = [] - - def connectionMade(self): - if self.protocolFactory is not None: - self.terminalProtocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs) - - try: - factory = self.factory - except AttributeError: - pass - else: - self.terminalProtocol.factory = factory - - self.terminalProtocol.makeConnection(self) - - def dataReceived(self, data): - for ch in data: - if self.state == 'data': - if ch == '\x1b': - self.state = 'escaped' - else: - self.terminalProtocol.keystrokeReceived(ch, None) - elif self.state == 'escaped': - if ch == '[': - self.state = 'bracket-escaped' - self.escBuf = [] - elif ch == 'O': - self.state = 'low-function-escaped' - else: - self.state = 'data' - self._handleShortControlSequence(ch) - elif self.state == 'bracket-escaped': - if ch == 'O': - self.state = 'low-function-escaped' - elif ch.isalpha() or ch == '~': - self._handleControlSequence(''.join(self.escBuf) + ch) - del self.escBuf - self.state = 'data' - else: - self.escBuf.append(ch) - elif self.state == 'low-function-escaped': - self._handleLowFunctionControlSequence(ch) - self.state = 'data' - else: - raise ValueError("Illegal state") - - def _handleShortControlSequence(self, ch): - self.terminalProtocol.keystrokeReceived(ch, self.ALT) - - def _handleControlSequence(self, buf): - buf = '\x1b[' + buf - f = getattr(self.controlSequenceParser, CST.get(buf[-1], buf[-1]), None) - if f is None: - self.unhandledControlSequence(buf) - else: - f(self, self.terminalProtocol, buf[:-1]) - - def unhandledControlSequence(self, buf): - self.terminalProtocol.unhandledControlSequence(buf) - - def _handleLowFunctionControlSequence(self, ch): - map = {'P': self.F1, 'Q': self.F2, 'R': self.F3, 'S': self.F4} - keyID = map.get(ch) - if keyID is not None: - self.terminalProtocol.keystrokeReceived(keyID, None) - else: - self.terminalProtocol.unhandledControlSequence('\x1b[O' + ch) - - class ControlSequenceParser: - def A(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.UP_ARROW, None) - else: - handler.unhandledControlSequence(buf + 'A') - - def B(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.DOWN_ARROW, None) - else: - handler.unhandledControlSequence(buf + 'B') - - def C(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.RIGHT_ARROW, None) - else: - handler.unhandledControlSequence(buf + 'C') - - def D(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.LEFT_ARROW, None) - else: - handler.unhandledControlSequence(buf + 'D') - - def E(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.NUMPAD_MIDDLE, None) - else: - handler.unhandledControlSequence(buf + 'E') - - def F(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.END, None) - else: - handler.unhandledControlSequence(buf + 'F') - - def H(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.HOME, None) - else: - handler.unhandledControlSequence(buf + 'H') - - def R(self, proto, handler, buf): - if not proto._cursorReports: - handler.unhandledControlSequence(buf + 'R') - elif buf.startswith('\x1b['): - report = buf[2:] - parts = report.split(';') - if len(parts) != 2: - handler.unhandledControlSequence(buf + 'R') - else: - Pl, Pc = parts - try: - Pl, Pc = int(Pl), int(Pc) - except ValueError: - handler.unhandledControlSequence(buf + 'R') - else: - d = proto._cursorReports.pop(0) - d.callback((Pc - 1, Pl - 1)) - else: - handler.unhandledControlSequence(buf + 'R') - - def Z(self, proto, handler, buf): - if buf == '\x1b[': - handler.keystrokeReceived(proto.TAB, proto.SHIFT) - else: - handler.unhandledControlSequence(buf + 'Z') - - def tilde(self, proto, handler, buf): - map = {1: proto.HOME, 2: proto.INSERT, 3: proto.DELETE, - 4: proto.END, 5: proto.PGUP, 6: proto.PGDN, - - 15: proto.F5, 17: proto.F6, 18: proto.F7, - 19: proto.F8, 20: proto.F9, 21: proto.F10, - 23: proto.F11, 24: proto.F12} - - if buf.startswith('\x1b['): - ch = buf[2:] - try: - v = int(ch) - except ValueError: - handler.unhandledControlSequence(buf + '~') - else: - symbolic = map.get(v) - if symbolic is not None: - handler.keystrokeReceived(map[v], None) - else: - handler.unhandledControlSequence(buf + '~') - else: - handler.unhandledControlSequence(buf + '~') - - controlSequenceParser = ControlSequenceParser() - - # ITerminalTransport - def cursorUp(self, n=1): - assert n >= 1 - self.cursorPos.y = max(self.cursorPos.y - n, 0) - self.write('\x1b[%dA' % (n,)) - - def cursorDown(self, n=1): - assert n >= 1 - self.cursorPos.y = min(self.cursorPos.y + n, self.termSize.y - 1) - self.write('\x1b[%dB' % (n,)) - - def cursorForward(self, n=1): - assert n >= 1 - self.cursorPos.x = min(self.cursorPos.x + n, self.termSize.x - 1) - self.write('\x1b[%dC' % (n,)) - - def cursorBackward(self, n=1): - assert n >= 1 - self.cursorPos.x = max(self.cursorPos.x - n, 0) - self.write('\x1b[%dD' % (n,)) - - def cursorPosition(self, column, line): - self.write('\x1b[%d;%dH' % (line + 1, column + 1)) - - def cursorHome(self): - self.cursorPos.x = self.cursorPos.y = 0 - self.write('\x1b[H') - - def index(self): - self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1) - self.write('\x1bD') - - def reverseIndex(self): - self.cursorPos.y = max(self.cursorPos.y - 1, 0) - self.write('\x1bM') - - def nextLine(self): - self.cursorPos.x = 0 - self.cursorPos.y = min(self.cursorPos.y + 1, self.termSize.y - 1) - self.write('\n') - - def saveCursor(self): - self._savedCursorPos = Vector(self.cursorPos.x, self.cursorPos.y) - self.write('\x1b7') - - def restoreCursor(self): - self.cursorPos = self._savedCursorPos - del self._savedCursorPos - self.write('\x1b8') - - def setModes(self, modes): - # XXX Support ANSI-Compatible private modes - self.write('\x1b[%sh' % (';'.join(map(str, modes)),)) - - def setPrivateModes(self, modes): - self.write('\x1b[?%sh' % (';'.join(map(str, modes)),)) - - def resetModes(self, modes): - # XXX Support ANSI-Compatible private modes - self.write('\x1b[%sl' % (';'.join(map(str, modes)),)) - - def resetPrivateModes(self, modes): - self.write('\x1b[?%sl' % (';'.join(map(str, modes)),)) - - def applicationKeypadMode(self): - self.write('\x1b=') - - def numericKeypadMode(self): - self.write('\x1b>') - - def selectCharacterSet(self, charSet, which): - # XXX Rewrite these as dict lookups - if which == G0: - which = '(' - elif which == G1: - which = ')' - else: - raise ValueError("`which' argument to selectCharacterSet must be G0 or G1") - if charSet == CS_UK: - charSet = 'A' - elif charSet == CS_US: - charSet = 'B' - elif charSet == CS_DRAWING: - charSet = '0' - elif charSet == CS_ALTERNATE: - charSet = '1' - elif charSet == CS_ALTERNATE_SPECIAL: - charSet = '2' - else: - raise ValueError("Invalid `charSet' argument to selectCharacterSet") - self.write('\x1b' + which + charSet) - - def shiftIn(self): - self.write('\x15') - - def shiftOut(self): - self.write('\x14') - - def singleShift2(self): - self.write('\x1bN') - - def singleShift3(self): - self.write('\x1bO') - - def selectGraphicRendition(self, *attributes): - attrs = [] - for a in attributes: - attrs.append(a) - self.write('\x1b[%sm' % (';'.join(attrs),)) - - def horizontalTabulationSet(self): - self.write('\x1bH') - - def tabulationClear(self): - self.write('\x1b[q') - - def tabulationClearAll(self): - self.write('\x1b[3q') - - def doubleHeightLine(self, top=True): - if top: - self.write('\x1b#3') - else: - self.write('\x1b#4') - - def singleWidthLine(self): - self.write('\x1b#5') - - def doubleWidthLine(self): - self.write('\x1b#6') - - def eraseToLineEnd(self): - self.write('\x1b[K') - - def eraseToLineBeginning(self): - self.write('\x1b[1K') - - def eraseLine(self): - self.write('\x1b[2K') - - def eraseToDisplayEnd(self): - self.write('\x1b[J') - - def eraseToDisplayBeginning(self): - self.write('\x1b[1J') - - def eraseDisplay(self): - self.write('\x1b[2J') - - def deleteCharacter(self, n=1): - self.write('\x1b[%dP' % (n,)) - - def insertLine(self, n=1): - self.write('\x1b[%dL' % (n,)) - - def deleteLine(self, n=1): - self.write('\x1b[%dM' % (n,)) - - def setScrollRegion(self, first=None, last=None): - if first is not None: - first = '%d' % (first,) - else: - first = '' - if last is not None: - last = '%d' % (last,) - else: - last = '' - self.write('\x1b[%s;%sr' % (first, last)) - - def resetScrollRegion(self): - self.setScrollRegion() - - def reportCursorPosition(self): - d = defer.Deferred() - self._cursorReports.append(d) - self.write('\x1b[6n') - return d - - def reset(self): - self.cursorPos.x = self.cursorPos.y = 0 - try: - del self._savedCursorPos - except AttributeError: - pass - self.write('\x1bc') - - # ITransport - def write(self, bytes): - if bytes: - self.lastWrite = bytes - self.transport.write('\r\n'.join(bytes.split('\n'))) - - def writeSequence(self, bytes): - self.write(''.join(bytes)) - - def loseConnection(self): - self.reset() - self.transport.loseConnection() - - def connectionLost(self, reason): - if self.terminalProtocol is not None: - try: - self.terminalProtocol.connectionLost(reason) - finally: - self.terminalProtocol = None -# Add symbolic names for function keys -for name, const in zip(_KEY_NAMES, FUNCTION_KEYS): - setattr(ServerProtocol, name, const) - - - -class ClientProtocol(protocol.Protocol): - - terminalFactory = None - terminal = None - - state = 'data' - - _escBuf = None - - _shorts = { - 'D': 'index', - 'M': 'reverseIndex', - 'E': 'nextLine', - '7': 'saveCursor', - '8': 'restoreCursor', - '=': 'applicationKeypadMode', - '>': 'numericKeypadMode', - 'N': 'singleShift2', - 'O': 'singleShift3', - 'H': 'horizontalTabulationSet', - 'c': 'reset'} - - _longs = { - '[': 'bracket-escape', - '(': 'select-g0', - ')': 'select-g1', - '#': 'select-height-width'} - - _charsets = { - 'A': CS_UK, - 'B': CS_US, - '0': CS_DRAWING, - '1': CS_ALTERNATE, - '2': CS_ALTERNATE_SPECIAL} - - # Factory who instantiated me - factory = None - - def __init__(self, terminalFactory=None, *a, **kw): - """ - @param terminalFactory: A callable which will be invoked with - *a, **kw and should return an ITerminalTransport provider. - This will be invoked when this ClientProtocol establishes a - connection. - - @param a: Any positional arguments to pass to terminalFactory. - @param kw: Any keyword arguments to pass to terminalFactory. - """ - # assert terminalFactory is None or ITerminalTransport.implementedBy(terminalFactory), "ClientProtocol.__init__ must be passed an ITerminalTransport implementor" - if terminalFactory is not None: - self.terminalFactory = terminalFactory - self.terminalArgs = a - self.terminalKwArgs = kw - - def connectionMade(self): - if self.terminalFactory is not None: - self.terminal = self.terminalFactory(*self.terminalArgs, **self.terminalKwArgs) - self.terminal.factory = self.factory - self.terminal.makeConnection(self) - - def connectionLost(self, reason): - if self.terminal is not None: - try: - self.terminal.connectionLost(reason) - finally: - del self.terminal - - def dataReceived(self, bytes): - """ - Parse the given data from a terminal server, dispatching to event - handlers defined by C{self.terminal}. - """ - toWrite = [] - for b in bytes: - if self.state == 'data': - if b == '\x1b': - if toWrite: - self.terminal.write(''.join(toWrite)) - del toWrite[:] - self.state = 'escaped' - elif b == '\x14': - if toWrite: - self.terminal.write(''.join(toWrite)) - del toWrite[:] - self.terminal.shiftOut() - elif b == '\x15': - if toWrite: - self.terminal.write(''.join(toWrite)) - del toWrite[:] - self.terminal.shiftIn() - elif b == '\x08': - if toWrite: - self.terminal.write(''.join(toWrite)) - del toWrite[:] - self.terminal.cursorBackward() - else: - toWrite.append(b) - elif self.state == 'escaped': - fName = self._shorts.get(b) - if fName is not None: - self.state = 'data' - getattr(self.terminal, fName)() - else: - state = self._longs.get(b) - if state is not None: - self.state = state - else: - self.terminal.unhandledControlSequence('\x1b' + b) - self.state = 'data' - elif self.state == 'bracket-escape': - if self._escBuf is None: - self._escBuf = [] - if b.isalpha() or b == '~': - self._handleControlSequence(''.join(self._escBuf), b) - del self._escBuf - self.state = 'data' - else: - self._escBuf.append(b) - elif self.state == 'select-g0': - self.terminal.selectCharacterSet(self._charsets.get(b, b), G0) - self.state = 'data' - elif self.state == 'select-g1': - self.terminal.selectCharacterSet(self._charsets.get(b, b), G1) - self.state = 'data' - elif self.state == 'select-height-width': - self._handleHeightWidth(b) - self.state = 'data' - else: - raise ValueError("Illegal state") - if toWrite: - self.terminal.write(''.join(toWrite)) - - - def _handleControlSequence(self, buf, terminal): - f = getattr(self.controlSequenceParser, CST.get(terminal, terminal), None) - if f is None: - self.terminal.unhandledControlSequence('\x1b[' + buf + terminal) - else: - f(self, self.terminal, buf) - - class ControlSequenceParser: - def _makeSimple(ch, fName): - n = 'cursor' + fName - def simple(self, proto, handler, buf): - if not buf: - getattr(handler, n)(1) - else: - try: - m = int(buf) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + ch) - else: - getattr(handler, n)(m) - return simple - for (ch, fName) in (('A', 'Up'), - ('B', 'Down'), - ('C', 'Forward'), - ('D', 'Backward')): - exec ch + " = _makeSimple(ch, fName)" - del _makeSimple - - def h(self, proto, handler, buf): - # XXX - Handle '?' to introduce ANSI-Compatible private modes. - try: - modes = map(int, buf.split(';')) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'h') - else: - handler.setModes(modes) - - def l(self, proto, handler, buf): - # XXX - Handle '?' to introduce ANSI-Compatible private modes. - try: - modes = map(int, buf.split(';')) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'l') - else: - handler.resetModes(modes) - - def r(self, proto, handler, buf): - parts = buf.split(';') - if len(parts) == 1: - handler.setScrollRegion(None, None) - elif len(parts) == 2: - try: - if parts[0]: - pt = int(parts[0]) - else: - pt = None - if parts[1]: - pb = int(parts[1]) - else: - pb = None - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'r') - else: - handler.setScrollRegion(pt, pb) - else: - handler.unhandledControlSequence('\x1b[' + buf + 'r') - - def K(self, proto, handler, buf): - if not buf: - handler.eraseToLineEnd() - elif buf == '1': - handler.eraseToLineBeginning() - elif buf == '2': - handler.eraseLine() - else: - handler.unhandledControlSequence('\x1b[' + buf + 'K') - - def H(self, proto, handler, buf): - handler.cursorHome() - - def J(self, proto, handler, buf): - if not buf: - handler.eraseToDisplayEnd() - elif buf == '1': - handler.eraseToDisplayBeginning() - elif buf == '2': - handler.eraseDisplay() - else: - handler.unhandledControlSequence('\x1b[' + buf + 'J') - - def P(self, proto, handler, buf): - if not buf: - handler.deleteCharacter(1) - else: - try: - n = int(buf) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'P') - else: - handler.deleteCharacter(n) - - def L(self, proto, handler, buf): - if not buf: - handler.insertLine(1) - else: - try: - n = int(buf) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'L') - else: - handler.insertLine(n) - - def M(self, proto, handler, buf): - if not buf: - handler.deleteLine(1) - else: - try: - n = int(buf) - except ValueError: - handler.unhandledControlSequence('\x1b[' + buf + 'M') - else: - handler.deleteLine(n) - - def n(self, proto, handler, buf): - if buf == '6': - x, y = handler.reportCursorPosition() - proto.transport.write('\x1b[%d;%dR' % (x + 1, y + 1)) - else: - handler.unhandledControlSequence('\x1b[' + buf + 'n') - - def m(self, proto, handler, buf): - if not buf: - handler.selectGraphicRendition(NORMAL) - else: - attrs = [] - for a in buf.split(';'): - try: - a = int(a) - except ValueError: - pass - attrs.append(a) - handler.selectGraphicRendition(*attrs) - - controlSequenceParser = ControlSequenceParser() - - def _handleHeightWidth(self, b): - if b == '3': - self.terminal.doubleHeightLine(True) - elif b == '4': - self.terminal.doubleHeightLine(False) - elif b == '5': - self.terminal.singleWidthLine() - elif b == '6': - self.terminal.doubleWidthLine() - else: - self.terminal.unhandledControlSequence('\x1b#' + b) - - -__all__ = [ - # Interfaces - 'ITerminalProtocol', 'ITerminalTransport', - - # Symbolic constants - 'modes', 'privateModes', 'FUNCTION_KEYS', - - 'CS_US', 'CS_UK', 'CS_DRAWING', 'CS_ALTERNATE', 'CS_ALTERNATE_SPECIAL', - 'G0', 'G1', 'G2', 'G3', - - 'UNDERLINE', 'REVERSE_VIDEO', 'BLINK', 'BOLD', 'NORMAL', - - # Protocol classes - 'ServerProtocol', 'ClientProtocol'] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py deleted file mode 100755 index e5c8fd12..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/text.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_text -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Character attribute manipulation API - -This module provides a domain-specific language (using Python syntax) -for the creation of text with additional display attributes associated -with it. It is intended as an alternative to manually building up -strings containing ECMA 48 character attribute control codes. It -currently supports foreground and background colors (black, red, -green, yellow, blue, magenta, cyan, and white), intensity selection, -underlining, blinking and reverse video. Character set selection -support is planned. - -Character attributes are specified by using two Python operations: -attribute lookup and indexing. For example, the string \"Hello -world\" with red foreground and all other attributes set to their -defaults, assuming the name twisted.conch.insults.text.attributes has -been imported and bound to the name \"A\" (with the statement C{from -twisted.conch.insults.text import attributes as A}, for example) one -uses this expression:: - - | A.fg.red[\"Hello world\"] - -Other foreground colors are set by substituting their name for -\"red\". To set both a foreground and a background color, this -expression is used:: - - | A.fg.red[A.bg.green[\"Hello world\"]] - -Note that either A.bg.green can be nested within A.fg.red or vice -versa. Also note that multiple items can be nested within a single -index operation by separating them with commas:: - - | A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]] - -Other character attributes are set in a similar fashion. To specify a -blinking version of the previous expression:: - - | A.blink[A.bg.green[A.fg.red[\"Hello\"], " ", A.fg.blue[\"world\"]]] - -C{A.reverseVideo}, C{A.underline}, and C{A.bold} are also valid. - -A third operation is actually supported: unary negation. This turns -off an attribute when an enclosing expression would otherwise have -caused it to be on. For example:: - - | A.underline[A.fg.red[\"Hello\", -A.underline[\" world\"]]] - -@author: Jp Calderone -""" - -from twisted.conch.insults import helper, insults - -class _Attribute(object): - def __init__(self): - self.children = [] - - def __getitem__(self, item): - assert isinstance(item, (list, tuple, _Attribute, str)) - if isinstance(item, (list, tuple)): - self.children.extend(item) - else: - self.children.append(item) - return self - - def serialize(self, write, attrs=None): - if attrs is None: - attrs = helper.CharacterAttribute() - for ch in self.children: - if isinstance(ch, _Attribute): - ch.serialize(write, attrs.copy()) - else: - write(attrs.toVT102()) - write(ch) - -class _NormalAttr(_Attribute): - def serialize(self, write, attrs): - attrs.__init__() - super(_NormalAttr, self).serialize(write, attrs) - -class _OtherAttr(_Attribute): - def __init__(self, attrname, attrvalue): - self.attrname = attrname - self.attrvalue = attrvalue - self.children = [] - - def __neg__(self): - result = _OtherAttr(self.attrname, not self.attrvalue) - result.children.extend(self.children) - return result - - def serialize(self, write, attrs): - attrs = attrs.wantOne(**{self.attrname: self.attrvalue}) - super(_OtherAttr, self).serialize(write, attrs) - -class _ColorAttr(_Attribute): - def __init__(self, color, ground): - self.color = color - self.ground = ground - self.children = [] - - def serialize(self, write, attrs): - attrs = attrs.wantOne(**{self.ground: self.color}) - super(_ColorAttr, self).serialize(write, attrs) - -class _ForegroundColorAttr(_ColorAttr): - def __init__(self, color): - super(_ForegroundColorAttr, self).__init__(color, 'foreground') - -class _BackgroundColorAttr(_ColorAttr): - def __init__(self, color): - super(_BackgroundColorAttr, self).__init__(color, 'background') - -class CharacterAttributes(object): - class _ColorAttribute(object): - def __init__(self, ground): - self.ground = ground - - attrs = { - 'black': helper.BLACK, - 'red': helper.RED, - 'green': helper.GREEN, - 'yellow': helper.YELLOW, - 'blue': helper.BLUE, - 'magenta': helper.MAGENTA, - 'cyan': helper.CYAN, - 'white': helper.WHITE} - - def __getattr__(self, name): - try: - return self.ground(self.attrs[name]) - except KeyError: - raise AttributeError(name) - - fg = _ColorAttribute(_ForegroundColorAttr) - bg = _ColorAttribute(_BackgroundColorAttr) - - attrs = { - 'bold': insults.BOLD, - 'blink': insults.BLINK, - 'underline': insults.UNDERLINE, - 'reverseVideo': insults.REVERSE_VIDEO} - - def __getattr__(self, name): - if name == 'normal': - return _NormalAttr() - if name in self.attrs: - return _OtherAttr(name, True) - raise AttributeError(name) - -def flatten(output, attrs): - """Serialize a sequence of characters with attribute information - - The resulting string can be interpreted by VT102-compatible - terminals so that the contained characters are displayed and, for - those attributes which the terminal supports, have the attributes - specified in the input. - - For example, if your terminal is VT102 compatible, you might run - this for a colorful variation on the \"hello world\" theme:: - - | from twisted.conch.insults.text import flatten, attributes as A - | from twisted.conch.insults.helper import CharacterAttribute - | print flatten( - | A.normal[A.bold[A.fg.red['He'], A.fg.green['ll'], A.fg.magenta['o'], ' ', - | A.fg.yellow['Wo'], A.fg.blue['rl'], A.fg.cyan['d!']]], - | CharacterAttribute()) - - @param output: Object returned by accessing attributes of the - module-level attributes object. - - @param attrs: A L{twisted.conch.insults.helper.CharacterAttribute} - instance - - @return: A VT102-friendly string - """ - L = [] - output.serialize(L.append, attrs) - return ''.join(L) - -attributes = CharacterAttributes() - -__all__ = ['attributes', 'flatten'] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py deleted file mode 100755 index 99013273..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/insults/window.py +++ /dev/null @@ -1,868 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_window -*- - -""" -Simple insults-based widget library - -@author: Jp Calderone -""" - -import array - -from twisted.conch.insults import insults, helper -from twisted.python import text as tptext - -class YieldFocus(Exception): - """Input focus manipulation exception - """ - -class BoundedTerminalWrapper(object): - def __init__(self, terminal, width, height, xoff, yoff): - self.width = width - self.height = height - self.xoff = xoff - self.yoff = yoff - self.terminal = terminal - self.cursorForward = terminal.cursorForward - self.selectCharacterSet = terminal.selectCharacterSet - self.selectGraphicRendition = terminal.selectGraphicRendition - self.saveCursor = terminal.saveCursor - self.restoreCursor = terminal.restoreCursor - - def cursorPosition(self, x, y): - return self.terminal.cursorPosition( - self.xoff + min(self.width, x), - self.yoff + min(self.height, y) - ) - - def cursorHome(self): - return self.terminal.cursorPosition( - self.xoff, self.yoff) - - def write(self, bytes): - return self.terminal.write(bytes) - -class Widget(object): - focused = False - parent = None - dirty = False - width = height = None - - def repaint(self): - if not self.dirty: - self.dirty = True - if self.parent is not None and not self.parent.dirty: - self.parent.repaint() - - def filthy(self): - self.dirty = True - - def redraw(self, width, height, terminal): - self.filthy() - self.draw(width, height, terminal) - - def draw(self, width, height, terminal): - if width != self.width or height != self.height or self.dirty: - self.width = width - self.height = height - self.dirty = False - self.render(width, height, terminal) - - def render(self, width, height, terminal): - pass - - def sizeHint(self): - return None - - def keystrokeReceived(self, keyID, modifier): - if keyID == '\t': - self.tabReceived(modifier) - elif keyID == '\x7f': - self.backspaceReceived() - elif keyID in insults.FUNCTION_KEYS: - self.functionKeyReceived(keyID, modifier) - else: - self.characterReceived(keyID, modifier) - - def tabReceived(self, modifier): - # XXX TODO - Handle shift+tab - raise YieldFocus() - - def focusReceived(self): - """Called when focus is being given to this widget. - - May raise YieldFocus is this widget does not want focus. - """ - self.focused = True - self.repaint() - - def focusLost(self): - self.focused = False - self.repaint() - - def backspaceReceived(self): - pass - - def functionKeyReceived(self, keyID, modifier): - func = getattr(self, 'func_' + keyID.name, None) - if func is not None: - func(modifier) - - def characterReceived(self, keyID, modifier): - pass - -class ContainerWidget(Widget): - """ - @ivar focusedChild: The contained widget which currently has - focus, or None. - """ - focusedChild = None - focused = False - - def __init__(self): - Widget.__init__(self) - self.children = [] - - def addChild(self, child): - assert child.parent is None - child.parent = self - self.children.append(child) - if self.focusedChild is None and self.focused: - try: - child.focusReceived() - except YieldFocus: - pass - else: - self.focusedChild = child - self.repaint() - - def remChild(self, child): - assert child.parent is self - child.parent = None - self.children.remove(child) - self.repaint() - - def filthy(self): - for ch in self.children: - ch.filthy() - Widget.filthy(self) - - def render(self, width, height, terminal): - for ch in self.children: - ch.draw(width, height, terminal) - - def changeFocus(self): - self.repaint() - - if self.focusedChild is not None: - self.focusedChild.focusLost() - focusedChild = self.focusedChild - self.focusedChild = None - try: - curFocus = self.children.index(focusedChild) + 1 - except ValueError: - raise YieldFocus() - else: - curFocus = 0 - while curFocus < len(self.children): - try: - self.children[curFocus].focusReceived() - except YieldFocus: - curFocus += 1 - else: - self.focusedChild = self.children[curFocus] - return - # None of our children wanted focus - raise YieldFocus() - - - def focusReceived(self): - self.changeFocus() - self.focused = True - - - def keystrokeReceived(self, keyID, modifier): - if self.focusedChild is not None: - try: - self.focusedChild.keystrokeReceived(keyID, modifier) - except YieldFocus: - self.changeFocus() - self.repaint() - else: - Widget.keystrokeReceived(self, keyID, modifier) - - -class TopWindow(ContainerWidget): - """ - A top-level container object which provides focus wrap-around and paint - scheduling. - - @ivar painter: A no-argument callable which will be invoked when this - widget needs to be redrawn. - - @ivar scheduler: A one-argument callable which will be invoked with a - no-argument callable and should arrange for it to invoked at some point in - the near future. The no-argument callable will cause this widget and all - its children to be redrawn. It is typically beneficial for the no-argument - callable to be invoked at the end of handling for whatever event is - currently active; for example, it might make sense to call it at the end of - L{twisted.conch.insults.insults.ITerminalProtocol.keystrokeReceived}. - Note, however, that since calls to this may also be made in response to no - apparent event, arrangements should be made for the function to be called - even if an event handler such as C{keystrokeReceived} is not on the call - stack (eg, using C{reactor.callLater} with a short timeout). - """ - focused = True - - def __init__(self, painter, scheduler): - ContainerWidget.__init__(self) - self.painter = painter - self.scheduler = scheduler - - _paintCall = None - def repaint(self): - if self._paintCall is None: - self._paintCall = object() - self.scheduler(self._paint) - ContainerWidget.repaint(self) - - def _paint(self): - self._paintCall = None - self.painter() - - def changeFocus(self): - try: - ContainerWidget.changeFocus(self) - except YieldFocus: - try: - ContainerWidget.changeFocus(self) - except YieldFocus: - pass - - def keystrokeReceived(self, keyID, modifier): - try: - ContainerWidget.keystrokeReceived(self, keyID, modifier) - except YieldFocus: - self.changeFocus() - - -class AbsoluteBox(ContainerWidget): - def moveChild(self, child, x, y): - for n in range(len(self.children)): - if self.children[n][0] is child: - self.children[n] = (child, x, y) - break - else: - raise ValueError("No such child", child) - - def render(self, width, height, terminal): - for (ch, x, y) in self.children: - wrap = BoundedTerminalWrapper(terminal, width - x, height - y, x, y) - ch.draw(width, height, wrap) - - -class _Box(ContainerWidget): - TOP, CENTER, BOTTOM = range(3) - - def __init__(self, gravity=CENTER): - ContainerWidget.__init__(self) - self.gravity = gravity - - def sizeHint(self): - height = 0 - width = 0 - for ch in self.children: - hint = ch.sizeHint() - if hint is None: - hint = (None, None) - - if self.variableDimension == 0: - if hint[0] is None: - width = None - elif width is not None: - width += hint[0] - if hint[1] is None: - height = None - elif height is not None: - height = max(height, hint[1]) - else: - if hint[0] is None: - width = None - elif width is not None: - width = max(width, hint[0]) - if hint[1] is None: - height = None - elif height is not None: - height += hint[1] - - return width, height - - - def render(self, width, height, terminal): - if not self.children: - return - - greedy = 0 - wants = [] - for ch in self.children: - hint = ch.sizeHint() - if hint is None: - hint = (None, None) - if hint[self.variableDimension] is None: - greedy += 1 - wants.append(hint[self.variableDimension]) - - length = (width, height)[self.variableDimension] - totalWant = sum([w for w in wants if w is not None]) - if greedy: - leftForGreedy = int((length - totalWant) / greedy) - - widthOffset = heightOffset = 0 - - for want, ch in zip(wants, self.children): - if want is None: - want = leftForGreedy - - subWidth, subHeight = width, height - if self.variableDimension == 0: - subWidth = want - else: - subHeight = want - - wrap = BoundedTerminalWrapper( - terminal, - subWidth, - subHeight, - widthOffset, - heightOffset, - ) - ch.draw(subWidth, subHeight, wrap) - if self.variableDimension == 0: - widthOffset += want - else: - heightOffset += want - - -class HBox(_Box): - variableDimension = 0 - -class VBox(_Box): - variableDimension = 1 - - -class Packer(ContainerWidget): - def render(self, width, height, terminal): - if not self.children: - return - - root = int(len(self.children) ** 0.5 + 0.5) - boxes = [VBox() for n in range(root)] - for n, ch in enumerate(self.children): - boxes[n % len(boxes)].addChild(ch) - h = HBox() - map(h.addChild, boxes) - h.render(width, height, terminal) - - -class Canvas(Widget): - focused = False - - contents = None - - def __init__(self): - Widget.__init__(self) - self.resize(1, 1) - - def resize(self, width, height): - contents = array.array('c', ' ' * width * height) - if self.contents is not None: - for x in range(min(width, self._width)): - for y in range(min(height, self._height)): - contents[width * y + x] = self[x, y] - self.contents = contents - self._width = width - self._height = height - if self.x >= width: - self.x = width - 1 - if self.y >= height: - self.y = height - 1 - - def __getitem__(self, (x, y)): - return self.contents[(self._width * y) + x] - - def __setitem__(self, (x, y), value): - self.contents[(self._width * y) + x] = value - - def clear(self): - self.contents = array.array('c', ' ' * len(self.contents)) - - def render(self, width, height, terminal): - if not width or not height: - return - - if width != self._width or height != self._height: - self.resize(width, height) - for i in range(height): - terminal.cursorPosition(0, i) - terminal.write(''.join(self.contents[self._width * i:self._width * i + self._width])[:width]) - - -def horizontalLine(terminal, y, left, right): - terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0) - terminal.cursorPosition(left, y) - terminal.write(chr(0161) * (right - left)) - terminal.selectCharacterSet(insults.CS_US, insults.G0) - -def verticalLine(terminal, x, top, bottom): - terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0) - for n in xrange(top, bottom): - terminal.cursorPosition(x, n) - terminal.write(chr(0170)) - terminal.selectCharacterSet(insults.CS_US, insults.G0) - - -def rectangle(terminal, (top, left), (width, height)): - terminal.selectCharacterSet(insults.CS_DRAWING, insults.G0) - - terminal.cursorPosition(top, left) - terminal.write(chr(0154)) - terminal.write(chr(0161) * (width - 2)) - terminal.write(chr(0153)) - for n in range(height - 2): - terminal.cursorPosition(left, top + n + 1) - terminal.write(chr(0170)) - terminal.cursorForward(width - 2) - terminal.write(chr(0170)) - terminal.cursorPosition(0, top + height - 1) - terminal.write(chr(0155)) - terminal.write(chr(0161) * (width - 2)) - terminal.write(chr(0152)) - - terminal.selectCharacterSet(insults.CS_US, insults.G0) - -class Border(Widget): - def __init__(self, containee): - Widget.__init__(self) - self.containee = containee - self.containee.parent = self - - def focusReceived(self): - return self.containee.focusReceived() - - def focusLost(self): - return self.containee.focusLost() - - def keystrokeReceived(self, keyID, modifier): - return self.containee.keystrokeReceived(keyID, modifier) - - def sizeHint(self): - hint = self.containee.sizeHint() - if hint is None: - hint = (None, None) - if hint[0] is None: - x = None - else: - x = hint[0] + 2 - if hint[1] is None: - y = None - else: - y = hint[1] + 2 - return x, y - - def filthy(self): - self.containee.filthy() - Widget.filthy(self) - - def render(self, width, height, terminal): - if self.containee.focused: - terminal.write('\x1b[31m') - rectangle(terminal, (0, 0), (width, height)) - terminal.write('\x1b[0m') - wrap = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1) - self.containee.draw(width - 2, height - 2, wrap) - - -class Button(Widget): - def __init__(self, label, onPress): - Widget.__init__(self) - self.label = label - self.onPress = onPress - - def sizeHint(self): - return len(self.label), 1 - - def characterReceived(self, keyID, modifier): - if keyID == '\r': - self.onPress() - - def render(self, width, height, terminal): - terminal.cursorPosition(0, 0) - if self.focused: - terminal.write('\x1b[1m' + self.label + '\x1b[0m') - else: - terminal.write(self.label) - -class TextInput(Widget): - def __init__(self, maxwidth, onSubmit): - Widget.__init__(self) - self.onSubmit = onSubmit - self.maxwidth = maxwidth - self.buffer = '' - self.cursor = 0 - - def setText(self, text): - self.buffer = text[:self.maxwidth] - self.cursor = len(self.buffer) - self.repaint() - - def func_LEFT_ARROW(self, modifier): - if self.cursor > 0: - self.cursor -= 1 - self.repaint() - - def func_RIGHT_ARROW(self, modifier): - if self.cursor < len(self.buffer): - self.cursor += 1 - self.repaint() - - def backspaceReceived(self): - if self.cursor > 0: - self.buffer = self.buffer[:self.cursor - 1] + self.buffer[self.cursor:] - self.cursor -= 1 - self.repaint() - - def characterReceived(self, keyID, modifier): - if keyID == '\r': - self.onSubmit(self.buffer) - else: - if len(self.buffer) < self.maxwidth: - self.buffer = self.buffer[:self.cursor] + keyID + self.buffer[self.cursor:] - self.cursor += 1 - self.repaint() - - def sizeHint(self): - return self.maxwidth + 1, 1 - - def render(self, width, height, terminal): - currentText = self._renderText() - terminal.cursorPosition(0, 0) - if self.focused: - terminal.write(currentText[:self.cursor]) - cursor(terminal, currentText[self.cursor:self.cursor+1] or ' ') - terminal.write(currentText[self.cursor+1:]) - terminal.write(' ' * (self.maxwidth - len(currentText) + 1)) - else: - more = self.maxwidth - len(currentText) - terminal.write(currentText + '_' * more) - - def _renderText(self): - return self.buffer - -class PasswordInput(TextInput): - def _renderText(self): - return '*' * len(self.buffer) - -class TextOutput(Widget): - text = '' - - def __init__(self, size=None): - Widget.__init__(self) - self.size = size - - def sizeHint(self): - return self.size - - def render(self, width, height, terminal): - terminal.cursorPosition(0, 0) - text = self.text[:width] - terminal.write(text + ' ' * (width - len(text))) - - def setText(self, text): - self.text = text - self.repaint() - - def focusReceived(self): - raise YieldFocus() - -class TextOutputArea(TextOutput): - WRAP, TRUNCATE = range(2) - - def __init__(self, size=None, longLines=WRAP): - TextOutput.__init__(self, size) - self.longLines = longLines - - def render(self, width, height, terminal): - n = 0 - inputLines = self.text.splitlines() - outputLines = [] - while inputLines: - if self.longLines == self.WRAP: - wrappedLines = tptext.greedyWrap(inputLines.pop(0), width) - outputLines.extend(wrappedLines or ['']) - else: - outputLines.append(inputLines.pop(0)[:width]) - if len(outputLines) >= height: - break - for n, L in enumerate(outputLines[:height]): - terminal.cursorPosition(0, n) - terminal.write(L) - -class Viewport(Widget): - _xOffset = 0 - _yOffset = 0 - - def xOffset(): - def get(self): - return self._xOffset - def set(self, value): - if self._xOffset != value: - self._xOffset = value - self.repaint() - return get, set - xOffset = property(*xOffset()) - - def yOffset(): - def get(self): - return self._yOffset - def set(self, value): - if self._yOffset != value: - self._yOffset = value - self.repaint() - return get, set - yOffset = property(*yOffset()) - - _width = 160 - _height = 24 - - def __init__(self, containee): - Widget.__init__(self) - self.containee = containee - self.containee.parent = self - - self._buf = helper.TerminalBuffer() - self._buf.width = self._width - self._buf.height = self._height - self._buf.connectionMade() - - def filthy(self): - self.containee.filthy() - Widget.filthy(self) - - def render(self, width, height, terminal): - self.containee.draw(self._width, self._height, self._buf) - - # XXX /Lame/ - for y, line in enumerate(self._buf.lines[self._yOffset:self._yOffset + height]): - terminal.cursorPosition(0, y) - n = 0 - for n, (ch, attr) in enumerate(line[self._xOffset:self._xOffset + width]): - if ch is self._buf.void: - ch = ' ' - terminal.write(ch) - if n < width: - terminal.write(' ' * (width - n - 1)) - - -class _Scrollbar(Widget): - def __init__(self, onScroll): - Widget.__init__(self) - self.onScroll = onScroll - self.percent = 0.0 - - def smaller(self): - self.percent = min(1.0, max(0.0, self.onScroll(-1))) - self.repaint() - - def bigger(self): - self.percent = min(1.0, max(0.0, self.onScroll(+1))) - self.repaint() - - -class HorizontalScrollbar(_Scrollbar): - def sizeHint(self): - return (None, 1) - - def func_LEFT_ARROW(self, modifier): - self.smaller() - - def func_RIGHT_ARROW(self, modifier): - self.bigger() - - _left = u'\N{BLACK LEFT-POINTING TRIANGLE}' - _right = u'\N{BLACK RIGHT-POINTING TRIANGLE}' - _bar = u'\N{LIGHT SHADE}' - _slider = u'\N{DARK SHADE}' - def render(self, width, height, terminal): - terminal.cursorPosition(0, 0) - n = width - 3 - before = int(n * self.percent) - after = n - before - me = self._left + (self._bar * before) + self._slider + (self._bar * after) + self._right - terminal.write(me.encode('utf-8')) - - -class VerticalScrollbar(_Scrollbar): - def sizeHint(self): - return (1, None) - - def func_UP_ARROW(self, modifier): - self.smaller() - - def func_DOWN_ARROW(self, modifier): - self.bigger() - - _up = u'\N{BLACK UP-POINTING TRIANGLE}' - _down = u'\N{BLACK DOWN-POINTING TRIANGLE}' - _bar = u'\N{LIGHT SHADE}' - _slider = u'\N{DARK SHADE}' - def render(self, width, height, terminal): - terminal.cursorPosition(0, 0) - knob = int(self.percent * (height - 2)) - terminal.write(self._up.encode('utf-8')) - for i in xrange(1, height - 1): - terminal.cursorPosition(0, i) - if i != (knob + 1): - terminal.write(self._bar.encode('utf-8')) - else: - terminal.write(self._slider.encode('utf-8')) - terminal.cursorPosition(0, height - 1) - terminal.write(self._down.encode('utf-8')) - - -class ScrolledArea(Widget): - """ - A L{ScrolledArea} contains another widget wrapped in a viewport and - vertical and horizontal scrollbars for moving the viewport around. - """ - def __init__(self, containee): - Widget.__init__(self) - self._viewport = Viewport(containee) - self._horiz = HorizontalScrollbar(self._horizScroll) - self._vert = VerticalScrollbar(self._vertScroll) - - for w in self._viewport, self._horiz, self._vert: - w.parent = self - - def _horizScroll(self, n): - self._viewport.xOffset += n - self._viewport.xOffset = max(0, self._viewport.xOffset) - return self._viewport.xOffset / 25.0 - - def _vertScroll(self, n): - self._viewport.yOffset += n - self._viewport.yOffset = max(0, self._viewport.yOffset) - return self._viewport.yOffset / 25.0 - - def func_UP_ARROW(self, modifier): - self._vert.smaller() - - def func_DOWN_ARROW(self, modifier): - self._vert.bigger() - - def func_LEFT_ARROW(self, modifier): - self._horiz.smaller() - - def func_RIGHT_ARROW(self, modifier): - self._horiz.bigger() - - def filthy(self): - self._viewport.filthy() - self._horiz.filthy() - self._vert.filthy() - Widget.filthy(self) - - def render(self, width, height, terminal): - wrapper = BoundedTerminalWrapper(terminal, width - 2, height - 2, 1, 1) - self._viewport.draw(width - 2, height - 2, wrapper) - if self.focused: - terminal.write('\x1b[31m') - horizontalLine(terminal, 0, 1, width - 1) - verticalLine(terminal, 0, 1, height - 1) - self._vert.draw(1, height - 1, BoundedTerminalWrapper(terminal, 1, height - 1, width - 1, 0)) - self._horiz.draw(width, 1, BoundedTerminalWrapper(terminal, width, 1, 0, height - 1)) - terminal.write('\x1b[0m') - -def cursor(terminal, ch): - terminal.saveCursor() - terminal.selectGraphicRendition(str(insults.REVERSE_VIDEO)) - terminal.write(ch) - terminal.restoreCursor() - terminal.cursorForward() - -class Selection(Widget): - # Index into the sequence - focusedIndex = 0 - - # Offset into the displayed subset of the sequence - renderOffset = 0 - - def __init__(self, sequence, onSelect, minVisible=None): - Widget.__init__(self) - self.sequence = sequence - self.onSelect = onSelect - self.minVisible = minVisible - if minVisible is not None: - self._width = max(map(len, self.sequence)) - - def sizeHint(self): - if self.minVisible is not None: - return self._width, self.minVisible - - def func_UP_ARROW(self, modifier): - if self.focusedIndex > 0: - self.focusedIndex -= 1 - if self.renderOffset > 0: - self.renderOffset -= 1 - self.repaint() - - def func_PGUP(self, modifier): - if self.renderOffset != 0: - self.focusedIndex -= self.renderOffset - self.renderOffset = 0 - else: - self.focusedIndex = max(0, self.focusedIndex - self.height) - self.repaint() - - def func_DOWN_ARROW(self, modifier): - if self.focusedIndex < len(self.sequence) - 1: - self.focusedIndex += 1 - if self.renderOffset < self.height - 1: - self.renderOffset += 1 - self.repaint() - - - def func_PGDN(self, modifier): - if self.renderOffset != self.height - 1: - change = self.height - self.renderOffset - 1 - if change + self.focusedIndex >= len(self.sequence): - change = len(self.sequence) - self.focusedIndex - 1 - self.focusedIndex += change - self.renderOffset = self.height - 1 - else: - self.focusedIndex = min(len(self.sequence) - 1, self.focusedIndex + self.height) - self.repaint() - - def characterReceived(self, keyID, modifier): - if keyID == '\r': - self.onSelect(self.sequence[self.focusedIndex]) - - def render(self, width, height, terminal): - self.height = height - start = self.focusedIndex - self.renderOffset - if start > len(self.sequence) - height: - start = max(0, len(self.sequence) - height) - - elements = self.sequence[start:start+height] - - for n, ele in enumerate(elements): - terminal.cursorPosition(0, n) - if n == self.renderOffset: - terminal.saveCursor() - if self.focused: - modes = str(insults.REVERSE_VIDEO), str(insults.BOLD) - else: - modes = str(insults.REVERSE_VIDEO), - terminal.selectGraphicRendition(*modes) - text = ele[:width] - terminal.write(text + (' ' * (width - len(text)))) - if n == self.renderOffset: - terminal.restoreCursor() diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py deleted file mode 100755 index d42811a8..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/interfaces.py +++ /dev/null @@ -1,402 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -This module contains interfaces defined for the L{twisted.conch} package. -""" - -from zope.interface import Interface, Attribute - -class IConchUser(Interface): - """ - A user who has been authenticated to Cred through Conch. This is - the interface between the SSH connection and the user. - """ - - conn = Attribute('The SSHConnection object for this user.') - - def lookupChannel(channelType, windowSize, maxPacket, data): - """ - The other side requested a channel of some sort. - channelType is the type of channel being requested, - windowSize is the initial size of the remote window, - maxPacket is the largest packet we should send, - data is any other packet data (often nothing). - - We return a subclass of L{SSHChannel<ssh.channel.SSHChannel>}. If - an appropriate channel can not be found, an exception will be - raised. If a L{ConchError<error.ConchError>} is raised, the .value - will be the message, and the .data will be the error code. - - @type channelType: C{str} - @type windowSize: C{int} - @type maxPacket: C{int} - @type data: C{str} - @rtype: subclass of L{SSHChannel}/C{tuple} - """ - - def lookupSubsystem(subsystem, data): - """ - The other side requested a subsystem. - subsystem is the name of the subsystem being requested. - data is any other packet data (often nothing). - - We return a L{Protocol}. - """ - - def gotGlobalRequest(requestType, data): - """ - A global request was sent from the other side. - - By default, this dispatches to a method 'channel_channelType' with any - non-alphanumerics in the channelType replace with _'s. If it cannot - find a suitable method, it returns an OPEN_UNKNOWN_CHANNEL_TYPE error. - The method is called with arguments of windowSize, maxPacket, data. - """ - -class ISession(Interface): - - def getPty(term, windowSize, modes): - """ - Get a psuedo-terminal for use by a shell or command. - - If a psuedo-terminal is not available, or the request otherwise - fails, raise an exception. - """ - - def openShell(proto): - """ - Open a shell and connect it to proto. - - @param proto: a L{ProcessProtocol} instance. - """ - - def execCommand(proto, command): - """ - Execute a command. - - @param proto: a L{ProcessProtocol} instance. - """ - - def windowChanged(newWindowSize): - """ - Called when the size of the remote screen has changed. - """ - - def eofReceived(): - """ - Called when the other side has indicated no more data will be sent. - """ - - def closed(): - """ - Called when the session is closed. - """ - - -class ISFTPServer(Interface): - """ - The only attribute of this class is "avatar". It is the avatar - returned by the Realm that we are authenticated with, and - represents the logged-in user. Each method should check to verify - that the user has permission for their actions. - """ - - def gotVersion(otherVersion, extData): - """ - Called when the client sends their version info. - - otherVersion is an integer representing the version of the SFTP - protocol they are claiming. - extData is a dictionary of extended_name : extended_data items. - These items are sent by the client to indicate additional features. - - This method should return a dictionary of extended_name : extended_data - items. These items are the additional features (if any) supported - by the server. - """ - return {} - - def openFile(filename, flags, attrs): - """ - Called when the clients asks to open a file. - - @param filename: a string representing the file to open. - - @param flags: an integer of the flags to open the file with, ORed together. - The flags and their values are listed at the bottom of this file. - - @param attrs: a list of attributes to open the file with. It is a - dictionary, consisting of 0 or more keys. The possible keys are:: - - size: the size of the file in bytes - uid: the user ID of the file as an integer - gid: the group ID of the file as an integer - permissions: the permissions of the file with as an integer. - the bit representation of this field is defined by POSIX. - atime: the access time of the file as seconds since the epoch. - mtime: the modification time of the file as seconds since the epoch. - ext_*: extended attributes. The server is not required to - understand this, but it may. - - NOTE: there is no way to indicate text or binary files. it is up - to the SFTP client to deal with this. - - This method returns an object that meets the ISFTPFile interface. - Alternatively, it can return a L{Deferred} that will be called back - with the object. - """ - - def removeFile(filename): - """ - Remove the given file. - - This method returns when the remove succeeds, or a Deferred that is - called back when it succeeds. - - @param filename: the name of the file as a string. - """ - - def renameFile(oldpath, newpath): - """ - Rename the given file. - - This method returns when the rename succeeds, or a L{Deferred} that is - called back when it succeeds. If the rename fails, C{renameFile} will - raise an implementation-dependent exception. - - @param oldpath: the current location of the file. - @param newpath: the new file name. - """ - - def makeDirectory(path, attrs): - """ - Make a directory. - - This method returns when the directory is created, or a Deferred that - is called back when it is created. - - @param path: the name of the directory to create as a string. - @param attrs: a dictionary of attributes to create the directory with. - Its meaning is the same as the attrs in the L{openFile} method. - """ - - def removeDirectory(path): - """ - Remove a directory (non-recursively) - - It is an error to remove a directory that has files or directories in - it. - - This method returns when the directory is removed, or a Deferred that - is called back when it is removed. - - @param path: the directory to remove. - """ - - def openDirectory(path): - """ - Open a directory for scanning. - - This method returns an iterable object that has a close() method, - or a Deferred that is called back with same. - - The close() method is called when the client is finished reading - from the directory. At this point, the iterable will no longer - be used. - - The iterable should return triples of the form (filename, - longname, attrs) or Deferreds that return the same. The - sequence must support __getitem__, but otherwise may be any - 'sequence-like' object. - - filename is the name of the file relative to the directory. - logname is an expanded format of the filename. The recommended format - is: - -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer - 1234567890 123 12345678 12345678 12345678 123456789012 - - The first line is sample output, the second is the length of the field. - The fields are: permissions, link count, user owner, group owner, - size in bytes, modification time. - - attrs is a dictionary in the format of the attrs argument to openFile. - - @param path: the directory to open. - """ - - def getAttrs(path, followLinks): - """ - Return the attributes for the given path. - - This method returns a dictionary in the same format as the attrs - argument to openFile or a Deferred that is called back with same. - - @param path: the path to return attributes for as a string. - @param followLinks: a boolean. If it is True, follow symbolic links - and return attributes for the real path at the base. If it is False, - return attributes for the specified path. - """ - - def setAttrs(path, attrs): - """ - Set the attributes for the path. - - This method returns when the attributes are set or a Deferred that is - called back when they are. - - @param path: the path to set attributes for as a string. - @param attrs: a dictionary in the same format as the attrs argument to - L{openFile}. - """ - - def readLink(path): - """ - Find the root of a set of symbolic links. - - This method returns the target of the link, or a Deferred that - returns the same. - - @param path: the path of the symlink to read. - """ - - def makeLink(linkPath, targetPath): - """ - Create a symbolic link. - - This method returns when the link is made, or a Deferred that - returns the same. - - @param linkPath: the pathname of the symlink as a string. - @param targetPath: the path of the target of the link as a string. - """ - - def realPath(path): - """ - Convert any path to an absolute path. - - This method returns the absolute path as a string, or a Deferred - that returns the same. - - @param path: the path to convert as a string. - """ - - def extendedRequest(extendedName, extendedData): - """ - This is the extension mechanism for SFTP. The other side can send us - arbitrary requests. - - If we don't implement the request given by extendedName, raise - NotImplementedError. - - The return value is a string, or a Deferred that will be called - back with a string. - - @param extendedName: the name of the request as a string. - @param extendedData: the data the other side sent with the request, - as a string. - """ - - - -class IKnownHostEntry(Interface): - """ - A L{IKnownHostEntry} is an entry in an OpenSSH-formatted C{known_hosts} - file. - - @since: 8.2 - """ - - def matchesKey(key): - """ - Return True if this entry matches the given Key object, False - otherwise. - - @param key: The key object to match against. - @type key: L{twisted.conch.ssh.Key} - """ - - - def matchesHost(hostname): - """ - Return True if this entry matches the given hostname, False otherwise. - - Note that this does no name resolution; if you want to match an IP - address, you have to resolve it yourself, and pass it in as a dotted - quad string. - - @param key: The hostname to match against. - @type key: L{str} - """ - - - def toString(): - """ - @return: a serialized string representation of this entry, suitable for - inclusion in a known_hosts file. (Newline not included.) - - @rtype: L{str} - """ - - - -class ISFTPFile(Interface): - """ - This represents an open file on the server. An object adhering to this - interface should be returned from L{openFile}(). - """ - - def close(): - """ - Close the file. - - This method returns nothing if the close succeeds immediately, or a - Deferred that is called back when the close succeeds. - """ - - def readChunk(offset, length): - """ - Read from the file. - - If EOF is reached before any data is read, raise EOFError. - - This method returns the data as a string, or a Deferred that is - called back with same. - - @param offset: an integer that is the index to start from in the file. - @param length: the maximum length of data to return. The actual amount - returned may less than this. For normal disk files, however, - this should read the requested number (up to the end of the file). - """ - - def writeChunk(offset, data): - """ - Write to the file. - - This method returns when the write completes, or a Deferred that is - called when it completes. - - @param offset: an integer that is the index to start from in the file. - @param data: a string that is the data to write. - """ - - def getAttrs(): - """ - Return the attributes for the file. - - This method returns a dictionary in the same format as the attrs - argument to L{openFile} or a L{Deferred} that is called back with same. - """ - - def setAttrs(attrs): - """ - Set the attributes for the file. - - This method returns when the attributes are set or a Deferred that is - called back when they are. - - @param attrs: a dictionary in the same format as the attrs argument to - L{openFile}. - """ - - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py deleted file mode 100755 index ab44f855..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ls.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_cftp -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -import array -import stat - -from time import time, strftime, localtime - -# locale-independent month names to use instead of strftime's -_MONTH_NAMES = dict(zip( - range(1, 13), - "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split())) - - -def lsLine(name, s): - """ - Build an 'ls' line for a file ('file' in its generic sense, it - can be of any type). - """ - mode = s.st_mode - perms = array.array('c', '-'*10) - ft = stat.S_IFMT(mode) - if stat.S_ISDIR(ft): perms[0] = 'd' - elif stat.S_ISCHR(ft): perms[0] = 'c' - elif stat.S_ISBLK(ft): perms[0] = 'b' - elif stat.S_ISREG(ft): perms[0] = '-' - elif stat.S_ISFIFO(ft): perms[0] = 'f' - elif stat.S_ISLNK(ft): perms[0] = 'l' - elif stat.S_ISSOCK(ft): perms[0] = 's' - else: perms[0] = '!' - # user - if mode&stat.S_IRUSR:perms[1] = 'r' - if mode&stat.S_IWUSR:perms[2] = 'w' - if mode&stat.S_IXUSR:perms[3] = 'x' - # group - if mode&stat.S_IRGRP:perms[4] = 'r' - if mode&stat.S_IWGRP:perms[5] = 'w' - if mode&stat.S_IXGRP:perms[6] = 'x' - # other - if mode&stat.S_IROTH:perms[7] = 'r' - if mode&stat.S_IWOTH:perms[8] = 'w' - if mode&stat.S_IXOTH:perms[9] = 'x' - # suid/sgid - if mode&stat.S_ISUID: - if perms[3] == 'x': perms[3] = 's' - else: perms[3] = 'S' - if mode&stat.S_ISGID: - if perms[6] == 'x': perms[6] = 's' - else: perms[6] = 'S' - - lsresult = [ - perms.tostring(), - str(s.st_nlink).rjust(5), - ' ', - str(s.st_uid).ljust(9), - str(s.st_gid).ljust(9), - str(s.st_size).rjust(8), - ' ', - ] - - # need to specify the month manually, as strftime depends on locale - ttup = localtime(s.st_mtime) - sixmonths = 60 * 60 * 24 * 7 * 26 - if s.st_mtime + sixmonths < time(): # last edited more than 6mo ago - strtime = strftime("%%s %d %Y ", ttup) - else: - strtime = strftime("%%s %d %H:%M ", ttup) - lsresult.append(strtime % (_MONTH_NAMES[ttup[1]],)) - - lsresult.append(name) - return ''.join(lsresult) - - -__all__ = ['lsLine'] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py deleted file mode 100755 index dee6a024..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole.py +++ /dev/null @@ -1,340 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_manhole -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Line-input oriented interactive interpreter loop. - -Provides classes for handling Python source input and arbitrary output -interactively from a Twisted application. Also included is syntax coloring -code with support for VT102 terminals, control code handling (^C, ^D, ^Q), -and reasonable handling of Deferreds. - -@author: Jp Calderone -""" - -import code, sys, StringIO, tokenize - -from twisted.conch import recvline - -from twisted.internet import defer -from twisted.python.htmlizer import TokenPrinter - -class FileWrapper: - """Minimal write-file-like object. - - Writes are translated into addOutput calls on an object passed to - __init__. Newlines are also converted from network to local style. - """ - - softspace = 0 - state = 'normal' - - def __init__(self, o): - self.o = o - - def flush(self): - pass - - def write(self, data): - self.o.addOutput(data.replace('\r\n', '\n')) - - def writelines(self, lines): - self.write(''.join(lines)) - -class ManholeInterpreter(code.InteractiveInterpreter): - """Interactive Interpreter with special output and Deferred support. - - Aside from the features provided by L{code.InteractiveInterpreter}, this - class captures sys.stdout output and redirects it to the appropriate - location (the Manhole protocol instance). It also treats Deferreds - which reach the top-level specially: each is formatted to the user with - a unique identifier and a new callback and errback added to it, each of - which will format the unique identifier and the result with which the - Deferred fires and then pass it on to the next participant in the - callback chain. - """ - - numDeferreds = 0 - def __init__(self, handler, locals=None, filename="<console>"): - code.InteractiveInterpreter.__init__(self, locals) - self._pendingDeferreds = {} - self.handler = handler - self.filename = filename - self.resetBuffer() - - def resetBuffer(self): - """Reset the input buffer.""" - self.buffer = [] - - def push(self, line): - """Push a line to the interpreter. - - The line should not have a trailing newline; it may have - internal newlines. The line is appended to a buffer and the - interpreter's runsource() method is called with the - concatenated contents of the buffer as source. If this - indicates that the command was executed or invalid, the buffer - is reset; otherwise, the command is incomplete, and the buffer - is left as it was after the line was appended. The return - value is 1 if more input is required, 0 if the line was dealt - with in some way (this is the same as runsource()). - - """ - self.buffer.append(line) - source = "\n".join(self.buffer) - more = self.runsource(source, self.filename) - if not more: - self.resetBuffer() - return more - - def runcode(self, *a, **kw): - orighook, sys.displayhook = sys.displayhook, self.displayhook - try: - origout, sys.stdout = sys.stdout, FileWrapper(self.handler) - try: - code.InteractiveInterpreter.runcode(self, *a, **kw) - finally: - sys.stdout = origout - finally: - sys.displayhook = orighook - - def displayhook(self, obj): - self.locals['_'] = obj - if isinstance(obj, defer.Deferred): - # XXX Ick, where is my "hasFired()" interface? - if hasattr(obj, "result"): - self.write(repr(obj)) - elif id(obj) in self._pendingDeferreds: - self.write("<Deferred #%d>" % (self._pendingDeferreds[id(obj)][0],)) - else: - d = self._pendingDeferreds - k = self.numDeferreds - d[id(obj)] = (k, obj) - self.numDeferreds += 1 - obj.addCallbacks(self._cbDisplayDeferred, self._ebDisplayDeferred, - callbackArgs=(k, obj), errbackArgs=(k, obj)) - self.write("<Deferred #%d>" % (k,)) - elif obj is not None: - self.write(repr(obj)) - - def _cbDisplayDeferred(self, result, k, obj): - self.write("Deferred #%d called back: %r" % (k, result), True) - del self._pendingDeferreds[id(obj)] - return result - - def _ebDisplayDeferred(self, failure, k, obj): - self.write("Deferred #%d failed: %r" % (k, failure.getErrorMessage()), True) - del self._pendingDeferreds[id(obj)] - return failure - - def write(self, data, async=False): - self.handler.addOutput(data, async) - -CTRL_C = '\x03' -CTRL_D = '\x04' -CTRL_BACKSLASH = '\x1c' -CTRL_L = '\x0c' -CTRL_A = '\x01' -CTRL_E = '\x05' - -class Manhole(recvline.HistoricRecvLine): - """Mediator between a fancy line source and an interactive interpreter. - - This accepts lines from its transport and passes them on to a - L{ManholeInterpreter}. Control commands (^C, ^D, ^\) are also handled - with something approximating their normal terminal-mode behavior. It - can optionally be constructed with a dict which will be used as the - local namespace for any code executed. - """ - - namespace = None - - def __init__(self, namespace=None): - recvline.HistoricRecvLine.__init__(self) - if namespace is not None: - self.namespace = namespace.copy() - - def connectionMade(self): - recvline.HistoricRecvLine.connectionMade(self) - self.interpreter = ManholeInterpreter(self, self.namespace) - self.keyHandlers[CTRL_C] = self.handle_INT - self.keyHandlers[CTRL_D] = self.handle_EOF - self.keyHandlers[CTRL_L] = self.handle_FF - self.keyHandlers[CTRL_A] = self.handle_HOME - self.keyHandlers[CTRL_E] = self.handle_END - self.keyHandlers[CTRL_BACKSLASH] = self.handle_QUIT - - - def handle_INT(self): - """ - Handle ^C as an interrupt keystroke by resetting the current input - variables to their initial state. - """ - self.pn = 0 - self.lineBuffer = [] - self.lineBufferIndex = 0 - self.interpreter.resetBuffer() - - self.terminal.nextLine() - self.terminal.write("KeyboardInterrupt") - self.terminal.nextLine() - self.terminal.write(self.ps[self.pn]) - - - def handle_EOF(self): - if self.lineBuffer: - self.terminal.write('\a') - else: - self.handle_QUIT() - - - def handle_FF(self): - """ - Handle a 'form feed' byte - generally used to request a screen - refresh/redraw. - """ - self.terminal.eraseDisplay() - self.terminal.cursorHome() - self.drawInputLine() - - - def handle_QUIT(self): - self.terminal.loseConnection() - - - def _needsNewline(self): - w = self.terminal.lastWrite - return not w.endswith('\n') and not w.endswith('\x1bE') - - def addOutput(self, bytes, async=False): - if async: - self.terminal.eraseLine() - self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn])) - - self.terminal.write(bytes) - - if async: - if self._needsNewline(): - self.terminal.nextLine() - - self.terminal.write(self.ps[self.pn]) - - if self.lineBuffer: - oldBuffer = self.lineBuffer - self.lineBuffer = [] - self.lineBufferIndex = 0 - - self._deliverBuffer(oldBuffer) - - def lineReceived(self, line): - more = self.interpreter.push(line) - self.pn = bool(more) - if self._needsNewline(): - self.terminal.nextLine() - self.terminal.write(self.ps[self.pn]) - -class VT102Writer: - """Colorizer for Python tokens. - - A series of tokens are written to instances of this object. Each is - colored in a particular way. The final line of the result of this is - generally added to the output. - """ - - typeToColor = { - 'identifier': '\x1b[31m', - 'keyword': '\x1b[32m', - 'parameter': '\x1b[33m', - 'variable': '\x1b[1;33m', - 'string': '\x1b[35m', - 'number': '\x1b[36m', - 'op': '\x1b[37m'} - - normalColor = '\x1b[0m' - - def __init__(self): - self.written = [] - - def color(self, type): - r = self.typeToColor.get(type, '') - return r - - def write(self, token, type=None): - if token and token != '\r': - c = self.color(type) - if c: - self.written.append(c) - self.written.append(token) - if c: - self.written.append(self.normalColor) - - def __str__(self): - s = ''.join(self.written) - return s.strip('\n').splitlines()[-1] - -def lastColorizedLine(source): - """Tokenize and colorize the given Python source. - - Returns a VT102-format colorized version of the last line of C{source}. - """ - w = VT102Writer() - p = TokenPrinter(w.write).printtoken - s = StringIO.StringIO(source) - - tokenize.tokenize(s.readline, p) - - return str(w) - -class ColoredManhole(Manhole): - """A REPL which syntax colors input as users type it. - """ - - def getSource(self): - """Return a string containing the currently entered source. - - This is only the code which will be considered for execution - next. - """ - return ('\n'.join(self.interpreter.buffer) + - '\n' + - ''.join(self.lineBuffer)) - - - def characterReceived(self, ch, moreCharactersComing): - if self.mode == 'insert': - self.lineBuffer.insert(self.lineBufferIndex, ch) - else: - self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch] - self.lineBufferIndex += 1 - - if moreCharactersComing: - # Skip it all, we'll get called with another character in - # like 2 femtoseconds. - return - - if ch == ' ': - # Don't bother to try to color whitespace - self.terminal.write(ch) - return - - source = self.getSource() - - # Try to write some junk - try: - coloredLine = lastColorizedLine(source) - except tokenize.TokenError: - # We couldn't do it. Strange. Oh well, just add the character. - self.terminal.write(ch) - else: - # Success! Clear the source on this line. - self.terminal.eraseLine() - self.terminal.cursorBackward(len(self.lineBuffer) + len(self.ps[self.pn]) - 1) - - # And write a new, colorized one. - self.terminal.write(self.ps[self.pn] + coloredLine) - - # And move the cursor to where it belongs - n = len(self.lineBuffer) - self.lineBufferIndex - if n: - self.terminal.cursorBackward(n) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py deleted file mode 100755 index a2297ef6..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_ssh.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_manhole -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -insults/SSH integration support. - -@author: Jp Calderone -""" - -from zope.interface import implements - -from twisted.conch import avatar, interfaces as iconch, error as econch -from twisted.conch.ssh import factory, keys, session -from twisted.cred import credentials, checkers, portal -from twisted.python import components - -from twisted.conch.insults import insults - -class _Glue: - """A feeble class for making one attribute look like another. - - This should be replaced with a real class at some point, probably. - Try not to write new code that uses it. - """ - def __init__(self, **kw): - self.__dict__.update(kw) - - def __getattr__(self, name): - raise AttributeError(self.name, "has no attribute", name) - -class TerminalSessionTransport: - def __init__(self, proto, chainedProtocol, avatar, width, height): - self.proto = proto - self.avatar = avatar - self.chainedProtocol = chainedProtocol - - session = self.proto.session - - self.proto.makeConnection( - _Glue(write=self.chainedProtocol.dataReceived, - loseConnection=lambda: avatar.conn.sendClose(session), - name="SSH Proto Transport")) - - def loseConnection(): - self.proto.loseConnection() - - self.chainedProtocol.makeConnection( - _Glue(write=self.proto.write, - loseConnection=loseConnection, - name="Chained Proto Transport")) - - # XXX TODO - # chainedProtocol is supposed to be an ITerminalTransport, - # maybe. That means perhaps its terminalProtocol attribute is - # an ITerminalProtocol, it could be. So calling terminalSize - # on that should do the right thing But it'd be nice to clean - # this bit up. - self.chainedProtocol.terminalProtocol.terminalSize(width, height) - -class TerminalSession(components.Adapter): - implements(iconch.ISession) - - transportFactory = TerminalSessionTransport - chainedProtocolFactory = insults.ServerProtocol - - def getPty(self, term, windowSize, attrs): - self.height, self.width = windowSize[:2] - - def openShell(self, proto): - self.transportFactory( - proto, self.chainedProtocolFactory(), - iconch.IConchUser(self.original), - self.width, self.height) - - def execCommand(self, proto, cmd): - raise econch.ConchError("Cannot execute commands") - - def closed(self): - pass - -class TerminalUser(avatar.ConchUser, components.Adapter): - def __init__(self, original, avatarId): - components.Adapter.__init__(self, original) - avatar.ConchUser.__init__(self) - self.channelLookup['session'] = session.SSHSession - -class TerminalRealm: - userFactory = TerminalUser - sessionFactory = TerminalSession - - transportFactory = TerminalSessionTransport - chainedProtocolFactory = insults.ServerProtocol - - def _getAvatar(self, avatarId): - comp = components.Componentized() - user = self.userFactory(comp, avatarId) - sess = self.sessionFactory(comp) - - sess.transportFactory = self.transportFactory - sess.chainedProtocolFactory = self.chainedProtocolFactory - - comp.setComponent(iconch.IConchUser, user) - comp.setComponent(iconch.ISession, sess) - - return user - - def __init__(self, transportFactory=None): - if transportFactory is not None: - self.transportFactory = transportFactory - - def requestAvatar(self, avatarId, mind, *interfaces): - for i in interfaces: - if i is iconch.IConchUser: - return (iconch.IConchUser, - self._getAvatar(avatarId), - lambda: None) - raise NotImplementedError() - -class ConchFactory(factory.SSHFactory): - publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV' - - publicKeys = { - 'ssh-rsa' : keys.Key.fromString(publicKey) - } - del publicKey - - privateKey = """-----BEGIN RSA PRIVATE KEY----- -MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW -4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw -vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb -Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1 -xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8 -PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2 -gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu -DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML -pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP -EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg== ------END RSA PRIVATE KEY-----""" - privateKeys = { - 'ssh-rsa' : keys.Key.fromString(privateKey) - } - del privateKey - - def __init__(self, portal): - self.portal = portal diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py deleted file mode 100755 index 4df7c839..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/manhole_tap.py +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -TAP plugin for creating telnet- and ssh-accessible manhole servers. - -@author: Jp Calderone -""" - -from zope.interface import implements - -from twisted.internet import protocol -from twisted.application import service, strports -from twisted.conch.ssh import session -from twisted.conch import interfaces as iconch -from twisted.cred import portal, checkers -from twisted.python import usage - -from twisted.conch.insults import insults -from twisted.conch import manhole, manhole_ssh, telnet - -class makeTelnetProtocol: - def __init__(self, portal): - self.portal = portal - - def __call__(self): - auth = telnet.AuthenticatingTelnetProtocol - args = (self.portal,) - return telnet.TelnetTransport(auth, *args) - -class chainedProtocolFactory: - def __init__(self, namespace): - self.namespace = namespace - - def __call__(self): - return insults.ServerProtocol(manhole.ColoredManhole, self.namespace) - -class _StupidRealm: - implements(portal.IRealm) - - def __init__(self, proto, *a, **kw): - self.protocolFactory = proto - self.protocolArgs = a - self.protocolKwArgs = kw - - def requestAvatar(self, avatarId, *interfaces): - if telnet.ITelnetProtocol in interfaces: - return (telnet.ITelnetProtocol, - self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs), - lambda: None) - raise NotImplementedError() - -class Options(usage.Options): - optParameters = [ - ["telnetPort", "t", None, "strports description of the address on which to listen for telnet connections"], - ["sshPort", "s", None, "strports description of the address on which to listen for ssh connections"], - ["passwd", "p", "/etc/passwd", "name of a passwd(5)-format username/password file"]] - - def __init__(self): - usage.Options.__init__(self) - self['namespace'] = None - - def postOptions(self): - if self['telnetPort'] is None and self['sshPort'] is None: - raise usage.UsageError("At least one of --telnetPort and --sshPort must be specified") - -def makeService(options): - """Create a manhole server service. - - @type options: C{dict} - @param options: A mapping describing the configuration of - the desired service. Recognized key/value pairs are:: - - "telnetPort": strports description of the address on which - to listen for telnet connections. If None, - no telnet service will be started. - - "sshPort": strports description of the address on which to - listen for ssh connections. If None, no ssh - service will be started. - - "namespace": dictionary containing desired initial locals - for manhole connections. If None, an empty - dictionary will be used. - - "passwd": Name of a passwd(5)-format username/password file. - - @rtype: L{twisted.application.service.IService} - @return: A manhole service. - """ - - svc = service.MultiService() - - namespace = options['namespace'] - if namespace is None: - namespace = {} - - checker = checkers.FilePasswordDB(options['passwd']) - - if options['telnetPort']: - telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol, - insults.ServerProtocol, - manhole.ColoredManhole, - namespace) - - telnetPortal = portal.Portal(telnetRealm, [checker]) - - telnetFactory = protocol.ServerFactory() - telnetFactory.protocol = makeTelnetProtocol(telnetPortal) - telnetService = strports.service(options['telnetPort'], - telnetFactory) - telnetService.setServiceParent(svc) - - if options['sshPort']: - sshRealm = manhole_ssh.TerminalRealm() - sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace) - - sshPortal = portal.Portal(sshRealm, [checker]) - sshFactory = manhole_ssh.ConchFactory(sshPortal) - sshService = strports.service(options['sshPort'], - sshFactory) - sshService.setServiceParent(svc) - - return svc diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py deleted file mode 100755 index 581e2ff0..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/mixin.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_mixin -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Experimental optimization - -This module provides a single mixin class which allows protocols to -collapse numerous small writes into a single larger one. - -@author: Jp Calderone -""" - -from twisted.internet import reactor - -class BufferingMixin: - """Mixin which adds write buffering. - """ - _delayedWriteCall = None - bytes = None - - DELAY = 0.0 - - def schedule(self): - return reactor.callLater(self.DELAY, self.flush) - - def reschedule(self, token): - token.reset(self.DELAY) - - def write(self, bytes): - """Buffer some bytes to be written soon. - - Every call to this function delays the real write by C{self.DELAY} - seconds. When the delay expires, all collected bytes are written - to the underlying transport using L{ITransport.writeSequence}. - """ - if self._delayedWriteCall is None: - self.bytes = [] - self._delayedWriteCall = self.schedule() - else: - self.reschedule(self._delayedWriteCall) - self.bytes.append(bytes) - - def flush(self): - """Flush the buffer immediately. - """ - self._delayedWriteCall = None - self.transport.writeSequence(self.bytes) - self.bytes = None diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py deleted file mode 100755 index 69d5927d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -""" -Support for OpenSSH configuration files. - -Maintainer: Paul Swartz -""" - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py deleted file mode 100755 index f0ad8f79..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/factory.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_openssh_compat -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Factory for reading openssh configuration files: public keys, private keys, and -moduli file. -""" - -import os, errno - -from twisted.python import log -from twisted.python.util import runAsEffectiveUser - -from twisted.conch.ssh import keys, factory, common -from twisted.conch.openssh_compat import primes - - - -class OpenSSHFactory(factory.SSHFactory): - dataRoot = '/usr/local/etc' - moduliRoot = '/usr/local/etc' # for openbsd which puts moduli in a different - # directory from keys - - - def getPublicKeys(self): - """ - Return the server public keys. - """ - ks = {} - for filename in os.listdir(self.dataRoot): - if filename[:9] == 'ssh_host_' and filename[-8:]=='_key.pub': - try: - k = keys.Key.fromFile( - os.path.join(self.dataRoot, filename)) - t = common.getNS(k.blob())[0] - ks[t] = k - except Exception, e: - log.msg('bad public key file %s: %s' % (filename, e)) - return ks - - - def getPrivateKeys(self): - """ - Return the server private keys. - """ - privateKeys = {} - for filename in os.listdir(self.dataRoot): - if filename[:9] == 'ssh_host_' and filename[-4:]=='_key': - fullPath = os.path.join(self.dataRoot, filename) - try: - key = keys.Key.fromFile(fullPath) - except IOError, e: - if e.errno == errno.EACCES: - # Not allowed, let's switch to root - key = runAsEffectiveUser(0, 0, keys.Key.fromFile, fullPath) - keyType = keys.objectType(key.keyObject) - privateKeys[keyType] = key - else: - raise - except Exception, e: - log.msg('bad private key file %s: %s' % (filename, e)) - else: - keyType = keys.objectType(key.keyObject) - privateKeys[keyType] = key - return privateKeys - - - def getPrimes(self): - try: - return primes.parseModuliFile(self.moduliRoot+'/moduli') - except IOError: - return None diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py deleted file mode 100755 index 5d939e6d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/openssh_compat/primes.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -""" -Parsing for the moduli file, which contains Diffie-Hellman prime groups. - -Maintainer: Paul Swartz -""" - -def parseModuliFile(filename): - lines = open(filename).readlines() - primes = {} - for l in lines: - l = l.strip() - if not l or l[0]=='#': - continue - tim, typ, tst, tri, size, gen, mod = l.split() - size = int(size) + 1 - gen = long(gen) - mod = long(mod, 16) - if not primes.has_key(size): - primes[size] = [] - primes[size].append((gen, mod)) - return primes diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py deleted file mode 100755 index 6c8416ae..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/recvline.py +++ /dev/null @@ -1,329 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_recvline -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Basic line editing support. - -@author: Jp Calderone -""" - -import string - -from zope.interface import implements - -from twisted.conch.insults import insults, helper - -from twisted.python import log, reflect - -_counters = {} -class Logging(object): - """Wrapper which logs attribute lookups. - - This was useful in debugging something, I guess. I forget what. - It can probably be deleted or moved somewhere more appropriate. - Nothing special going on here, really. - """ - def __init__(self, original): - self.original = original - key = reflect.qual(original.__class__) - count = _counters.get(key, 0) - _counters[key] = count + 1 - self._logFile = file(key + '-' + str(count), 'w') - - def __str__(self): - return str(super(Logging, self).__getattribute__('original')) - - def __repr__(self): - return repr(super(Logging, self).__getattribute__('original')) - - def __getattribute__(self, name): - original = super(Logging, self).__getattribute__('original') - logFile = super(Logging, self).__getattribute__('_logFile') - logFile.write(name + '\n') - return getattr(original, name) - -class TransportSequence(object): - """An L{ITerminalTransport} implementation which forwards calls to - one or more other L{ITerminalTransport}s. - - This is a cheap way for servers to keep track of the state they - expect the client to see, since all terminal manipulations can be - send to the real client and to a terminal emulator that lives in - the server process. - """ - implements(insults.ITerminalTransport) - - for keyID in ('UP_ARROW', 'DOWN_ARROW', 'RIGHT_ARROW', 'LEFT_ARROW', - 'HOME', 'INSERT', 'DELETE', 'END', 'PGUP', 'PGDN', - 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', - 'F10', 'F11', 'F12'): - exec '%s = object()' % (keyID,) - - TAB = '\t' - BACKSPACE = '\x7f' - - def __init__(self, *transports): - assert transports, "Cannot construct a TransportSequence with no transports" - self.transports = transports - - for method in insults.ITerminalTransport: - exec """\ -def %s(self, *a, **kw): - for tpt in self.transports: - result = tpt.%s(*a, **kw) - return result -""" % (method, method) - -class LocalTerminalBufferMixin(object): - """A mixin for RecvLine subclasses which records the state of the terminal. - - This is accomplished by performing all L{ITerminalTransport} operations on both - the transport passed to makeConnection and an instance of helper.TerminalBuffer. - - @ivar terminalCopy: A L{helper.TerminalBuffer} instance which efforts - will be made to keep up to date with the actual terminal - associated with this protocol instance. - """ - - def makeConnection(self, transport): - self.terminalCopy = helper.TerminalBuffer() - self.terminalCopy.connectionMade() - return super(LocalTerminalBufferMixin, self).makeConnection( - TransportSequence(transport, self.terminalCopy)) - - def __str__(self): - return str(self.terminalCopy) - -class RecvLine(insults.TerminalProtocol): - """L{TerminalProtocol} which adds line editing features. - - Clients will be prompted for lines of input with all the usual - features: character echoing, left and right arrow support for - moving the cursor to different areas of the line buffer, backspace - and delete for removing characters, and insert for toggling - between typeover and insert mode. Tabs will be expanded to enough - spaces to move the cursor to the next tabstop (every four - characters by default). Enter causes the line buffer to be - cleared and the line to be passed to the lineReceived() method - which, by default, does nothing. Subclasses are responsible for - redrawing the input prompt (this will probably change). - """ - width = 80 - height = 24 - - TABSTOP = 4 - - ps = ('>>> ', '... ') - pn = 0 - _printableChars = set(string.printable) - - def connectionMade(self): - # A list containing the characters making up the current line - self.lineBuffer = [] - - # A zero-based (wtf else?) index into self.lineBuffer. - # Indicates the current cursor position. - self.lineBufferIndex = 0 - - t = self.terminal - # A map of keyIDs to bound instance methods. - self.keyHandlers = { - t.LEFT_ARROW: self.handle_LEFT, - t.RIGHT_ARROW: self.handle_RIGHT, - t.TAB: self.handle_TAB, - - # Both of these should not be necessary, but figuring out - # which is necessary is a huge hassle. - '\r': self.handle_RETURN, - '\n': self.handle_RETURN, - - t.BACKSPACE: self.handle_BACKSPACE, - t.DELETE: self.handle_DELETE, - t.INSERT: self.handle_INSERT, - t.HOME: self.handle_HOME, - t.END: self.handle_END} - - self.initializeScreen() - - def initializeScreen(self): - # Hmm, state sucks. Oh well. - # For now we will just take over the whole terminal. - self.terminal.reset() - self.terminal.write(self.ps[self.pn]) - # XXX Note: I would prefer to default to starting in insert - # mode, however this does not seem to actually work! I do not - # know why. This is probably of interest to implementors - # subclassing RecvLine. - - # XXX XXX Note: But the unit tests all expect the initial mode - # to be insert right now. Fuck, there needs to be a way to - # query the current mode or something. - # self.setTypeoverMode() - self.setInsertMode() - - def currentLineBuffer(self): - s = ''.join(self.lineBuffer) - return s[:self.lineBufferIndex], s[self.lineBufferIndex:] - - def setInsertMode(self): - self.mode = 'insert' - self.terminal.setModes([insults.modes.IRM]) - - def setTypeoverMode(self): - self.mode = 'typeover' - self.terminal.resetModes([insults.modes.IRM]) - - def drawInputLine(self): - """ - Write a line containing the current input prompt and the current line - buffer at the current cursor position. - """ - self.terminal.write(self.ps[self.pn] + ''.join(self.lineBuffer)) - - def terminalSize(self, width, height): - # XXX - Clear the previous input line, redraw it at the new - # cursor position - self.terminal.eraseDisplay() - self.terminal.cursorHome() - self.width = width - self.height = height - self.drawInputLine() - - def unhandledControlSequence(self, seq): - pass - - def keystrokeReceived(self, keyID, modifier): - m = self.keyHandlers.get(keyID) - if m is not None: - m() - elif keyID in self._printableChars: - self.characterReceived(keyID, False) - else: - log.msg("Received unhandled keyID: %r" % (keyID,)) - - def characterReceived(self, ch, moreCharactersComing): - if self.mode == 'insert': - self.lineBuffer.insert(self.lineBufferIndex, ch) - else: - self.lineBuffer[self.lineBufferIndex:self.lineBufferIndex+1] = [ch] - self.lineBufferIndex += 1 - self.terminal.write(ch) - - def handle_TAB(self): - n = self.TABSTOP - (len(self.lineBuffer) % self.TABSTOP) - self.terminal.cursorForward(n) - self.lineBufferIndex += n - self.lineBuffer.extend(' ' * n) - - def handle_LEFT(self): - if self.lineBufferIndex > 0: - self.lineBufferIndex -= 1 - self.terminal.cursorBackward() - - def handle_RIGHT(self): - if self.lineBufferIndex < len(self.lineBuffer): - self.lineBufferIndex += 1 - self.terminal.cursorForward() - - def handle_HOME(self): - if self.lineBufferIndex: - self.terminal.cursorBackward(self.lineBufferIndex) - self.lineBufferIndex = 0 - - def handle_END(self): - offset = len(self.lineBuffer) - self.lineBufferIndex - if offset: - self.terminal.cursorForward(offset) - self.lineBufferIndex = len(self.lineBuffer) - - def handle_BACKSPACE(self): - if self.lineBufferIndex > 0: - self.lineBufferIndex -= 1 - del self.lineBuffer[self.lineBufferIndex] - self.terminal.cursorBackward() - self.terminal.deleteCharacter() - - def handle_DELETE(self): - if self.lineBufferIndex < len(self.lineBuffer): - del self.lineBuffer[self.lineBufferIndex] - self.terminal.deleteCharacter() - - def handle_RETURN(self): - line = ''.join(self.lineBuffer) - self.lineBuffer = [] - self.lineBufferIndex = 0 - self.terminal.nextLine() - self.lineReceived(line) - - def handle_INSERT(self): - assert self.mode in ('typeover', 'insert') - if self.mode == 'typeover': - self.setInsertMode() - else: - self.setTypeoverMode() - - def lineReceived(self, line): - pass - -class HistoricRecvLine(RecvLine): - """L{TerminalProtocol} which adds both basic line-editing features and input history. - - Everything supported by L{RecvLine} is also supported by this class. In addition, the - up and down arrows traverse the input history. Each received line is automatically - added to the end of the input history. - """ - def connectionMade(self): - RecvLine.connectionMade(self) - - self.historyLines = [] - self.historyPosition = 0 - - t = self.terminal - self.keyHandlers.update({t.UP_ARROW: self.handle_UP, - t.DOWN_ARROW: self.handle_DOWN}) - - def currentHistoryBuffer(self): - b = tuple(self.historyLines) - return b[:self.historyPosition], b[self.historyPosition:] - - def _deliverBuffer(self, buf): - if buf: - for ch in buf[:-1]: - self.characterReceived(ch, True) - self.characterReceived(buf[-1], False) - - def handle_UP(self): - if self.lineBuffer and self.historyPosition == len(self.historyLines): - self.historyLines.append(self.lineBuffer) - if self.historyPosition > 0: - self.handle_HOME() - self.terminal.eraseToLineEnd() - - self.historyPosition -= 1 - self.lineBuffer = [] - - self._deliverBuffer(self.historyLines[self.historyPosition]) - - def handle_DOWN(self): - if self.historyPosition < len(self.historyLines) - 1: - self.handle_HOME() - self.terminal.eraseToLineEnd() - - self.historyPosition += 1 - self.lineBuffer = [] - - self._deliverBuffer(self.historyLines[self.historyPosition]) - else: - self.handle_HOME() - self.terminal.eraseToLineEnd() - - self.historyPosition = len(self.historyLines) - self.lineBuffer = [] - self.lineBufferIndex = 0 - - def handle_RETURN(self): - if self.lineBuffer: - self.historyLines.append(''.join(self.lineBuffer)) - self.historyPosition = len(self.historyLines) - return RecvLine.handle_RETURN(self) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py deleted file mode 100755 index 63fdb3d2..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/__init__.py +++ /dev/null @@ -1 +0,0 @@ -'conch scripts' diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py deleted file mode 100755 index e6db67f0..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/cftp.py +++ /dev/null @@ -1,832 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_cftp -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Implementation module for the I{cftp} command. -""" - -import os, sys, getpass, struct, tty, fcntl, stat -import fnmatch, pwd, glob - -from twisted.conch.client import connect, default, options -from twisted.conch.ssh import connection, common -from twisted.conch.ssh import channel, filetransfer -from twisted.protocols import basic -from twisted.internet import reactor, stdio, defer, utils -from twisted.python import log, usage, failure - -class ClientOptions(options.ConchOptions): - - synopsis = """Usage: cftp [options] [user@]host - cftp [options] [user@]host[:dir[/]] - cftp [options] [user@]host[:file [localfile]] -""" - longdesc = ("cftp is a client for logging into a remote machine and " - "executing commands to send and receive file information") - - optParameters = [ - ['buffersize', 'B', 32768, 'Size of the buffer to use for sending/receiving.'], - ['batchfile', 'b', None, 'File to read commands from, or \'-\' for stdin.'], - ['requests', 'R', 5, 'Number of requests to make before waiting for a reply.'], - ['subsystem', 's', 'sftp', 'Subsystem/server program to connect to.']] - - compData = usage.Completions( - descriptions={ - "buffersize": "Size of send/receive buffer (default: 32768)"}, - extraActions=[usage.CompleteUserAtHost(), - usage.CompleteFiles(descr="local file")]) - - def parseArgs(self, host, localPath=None): - self['remotePath'] = '' - if ':' in host: - host, self['remotePath'] = host.split(':', 1) - self['remotePath'].rstrip('/') - self['host'] = host - self['localPath'] = localPath - -def run(): -# import hotshot -# prof = hotshot.Profile('cftp.prof') -# prof.start() - args = sys.argv[1:] - if '-l' in args: # cvs is an idiot - i = args.index('-l') - args = args[i:i+2]+args - del args[i+2:i+4] - options = ClientOptions() - try: - options.parseOptions(args) - except usage.UsageError, u: - print 'ERROR: %s' % u - sys.exit(1) - if options['log']: - realout = sys.stdout - log.startLogging(sys.stderr) - sys.stdout = realout - else: - log.discardLogs() - doConnect(options) - reactor.run() -# prof.stop() -# prof.close() - -def handleError(): - global exitStatus - exitStatus = 2 - try: - reactor.stop() - except: pass - log.err(failure.Failure()) - raise - -def doConnect(options): -# log.deferr = handleError # HACK - if '@' in options['host']: - options['user'], options['host'] = options['host'].split('@',1) - host = options['host'] - if not options['user']: - options['user'] = getpass.getuser() - if not options['port']: - options['port'] = 22 - else: - options['port'] = int(options['port']) - host = options['host'] - port = options['port'] - conn = SSHConnection() - conn.options = options - vhk = default.verifyHostKey - uao = default.SSHUserAuthClient(options['user'], options, conn) - connect.connect(host, port, options, vhk, uao).addErrback(_ebExit) - -def _ebExit(f): - #global exitStatus - if hasattr(f.value, 'value'): - s = f.value.value - else: - s = str(f) - print s - #exitStatus = "conch: exiting with error %s" % f - try: - reactor.stop() - except: pass - -def _ignore(*args): pass - -class FileWrapper: - - def __init__(self, f): - self.f = f - self.total = 0.0 - f.seek(0, 2) # seek to the end - self.size = f.tell() - - def __getattr__(self, attr): - return getattr(self.f, attr) - -class StdioClient(basic.LineReceiver): - - _pwd = pwd - - ps = 'cftp> ' - delimiter = '\n' - - reactor = reactor - - def __init__(self, client, f = None): - self.client = client - self.currentDirectory = '' - self.file = f - self.useProgressBar = (not f and 1) or 0 - - def connectionMade(self): - self.client.realPath('').addCallback(self._cbSetCurDir) - - def _cbSetCurDir(self, path): - self.currentDirectory = path - self._newLine() - - def lineReceived(self, line): - if self.client.transport.localClosed: - return - log.msg('got line %s' % repr(line)) - line = line.lstrip() - if not line: - self._newLine() - return - if self.file and line.startswith('-'): - self.ignoreErrors = 1 - line = line[1:] - else: - self.ignoreErrors = 0 - d = self._dispatchCommand(line) - if d is not None: - d.addCallback(self._cbCommand) - d.addErrback(self._ebCommand) - - - def _dispatchCommand(self, line): - if ' ' in line: - command, rest = line.split(' ', 1) - rest = rest.lstrip() - else: - command, rest = line, '' - if command.startswith('!'): # command - f = self.cmd_EXEC - rest = (command[1:] + ' ' + rest).strip() - else: - command = command.upper() - log.msg('looking up cmd %s' % command) - f = getattr(self, 'cmd_%s' % command, None) - if f is not None: - return defer.maybeDeferred(f, rest) - else: - self._ebCommand(failure.Failure(NotImplementedError( - "No command called `%s'" % command))) - self._newLine() - - def _printFailure(self, f): - log.msg(f) - e = f.trap(NotImplementedError, filetransfer.SFTPError, OSError, IOError) - if e == NotImplementedError: - self.transport.write(self.cmd_HELP('')) - elif e == filetransfer.SFTPError: - self.transport.write("remote error %i: %s\n" % - (f.value.code, f.value.message)) - elif e in (OSError, IOError): - self.transport.write("local error %i: %s\n" % - (f.value.errno, f.value.strerror)) - - def _newLine(self): - if self.client.transport.localClosed: - return - self.transport.write(self.ps) - self.ignoreErrors = 0 - if self.file: - l = self.file.readline() - if not l: - self.client.transport.loseConnection() - else: - self.transport.write(l) - self.lineReceived(l.strip()) - - def _cbCommand(self, result): - if result is not None: - self.transport.write(result) - if not result.endswith('\n'): - self.transport.write('\n') - self._newLine() - - def _ebCommand(self, f): - self._printFailure(f) - if self.file and not self.ignoreErrors: - self.client.transport.loseConnection() - self._newLine() - - def cmd_CD(self, path): - path, rest = self._getFilename(path) - if not path.endswith('/'): - path += '/' - newPath = path and os.path.join(self.currentDirectory, path) or '' - d = self.client.openDirectory(newPath) - d.addCallback(self._cbCd) - d.addErrback(self._ebCommand) - return d - - def _cbCd(self, directory): - directory.close() - d = self.client.realPath(directory.name) - d.addCallback(self._cbCurDir) - return d - - def _cbCurDir(self, path): - self.currentDirectory = path - - def cmd_CHGRP(self, rest): - grp, rest = rest.split(None, 1) - path, rest = self._getFilename(rest) - grp = int(grp) - d = self.client.getAttrs(path) - d.addCallback(self._cbSetUsrGrp, path, grp=grp) - return d - - def cmd_CHMOD(self, rest): - mod, rest = rest.split(None, 1) - path, rest = self._getFilename(rest) - mod = int(mod, 8) - d = self.client.setAttrs(path, {'permissions':mod}) - d.addCallback(_ignore) - return d - - def cmd_CHOWN(self, rest): - usr, rest = rest.split(None, 1) - path, rest = self._getFilename(rest) - usr = int(usr) - d = self.client.getAttrs(path) - d.addCallback(self._cbSetUsrGrp, path, usr=usr) - return d - - def _cbSetUsrGrp(self, attrs, path, usr=None, grp=None): - new = {} - new['uid'] = (usr is not None) and usr or attrs['uid'] - new['gid'] = (grp is not None) and grp or attrs['gid'] - d = self.client.setAttrs(path, new) - d.addCallback(_ignore) - return d - - def cmd_GET(self, rest): - remote, rest = self._getFilename(rest) - if '*' in remote or '?' in remote: # wildcard - if rest: - local, rest = self._getFilename(rest) - if not os.path.isdir(local): - return "Wildcard get with non-directory target." - else: - local = '' - d = self._remoteGlob(remote) - d.addCallback(self._cbGetMultiple, local) - return d - if rest: - local, rest = self._getFilename(rest) - else: - local = os.path.split(remote)[1] - log.msg((remote, local)) - lf = file(local, 'w', 0) - path = os.path.join(self.currentDirectory, remote) - d = self.client.openFile(path, filetransfer.FXF_READ, {}) - d.addCallback(self._cbGetOpenFile, lf) - d.addErrback(self._ebCloseLf, lf) - return d - - def _cbGetMultiple(self, files, local): - #if self._useProgressBar: # one at a time - # XXX this can be optimized for times w/o progress bar - return self._cbGetMultipleNext(None, files, local) - - def _cbGetMultipleNext(self, res, files, local): - if isinstance(res, failure.Failure): - self._printFailure(res) - elif res: - self.transport.write(res) - if not res.endswith('\n'): - self.transport.write('\n') - if not files: - return - f = files.pop(0)[0] - lf = file(os.path.join(local, os.path.split(f)[1]), 'w', 0) - path = os.path.join(self.currentDirectory, f) - d = self.client.openFile(path, filetransfer.FXF_READ, {}) - d.addCallback(self._cbGetOpenFile, lf) - d.addErrback(self._ebCloseLf, lf) - d.addBoth(self._cbGetMultipleNext, files, local) - return d - - def _ebCloseLf(self, f, lf): - lf.close() - return f - - def _cbGetOpenFile(self, rf, lf): - return rf.getAttrs().addCallback(self._cbGetFileSize, rf, lf) - - def _cbGetFileSize(self, attrs, rf, lf): - if not stat.S_ISREG(attrs['permissions']): - rf.close() - lf.close() - return "Can't get non-regular file: %s" % rf.name - rf.size = attrs['size'] - bufferSize = self.client.transport.conn.options['buffersize'] - numRequests = self.client.transport.conn.options['requests'] - rf.total = 0.0 - dList = [] - chunks = [] - startTime = self.reactor.seconds() - for i in range(numRequests): - d = self._cbGetRead('', rf, lf, chunks, 0, bufferSize, startTime) - dList.append(d) - dl = defer.DeferredList(dList, fireOnOneErrback=1) - dl.addCallback(self._cbGetDone, rf, lf) - return dl - - def _getNextChunk(self, chunks): - end = 0 - for chunk in chunks: - if end == 'eof': - return # nothing more to get - if end != chunk[0]: - i = chunks.index(chunk) - chunks.insert(i, (end, chunk[0])) - return (end, chunk[0] - end) - end = chunk[1] - bufSize = int(self.client.transport.conn.options['buffersize']) - chunks.append((end, end + bufSize)) - return (end, bufSize) - - def _cbGetRead(self, data, rf, lf, chunks, start, size, startTime): - if data and isinstance(data, failure.Failure): - log.msg('get read err: %s' % data) - reason = data - reason.trap(EOFError) - i = chunks.index((start, start + size)) - del chunks[i] - chunks.insert(i, (start, 'eof')) - elif data: - log.msg('get read data: %i' % len(data)) - lf.seek(start) - lf.write(data) - if len(data) != size: - log.msg('got less than we asked for: %i < %i' % - (len(data), size)) - i = chunks.index((start, start + size)) - del chunks[i] - chunks.insert(i, (start, start + len(data))) - rf.total += len(data) - if self.useProgressBar: - self._printProgressBar(rf, startTime) - chunk = self._getNextChunk(chunks) - if not chunk: - return - else: - start, length = chunk - log.msg('asking for %i -> %i' % (start, start+length)) - d = rf.readChunk(start, length) - d.addBoth(self._cbGetRead, rf, lf, chunks, start, length, startTime) - return d - - def _cbGetDone(self, ignored, rf, lf): - log.msg('get done') - rf.close() - lf.close() - if self.useProgressBar: - self.transport.write('\n') - return "Transferred %s to %s" % (rf.name, lf.name) - - def cmd_PUT(self, rest): - local, rest = self._getFilename(rest) - if '*' in local or '?' in local: # wildcard - if rest: - remote, rest = self._getFilename(rest) - path = os.path.join(self.currentDirectory, remote) - d = self.client.getAttrs(path) - d.addCallback(self._cbPutTargetAttrs, remote, local) - return d - else: - remote = '' - files = glob.glob(local) - return self._cbPutMultipleNext(None, files, remote) - if rest: - remote, rest = self._getFilename(rest) - else: - remote = os.path.split(local)[1] - lf = file(local, 'r') - path = os.path.join(self.currentDirectory, remote) - flags = filetransfer.FXF_WRITE|filetransfer.FXF_CREAT|filetransfer.FXF_TRUNC - d = self.client.openFile(path, flags, {}) - d.addCallback(self._cbPutOpenFile, lf) - d.addErrback(self._ebCloseLf, lf) - return d - - def _cbPutTargetAttrs(self, attrs, path, local): - if not stat.S_ISDIR(attrs['permissions']): - return "Wildcard put with non-directory target." - return self._cbPutMultipleNext(None, files, path) - - def _cbPutMultipleNext(self, res, files, path): - if isinstance(res, failure.Failure): - self._printFailure(res) - elif res: - self.transport.write(res) - if not res.endswith('\n'): - self.transport.write('\n') - f = None - while files and not f: - try: - f = files.pop(0) - lf = file(f, 'r') - except: - self._printFailure(failure.Failure()) - f = None - if not f: - return - name = os.path.split(f)[1] - remote = os.path.join(self.currentDirectory, path, name) - log.msg((name, remote, path)) - flags = filetransfer.FXF_WRITE|filetransfer.FXF_CREAT|filetransfer.FXF_TRUNC - d = self.client.openFile(remote, flags, {}) - d.addCallback(self._cbPutOpenFile, lf) - d.addErrback(self._ebCloseLf, lf) - d.addBoth(self._cbPutMultipleNext, files, path) - return d - - def _cbPutOpenFile(self, rf, lf): - numRequests = self.client.transport.conn.options['requests'] - if self.useProgressBar: - lf = FileWrapper(lf) - dList = [] - chunks = [] - startTime = self.reactor.seconds() - for i in range(numRequests): - d = self._cbPutWrite(None, rf, lf, chunks, startTime) - if d: - dList.append(d) - dl = defer.DeferredList(dList, fireOnOneErrback=1) - dl.addCallback(self._cbPutDone, rf, lf) - return dl - - def _cbPutWrite(self, ignored, rf, lf, chunks, startTime): - chunk = self._getNextChunk(chunks) - start, size = chunk - lf.seek(start) - data = lf.read(size) - if self.useProgressBar: - lf.total += len(data) - self._printProgressBar(lf, startTime) - if data: - d = rf.writeChunk(start, data) - d.addCallback(self._cbPutWrite, rf, lf, chunks, startTime) - return d - else: - return - - def _cbPutDone(self, ignored, rf, lf): - lf.close() - rf.close() - if self.useProgressBar: - self.transport.write('\n') - return 'Transferred %s to %s' % (lf.name, rf.name) - - def cmd_LCD(self, path): - os.chdir(path) - - def cmd_LN(self, rest): - linkpath, rest = self._getFilename(rest) - targetpath, rest = self._getFilename(rest) - linkpath, targetpath = map( - lambda x: os.path.join(self.currentDirectory, x), - (linkpath, targetpath)) - return self.client.makeLink(linkpath, targetpath).addCallback(_ignore) - - def cmd_LS(self, rest): - # possible lines: - # ls current directory - # ls name_of_file that file - # ls name_of_directory that directory - # ls some_glob_string current directory, globbed for that string - options = [] - rest = rest.split() - while rest and rest[0] and rest[0][0] == '-': - opts = rest.pop(0)[1:] - for o in opts: - if o == 'l': - options.append('verbose') - elif o == 'a': - options.append('all') - rest = ' '.join(rest) - path, rest = self._getFilename(rest) - if not path: - fullPath = self.currentDirectory + '/' - else: - fullPath = os.path.join(self.currentDirectory, path) - d = self._remoteGlob(fullPath) - d.addCallback(self._cbDisplayFiles, options) - return d - - def _cbDisplayFiles(self, files, options): - files.sort() - if 'all' not in options: - files = [f for f in files if not f[0].startswith('.')] - if 'verbose' in options: - lines = [f[1] for f in files] - else: - lines = [f[0] for f in files] - if not lines: - return None - else: - return '\n'.join(lines) - - def cmd_MKDIR(self, path): - path, rest = self._getFilename(path) - path = os.path.join(self.currentDirectory, path) - return self.client.makeDirectory(path, {}).addCallback(_ignore) - - def cmd_RMDIR(self, path): - path, rest = self._getFilename(path) - path = os.path.join(self.currentDirectory, path) - return self.client.removeDirectory(path).addCallback(_ignore) - - def cmd_LMKDIR(self, path): - os.system("mkdir %s" % path) - - def cmd_RM(self, path): - path, rest = self._getFilename(path) - path = os.path.join(self.currentDirectory, path) - return self.client.removeFile(path).addCallback(_ignore) - - def cmd_LLS(self, rest): - os.system("ls %s" % rest) - - def cmd_RENAME(self, rest): - oldpath, rest = self._getFilename(rest) - newpath, rest = self._getFilename(rest) - oldpath, newpath = map ( - lambda x: os.path.join(self.currentDirectory, x), - (oldpath, newpath)) - return self.client.renameFile(oldpath, newpath).addCallback(_ignore) - - def cmd_EXIT(self, ignored): - self.client.transport.loseConnection() - - cmd_QUIT = cmd_EXIT - - def cmd_VERSION(self, ignored): - return "SFTP version %i" % self.client.version - - def cmd_HELP(self, ignored): - return """Available commands: -cd path Change remote directory to 'path'. -chgrp gid path Change gid of 'path' to 'gid'. -chmod mode path Change mode of 'path' to 'mode'. -chown uid path Change uid of 'path' to 'uid'. -exit Disconnect from the server. -get remote-path [local-path] Get remote file. -help Get a list of available commands. -lcd path Change local directory to 'path'. -lls [ls-options] [path] Display local directory listing. -lmkdir path Create local directory. -ln linkpath targetpath Symlink remote file. -lpwd Print the local working directory. -ls [-l] [path] Display remote directory listing. -mkdir path Create remote directory. -progress Toggle progress bar. -put local-path [remote-path] Put local file. -pwd Print the remote working directory. -quit Disconnect from the server. -rename oldpath newpath Rename remote file. -rmdir path Remove remote directory. -rm path Remove remote file. -version Print the SFTP version. -? Synonym for 'help'. -""" - - def cmd_PWD(self, ignored): - return self.currentDirectory - - def cmd_LPWD(self, ignored): - return os.getcwd() - - def cmd_PROGRESS(self, ignored): - self.useProgressBar = not self.useProgressBar - return "%ssing progess bar." % (self.useProgressBar and "U" or "Not u") - - def cmd_EXEC(self, rest): - """ - Run C{rest} using the user's shell (or /bin/sh if they do not have - one). - """ - shell = self._pwd.getpwnam(getpass.getuser())[6] - if not shell: - shell = '/bin/sh' - if rest: - cmds = ['-c', rest] - return utils.getProcessOutput(shell, cmds, errortoo=1) - else: - os.system(shell) - - # accessory functions - - def _remoteGlob(self, fullPath): - log.msg('looking up %s' % fullPath) - head, tail = os.path.split(fullPath) - if '*' in tail or '?' in tail: - glob = 1 - else: - glob = 0 - if tail and not glob: # could be file or directory - # try directory first - d = self.client.openDirectory(fullPath) - d.addCallback(self._cbOpenList, '') - d.addErrback(self._ebNotADirectory, head, tail) - else: - d = self.client.openDirectory(head) - d.addCallback(self._cbOpenList, tail) - return d - - def _cbOpenList(self, directory, glob): - files = [] - d = directory.read() - d.addBoth(self._cbReadFile, files, directory, glob) - return d - - def _ebNotADirectory(self, reason, path, glob): - d = self.client.openDirectory(path) - d.addCallback(self._cbOpenList, glob) - return d - - def _cbReadFile(self, files, l, directory, glob): - if not isinstance(files, failure.Failure): - if glob: - l.extend([f for f in files if fnmatch.fnmatch(f[0], glob)]) - else: - l.extend(files) - d = directory.read() - d.addBoth(self._cbReadFile, l, directory, glob) - return d - else: - reason = files - reason.trap(EOFError) - directory.close() - return l - - def _abbrevSize(self, size): - # from http://mail.python.org/pipermail/python-list/1999-December/018395.html - _abbrevs = [ - (1<<50L, 'PB'), - (1<<40L, 'TB'), - (1<<30L, 'GB'), - (1<<20L, 'MB'), - (1<<10L, 'kB'), - (1, 'B') - ] - - for factor, suffix in _abbrevs: - if size > factor: - break - return '%.1f' % (size/factor) + suffix - - def _abbrevTime(self, t): - if t > 3600: # 1 hour - hours = int(t / 3600) - t -= (3600 * hours) - mins = int(t / 60) - t -= (60 * mins) - return "%i:%02i:%02i" % (hours, mins, t) - else: - mins = int(t/60) - t -= (60 * mins) - return "%02i:%02i" % (mins, t) - - - def _printProgressBar(self, f, startTime): - """ - Update a console progress bar on this L{StdioClient}'s transport, based - on the difference between the start time of the operation and the - current time according to the reactor, and appropriate to the size of - the console window. - - @param f: a wrapper around the file which is being written or read - @type f: L{FileWrapper} - - @param startTime: The time at which the operation being tracked began. - @type startTime: C{float} - """ - diff = self.reactor.seconds() - startTime - total = f.total - try: - winSize = struct.unpack('4H', - fcntl.ioctl(0, tty.TIOCGWINSZ, '12345679')) - except IOError: - winSize = [None, 80] - if diff == 0.0: - speed = 0.0 - else: - speed = total / diff - if speed: - timeLeft = (f.size - total) / speed - else: - timeLeft = 0 - front = f.name - back = '%3i%% %s %sps %s ' % ((total / f.size) * 100, - self._abbrevSize(total), - self._abbrevSize(speed), - self._abbrevTime(timeLeft)) - spaces = (winSize[1] - (len(front) + len(back) + 1)) * ' ' - self.transport.write('\r%s%s%s' % (front, spaces, back)) - - - def _getFilename(self, line): - line.lstrip() - if not line: - return None, '' - if line[0] in '\'"': - ret = [] - line = list(line) - try: - for i in range(1,len(line)): - c = line[i] - if c == line[0]: - return ''.join(ret), ''.join(line[i+1:]).lstrip() - elif c == '\\': # quoted character - del line[i] - if line[i] not in '\'"\\': - raise IndexError, "bad quote: \\%s" % line[i] - ret.append(line[i]) - else: - ret.append(line[i]) - except IndexError: - raise IndexError, "unterminated quote" - ret = line.split(None, 1) - if len(ret) == 1: - return ret[0], '' - else: - return ret - -StdioClient.__dict__['cmd_?'] = StdioClient.cmd_HELP - -class SSHConnection(connection.SSHConnection): - def serviceStarted(self): - self.openChannel(SSHSession()) - -class SSHSession(channel.SSHChannel): - - name = 'session' - - def channelOpen(self, foo): - log.msg('session %s open' % self.id) - if self.conn.options['subsystem'].startswith('/'): - request = 'exec' - else: - request = 'subsystem' - d = self.conn.sendRequest(self, request, \ - common.NS(self.conn.options['subsystem']), wantReply=1) - d.addCallback(self._cbSubsystem) - d.addErrback(_ebExit) - - def _cbSubsystem(self, result): - self.client = filetransfer.FileTransferClient() - self.client.makeConnection(self) - self.dataReceived = self.client.dataReceived - f = None - if self.conn.options['batchfile']: - fn = self.conn.options['batchfile'] - if fn != '-': - f = file(fn) - self.stdio = stdio.StandardIO(StdioClient(self.client, f)) - - def extReceived(self, t, data): - if t==connection.EXTENDED_DATA_STDERR: - log.msg('got %s stderr data' % len(data)) - sys.stderr.write(data) - sys.stderr.flush() - - def eofReceived(self): - log.msg('got eof') - self.stdio.closeStdin() - - def closeReceived(self): - log.msg('remote side closed %s' % self) - self.conn.sendClose(self) - - def closed(self): - try: - reactor.stop() - except: - pass - - def stopWriting(self): - self.stdio.pauseProducing() - - def startWriting(self): - self.stdio.resumeProducing() - -if __name__ == '__main__': - run() - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py deleted file mode 100755 index ab51fc19..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/ckeygen.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_ckeygen -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Implementation module for the `ckeygen` command. -""" - -import sys, os, getpass, socket -if getpass.getpass == getpass.unix_getpass: - try: - import termios # hack around broken termios - termios.tcgetattr, termios.tcsetattr - except (ImportError, AttributeError): - sys.modules['termios'] = None - reload(getpass) - -from twisted.conch.ssh import keys -from twisted.python import filepath, log, usage, randbytes - - -class GeneralOptions(usage.Options): - synopsis = """Usage: ckeygen [options] - """ - - longdesc = "ckeygen manipulates public/private keys in various ways." - - optParameters = [['bits', 'b', 1024, 'Number of bits in the key to create.'], - ['filename', 'f', None, 'Filename of the key file.'], - ['type', 't', None, 'Specify type of key to create.'], - ['comment', 'C', None, 'Provide new comment.'], - ['newpass', 'N', None, 'Provide new passphrase.'], - ['pass', 'P', None, 'Provide old passphrase']] - - optFlags = [['fingerprint', 'l', 'Show fingerprint of key file.'], - ['changepass', 'p', 'Change passphrase of private key file.'], - ['quiet', 'q', 'Quiet.'], - ['showpub', 'y', 'Read private key file and print public key.']] - - compData = usage.Completions( - optActions={"type": usage.CompleteList(["rsa", "dsa"])}) - -def run(): - options = GeneralOptions() - try: - options.parseOptions(sys.argv[1:]) - except usage.UsageError, u: - print 'ERROR: %s' % u - options.opt_help() - sys.exit(1) - log.discardLogs() - log.deferr = handleError # HACK - if options['type']: - if options['type'] == 'rsa': - generateRSAkey(options) - elif options['type'] == 'dsa': - generateDSAkey(options) - else: - sys.exit('Key type was %s, must be one of: rsa, dsa' % options['type']) - elif options['fingerprint']: - printFingerprint(options) - elif options['changepass']: - changePassPhrase(options) - elif options['showpub']: - displayPublicKey(options) - else: - options.opt_help() - sys.exit(1) - -def handleError(): - from twisted.python import failure - global exitStatus - exitStatus = 2 - log.err(failure.Failure()) - reactor.stop() - raise - -def generateRSAkey(options): - from Crypto.PublicKey import RSA - print 'Generating public/private rsa key pair.' - key = RSA.generate(int(options['bits']), randbytes.secureRandom) - _saveKey(key, options) - -def generateDSAkey(options): - from Crypto.PublicKey import DSA - print 'Generating public/private dsa key pair.' - key = DSA.generate(int(options['bits']), randbytes.secureRandom) - _saveKey(key, options) - - -def printFingerprint(options): - if not options['filename']: - filename = os.path.expanduser('~/.ssh/id_rsa') - options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename) - if os.path.exists(options['filename']+'.pub'): - options['filename'] += '.pub' - try: - key = keys.Key.fromFile(options['filename']) - obj = key.keyObject - string = key.blob() - print '%s %s %s' % ( - obj.size() + 1, - key.fingerprint(), - os.path.basename(options['filename'])) - except: - sys.exit('bad key') - - -def changePassPhrase(options): - if not options['filename']: - filename = os.path.expanduser('~/.ssh/id_rsa') - options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename) - try: - key = keys.Key.fromFile(options['filename']).keyObject - except keys.BadKeyError, e: - if e.args[0] != 'encrypted key with no passphrase': - raise - else: - if not options['pass']: - options['pass'] = getpass.getpass('Enter old passphrase: ') - key = keys.Key.fromFile( - options['filename'], passphrase = options['pass']).keyObject - if not options['newpass']: - while 1: - p1 = getpass.getpass('Enter new passphrase (empty for no passphrase): ') - p2 = getpass.getpass('Enter same passphrase again: ') - if p1 == p2: - break - print 'Passphrases do not match. Try again.' - options['newpass'] = p1 - open(options['filename'], 'w').write( - keys.Key(key).toString(passphrase=options['newpass'])) - print 'Your identification has been saved with the new passphrase.' - - -def displayPublicKey(options): - if not options['filename']: - filename = os.path.expanduser('~/.ssh/id_rsa') - options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename) - try: - key = keys.Key.fromFile(options['filename']).keyObject - except keys.BadKeyError, e: - if e.args[0] != 'encrypted key with no passphrase': - raise - else: - if not options['pass']: - options['pass'] = getpass.getpass('Enter passphrase: ') - key = keys.Key.fromFile( - options['filename'], passphrase = options['pass']).keyObject - print keys.Key(key).public().toString() - - -def _saveKey(key, options): - if not options['filename']: - kind = keys.objectType(key) - kind = {'ssh-rsa':'rsa','ssh-dss':'dsa'}[kind] - filename = os.path.expanduser('~/.ssh/id_%s'%kind) - options['filename'] = raw_input('Enter file in which to save the key (%s): '%filename).strip() or filename - if os.path.exists(options['filename']): - print '%s already exists.' % options['filename'] - yn = raw_input('Overwrite (y/n)? ') - if yn[0].lower() != 'y': - sys.exit() - if not options['pass']: - while 1: - p1 = getpass.getpass('Enter passphrase (empty for no passphrase): ') - p2 = getpass.getpass('Enter same passphrase again: ') - if p1 == p2: - break - print 'Passphrases do not match. Try again.' - options['pass'] = p1 - - keyObj = keys.Key(key) - comment = '%s@%s' % (getpass.getuser(), socket.gethostname()) - - filepath.FilePath(options['filename']).setContent( - keyObj.toString('openssh', options['pass'])) - os.chmod(options['filename'], 33152) - - filepath.FilePath(options['filename'] + '.pub').setContent( - keyObj.public().toString('openssh', comment)) - - print 'Your identification has been saved in %s' % options['filename'] - print 'Your public key has been saved in %s.pub' % options['filename'] - print 'The key fingerprint is:' - print keyObj.fingerprint() - -if __name__ == '__main__': - run() - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py deleted file mode 100755 index 8c495441..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/conch.py +++ /dev/null @@ -1,512 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_conch -*- -# -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -# $Id: conch.py,v 1.65 2004/03/11 00:29:14 z3p Exp $ - -#""" Implementation module for the `conch` command. -#""" -from twisted.conch.client import connect, default, options -from twisted.conch.error import ConchError -from twisted.conch.ssh import connection, common -from twisted.conch.ssh import session, forwarding, channel -from twisted.internet import reactor, stdio, task -from twisted.python import log, usage - -import os, sys, getpass, struct, tty, fcntl, signal - -class ClientOptions(options.ConchOptions): - - synopsis = """Usage: conch [options] host [command] -""" - longdesc = ("conch is a SSHv2 client that allows logging into a remote " - "machine and executing commands.") - - optParameters = [['escape', 'e', '~'], - ['localforward', 'L', None, 'listen-port:host:port Forward local port to remote address'], - ['remoteforward', 'R', None, 'listen-port:host:port Forward remote port to local address'], - ] - - optFlags = [['null', 'n', 'Redirect input from /dev/null.'], - ['fork', 'f', 'Fork to background after authentication.'], - ['tty', 't', 'Tty; allocate a tty even if command is given.'], - ['notty', 'T', 'Do not allocate a tty.'], - ['noshell', 'N', 'Do not execute a shell or command.'], - ['subsystem', 's', 'Invoke command (mandatory) as SSH2 subsystem.'], - ] - - compData = usage.Completions( - mutuallyExclusive=[("tty", "notty")], - optActions={ - "localforward": usage.Completer(descr="listen-port:host:port"), - "remoteforward": usage.Completer(descr="listen-port:host:port")}, - extraActions=[usage.CompleteUserAtHost(), - usage.Completer(descr="command"), - usage.Completer(descr="argument", repeat=True)] - ) - - localForwards = [] - remoteForwards = [] - - def opt_escape(self, esc): - "Set escape character; ``none'' = disable" - if esc == 'none': - self['escape'] = None - elif esc[0] == '^' and len(esc) == 2: - self['escape'] = chr(ord(esc[1])-64) - elif len(esc) == 1: - self['escape'] = esc - else: - sys.exit("Bad escape character '%s'." % esc) - - def opt_localforward(self, f): - "Forward local port to remote address (lport:host:port)" - localPort, remoteHost, remotePort = f.split(':') # doesn't do v6 yet - localPort = int(localPort) - remotePort = int(remotePort) - self.localForwards.append((localPort, (remoteHost, remotePort))) - - def opt_remoteforward(self, f): - """Forward remote port to local address (rport:host:port)""" - remotePort, connHost, connPort = f.split(':') # doesn't do v6 yet - remotePort = int(remotePort) - connPort = int(connPort) - self.remoteForwards.append((remotePort, (connHost, connPort))) - - def parseArgs(self, host, *command): - self['host'] = host - self['command'] = ' '.join(command) - -# Rest of code in "run" -options = None -conn = None -exitStatus = 0 -old = None -_inRawMode = 0 -_savedRawMode = None - -def run(): - global options, old - args = sys.argv[1:] - if '-l' in args: # cvs is an idiot - i = args.index('-l') - args = args[i:i+2]+args - del args[i+2:i+4] - for arg in args[:]: - try: - i = args.index(arg) - if arg[:2] == '-o' and args[i+1][0]!='-': - args[i:i+2] = [] # suck on it scp - except ValueError: - pass - options = ClientOptions() - try: - options.parseOptions(args) - except usage.UsageError, u: - print 'ERROR: %s' % u - options.opt_help() - sys.exit(1) - if options['log']: - if options['logfile']: - if options['logfile'] == '-': - f = sys.stdout - else: - f = file(options['logfile'], 'a+') - else: - f = sys.stderr - realout = sys.stdout - log.startLogging(f) - sys.stdout = realout - else: - log.discardLogs() - doConnect() - fd = sys.stdin.fileno() - try: - old = tty.tcgetattr(fd) - except: - old = None - try: - oldUSR1 = signal.signal(signal.SIGUSR1, lambda *a: reactor.callLater(0, reConnect)) - except: - oldUSR1 = None - try: - reactor.run() - finally: - if old: - tty.tcsetattr(fd, tty.TCSANOW, old) - if oldUSR1: - signal.signal(signal.SIGUSR1, oldUSR1) - if (options['command'] and options['tty']) or not options['notty']: - signal.signal(signal.SIGWINCH, signal.SIG_DFL) - if sys.stdout.isatty() and not options['command']: - print 'Connection to %s closed.' % options['host'] - sys.exit(exitStatus) - -def handleError(): - from twisted.python import failure - global exitStatus - exitStatus = 2 - reactor.callLater(0.01, _stopReactor) - log.err(failure.Failure()) - raise - -def _stopReactor(): - try: - reactor.stop() - except: pass - -def doConnect(): -# log.deferr = handleError # HACK - if '@' in options['host']: - options['user'], options['host'] = options['host'].split('@',1) - if not options.identitys: - options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa'] - host = options['host'] - if not options['user']: - options['user'] = getpass.getuser() - if not options['port']: - options['port'] = 22 - else: - options['port'] = int(options['port']) - host = options['host'] - port = options['port'] - vhk = default.verifyHostKey - uao = default.SSHUserAuthClient(options['user'], options, SSHConnection()) - connect.connect(host, port, options, vhk, uao).addErrback(_ebExit) - -def _ebExit(f): - global exitStatus - if hasattr(f.value, 'value'): - s = f.value.value - else: - s = str(f) - exitStatus = "conch: exiting with error %s" % f - reactor.callLater(0.1, _stopReactor) - -def onConnect(): -# if keyAgent and options['agent']: -# cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal, conn) -# cc.connectUNIX(os.environ['SSH_AUTH_SOCK']) - if hasattr(conn.transport, 'sendIgnore'): - _KeepAlive(conn) - if options.localForwards: - for localPort, hostport in options.localForwards: - s = reactor.listenTCP(localPort, - forwarding.SSHListenForwardingFactory(conn, - hostport, - SSHListenClientForwardingChannel)) - conn.localForwards.append(s) - if options.remoteForwards: - for remotePort, hostport in options.remoteForwards: - log.msg('asking for remote forwarding for %s:%s' % - (remotePort, hostport)) - conn.requestRemoteForwarding(remotePort, hostport) - reactor.addSystemEventTrigger('before', 'shutdown', beforeShutdown) - if not options['noshell'] or options['agent']: - conn.openChannel(SSHSession()) - if options['fork']: - if os.fork(): - os._exit(0) - os.setsid() - for i in range(3): - try: - os.close(i) - except OSError, e: - import errno - if e.errno != errno.EBADF: - raise - -def reConnect(): - beforeShutdown() - conn.transport.transport.loseConnection() - -def beforeShutdown(): - remoteForwards = options.remoteForwards - for remotePort, hostport in remoteForwards: - log.msg('cancelling %s:%s' % (remotePort, hostport)) - conn.cancelRemoteForwarding(remotePort) - -def stopConnection(): - if not options['reconnect']: - reactor.callLater(0.1, _stopReactor) - -class _KeepAlive: - - def __init__(self, conn): - self.conn = conn - self.globalTimeout = None - self.lc = task.LoopingCall(self.sendGlobal) - self.lc.start(300) - - def sendGlobal(self): - d = self.conn.sendGlobalRequest("conch-keep-alive@twistedmatrix.com", - "", wantReply = 1) - d.addBoth(self._cbGlobal) - self.globalTimeout = reactor.callLater(30, self._ebGlobal) - - def _cbGlobal(self, res): - if self.globalTimeout: - self.globalTimeout.cancel() - self.globalTimeout = None - - def _ebGlobal(self): - if self.globalTimeout: - self.globalTimeout = None - self.conn.transport.loseConnection() - -class SSHConnection(connection.SSHConnection): - def serviceStarted(self): - global conn - conn = self - self.localForwards = [] - self.remoteForwards = {} - if not isinstance(self, connection.SSHConnection): - # make these fall through - del self.__class__.requestRemoteForwarding - del self.__class__.cancelRemoteForwarding - onConnect() - - def serviceStopped(self): - lf = self.localForwards - self.localForwards = [] - for s in lf: - s.loseConnection() - stopConnection() - - def requestRemoteForwarding(self, remotePort, hostport): - data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort)) - d = self.sendGlobalRequest('tcpip-forward', data, - wantReply=1) - log.msg('requesting remote forwarding %s:%s' %(remotePort, hostport)) - d.addCallback(self._cbRemoteForwarding, remotePort, hostport) - d.addErrback(self._ebRemoteForwarding, remotePort, hostport) - - def _cbRemoteForwarding(self, result, remotePort, hostport): - log.msg('accepted remote forwarding %s:%s' % (remotePort, hostport)) - self.remoteForwards[remotePort] = hostport - log.msg(repr(self.remoteForwards)) - - def _ebRemoteForwarding(self, f, remotePort, hostport): - log.msg('remote forwarding %s:%s failed' % (remotePort, hostport)) - log.msg(f) - - def cancelRemoteForwarding(self, remotePort): - data = forwarding.packGlobal_tcpip_forward(('0.0.0.0', remotePort)) - self.sendGlobalRequest('cancel-tcpip-forward', data) - log.msg('cancelling remote forwarding %s' % remotePort) - try: - del self.remoteForwards[remotePort] - except: - pass - log.msg(repr(self.remoteForwards)) - - def channel_forwarded_tcpip(self, windowSize, maxPacket, data): - log.msg('%s %s' % ('FTCP', repr(data))) - remoteHP, origHP = forwarding.unpackOpen_forwarded_tcpip(data) - log.msg(self.remoteForwards) - log.msg(remoteHP) - if self.remoteForwards.has_key(remoteHP[1]): - connectHP = self.remoteForwards[remoteHP[1]] - log.msg('connect forwarding %s' % (connectHP,)) - return SSHConnectForwardingChannel(connectHP, - remoteWindow = windowSize, - remoteMaxPacket = maxPacket, - conn = self) - else: - raise ConchError(connection.OPEN_CONNECT_FAILED, "don't know about that port") - -# def channel_auth_agent_openssh_com(self, windowSize, maxPacket, data): -# if options['agent'] and keyAgent: -# return agent.SSHAgentForwardingChannel(remoteWindow = windowSize, -# remoteMaxPacket = maxPacket, -# conn = self) -# else: -# return connection.OPEN_CONNECT_FAILED, "don't have an agent" - - def channelClosed(self, channel): - log.msg('connection closing %s' % channel) - log.msg(self.channels) - if len(self.channels) == 1: # just us left - log.msg('stopping connection') - stopConnection() - else: - # because of the unix thing - self.__class__.__bases__[0].channelClosed(self, channel) - -class SSHSession(channel.SSHChannel): - - name = 'session' - - def channelOpen(self, foo): - log.msg('session %s open' % self.id) - if options['agent']: - d = self.conn.sendRequest(self, 'auth-agent-req@openssh.com', '', wantReply=1) - d.addBoth(lambda x:log.msg(x)) - if options['noshell']: return - if (options['command'] and options['tty']) or not options['notty']: - _enterRawMode() - c = session.SSHSessionClient() - if options['escape'] and not options['notty']: - self.escapeMode = 1 - c.dataReceived = self.handleInput - else: - c.dataReceived = self.write - c.connectionLost = lambda x=None,s=self:s.sendEOF() - self.stdio = stdio.StandardIO(c) - fd = 0 - if options['subsystem']: - self.conn.sendRequest(self, 'subsystem', \ - common.NS(options['command'])) - elif options['command']: - if options['tty']: - term = os.environ['TERM'] - winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678') - winSize = struct.unpack('4H', winsz) - ptyReqData = session.packRequest_pty_req(term, winSize, '') - self.conn.sendRequest(self, 'pty-req', ptyReqData) - signal.signal(signal.SIGWINCH, self._windowResized) - self.conn.sendRequest(self, 'exec', \ - common.NS(options['command'])) - else: - if not options['notty']: - term = os.environ['TERM'] - winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678') - winSize = struct.unpack('4H', winsz) - ptyReqData = session.packRequest_pty_req(term, winSize, '') - self.conn.sendRequest(self, 'pty-req', ptyReqData) - signal.signal(signal.SIGWINCH, self._windowResized) - self.conn.sendRequest(self, 'shell', '') - #if hasattr(conn.transport, 'transport'): - # conn.transport.transport.setTcpNoDelay(1) - - def handleInput(self, char): - #log.msg('handling %s' % repr(char)) - if char in ('\n', '\r'): - self.escapeMode = 1 - self.write(char) - elif self.escapeMode == 1 and char == options['escape']: - self.escapeMode = 2 - elif self.escapeMode == 2: - self.escapeMode = 1 # so we can chain escapes together - if char == '.': # disconnect - log.msg('disconnecting from escape') - stopConnection() - return - elif char == '\x1a': # ^Z, suspend - def _(): - _leaveRawMode() - sys.stdout.flush() - sys.stdin.flush() - os.kill(os.getpid(), signal.SIGTSTP) - _enterRawMode() - reactor.callLater(0, _) - return - elif char == 'R': # rekey connection - log.msg('rekeying connection') - self.conn.transport.sendKexInit() - return - elif char == '#': # display connections - self.stdio.write('\r\nThe following connections are open:\r\n') - channels = self.conn.channels.keys() - channels.sort() - for channelId in channels: - self.stdio.write(' #%i %s\r\n' % (channelId, str(self.conn.channels[channelId]))) - return - self.write('~' + char) - else: - self.escapeMode = 0 - self.write(char) - - def dataReceived(self, data): - self.stdio.write(data) - - def extReceived(self, t, data): - if t==connection.EXTENDED_DATA_STDERR: - log.msg('got %s stderr data' % len(data)) - sys.stderr.write(data) - - def eofReceived(self): - log.msg('got eof') - self.stdio.loseWriteConnection() - - def closeReceived(self): - log.msg('remote side closed %s' % self) - self.conn.sendClose(self) - - def closed(self): - global old - log.msg('closed %s' % self) - log.msg(repr(self.conn.channels)) - - def request_exit_status(self, data): - global exitStatus - exitStatus = int(struct.unpack('>L', data)[0]) - log.msg('exit status: %s' % exitStatus) - - def sendEOF(self): - self.conn.sendEOF(self) - - def stopWriting(self): - self.stdio.pauseProducing() - - def startWriting(self): - self.stdio.resumeProducing() - - def _windowResized(self, *args): - winsz = fcntl.ioctl(0, tty.TIOCGWINSZ, '12345678') - winSize = struct.unpack('4H', winsz) - newSize = winSize[1], winSize[0], winSize[2], winSize[3] - self.conn.sendRequest(self, 'window-change', struct.pack('!4L', *newSize)) - - -class SSHListenClientForwardingChannel(forwarding.SSHListenClientForwardingChannel): pass -class SSHConnectForwardingChannel(forwarding.SSHConnectForwardingChannel): pass - -def _leaveRawMode(): - global _inRawMode - if not _inRawMode: - return - fd = sys.stdin.fileno() - tty.tcsetattr(fd, tty.TCSANOW, _savedMode) - _inRawMode = 0 - -def _enterRawMode(): - global _inRawMode, _savedMode - if _inRawMode: - return - fd = sys.stdin.fileno() - try: - old = tty.tcgetattr(fd) - new = old[:] - except: - log.msg('not a typewriter!') - else: - # iflage - new[0] = new[0] | tty.IGNPAR - new[0] = new[0] & ~(tty.ISTRIP | tty.INLCR | tty.IGNCR | tty.ICRNL | - tty.IXON | tty.IXANY | tty.IXOFF) - if hasattr(tty, 'IUCLC'): - new[0] = new[0] & ~tty.IUCLC - - # lflag - new[3] = new[3] & ~(tty.ISIG | tty.ICANON | tty.ECHO | tty.ECHO | - tty.ECHOE | tty.ECHOK | tty.ECHONL) - if hasattr(tty, 'IEXTEN'): - new[3] = new[3] & ~tty.IEXTEN - - #oflag - new[1] = new[1] & ~tty.OPOST - - new[6][tty.VMIN] = 1 - new[6][tty.VTIME] = 0 - - _savedMode = old - tty.tcsetattr(fd, tty.TCSANOW, new) - #tty.setraw(fd) - _inRawMode = 1 - -if __name__ == '__main__': - run() - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py deleted file mode 100755 index eb001869..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/scripts/tkconch.py +++ /dev/null @@ -1,572 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_scripts -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Implementation module for the `tkconch` command. -""" - -import Tkinter, tkFileDialog, tkFont, tkMessageBox, string -from twisted.conch.ui import tkvt100 -from twisted.conch.ssh import transport, userauth, connection, common, keys -from twisted.conch.ssh import session, forwarding, channel -from twisted.conch.client.default import isInKnownHosts -from twisted.internet import reactor, defer, protocol, tksupport -from twisted.python import usage, log - -import os, sys, getpass, struct, base64, signal - -class TkConchMenu(Tkinter.Frame): - def __init__(self, *args, **params): - ## Standard heading: initialization - apply(Tkinter.Frame.__init__, (self,) + args, params) - - self.master.title('TkConch') - self.localRemoteVar = Tkinter.StringVar() - self.localRemoteVar.set('local') - - Tkinter.Label(self, anchor='w', justify='left', text='Hostname').grid(column=1, row=1, sticky='w') - self.host = Tkinter.Entry(self) - self.host.grid(column=2, columnspan=2, row=1, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Port').grid(column=1, row=2, sticky='w') - self.port = Tkinter.Entry(self) - self.port.grid(column=2, columnspan=2, row=2, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Username').grid(column=1, row=3, sticky='w') - self.user = Tkinter.Entry(self) - self.user.grid(column=2, columnspan=2, row=3, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Command').grid(column=1, row=4, sticky='w') - self.command = Tkinter.Entry(self) - self.command.grid(column=2, columnspan=2, row=4, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Identity').grid(column=1, row=5, sticky='w') - self.identity = Tkinter.Entry(self) - self.identity.grid(column=2, row=5, sticky='nesw') - Tkinter.Button(self, command=self.getIdentityFile, text='Browse').grid(column=3, row=5, sticky='nesw') - - Tkinter.Label(self, text='Port Forwarding').grid(column=1, row=6, sticky='w') - self.forwards = Tkinter.Listbox(self, height=0, width=0) - self.forwards.grid(column=2, columnspan=2, row=6, sticky='nesw') - Tkinter.Button(self, text='Add', command=self.addForward).grid(column=1, row=7) - Tkinter.Button(self, text='Remove', command=self.removeForward).grid(column=1, row=8) - self.forwardPort = Tkinter.Entry(self) - self.forwardPort.grid(column=2, row=7, sticky='nesw') - Tkinter.Label(self, text='Port').grid(column=3, row=7, sticky='nesw') - self.forwardHost = Tkinter.Entry(self) - self.forwardHost.grid(column=2, row=8, sticky='nesw') - Tkinter.Label(self, text='Host').grid(column=3, row=8, sticky='nesw') - self.localForward = Tkinter.Radiobutton(self, text='Local', variable=self.localRemoteVar, value='local') - self.localForward.grid(column=2, row=9) - self.remoteForward = Tkinter.Radiobutton(self, text='Remote', variable=self.localRemoteVar, value='remote') - self.remoteForward.grid(column=3, row=9) - - Tkinter.Label(self, text='Advanced Options').grid(column=1, columnspan=3, row=10, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Cipher').grid(column=1, row=11, sticky='w') - self.cipher = Tkinter.Entry(self, name='cipher') - self.cipher.grid(column=2, columnspan=2, row=11, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='MAC').grid(column=1, row=12, sticky='w') - self.mac = Tkinter.Entry(self, name='mac') - self.mac.grid(column=2, columnspan=2, row=12, sticky='nesw') - - Tkinter.Label(self, anchor='w', justify='left', text='Escape Char').grid(column=1, row=13, sticky='w') - self.escape = Tkinter.Entry(self, name='escape') - self.escape.grid(column=2, columnspan=2, row=13, sticky='nesw') - Tkinter.Button(self, text='Connect!', command=self.doConnect).grid(column=1, columnspan=3, row=14, sticky='nesw') - - # Resize behavior(s) - self.grid_rowconfigure(6, weight=1, minsize=64) - self.grid_columnconfigure(2, weight=1, minsize=2) - - self.master.protocol("WM_DELETE_WINDOW", sys.exit) - - - def getIdentityFile(self): - r = tkFileDialog.askopenfilename() - if r: - self.identity.delete(0, Tkinter.END) - self.identity.insert(Tkinter.END, r) - - def addForward(self): - port = self.forwardPort.get() - self.forwardPort.delete(0, Tkinter.END) - host = self.forwardHost.get() - self.forwardHost.delete(0, Tkinter.END) - if self.localRemoteVar.get() == 'local': - self.forwards.insert(Tkinter.END, 'L:%s:%s' % (port, host)) - else: - self.forwards.insert(Tkinter.END, 'R:%s:%s' % (port, host)) - - def removeForward(self): - cur = self.forwards.curselection() - if cur: - self.forwards.remove(cur[0]) - - def doConnect(self): - finished = 1 - options['host'] = self.host.get() - options['port'] = self.port.get() - options['user'] = self.user.get() - options['command'] = self.command.get() - cipher = self.cipher.get() - mac = self.mac.get() - escape = self.escape.get() - if cipher: - if cipher in SSHClientTransport.supportedCiphers: - SSHClientTransport.supportedCiphers = [cipher] - else: - tkMessageBox.showerror('TkConch', 'Bad cipher.') - finished = 0 - - if mac: - if mac in SSHClientTransport.supportedMACs: - SSHClientTransport.supportedMACs = [mac] - elif finished: - tkMessageBox.showerror('TkConch', 'Bad MAC.') - finished = 0 - - if escape: - if escape == 'none': - options['escape'] = None - elif escape[0] == '^' and len(escape) == 2: - options['escape'] = chr(ord(escape[1])-64) - elif len(escape) == 1: - options['escape'] = escape - elif finished: - tkMessageBox.showerror('TkConch', "Bad escape character '%s'." % escape) - finished = 0 - - if self.identity.get(): - options.identitys.append(self.identity.get()) - - for line in self.forwards.get(0,Tkinter.END): - if line[0]=='L': - options.opt_localforward(line[2:]) - else: - options.opt_remoteforward(line[2:]) - - if '@' in options['host']: - options['user'], options['host'] = options['host'].split('@',1) - - if (not options['host'] or not options['user']) and finished: - tkMessageBox.showerror('TkConch', 'Missing host or username.') - finished = 0 - if finished: - self.master.quit() - self.master.destroy() - if options['log']: - realout = sys.stdout - log.startLogging(sys.stderr) - sys.stdout = realout - else: - log.discardLogs() - log.deferr = handleError # HACK - if not options.identitys: - options.identitys = ['~/.ssh/id_rsa', '~/.ssh/id_dsa'] - host = options['host'] - port = int(options['port'] or 22) - log.msg((host,port)) - reactor.connectTCP(host, port, SSHClientFactory()) - frame.master.deiconify() - frame.master.title('%s@%s - TkConch' % (options['user'], options['host'])) - else: - self.focus() - -class GeneralOptions(usage.Options): - synopsis = """Usage: tkconch [options] host [command] - """ - - optParameters = [['user', 'l', None, 'Log in using this user name.'], - ['identity', 'i', '~/.ssh/identity', 'Identity for public key authentication'], - ['escape', 'e', '~', "Set escape character; ``none'' = disable"], - ['cipher', 'c', None, 'Select encryption algorithm.'], - ['macs', 'm', None, 'Specify MAC algorithms for protocol version 2.'], - ['port', 'p', None, 'Connect to this port. Server must be on the same port.'], - ['localforward', 'L', None, 'listen-port:host:port Forward local port to remote address'], - ['remoteforward', 'R', None, 'listen-port:host:port Forward remote port to local address'], - ] - - optFlags = [['tty', 't', 'Tty; allocate a tty even if command is given.'], - ['notty', 'T', 'Do not allocate a tty.'], - ['version', 'V', 'Display version number only.'], - ['compress', 'C', 'Enable compression.'], - ['noshell', 'N', 'Do not execute a shell or command.'], - ['subsystem', 's', 'Invoke command (mandatory) as SSH2 subsystem.'], - ['log', 'v', 'Log to stderr'], - ['ansilog', 'a', 'Print the receieved data to stdout']] - - _ciphers = transport.SSHClientTransport.supportedCiphers - _macs = transport.SSHClientTransport.supportedMACs - - compData = usage.Completions( - mutuallyExclusive=[("tty", "notty")], - optActions={ - "cipher": usage.CompleteList(_ciphers), - "macs": usage.CompleteList(_macs), - "localforward": usage.Completer(descr="listen-port:host:port"), - "remoteforward": usage.Completer(descr="listen-port:host:port")}, - extraActions=[usage.CompleteUserAtHost(), - usage.Completer(descr="command"), - usage.Completer(descr="argument", repeat=True)] - ) - - identitys = [] - localForwards = [] - remoteForwards = [] - - def opt_identity(self, i): - self.identitys.append(i) - - def opt_localforward(self, f): - localPort, remoteHost, remotePort = f.split(':') # doesn't do v6 yet - localPort = int(localPort) - remotePort = int(remotePort) - self.localForwards.append((localPort, (remoteHost, remotePort))) - - def opt_remoteforward(self, f): - remotePort, connHost, connPort = f.split(':') # doesn't do v6 yet - remotePort = int(remotePort) - connPort = int(connPort) - self.remoteForwards.append((remotePort, (connHost, connPort))) - - def opt_compress(self): - SSHClientTransport.supportedCompressions[0:1] = ['zlib'] - - def parseArgs(self, *args): - if args: - self['host'] = args[0] - self['command'] = ' '.join(args[1:]) - else: - self['host'] = '' - self['command'] = '' - -# Rest of code in "run" -options = None -menu = None -exitStatus = 0 -frame = None - -def deferredAskFrame(question, echo): - if frame.callback: - raise ValueError("can't ask 2 questions at once!") - d = defer.Deferred() - resp = [] - def gotChar(ch, resp=resp): - if not ch: return - if ch=='\x03': # C-c - reactor.stop() - if ch=='\r': - frame.write('\r\n') - stresp = ''.join(resp) - del resp - frame.callback = None - d.callback(stresp) - return - elif 32 <= ord(ch) < 127: - resp.append(ch) - if echo: - frame.write(ch) - elif ord(ch) == 8 and resp: # BS - if echo: frame.write('\x08 \x08') - resp.pop() - frame.callback = gotChar - frame.write(question) - frame.canvas.focus_force() - return d - -def run(): - global menu, options, frame - args = sys.argv[1:] - if '-l' in args: # cvs is an idiot - i = args.index('-l') - args = args[i:i+2]+args - del args[i+2:i+4] - for arg in args[:]: - try: - i = args.index(arg) - if arg[:2] == '-o' and args[i+1][0]!='-': - args[i:i+2] = [] # suck on it scp - except ValueError: - pass - root = Tkinter.Tk() - root.withdraw() - top = Tkinter.Toplevel() - menu = TkConchMenu(top) - menu.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1) - options = GeneralOptions() - try: - options.parseOptions(args) - except usage.UsageError, u: - print 'ERROR: %s' % u - options.opt_help() - sys.exit(1) - for k,v in options.items(): - if v and hasattr(menu, k): - getattr(menu,k).insert(Tkinter.END, v) - for (p, (rh, rp)) in options.localForwards: - menu.forwards.insert(Tkinter.END, 'L:%s:%s:%s' % (p, rh, rp)) - options.localForwards = [] - for (p, (rh, rp)) in options.remoteForwards: - menu.forwards.insert(Tkinter.END, 'R:%s:%s:%s' % (p, rh, rp)) - options.remoteForwards = [] - frame = tkvt100.VT100Frame(root, callback=None) - root.geometry('%dx%d'%(tkvt100.fontWidth*frame.width+3, tkvt100.fontHeight*frame.height+3)) - frame.pack(side = Tkinter.TOP) - tksupport.install(root) - root.withdraw() - if (options['host'] and options['user']) or '@' in options['host']: - menu.doConnect() - else: - top.mainloop() - reactor.run() - sys.exit(exitStatus) - -def handleError(): - from twisted.python import failure - global exitStatus - exitStatus = 2 - log.err(failure.Failure()) - reactor.stop() - raise - -class SSHClientFactory(protocol.ClientFactory): - noisy = 1 - - def stopFactory(self): - reactor.stop() - - def buildProtocol(self, addr): - return SSHClientTransport() - - def clientConnectionFailed(self, connector, reason): - tkMessageBox.showwarning('TkConch','Connection Failed, Reason:\n %s: %s' % (reason.type, reason.value)) - -class SSHClientTransport(transport.SSHClientTransport): - - def receiveError(self, code, desc): - global exitStatus - exitStatus = 'conch:\tRemote side disconnected with error code %i\nconch:\treason: %s' % (code, desc) - - def sendDisconnect(self, code, reason): - global exitStatus - exitStatus = 'conch:\tSending disconnect with error code %i\nconch:\treason: %s' % (code, reason) - transport.SSHClientTransport.sendDisconnect(self, code, reason) - - def receiveDebug(self, alwaysDisplay, message, lang): - global options - if alwaysDisplay or options['log']: - log.msg('Received Debug Message: %s' % message) - - def verifyHostKey(self, pubKey, fingerprint): - #d = defer.Deferred() - #d.addCallback(lambda x:defer.succeed(1)) - #d.callback(2) - #return d - goodKey = isInKnownHosts(options['host'], pubKey, {'known-hosts': None}) - if goodKey == 1: # good key - return defer.succeed(1) - elif goodKey == 2: # AAHHHHH changed - return defer.fail(error.ConchError('bad host key')) - else: - if options['host'] == self.transport.getPeer()[1]: - host = options['host'] - khHost = options['host'] - else: - host = '%s (%s)' % (options['host'], - self.transport.getPeer()[1]) - khHost = '%s,%s' % (options['host'], - self.transport.getPeer()[1]) - keyType = common.getNS(pubKey)[0] - ques = """The authenticity of host '%s' can't be established.\r -%s key fingerprint is %s.""" % (host, - {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType], - fingerprint) - ques+='\r\nAre you sure you want to continue connecting (yes/no)? ' - return deferredAskFrame(ques, 1).addCallback(self._cbVerifyHostKey, pubKey, khHost, keyType) - - def _cbVerifyHostKey(self, ans, pubKey, khHost, keyType): - if ans.lower() not in ('yes', 'no'): - return deferredAskFrame("Please type 'yes' or 'no': ",1).addCallback(self._cbVerifyHostKey, pubKey, khHost, keyType) - if ans.lower() == 'no': - frame.write('Host key verification failed.\r\n') - raise error.ConchError('bad host key') - try: - frame.write("Warning: Permanently added '%s' (%s) to the list of known hosts.\r\n" % (khHost, {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType])) - known_hosts = open(os.path.expanduser('~/.ssh/known_hosts'), 'a') - encodedKey = base64.encodestring(pubKey).replace('\n', '') - known_hosts.write('\n%s %s %s' % (khHost, keyType, encodedKey)) - known_hosts.close() - except: - log.deferr() - raise error.ConchError - - def connectionSecure(self): - if options['user']: - user = options['user'] - else: - user = getpass.getuser() - self.requestService(SSHUserAuthClient(user, SSHConnection())) - -class SSHUserAuthClient(userauth.SSHUserAuthClient): - usedFiles = [] - - def getPassword(self, prompt = None): - if not prompt: - prompt = "%s@%s's password: " % (self.user, options['host']) - return deferredAskFrame(prompt,0) - - def getPublicKey(self): - files = [x for x in options.identitys if x not in self.usedFiles] - if not files: - return None - file = files[0] - log.msg(file) - self.usedFiles.append(file) - file = os.path.expanduser(file) - file += '.pub' - if not os.path.exists(file): - return - try: - return keys.Key.fromFile(file).blob() - except: - return self.getPublicKey() # try again - - def getPrivateKey(self): - file = os.path.expanduser(self.usedFiles[-1]) - if not os.path.exists(file): - return None - try: - return defer.succeed(keys.Key.fromFile(file).keyObject) - except keys.BadKeyError, e: - if e.args[0] == 'encrypted key with no password': - prompt = "Enter passphrase for key '%s': " % \ - self.usedFiles[-1] - return deferredAskFrame(prompt, 0).addCallback(self._cbGetPrivateKey, 0) - def _cbGetPrivateKey(self, ans, count): - file = os.path.expanduser(self.usedFiles[-1]) - try: - return keys.Key.fromFile(file, password = ans).keyObject - except keys.BadKeyError: - if count == 2: - raise - prompt = "Enter passphrase for key '%s': " % \ - self.usedFiles[-1] - return deferredAskFrame(prompt, 0).addCallback(self._cbGetPrivateKey, count+1) - -class SSHConnection(connection.SSHConnection): - def serviceStarted(self): - if not options['noshell']: - self.openChannel(SSHSession()) - if options.localForwards: - for localPort, hostport in options.localForwards: - reactor.listenTCP(localPort, - forwarding.SSHListenForwardingFactory(self, - hostport, - forwarding.SSHListenClientForwardingChannel)) - if options.remoteForwards: - for remotePort, hostport in options.remoteForwards: - log.msg('asking for remote forwarding for %s:%s' % - (remotePort, hostport)) - data = forwarding.packGlobal_tcpip_forward( - ('0.0.0.0', remotePort)) - d = self.sendGlobalRequest('tcpip-forward', data) - self.remoteForwards[remotePort] = hostport - -class SSHSession(channel.SSHChannel): - - name = 'session' - - def channelOpen(self, foo): - #global globalSession - #globalSession = self - # turn off local echo - self.escapeMode = 1 - c = session.SSHSessionClient() - if options['escape']: - c.dataReceived = self.handleInput - else: - c.dataReceived = self.write - c.connectionLost = self.sendEOF - frame.callback = c.dataReceived - frame.canvas.focus_force() - if options['subsystem']: - self.conn.sendRequest(self, 'subsystem', \ - common.NS(options['command'])) - elif options['command']: - if options['tty']: - term = os.environ.get('TERM', 'xterm') - #winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678') - winSize = (25,80,0,0) #struct.unpack('4H', winsz) - ptyReqData = session.packRequest_pty_req(term, winSize, '') - self.conn.sendRequest(self, 'pty-req', ptyReqData) - self.conn.sendRequest(self, 'exec', \ - common.NS(options['command'])) - else: - if not options['notty']: - term = os.environ.get('TERM', 'xterm') - #winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678') - winSize = (25,80,0,0) #struct.unpack('4H', winsz) - ptyReqData = session.packRequest_pty_req(term, winSize, '') - self.conn.sendRequest(self, 'pty-req', ptyReqData) - self.conn.sendRequest(self, 'shell', '') - self.conn.transport.transport.setTcpNoDelay(1) - - def handleInput(self, char): - #log.msg('handling %s' % repr(char)) - if char in ('\n', '\r'): - self.escapeMode = 1 - self.write(char) - elif self.escapeMode == 1 and char == options['escape']: - self.escapeMode = 2 - elif self.escapeMode == 2: - self.escapeMode = 1 # so we can chain escapes together - if char == '.': # disconnect - log.msg('disconnecting from escape') - reactor.stop() - return - elif char == '\x1a': # ^Z, suspend - # following line courtesy of Erwin@freenode - os.kill(os.getpid(), signal.SIGSTOP) - return - elif char == 'R': # rekey connection - log.msg('rekeying connection') - self.conn.transport.sendKexInit() - return - self.write('~' + char) - else: - self.escapeMode = 0 - self.write(char) - - def dataReceived(self, data): - if options['ansilog']: - print repr(data) - frame.write(data) - - def extReceived(self, t, data): - if t==connection.EXTENDED_DATA_STDERR: - log.msg('got %s stderr data' % len(data)) - sys.stderr.write(data) - sys.stderr.flush() - - def eofReceived(self): - log.msg('got eof') - sys.stdin.close() - - def closed(self): - log.msg('closed %s' % self) - if len(self.conn.channels) == 1: # just us left - reactor.stop() - - def request_exit_status(self, data): - global exitStatus - exitStatus = int(struct.unpack('>L', data)[0]) - log.msg('exit status: %s' % exitStatus) - - def sendEOF(self): - self.conn.sendEOF(self) - -if __name__=="__main__": - run() diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py deleted file mode 100755 index 4b7f024b..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -""" -An SSHv2 implementation for Twisted. Part of the Twisted.Conch package. - -Maintainer: Paul Swartz -""" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py deleted file mode 100755 index c06f2bfa..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/address.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_address -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Address object for SSH network connections. - -Maintainer: Paul Swartz - -@since: 12.1 -""" -from zope.interface import implements -from twisted.internet.interfaces import IAddress -from twisted.python import util - - - -class SSHTransportAddress(object, util.FancyEqMixin): - """ - Object representing an SSH Transport endpoint. - - @ivar address: A instance of an object which implements I{IAddress} to - which this transport address is connected. - """ - - implements(IAddress) - - compareAttributes = ('address',) - - def __init__(self, address): - self.address = address - - def __repr__(self): - return 'SSHTransportAddress(%r)' % (self.address,) - - def __hash__(self): - return hash(('SSH', self.address)) - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py deleted file mode 100755 index c1bf1a09..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/agent.py +++ /dev/null @@ -1,294 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Implements the SSH v2 key agent protocol. This protocol is documented in the -SSH source code, in the file -U{PROTOCOL.agent<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent>}. - -Maintainer: Paul Swartz -""" - -import struct - -from twisted.conch.ssh.common import NS, getNS, getMP -from twisted.conch.error import ConchError, MissingKeyStoreError -from twisted.conch.ssh import keys -from twisted.internet import defer, protocol - - - -class SSHAgentClient(protocol.Protocol): - """ - The client side of the SSH agent protocol. This is equivalent to - ssh-add(1) and can be used with either ssh-agent(1) or the SSHAgentServer - protocol, also in this package. - """ - - def __init__(self): - self.buf = '' - self.deferreds = [] - - - def dataReceived(self, data): - self.buf += data - while 1: - if len(self.buf) <= 4: - return - packLen = struct.unpack('!L', self.buf[:4])[0] - if len(self.buf) < 4 + packLen: - return - packet, self.buf = self.buf[4:4 + packLen], self.buf[4 + packLen:] - reqType = ord(packet[0]) - d = self.deferreds.pop(0) - if reqType == AGENT_FAILURE: - d.errback(ConchError('agent failure')) - elif reqType == AGENT_SUCCESS: - d.callback('') - else: - d.callback(packet) - - - def sendRequest(self, reqType, data): - pack = struct.pack('!LB',len(data) + 1, reqType) + data - self.transport.write(pack) - d = defer.Deferred() - self.deferreds.append(d) - return d - - - def requestIdentities(self): - """ - @return: A L{Deferred} which will fire with a list of all keys found in - the SSH agent. The list of keys is comprised of (public key blob, - comment) tuples. - """ - d = self.sendRequest(AGENTC_REQUEST_IDENTITIES, '') - d.addCallback(self._cbRequestIdentities) - return d - - - def _cbRequestIdentities(self, data): - """ - Unpack a collection of identities into a list of tuples comprised of - public key blobs and comments. - """ - if ord(data[0]) != AGENT_IDENTITIES_ANSWER: - raise ConchError('unexpected response: %i' % ord(data[0])) - numKeys = struct.unpack('!L', data[1:5])[0] - keys = [] - data = data[5:] - for i in range(numKeys): - blob, data = getNS(data) - comment, data = getNS(data) - keys.append((blob, comment)) - return keys - - - def addIdentity(self, blob, comment = ''): - """ - Add a private key blob to the agent's collection of keys. - """ - req = blob - req += NS(comment) - return self.sendRequest(AGENTC_ADD_IDENTITY, req) - - - def signData(self, blob, data): - """ - Request that the agent sign the given C{data} with the private key - which corresponds to the public key given by C{blob}. The private - key should have been added to the agent already. - - @type blob: C{str} - @type data: C{str} - @return: A L{Deferred} which fires with a signature for given data - created with the given key. - """ - req = NS(blob) - req += NS(data) - req += '\000\000\000\000' # flags - return self.sendRequest(AGENTC_SIGN_REQUEST, req).addCallback(self._cbSignData) - - - def _cbSignData(self, data): - if ord(data[0]) != AGENT_SIGN_RESPONSE: - raise ConchError('unexpected data: %i' % ord(data[0])) - signature = getNS(data[1:])[0] - return signature - - - def removeIdentity(self, blob): - """ - Remove the private key corresponding to the public key in blob from the - running agent. - """ - req = NS(blob) - return self.sendRequest(AGENTC_REMOVE_IDENTITY, req) - - - def removeAllIdentities(self): - """ - Remove all keys from the running agent. - """ - return self.sendRequest(AGENTC_REMOVE_ALL_IDENTITIES, '') - - - -class SSHAgentServer(protocol.Protocol): - """ - The server side of the SSH agent protocol. This is equivalent to - ssh-agent(1) and can be used with either ssh-add(1) or the SSHAgentClient - protocol, also in this package. - """ - - def __init__(self): - self.buf = '' - - - def dataReceived(self, data): - self.buf += data - while 1: - if len(self.buf) <= 4: - return - packLen = struct.unpack('!L', self.buf[:4])[0] - if len(self.buf) < 4 + packLen: - return - packet, self.buf = self.buf[4:4 + packLen], self.buf[4 + packLen:] - reqType = ord(packet[0]) - reqName = messages.get(reqType, None) - if not reqName: - self.sendResponse(AGENT_FAILURE, '') - else: - f = getattr(self, 'agentc_%s' % reqName) - if getattr(self.factory, 'keys', None) is None: - self.sendResponse(AGENT_FAILURE, '') - raise MissingKeyStoreError() - f(packet[1:]) - - - def sendResponse(self, reqType, data): - pack = struct.pack('!LB', len(data) + 1, reqType) + data - self.transport.write(pack) - - - def agentc_REQUEST_IDENTITIES(self, data): - """ - Return all of the identities that have been added to the server - """ - assert data == '' - numKeys = len(self.factory.keys) - resp = [] - - resp.append(struct.pack('!L', numKeys)) - for key, comment in self.factory.keys.itervalues(): - resp.append(NS(key.blob())) # yes, wrapped in an NS - resp.append(NS(comment)) - self.sendResponse(AGENT_IDENTITIES_ANSWER, ''.join(resp)) - - - def agentc_SIGN_REQUEST(self, data): - """ - Data is a structure with a reference to an already added key object and - some data that the clients wants signed with that key. If the key - object wasn't loaded, return AGENT_FAILURE, else return the signature. - """ - blob, data = getNS(data) - if blob not in self.factory.keys: - return self.sendResponse(AGENT_FAILURE, '') - signData, data = getNS(data) - assert data == '\000\000\000\000' - self.sendResponse(AGENT_SIGN_RESPONSE, NS(self.factory.keys[blob][0].sign(signData))) - - - def agentc_ADD_IDENTITY(self, data): - """ - Adds a private key to the agent's collection of identities. On - subsequent interactions, the private key can be accessed using only the - corresponding public key. - """ - - # need to pre-read the key data so we can get past it to the comment string - keyType, rest = getNS(data) - if keyType == 'ssh-rsa': - nmp = 6 - elif keyType == 'ssh-dss': - nmp = 5 - else: - raise keys.BadKeyError('unknown blob type: %s' % keyType) - - rest = getMP(rest, nmp)[-1] # ignore the key data for now, we just want the comment - comment, rest = getNS(rest) # the comment, tacked onto the end of the key blob - - k = keys.Key.fromString(data, type='private_blob') # not wrapped in NS here - self.factory.keys[k.blob()] = (k, comment) - self.sendResponse(AGENT_SUCCESS, '') - - - def agentc_REMOVE_IDENTITY(self, data): - """ - Remove a specific key from the agent's collection of identities. - """ - blob, _ = getNS(data) - k = keys.Key.fromString(blob, type='blob') - del self.factory.keys[k.blob()] - self.sendResponse(AGENT_SUCCESS, '') - - - def agentc_REMOVE_ALL_IDENTITIES(self, data): - """ - Remove all keys from the agent's collection of identities. - """ - assert data == '' - self.factory.keys = {} - self.sendResponse(AGENT_SUCCESS, '') - - # v1 messages that we ignore because we don't keep v1 keys - # open-ssh sends both v1 and v2 commands, so we have to - # do no-ops for v1 commands or we'll get "bad request" errors - - def agentc_REQUEST_RSA_IDENTITIES(self, data): - """ - v1 message for listing RSA1 keys; superseded by - agentc_REQUEST_IDENTITIES, which handles different key types. - """ - self.sendResponse(AGENT_RSA_IDENTITIES_ANSWER, struct.pack('!L', 0)) - - - def agentc_REMOVE_RSA_IDENTITY(self, data): - """ - v1 message for removing RSA1 keys; superseded by - agentc_REMOVE_IDENTITY, which handles different key types. - """ - self.sendResponse(AGENT_SUCCESS, '') - - - def agentc_REMOVE_ALL_RSA_IDENTITIES(self, data): - """ - v1 message for removing all RSA1 keys; superseded by - agentc_REMOVE_ALL_IDENTITIES, which handles different key types. - """ - self.sendResponse(AGENT_SUCCESS, '') - - -AGENTC_REQUEST_RSA_IDENTITIES = 1 -AGENT_RSA_IDENTITIES_ANSWER = 2 -AGENT_FAILURE = 5 -AGENT_SUCCESS = 6 - -AGENTC_REMOVE_RSA_IDENTITY = 8 -AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9 - -AGENTC_REQUEST_IDENTITIES = 11 -AGENT_IDENTITIES_ANSWER = 12 -AGENTC_SIGN_REQUEST = 13 -AGENT_SIGN_RESPONSE = 14 -AGENTC_ADD_IDENTITY = 17 -AGENTC_REMOVE_IDENTITY = 18 -AGENTC_REMOVE_ALL_IDENTITIES = 19 - -messages = {} -for name, value in locals().copy().items(): - if name[:7] == 'AGENTC_': - messages[value] = name[7:] # doesn't handle doubles - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py deleted file mode 100755 index f498aec0..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/channel.py +++ /dev/null @@ -1,281 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_channel -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -""" -The parent class for all the SSH Channels. Currently implemented channels -are session. direct-tcp, and forwarded-tcp. - -Maintainer: Paul Swartz -""" - -from twisted.python import log -from twisted.internet import interfaces -from zope.interface import implements - - -class SSHChannel(log.Logger): - """ - A class that represents a multiplexed channel over an SSH connection. - The channel has a local window which is the maximum amount of data it will - receive, and a remote which is the maximum amount of data the remote side - will accept. There is also a maximum packet size for any individual data - packet going each way. - - @ivar name: the name of the channel. - @type name: C{str} - @ivar localWindowSize: the maximum size of the local window in bytes. - @type localWindowSize: C{int} - @ivar localWindowLeft: how many bytes are left in the local window. - @type localWindowLeft: C{int} - @ivar localMaxPacket: the maximum size of packet we will accept in bytes. - @type localMaxPacket: C{int} - @ivar remoteWindowLeft: how many bytes are left in the remote window. - @type remoteWindowLeft: C{int} - @ivar remoteMaxPacket: the maximum size of a packet the remote side will - accept in bytes. - @type remoteMaxPacket: C{int} - @ivar conn: the connection this channel is multiplexed through. - @type conn: L{SSHConnection} - @ivar data: any data to send to the other size when the channel is - requested. - @type data: C{str} - @ivar avatar: an avatar for the logged-in user (if a server channel) - @ivar localClosed: True if we aren't accepting more data. - @type localClosed: C{bool} - @ivar remoteClosed: True if the other size isn't accepting more data. - @type remoteClosed: C{bool} - """ - - implements(interfaces.ITransport) - - name = None # only needed for client channels - - def __init__(self, localWindow = 0, localMaxPacket = 0, - remoteWindow = 0, remoteMaxPacket = 0, - conn = None, data=None, avatar = None): - self.localWindowSize = localWindow or 131072 - self.localWindowLeft = self.localWindowSize - self.localMaxPacket = localMaxPacket or 32768 - self.remoteWindowLeft = remoteWindow - self.remoteMaxPacket = remoteMaxPacket - self.areWriting = 1 - self.conn = conn - self.data = data - self.avatar = avatar - self.specificData = '' - self.buf = '' - self.extBuf = [] - self.closing = 0 - self.localClosed = 0 - self.remoteClosed = 0 - self.id = None # gets set later by SSHConnection - - def __str__(self): - return '<SSHChannel %s (lw %i rw %i)>' % (self.name, - self.localWindowLeft, self.remoteWindowLeft) - - def logPrefix(self): - id = (self.id is not None and str(self.id)) or "unknown" - return "SSHChannel %s (%s) on %s" % (self.name, id, - self.conn.logPrefix()) - - def channelOpen(self, specificData): - """ - Called when the channel is opened. specificData is any data that the - other side sent us when opening the channel. - - @type specificData: C{str} - """ - log.msg('channel open') - - def openFailed(self, reason): - """ - Called when the the open failed for some reason. - reason.desc is a string descrption, reason.code the the SSH error code. - - @type reason: L{error.ConchError} - """ - log.msg('other side refused open\nreason: %s'% reason) - - def addWindowBytes(self, bytes): - """ - Called when bytes are added to the remote window. By default it clears - the data buffers. - - @type bytes: C{int} - """ - self.remoteWindowLeft = self.remoteWindowLeft+bytes - if not self.areWriting and not self.closing: - self.areWriting = True - self.startWriting() - if self.buf: - b = self.buf - self.buf = '' - self.write(b) - if self.extBuf: - b = self.extBuf - self.extBuf = [] - for (type, data) in b: - self.writeExtended(type, data) - - def requestReceived(self, requestType, data): - """ - Called when a request is sent to this channel. By default it delegates - to self.request_<requestType>. - If this function returns true, the request succeeded, otherwise it - failed. - - @type requestType: C{str} - @type data: C{str} - @rtype: C{bool} - """ - foo = requestType.replace('-', '_') - f = getattr(self, 'request_%s'%foo, None) - if f: - return f(data) - log.msg('unhandled request for %s'%requestType) - return 0 - - def dataReceived(self, data): - """ - Called when we receive data. - - @type data: C{str} - """ - log.msg('got data %s'%repr(data)) - - def extReceived(self, dataType, data): - """ - Called when we receive extended data (usually standard error). - - @type dataType: C{int} - @type data: C{str} - """ - log.msg('got extended data %s %s'%(dataType, repr(data))) - - def eofReceived(self): - """ - Called when the other side will send no more data. - """ - log.msg('remote eof') - - def closeReceived(self): - """ - Called when the other side has closed the channel. - """ - log.msg('remote close') - self.loseConnection() - - def closed(self): - """ - Called when the channel is closed. This means that both our side and - the remote side have closed the channel. - """ - log.msg('closed') - - # transport stuff - def write(self, data): - """ - Write some data to the channel. If there is not enough remote window - available, buffer until it is. Otherwise, split the data into - packets of length remoteMaxPacket and send them. - - @type data: C{str} - """ - if self.buf: - self.buf += data - return - top = len(data) - if top > self.remoteWindowLeft: - data, self.buf = (data[:self.remoteWindowLeft], - data[self.remoteWindowLeft:]) - self.areWriting = 0 - self.stopWriting() - top = self.remoteWindowLeft - rmp = self.remoteMaxPacket - write = self.conn.sendData - r = range(0, top, rmp) - for offset in r: - write(self, data[offset: offset+rmp]) - self.remoteWindowLeft -= top - if self.closing and not self.buf: - self.loseConnection() # try again - - def writeExtended(self, dataType, data): - """ - Send extended data to this channel. If there is not enough remote - window available, buffer until there is. Otherwise, split the data - into packets of length remoteMaxPacket and send them. - - @type dataType: C{int} - @type data: C{str} - """ - if self.extBuf: - if self.extBuf[-1][0] == dataType: - self.extBuf[-1][1] += data - else: - self.extBuf.append([dataType, data]) - return - if len(data) > self.remoteWindowLeft: - data, self.extBuf = (data[:self.remoteWindowLeft], - [[dataType, data[self.remoteWindowLeft:]]]) - self.areWriting = 0 - self.stopWriting() - while len(data) > self.remoteMaxPacket: - self.conn.sendExtendedData(self, dataType, - data[:self.remoteMaxPacket]) - data = data[self.remoteMaxPacket:] - self.remoteWindowLeft -= self.remoteMaxPacket - if data: - self.conn.sendExtendedData(self, dataType, data) - self.remoteWindowLeft -= len(data) - if self.closing: - self.loseConnection() # try again - - def writeSequence(self, data): - """ - Part of the Transport interface. Write a list of strings to the - channel. - - @type data: C{list} of C{str} - """ - self.write(''.join(data)) - - def loseConnection(self): - """ - Close the channel if there is no buferred data. Otherwise, note the - request and return. - """ - self.closing = 1 - if not self.buf and not self.extBuf: - self.conn.sendClose(self) - - def getPeer(self): - """ - Return a tuple describing the other side of the connection. - - @rtype: C{tuple} - """ - return('SSH', )+self.conn.transport.getPeer() - - def getHost(self): - """ - Return a tuple describing our side of the connection. - - @rtype: C{tuple} - """ - return('SSH', )+self.conn.transport.getHost() - - def stopWriting(self): - """ - Called when the remote buffer is full, as a hint to stop writing. - This can be ignored, but it can be helpful. - """ - - def startWriting(self): - """ - Called when the remote buffer has more room, as a hint to continue - writing. - """ diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py deleted file mode 100755 index 3afa3413..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/common.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_ssh -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - - -""" -Common functions for the SSH classes. - -Maintainer: Paul Swartz -""" - -import struct, warnings, __builtin__ - -try: - from Crypto import Util -except ImportError: - warnings.warn("PyCrypto not installed, but continuing anyways!", - RuntimeWarning) - -from twisted.python import randbytes - - -def NS(t): - """ - net string - """ - return struct.pack('!L',len(t)) + t - -def getNS(s, count=1): - """ - get net string - """ - ns = [] - c = 0 - for i in range(count): - l, = struct.unpack('!L',s[c:c+4]) - ns.append(s[c+4:4+l+c]) - c += 4 + l - return tuple(ns) + (s[c:],) - -def MP(number): - if number==0: return '\000'*4 - assert number>0 - bn = Util.number.long_to_bytes(number) - if ord(bn[0])&128: - bn = '\000' + bn - return struct.pack('>L',len(bn)) + bn - -def getMP(data, count=1): - """ - Get multiple precision integer out of the string. A multiple precision - integer is stored as a 4-byte length followed by length bytes of the - integer. If count is specified, get count integers out of the string. - The return value is a tuple of count integers followed by the rest of - the data. - """ - mp = [] - c = 0 - for i in range(count): - length, = struct.unpack('>L',data[c:c+4]) - mp.append(Util.number.bytes_to_long(data[c+4:c+4+length])) - c += 4 + length - return tuple(mp) + (data[c:],) - -def _MPpow(x, y, z): - """return the MP version of (x**y)%z - """ - return MP(pow(x,y,z)) - -def ffs(c, s): - """ - first from second - goes through the first list, looking for items in the second, returns the first one - """ - for i in c: - if i in s: return i - -getMP_py = getMP -MP_py = MP -_MPpow_py = _MPpow -pyPow = pow - -def _fastgetMP(data, count=1): - mp = [] - c = 0 - for i in range(count): - length = struct.unpack('!L', data[c:c+4])[0] - mp.append(long(gmpy.mpz(data[c + 4:c + 4 + length][::-1] + '\x00', 256))) - c += length + 4 - return tuple(mp) + (data[c:],) - -def _fastMP(i): - i2 = gmpy.mpz(i).binary()[::-1] - return struct.pack('!L', len(i2)) + i2 - -def _fastMPpow(x, y, z=None): - r = pyPow(gmpy.mpz(x),y,z).binary()[::-1] - return struct.pack('!L', len(r)) + r - -def install(): - global getMP, MP, _MPpow - getMP = _fastgetMP - MP = _fastMP - _MPpow = _fastMPpow - # XXX: We override builtin pow so that PyCrypto can benefit from gmpy too. - def _fastpow(x, y, z=None, mpz=gmpy.mpz): - if type(x) in (long, int): - x = mpz(x) - return pyPow(x, y, z) - __builtin__.pow = _fastpow # evil evil - -try: - import gmpy - install() -except ImportError: - pass - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py deleted file mode 100755 index 25271995..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/connection.py +++ /dev/null @@ -1,637 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_connection -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -This module contains the implementation of the ssh-connection service, which -allows access to the shell and port-forwarding. - -Maintainer: Paul Swartz -""" - -import struct - -from twisted.conch.ssh import service, common -from twisted.conch import error -from twisted.internet import defer -from twisted.python import log - -class SSHConnection(service.SSHService): - """ - An implementation of the 'ssh-connection' service. It is used to - multiplex multiple channels over the single SSH connection. - - @ivar localChannelID: the next number to use as a local channel ID. - @type localChannelID: C{int} - @ivar channels: a C{dict} mapping a local channel ID to C{SSHChannel} - subclasses. - @type channels: C{dict} - @ivar localToRemoteChannel: a C{dict} mapping a local channel ID to a - remote channel ID. - @type localToRemoteChannel: C{dict} - @ivar channelsToRemoteChannel: a C{dict} mapping a C{SSHChannel} subclass - to remote channel ID. - @type channelsToRemoteChannel: C{dict} - @ivar deferreds: a C{dict} mapping a local channel ID to a C{list} of - C{Deferreds} for outstanding channel requests. Also, the 'global' - key stores the C{list} of pending global request C{Deferred}s. - """ - name = 'ssh-connection' - - def __init__(self): - self.localChannelID = 0 # this is the current # to use for channel ID - self.localToRemoteChannel = {} # local channel ID -> remote channel ID - self.channels = {} # local channel ID -> subclass of SSHChannel - self.channelsToRemoteChannel = {} # subclass of SSHChannel -> - # remote channel ID - self.deferreds = {"global": []} # local channel -> list of deferreds - # for pending requests or 'global' -> list of - # deferreds for global requests - self.transport = None # gets set later - - - def serviceStarted(self): - if hasattr(self.transport, 'avatar'): - self.transport.avatar.conn = self - - - def serviceStopped(self): - """ - Called when the connection is stopped. - """ - map(self.channelClosed, self.channels.values()) - self._cleanupGlobalDeferreds() - - - def _cleanupGlobalDeferreds(self): - """ - All pending requests that have returned a deferred must be errbacked - when this service is stopped, otherwise they might be left uncalled and - uncallable. - """ - for d in self.deferreds["global"]: - d.errback(error.ConchError("Connection stopped.")) - del self.deferreds["global"][:] - - - # packet methods - def ssh_GLOBAL_REQUEST(self, packet): - """ - The other side has made a global request. Payload:: - string request type - bool want reply - <request specific data> - - This dispatches to self.gotGlobalRequest. - """ - requestType, rest = common.getNS(packet) - wantReply, rest = ord(rest[0]), rest[1:] - ret = self.gotGlobalRequest(requestType, rest) - if wantReply: - reply = MSG_REQUEST_FAILURE - data = '' - if ret: - reply = MSG_REQUEST_SUCCESS - if isinstance(ret, (tuple, list)): - data = ret[1] - self.transport.sendPacket(reply, data) - - def ssh_REQUEST_SUCCESS(self, packet): - """ - Our global request succeeded. Get the appropriate Deferred and call - it back with the packet we received. - """ - log.msg('RS') - self.deferreds['global'].pop(0).callback(packet) - - def ssh_REQUEST_FAILURE(self, packet): - """ - Our global request failed. Get the appropriate Deferred and errback - it with the packet we received. - """ - log.msg('RF') - self.deferreds['global'].pop(0).errback( - error.ConchError('global request failed', packet)) - - def ssh_CHANNEL_OPEN(self, packet): - """ - The other side wants to get a channel. Payload:: - string channel name - uint32 remote channel number - uint32 remote window size - uint32 remote maximum packet size - <channel specific data> - - We get a channel from self.getChannel(), give it a local channel number - and notify the other side. Then notify the channel by calling its - channelOpen method. - """ - channelType, rest = common.getNS(packet) - senderChannel, windowSize, maxPacket = struct.unpack('>3L', rest[:12]) - packet = rest[12:] - try: - channel = self.getChannel(channelType, windowSize, maxPacket, - packet) - localChannel = self.localChannelID - self.localChannelID += 1 - channel.id = localChannel - self.channels[localChannel] = channel - self.channelsToRemoteChannel[channel] = senderChannel - self.localToRemoteChannel[localChannel] = senderChannel - self.transport.sendPacket(MSG_CHANNEL_OPEN_CONFIRMATION, - struct.pack('>4L', senderChannel, localChannel, - channel.localWindowSize, - channel.localMaxPacket)+channel.specificData) - log.callWithLogger(channel, channel.channelOpen, packet) - except Exception, e: - log.msg('channel open failed') - log.err(e) - if isinstance(e, error.ConchError): - textualInfo, reason = e.args - if isinstance(textualInfo, (int, long)): - # See #3657 and #3071 - textualInfo, reason = reason, textualInfo - else: - reason = OPEN_CONNECT_FAILED - textualInfo = "unknown failure" - self.transport.sendPacket( - MSG_CHANNEL_OPEN_FAILURE, - struct.pack('>2L', senderChannel, reason) + - common.NS(textualInfo) + common.NS('')) - - def ssh_CHANNEL_OPEN_CONFIRMATION(self, packet): - """ - The other side accepted our MSG_CHANNEL_OPEN request. Payload:: - uint32 local channel number - uint32 remote channel number - uint32 remote window size - uint32 remote maximum packet size - <channel specific data> - - Find the channel using the local channel number and notify its - channelOpen method. - """ - (localChannel, remoteChannel, windowSize, - maxPacket) = struct.unpack('>4L', packet[: 16]) - specificData = packet[16:] - channel = self.channels[localChannel] - channel.conn = self - self.localToRemoteChannel[localChannel] = remoteChannel - self.channelsToRemoteChannel[channel] = remoteChannel - channel.remoteWindowLeft = windowSize - channel.remoteMaxPacket = maxPacket - log.callWithLogger(channel, channel.channelOpen, specificData) - - def ssh_CHANNEL_OPEN_FAILURE(self, packet): - """ - The other side did not accept our MSG_CHANNEL_OPEN request. Payload:: - uint32 local channel number - uint32 reason code - string reason description - - Find the channel using the local channel number and notify it by - calling its openFailed() method. - """ - localChannel, reasonCode = struct.unpack('>2L', packet[:8]) - reasonDesc = common.getNS(packet[8:])[0] - channel = self.channels[localChannel] - del self.channels[localChannel] - channel.conn = self - reason = error.ConchError(reasonDesc, reasonCode) - log.callWithLogger(channel, channel.openFailed, reason) - - def ssh_CHANNEL_WINDOW_ADJUST(self, packet): - """ - The other side is adding bytes to its window. Payload:: - uint32 local channel number - uint32 bytes to add - - Call the channel's addWindowBytes() method to add new bytes to the - remote window. - """ - localChannel, bytesToAdd = struct.unpack('>2L', packet[:8]) - channel = self.channels[localChannel] - log.callWithLogger(channel, channel.addWindowBytes, bytesToAdd) - - def ssh_CHANNEL_DATA(self, packet): - """ - The other side is sending us data. Payload:: - uint32 local channel number - string data - - Check to make sure the other side hasn't sent too much data (more - than what's in the window, or more than the maximum packet size). If - they have, close the channel. Otherwise, decrease the available - window and pass the data to the channel's dataReceived(). - """ - localChannel, dataLength = struct.unpack('>2L', packet[:8]) - channel = self.channels[localChannel] - # XXX should this move to dataReceived to put client in charge? - if (dataLength > channel.localWindowLeft or - dataLength > channel.localMaxPacket): # more data than we want - log.callWithLogger(channel, log.msg, 'too much data') - self.sendClose(channel) - return - #packet = packet[:channel.localWindowLeft+4] - data = common.getNS(packet[4:])[0] - channel.localWindowLeft -= dataLength - if channel.localWindowLeft < channel.localWindowSize // 2: - self.adjustWindow(channel, channel.localWindowSize - \ - channel.localWindowLeft) - #log.msg('local window left: %s/%s' % (channel.localWindowLeft, - # channel.localWindowSize)) - log.callWithLogger(channel, channel.dataReceived, data) - - def ssh_CHANNEL_EXTENDED_DATA(self, packet): - """ - The other side is sending us exteneded data. Payload:: - uint32 local channel number - uint32 type code - string data - - Check to make sure the other side hasn't sent too much data (more - than what's in the window, or or than the maximum packet size). If - they have, close the channel. Otherwise, decrease the available - window and pass the data and type code to the channel's - extReceived(). - """ - localChannel, typeCode, dataLength = struct.unpack('>3L', packet[:12]) - channel = self.channels[localChannel] - if (dataLength > channel.localWindowLeft or - dataLength > channel.localMaxPacket): - log.callWithLogger(channel, log.msg, 'too much extdata') - self.sendClose(channel) - return - data = common.getNS(packet[8:])[0] - channel.localWindowLeft -= dataLength - if channel.localWindowLeft < channel.localWindowSize // 2: - self.adjustWindow(channel, channel.localWindowSize - - channel.localWindowLeft) - log.callWithLogger(channel, channel.extReceived, typeCode, data) - - def ssh_CHANNEL_EOF(self, packet): - """ - The other side is not sending any more data. Payload:: - uint32 local channel number - - Notify the channel by calling its eofReceived() method. - """ - localChannel = struct.unpack('>L', packet[:4])[0] - channel = self.channels[localChannel] - log.callWithLogger(channel, channel.eofReceived) - - def ssh_CHANNEL_CLOSE(self, packet): - """ - The other side is closing its end; it does not want to receive any - more data. Payload:: - uint32 local channel number - - Notify the channnel by calling its closeReceived() method. If - the channel has also sent a close message, call self.channelClosed(). - """ - localChannel = struct.unpack('>L', packet[:4])[0] - channel = self.channels[localChannel] - log.callWithLogger(channel, channel.closeReceived) - channel.remoteClosed = True - if channel.localClosed and channel.remoteClosed: - self.channelClosed(channel) - - def ssh_CHANNEL_REQUEST(self, packet): - """ - The other side is sending a request to a channel. Payload:: - uint32 local channel number - string request name - bool want reply - <request specific data> - - Pass the message to the channel's requestReceived method. If the - other side wants a reply, add callbacks which will send the - reply. - """ - localChannel = struct.unpack('>L', packet[: 4])[0] - requestType, rest = common.getNS(packet[4:]) - wantReply = ord(rest[0]) - channel = self.channels[localChannel] - d = defer.maybeDeferred(log.callWithLogger, channel, - channel.requestReceived, requestType, rest[1:]) - if wantReply: - d.addCallback(self._cbChannelRequest, localChannel) - d.addErrback(self._ebChannelRequest, localChannel) - return d - - def _cbChannelRequest(self, result, localChannel): - """ - Called back if the other side wanted a reply to a channel request. If - the result is true, send a MSG_CHANNEL_SUCCESS. Otherwise, raise - a C{error.ConchError} - - @param result: the value returned from the channel's requestReceived() - method. If it's False, the request failed. - @type result: C{bool} - @param localChannel: the local channel ID of the channel to which the - request was made. - @type localChannel: C{int} - @raises ConchError: if the result is False. - """ - if not result: - raise error.ConchError('failed request') - self.transport.sendPacket(MSG_CHANNEL_SUCCESS, struct.pack('>L', - self.localToRemoteChannel[localChannel])) - - def _ebChannelRequest(self, result, localChannel): - """ - Called if the other wisde wanted a reply to the channel requeset and - the channel request failed. - - @param result: a Failure, but it's not used. - @param localChannel: the local channel ID of the channel to which the - request was made. - @type localChannel: C{int} - """ - self.transport.sendPacket(MSG_CHANNEL_FAILURE, struct.pack('>L', - self.localToRemoteChannel[localChannel])) - - def ssh_CHANNEL_SUCCESS(self, packet): - """ - Our channel request to the other other side succeeded. Payload:: - uint32 local channel number - - Get the C{Deferred} out of self.deferreds and call it back. - """ - localChannel = struct.unpack('>L', packet[:4])[0] - if self.deferreds.get(localChannel): - d = self.deferreds[localChannel].pop(0) - log.callWithLogger(self.channels[localChannel], - d.callback, '') - - def ssh_CHANNEL_FAILURE(self, packet): - """ - Our channel request to the other side failed. Payload:: - uint32 local channel number - - Get the C{Deferred} out of self.deferreds and errback it with a - C{error.ConchError}. - """ - localChannel = struct.unpack('>L', packet[:4])[0] - if self.deferreds.get(localChannel): - d = self.deferreds[localChannel].pop(0) - log.callWithLogger(self.channels[localChannel], - d.errback, - error.ConchError('channel request failed')) - - # methods for users of the connection to call - - def sendGlobalRequest(self, request, data, wantReply=0): - """ - Send a global request for this connection. Current this is only used - for remote->local TCP forwarding. - - @type request: C{str} - @type data: C{str} - @type wantReply: C{bool} - @rtype C{Deferred}/C{None} - """ - self.transport.sendPacket(MSG_GLOBAL_REQUEST, - common.NS(request) - + (wantReply and '\xff' or '\x00') - + data) - if wantReply: - d = defer.Deferred() - self.deferreds['global'].append(d) - return d - - def openChannel(self, channel, extra=''): - """ - Open a new channel on this connection. - - @type channel: subclass of C{SSHChannel} - @type extra: C{str} - """ - log.msg('opening channel %s with %s %s'%(self.localChannelID, - channel.localWindowSize, channel.localMaxPacket)) - self.transport.sendPacket(MSG_CHANNEL_OPEN, common.NS(channel.name) - + struct.pack('>3L', self.localChannelID, - channel.localWindowSize, channel.localMaxPacket) - + extra) - channel.id = self.localChannelID - self.channels[self.localChannelID] = channel - self.localChannelID += 1 - - def sendRequest(self, channel, requestType, data, wantReply=0): - """ - Send a request to a channel. - - @type channel: subclass of C{SSHChannel} - @type requestType: C{str} - @type data: C{str} - @type wantReply: C{bool} - @rtype C{Deferred}/C{None} - """ - if channel.localClosed: - return - log.msg('sending request %s' % requestType) - self.transport.sendPacket(MSG_CHANNEL_REQUEST, struct.pack('>L', - self.channelsToRemoteChannel[channel]) - + common.NS(requestType)+chr(wantReply) - + data) - if wantReply: - d = defer.Deferred() - self.deferreds.setdefault(channel.id, []).append(d) - return d - - def adjustWindow(self, channel, bytesToAdd): - """ - Tell the other side that we will receive more data. This should not - normally need to be called as it is managed automatically. - - @type channel: subclass of L{SSHChannel} - @type bytesToAdd: C{int} - """ - if channel.localClosed: - return # we're already closed - self.transport.sendPacket(MSG_CHANNEL_WINDOW_ADJUST, struct.pack('>2L', - self.channelsToRemoteChannel[channel], - bytesToAdd)) - log.msg('adding %i to %i in channel %i' % (bytesToAdd, - channel.localWindowLeft, channel.id)) - channel.localWindowLeft += bytesToAdd - - def sendData(self, channel, data): - """ - Send data to a channel. This should not normally be used: instead use - channel.write(data) as it manages the window automatically. - - @type channel: subclass of L{SSHChannel} - @type data: C{str} - """ - if channel.localClosed: - return # we're already closed - self.transport.sendPacket(MSG_CHANNEL_DATA, struct.pack('>L', - self.channelsToRemoteChannel[channel]) + - common.NS(data)) - - def sendExtendedData(self, channel, dataType, data): - """ - Send extended data to a channel. This should not normally be used: - instead use channel.writeExtendedData(data, dataType) as it manages - the window automatically. - - @type channel: subclass of L{SSHChannel} - @type dataType: C{int} - @type data: C{str} - """ - if channel.localClosed: - return # we're already closed - self.transport.sendPacket(MSG_CHANNEL_EXTENDED_DATA, struct.pack('>2L', - self.channelsToRemoteChannel[channel],dataType) \ - + common.NS(data)) - - def sendEOF(self, channel): - """ - Send an EOF (End of File) for a channel. - - @type channel: subclass of L{SSHChannel} - """ - if channel.localClosed: - return # we're already closed - log.msg('sending eof') - self.transport.sendPacket(MSG_CHANNEL_EOF, struct.pack('>L', - self.channelsToRemoteChannel[channel])) - - def sendClose(self, channel): - """ - Close a channel. - - @type channel: subclass of L{SSHChannel} - """ - if channel.localClosed: - return # we're already closed - log.msg('sending close %i' % channel.id) - self.transport.sendPacket(MSG_CHANNEL_CLOSE, struct.pack('>L', - self.channelsToRemoteChannel[channel])) - channel.localClosed = True - if channel.localClosed and channel.remoteClosed: - self.channelClosed(channel) - - # methods to override - def getChannel(self, channelType, windowSize, maxPacket, data): - """ - The other side requested a channel of some sort. - channelType is the type of channel being requested, - windowSize is the initial size of the remote window, - maxPacket is the largest packet we should send, - data is any other packet data (often nothing). - - We return a subclass of L{SSHChannel}. - - By default, this dispatches to a method 'channel_channelType' with any - non-alphanumerics in the channelType replace with _'s. If it cannot - find a suitable method, it returns an OPEN_UNKNOWN_CHANNEL_TYPE error. - The method is called with arguments of windowSize, maxPacket, data. - - @type channelType: C{str} - @type windowSize: C{int} - @type maxPacket: C{int} - @type data: C{str} - @rtype: subclass of L{SSHChannel}/C{tuple} - """ - log.msg('got channel %s request' % channelType) - if hasattr(self.transport, "avatar"): # this is a server! - chan = self.transport.avatar.lookupChannel(channelType, - windowSize, - maxPacket, - data) - else: - channelType = channelType.translate(TRANSLATE_TABLE) - f = getattr(self, 'channel_%s' % channelType, None) - if f is not None: - chan = f(windowSize, maxPacket, data) - else: - chan = None - if chan is None: - raise error.ConchError('unknown channel', - OPEN_UNKNOWN_CHANNEL_TYPE) - else: - chan.conn = self - return chan - - def gotGlobalRequest(self, requestType, data): - """ - We got a global request. pretty much, this is just used by the client - to request that we forward a port from the server to the client. - Returns either: - - 1: request accepted - - 1, <data>: request accepted with request specific data - - 0: request denied - - By default, this dispatches to a method 'global_requestType' with - -'s in requestType replaced with _'s. The found method is passed data. - If this method cannot be found, this method returns 0. Otherwise, it - returns the return value of that method. - - @type requestType: C{str} - @type data: C{str} - @rtype: C{int}/C{tuple} - """ - log.msg('got global %s request' % requestType) - if hasattr(self.transport, 'avatar'): # this is a server! - return self.transport.avatar.gotGlobalRequest(requestType, data) - - requestType = requestType.replace('-','_') - f = getattr(self, 'global_%s' % requestType, None) - if not f: - return 0 - return f(data) - - def channelClosed(self, channel): - """ - Called when a channel is closed. - It clears the local state related to the channel, and calls - channel.closed(). - MAKE SURE YOU CALL THIS METHOD, even if you subclass L{SSHConnection}. - If you don't, things will break mysteriously. - - @type channel: L{SSHChannel} - """ - if channel in self.channelsToRemoteChannel: # actually open - channel.localClosed = channel.remoteClosed = True - del self.localToRemoteChannel[channel.id] - del self.channels[channel.id] - del self.channelsToRemoteChannel[channel] - for d in self.deferreds.setdefault(channel.id, []): - d.errback(error.ConchError("Channel closed.")) - del self.deferreds[channel.id][:] - log.callWithLogger(channel, channel.closed) - -MSG_GLOBAL_REQUEST = 80 -MSG_REQUEST_SUCCESS = 81 -MSG_REQUEST_FAILURE = 82 -MSG_CHANNEL_OPEN = 90 -MSG_CHANNEL_OPEN_CONFIRMATION = 91 -MSG_CHANNEL_OPEN_FAILURE = 92 -MSG_CHANNEL_WINDOW_ADJUST = 93 -MSG_CHANNEL_DATA = 94 -MSG_CHANNEL_EXTENDED_DATA = 95 -MSG_CHANNEL_EOF = 96 -MSG_CHANNEL_CLOSE = 97 -MSG_CHANNEL_REQUEST = 98 -MSG_CHANNEL_SUCCESS = 99 -MSG_CHANNEL_FAILURE = 100 - -OPEN_ADMINISTRATIVELY_PROHIBITED = 1 -OPEN_CONNECT_FAILED = 2 -OPEN_UNKNOWN_CHANNEL_TYPE = 3 -OPEN_RESOURCE_SHORTAGE = 4 - -EXTENDED_DATA_STDERR = 1 - -messages = {} -for name, value in locals().copy().items(): - if name[:4] == 'MSG_': - messages[value] = name # doesn't handle doubles - -import string -alphanums = string.letters + string.digits -TRANSLATE_TABLE = ''.join([chr(i) in alphanums and chr(i) or '_' - for i in range(256)]) -SSHConnection.protocolMessages = messages diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py deleted file mode 100755 index 3c50932f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/factory.py +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -A Factory for SSH servers, along with an OpenSSHFactory to use the same -data sources as OpenSSH. - -Maintainer: Paul Swartz -""" - -from twisted.internet import protocol -from twisted.python import log -from twisted.python.reflect import qual - -from twisted.conch import error -from twisted.conch.ssh import keys -import transport, userauth, connection - -import random -import warnings - -class SSHFactory(protocol.Factory): - """ - A Factory for SSH servers. - """ - protocol = transport.SSHServerTransport - - services = { - 'ssh-userauth':userauth.SSHUserAuthServer, - 'ssh-connection':connection.SSHConnection - } - def startFactory(self): - """ - Check for public and private keys. - """ - if not hasattr(self,'publicKeys'): - self.publicKeys = self.getPublicKeys() - for keyType, value in self.publicKeys.items(): - if isinstance(value, str): - warnings.warn("Returning a mapping from strings to " - "strings from getPublicKeys()/publicKeys (in %s) " - "is deprecated. Return a mapping from " - "strings to Key objects instead." % - (qual(self.__class__)), - DeprecationWarning, stacklevel=1) - self.publicKeys[keyType] = keys.Key.fromString(value) - if not hasattr(self,'privateKeys'): - self.privateKeys = self.getPrivateKeys() - for keyType, value in self.privateKeys.items(): - if not isinstance(value, keys.Key): - warnings.warn("Returning a mapping from strings to " - "PyCrypto key objects from " - "getPrivateKeys()/privateKeys (in %s) " - "is deprecated. Return a mapping from " - "strings to Key objects instead." % - (qual(self.__class__),), - DeprecationWarning, stacklevel=1) - self.privateKeys[keyType] = keys.Key(value) - if not self.publicKeys or not self.privateKeys: - raise error.ConchError('no host keys, failing') - if not hasattr(self,'primes'): - self.primes = self.getPrimes() - - - def buildProtocol(self, addr): - """ - Create an instance of the server side of the SSH protocol. - - @type addr: L{twisted.internet.interfaces.IAddress} provider - @param addr: The address at which the server will listen. - - @rtype: L{twisted.conch.ssh.SSHServerTransport} - @return: The built transport. - """ - t = protocol.Factory.buildProtocol(self, addr) - t.supportedPublicKeys = self.privateKeys.keys() - if not self.primes: - log.msg('disabling diffie-hellman-group-exchange because we ' - 'cannot find moduli file') - ske = t.supportedKeyExchanges[:] - ske.remove('diffie-hellman-group-exchange-sha1') - t.supportedKeyExchanges = ske - return t - - - def getPublicKeys(self): - """ - Called when the factory is started to get the public portions of the - servers host keys. Returns a dictionary mapping SSH key types to - public key strings. - - @rtype: C{dict} - """ - raise NotImplementedError('getPublicKeys unimplemented') - - - def getPrivateKeys(self): - """ - Called when the factory is started to get the private portions of the - servers host keys. Returns a dictionary mapping SSH key types to - C{Crypto.PublicKey.pubkey.pubkey} objects. - - @rtype: C{dict} - """ - raise NotImplementedError('getPrivateKeys unimplemented') - - - def getPrimes(self): - """ - Called when the factory is started to get Diffie-Hellman generators and - primes to use. Returns a dictionary mapping number of bits to lists - of tuple of (generator, prime). - - @rtype: C{dict} - """ - - - def getDHPrime(self, bits): - """ - Return a tuple of (g, p) for a Diffe-Hellman process, with p being as - close to bits bits as possible. - - @type bits: C{int} - @rtype: C{tuple} - """ - primesKeys = self.primes.keys() - primesKeys.sort(lambda x, y: cmp(abs(x - bits), abs(y - bits))) - realBits = primesKeys[0] - return random.choice(self.primes[realBits]) - - - def getService(self, transport, service): - """ - Return a class to use as a service for the given transport. - - @type transport: L{transport.SSHServerTransport} - @type service: C{str} - @rtype: subclass of L{service.SSHService} - """ - if service == 'ssh-userauth' or hasattr(transport, 'avatar'): - return self.services[service] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py deleted file mode 100755 index 9b11db0d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/filetransfer.py +++ /dev/null @@ -1,934 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_filetransfer -*- -# -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - - -import struct, errno - -from twisted.internet import defer, protocol -from twisted.python import failure, log - -from common import NS, getNS -from twisted.conch.interfaces import ISFTPServer, ISFTPFile - -from zope import interface - - - -class FileTransferBase(protocol.Protocol): - - versions = (3, ) - - packetTypes = {} - - def __init__(self): - self.buf = '' - self.otherVersion = None # this gets set - - def sendPacket(self, kind, data): - self.transport.write(struct.pack('!LB', len(data)+1, kind) + data) - - def dataReceived(self, data): - self.buf += data - while len(self.buf) > 5: - length, kind = struct.unpack('!LB', self.buf[:5]) - if len(self.buf) < 4 + length: - return - data, self.buf = self.buf[5:4+length], self.buf[4+length:] - packetType = self.packetTypes.get(kind, None) - if not packetType: - log.msg('no packet type for', kind) - continue - f = getattr(self, 'packet_%s' % packetType, None) - if not f: - log.msg('not implemented: %s' % packetType) - log.msg(repr(data[4:])) - reqId, = struct.unpack('!L', data[:4]) - self._sendStatus(reqId, FX_OP_UNSUPPORTED, - "don't understand %s" % packetType) - #XXX not implemented - continue - try: - f(data) - except: - log.err() - continue - reqId ,= struct.unpack('!L', data[:4]) - self._ebStatus(failure.Failure(e), reqId) - - def _parseAttributes(self, data): - flags ,= struct.unpack('!L', data[:4]) - attrs = {} - data = data[4:] - if flags & FILEXFER_ATTR_SIZE == FILEXFER_ATTR_SIZE: - size ,= struct.unpack('!Q', data[:8]) - attrs['size'] = size - data = data[8:] - if flags & FILEXFER_ATTR_OWNERGROUP == FILEXFER_ATTR_OWNERGROUP: - uid, gid = struct.unpack('!2L', data[:8]) - attrs['uid'] = uid - attrs['gid'] = gid - data = data[8:] - if flags & FILEXFER_ATTR_PERMISSIONS == FILEXFER_ATTR_PERMISSIONS: - perms ,= struct.unpack('!L', data[:4]) - attrs['permissions'] = perms - data = data[4:] - if flags & FILEXFER_ATTR_ACMODTIME == FILEXFER_ATTR_ACMODTIME: - atime, mtime = struct.unpack('!2L', data[:8]) - attrs['atime'] = atime - attrs['mtime'] = mtime - data = data[8:] - if flags & FILEXFER_ATTR_EXTENDED == FILEXFER_ATTR_EXTENDED: - extended_count ,= struct.unpack('!L', data[:4]) - data = data[4:] - for i in xrange(extended_count): - extended_type, data = getNS(data) - extended_data, data = getNS(data) - attrs['ext_%s' % extended_type] = extended_data - return attrs, data - - def _packAttributes(self, attrs): - flags = 0 - data = '' - if 'size' in attrs: - data += struct.pack('!Q', attrs['size']) - flags |= FILEXFER_ATTR_SIZE - if 'uid' in attrs and 'gid' in attrs: - data += struct.pack('!2L', attrs['uid'], attrs['gid']) - flags |= FILEXFER_ATTR_OWNERGROUP - if 'permissions' in attrs: - data += struct.pack('!L', attrs['permissions']) - flags |= FILEXFER_ATTR_PERMISSIONS - if 'atime' in attrs and 'mtime' in attrs: - data += struct.pack('!2L', attrs['atime'], attrs['mtime']) - flags |= FILEXFER_ATTR_ACMODTIME - extended = [] - for k in attrs: - if k.startswith('ext_'): - ext_type = NS(k[4:]) - ext_data = NS(attrs[k]) - extended.append(ext_type+ext_data) - if extended: - data += struct.pack('!L', len(extended)) - data += ''.join(extended) - flags |= FILEXFER_ATTR_EXTENDED - return struct.pack('!L', flags) + data - -class FileTransferServer(FileTransferBase): - - def __init__(self, data=None, avatar=None): - FileTransferBase.__init__(self) - self.client = ISFTPServer(avatar) # yay interfaces - self.openFiles = {} - self.openDirs = {} - - def packet_INIT(self, data): - version ,= struct.unpack('!L', data[:4]) - self.version = min(list(self.versions) + [version]) - data = data[4:] - ext = {} - while data: - ext_name, data = getNS(data) - ext_data, data = getNS(data) - ext[ext_name] = ext_data - our_ext = self.client.gotVersion(version, ext) - our_ext_data = "" - for (k,v) in our_ext.items(): - our_ext_data += NS(k) + NS(v) - self.sendPacket(FXP_VERSION, struct.pack('!L', self.version) + \ - our_ext_data) - - def packet_OPEN(self, data): - requestId = data[:4] - data = data[4:] - filename, data = getNS(data) - flags ,= struct.unpack('!L', data[:4]) - data = data[4:] - attrs, data = self._parseAttributes(data) - assert data == '', 'still have data in OPEN: %s' % repr(data) - d = defer.maybeDeferred(self.client.openFile, filename, flags, attrs) - d.addCallback(self._cbOpenFile, requestId) - d.addErrback(self._ebStatus, requestId, "open failed") - - def _cbOpenFile(self, fileObj, requestId): - fileId = str(hash(fileObj)) - if fileId in self.openFiles: - raise KeyError, 'id already open' - self.openFiles[fileId] = fileObj - self.sendPacket(FXP_HANDLE, requestId + NS(fileId)) - - def packet_CLOSE(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - assert data == '', 'still have data in CLOSE: %s' % repr(data) - if handle in self.openFiles: - fileObj = self.openFiles[handle] - d = defer.maybeDeferred(fileObj.close) - d.addCallback(self._cbClose, handle, requestId) - d.addErrback(self._ebStatus, requestId, "close failed") - elif handle in self.openDirs: - dirObj = self.openDirs[handle][0] - d = defer.maybeDeferred(dirObj.close) - d.addCallback(self._cbClose, handle, requestId, 1) - d.addErrback(self._ebStatus, requestId, "close failed") - else: - self._ebClose(failure.Failure(KeyError()), requestId) - - def _cbClose(self, result, handle, requestId, isDir = 0): - if isDir: - del self.openDirs[handle] - else: - del self.openFiles[handle] - self._sendStatus(requestId, FX_OK, 'file closed') - - def packet_READ(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - (offset, length), data = struct.unpack('!QL', data[:12]), data[12:] - assert data == '', 'still have data in READ: %s' % repr(data) - if handle not in self.openFiles: - self._ebRead(failure.Failure(KeyError()), requestId) - else: - fileObj = self.openFiles[handle] - d = defer.maybeDeferred(fileObj.readChunk, offset, length) - d.addCallback(self._cbRead, requestId) - d.addErrback(self._ebStatus, requestId, "read failed") - - def _cbRead(self, result, requestId): - if result == '': # python's read will return this for EOF - raise EOFError() - self.sendPacket(FXP_DATA, requestId + NS(result)) - - def packet_WRITE(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - offset, = struct.unpack('!Q', data[:8]) - data = data[8:] - writeData, data = getNS(data) - assert data == '', 'still have data in WRITE: %s' % repr(data) - if handle not in self.openFiles: - self._ebWrite(failure.Failure(KeyError()), requestId) - else: - fileObj = self.openFiles[handle] - d = defer.maybeDeferred(fileObj.writeChunk, offset, writeData) - d.addCallback(self._cbStatus, requestId, "write succeeded") - d.addErrback(self._ebStatus, requestId, "write failed") - - def packet_REMOVE(self, data): - requestId = data[:4] - data = data[4:] - filename, data = getNS(data) - assert data == '', 'still have data in REMOVE: %s' % repr(data) - d = defer.maybeDeferred(self.client.removeFile, filename) - d.addCallback(self._cbStatus, requestId, "remove succeeded") - d.addErrback(self._ebStatus, requestId, "remove failed") - - def packet_RENAME(self, data): - requestId = data[:4] - data = data[4:] - oldPath, data = getNS(data) - newPath, data = getNS(data) - assert data == '', 'still have data in RENAME: %s' % repr(data) - d = defer.maybeDeferred(self.client.renameFile, oldPath, newPath) - d.addCallback(self._cbStatus, requestId, "rename succeeded") - d.addErrback(self._ebStatus, requestId, "rename failed") - - def packet_MKDIR(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - attrs, data = self._parseAttributes(data) - assert data == '', 'still have data in MKDIR: %s' % repr(data) - d = defer.maybeDeferred(self.client.makeDirectory, path, attrs) - d.addCallback(self._cbStatus, requestId, "mkdir succeeded") - d.addErrback(self._ebStatus, requestId, "mkdir failed") - - def packet_RMDIR(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - assert data == '', 'still have data in RMDIR: %s' % repr(data) - d = defer.maybeDeferred(self.client.removeDirectory, path) - d.addCallback(self._cbStatus, requestId, "rmdir succeeded") - d.addErrback(self._ebStatus, requestId, "rmdir failed") - - def packet_OPENDIR(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - assert data == '', 'still have data in OPENDIR: %s' % repr(data) - d = defer.maybeDeferred(self.client.openDirectory, path) - d.addCallback(self._cbOpenDirectory, requestId) - d.addErrback(self._ebStatus, requestId, "opendir failed") - - def _cbOpenDirectory(self, dirObj, requestId): - handle = str(hash(dirObj)) - if handle in self.openDirs: - raise KeyError, "already opened this directory" - self.openDirs[handle] = [dirObj, iter(dirObj)] - self.sendPacket(FXP_HANDLE, requestId + NS(handle)) - - def packet_READDIR(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - assert data == '', 'still have data in READDIR: %s' % repr(data) - if handle not in self.openDirs: - self._ebStatus(failure.Failure(KeyError()), requestId) - else: - dirObj, dirIter = self.openDirs[handle] - d = defer.maybeDeferred(self._scanDirectory, dirIter, []) - d.addCallback(self._cbSendDirectory, requestId) - d.addErrback(self._ebStatus, requestId, "scan directory failed") - - def _scanDirectory(self, dirIter, f): - while len(f) < 250: - try: - info = dirIter.next() - except StopIteration: - if not f: - raise EOFError - return f - if isinstance(info, defer.Deferred): - info.addCallback(self._cbScanDirectory, dirIter, f) - return - else: - f.append(info) - return f - - def _cbScanDirectory(self, result, dirIter, f): - f.append(result) - return self._scanDirectory(dirIter, f) - - def _cbSendDirectory(self, result, requestId): - data = '' - for (filename, longname, attrs) in result: - data += NS(filename) - data += NS(longname) - data += self._packAttributes(attrs) - self.sendPacket(FXP_NAME, requestId + - struct.pack('!L', len(result))+data) - - def packet_STAT(self, data, followLinks = 1): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - assert data == '', 'still have data in STAT/LSTAT: %s' % repr(data) - d = defer.maybeDeferred(self.client.getAttrs, path, followLinks) - d.addCallback(self._cbStat, requestId) - d.addErrback(self._ebStatus, requestId, 'stat/lstat failed') - - def packet_LSTAT(self, data): - self.packet_STAT(data, 0) - - def packet_FSTAT(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - assert data == '', 'still have data in FSTAT: %s' % repr(data) - if handle not in self.openFiles: - self._ebStatus(failure.Failure(KeyError('%s not in self.openFiles' - % handle)), requestId) - else: - fileObj = self.openFiles[handle] - d = defer.maybeDeferred(fileObj.getAttrs) - d.addCallback(self._cbStat, requestId) - d.addErrback(self._ebStatus, requestId, 'fstat failed') - - def _cbStat(self, result, requestId): - data = requestId + self._packAttributes(result) - self.sendPacket(FXP_ATTRS, data) - - def packet_SETSTAT(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - attrs, data = self._parseAttributes(data) - if data != '': - log.msg('WARN: still have data in SETSTAT: %s' % repr(data)) - d = defer.maybeDeferred(self.client.setAttrs, path, attrs) - d.addCallback(self._cbStatus, requestId, 'setstat succeeded') - d.addErrback(self._ebStatus, requestId, 'setstat failed') - - def packet_FSETSTAT(self, data): - requestId = data[:4] - data = data[4:] - handle, data = getNS(data) - attrs, data = self._parseAttributes(data) - assert data == '', 'still have data in FSETSTAT: %s' % repr(data) - if handle not in self.openFiles: - self._ebStatus(failure.Failure(KeyError()), requestId) - else: - fileObj = self.openFiles[handle] - d = defer.maybeDeferred(fileObj.setAttrs, attrs) - d.addCallback(self._cbStatus, requestId, 'fsetstat succeeded') - d.addErrback(self._ebStatus, requestId, 'fsetstat failed') - - def packet_READLINK(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - assert data == '', 'still have data in READLINK: %s' % repr(data) - d = defer.maybeDeferred(self.client.readLink, path) - d.addCallback(self._cbReadLink, requestId) - d.addErrback(self._ebStatus, requestId, 'readlink failed') - - def _cbReadLink(self, result, requestId): - self._cbSendDirectory([(result, '', {})], requestId) - - def packet_SYMLINK(self, data): - requestId = data[:4] - data = data[4:] - linkPath, data = getNS(data) - targetPath, data = getNS(data) - d = defer.maybeDeferred(self.client.makeLink, linkPath, targetPath) - d.addCallback(self._cbStatus, requestId, 'symlink succeeded') - d.addErrback(self._ebStatus, requestId, 'symlink failed') - - def packet_REALPATH(self, data): - requestId = data[:4] - data = data[4:] - path, data = getNS(data) - assert data == '', 'still have data in REALPATH: %s' % repr(data) - d = defer.maybeDeferred(self.client.realPath, path) - d.addCallback(self._cbReadLink, requestId) # same return format - d.addErrback(self._ebStatus, requestId, 'realpath failed') - - def packet_EXTENDED(self, data): - requestId = data[:4] - data = data[4:] - extName, extData = getNS(data) - d = defer.maybeDeferred(self.client.extendedRequest, extName, extData) - d.addCallback(self._cbExtended, requestId) - d.addErrback(self._ebStatus, requestId, 'extended %s failed' % extName) - - def _cbExtended(self, data, requestId): - self.sendPacket(FXP_EXTENDED_REPLY, requestId + data) - - def _cbStatus(self, result, requestId, msg = "request succeeded"): - self._sendStatus(requestId, FX_OK, msg) - - def _ebStatus(self, reason, requestId, msg = "request failed"): - code = FX_FAILURE - message = msg - if reason.type in (IOError, OSError): - if reason.value.errno == errno.ENOENT: # no such file - code = FX_NO_SUCH_FILE - message = reason.value.strerror - elif reason.value.errno == errno.EACCES: # permission denied - code = FX_PERMISSION_DENIED - message = reason.value.strerror - elif reason.value.errno == errno.EEXIST: - code = FX_FILE_ALREADY_EXISTS - else: - log.err(reason) - elif reason.type == EOFError: # EOF - code = FX_EOF - if reason.value.args: - message = reason.value.args[0] - elif reason.type == NotImplementedError: - code = FX_OP_UNSUPPORTED - if reason.value.args: - message = reason.value.args[0] - elif reason.type == SFTPError: - code = reason.value.code - message = reason.value.message - else: - log.err(reason) - self._sendStatus(requestId, code, message) - - def _sendStatus(self, requestId, code, message, lang = ''): - """ - Helper method to send a FXP_STATUS message. - """ - data = requestId + struct.pack('!L', code) - data += NS(message) - data += NS(lang) - self.sendPacket(FXP_STATUS, data) - - - def connectionLost(self, reason): - """ - Clean all opened files and directories. - """ - for fileObj in self.openFiles.values(): - fileObj.close() - self.openFiles = {} - for (dirObj, dirIter) in self.openDirs.values(): - dirObj.close() - self.openDirs = {} - - - -class FileTransferClient(FileTransferBase): - - def __init__(self, extData = {}): - """ - @param extData: a dict of extended_name : extended_data items - to be sent to the server. - """ - FileTransferBase.__init__(self) - self.extData = {} - self.counter = 0 - self.openRequests = {} # id -> Deferred - self.wasAFile = {} # Deferred -> 1 TERRIBLE HACK - - def connectionMade(self): - data = struct.pack('!L', max(self.versions)) - for k,v in self.extData.itervalues(): - data += NS(k) + NS(v) - self.sendPacket(FXP_INIT, data) - - def _sendRequest(self, msg, data): - data = struct.pack('!L', self.counter) + data - d = defer.Deferred() - self.openRequests[self.counter] = d - self.counter += 1 - self.sendPacket(msg, data) - return d - - def _parseRequest(self, data): - (id,) = struct.unpack('!L', data[:4]) - d = self.openRequests[id] - del self.openRequests[id] - return d, data[4:] - - def openFile(self, filename, flags, attrs): - """ - Open a file. - - This method returns a L{Deferred} that is called back with an object - that provides the L{ISFTPFile} interface. - - @param filename: a string representing the file to open. - - @param flags: a integer of the flags to open the file with, ORed together. - The flags and their values are listed at the bottom of this file. - - @param attrs: a list of attributes to open the file with. It is a - dictionary, consisting of 0 or more keys. The possible keys are:: - - size: the size of the file in bytes - uid: the user ID of the file as an integer - gid: the group ID of the file as an integer - permissions: the permissions of the file with as an integer. - the bit representation of this field is defined by POSIX. - atime: the access time of the file as seconds since the epoch. - mtime: the modification time of the file as seconds since the epoch. - ext_*: extended attributes. The server is not required to - understand this, but it may. - - NOTE: there is no way to indicate text or binary files. it is up - to the SFTP client to deal with this. - """ - data = NS(filename) + struct.pack('!L', flags) + self._packAttributes(attrs) - d = self._sendRequest(FXP_OPEN, data) - self.wasAFile[d] = (1, filename) # HACK - return d - - def removeFile(self, filename): - """ - Remove the given file. - - This method returns a Deferred that is called back when it succeeds. - - @param filename: the name of the file as a string. - """ - return self._sendRequest(FXP_REMOVE, NS(filename)) - - def renameFile(self, oldpath, newpath): - """ - Rename the given file. - - This method returns a Deferred that is called back when it succeeds. - - @param oldpath: the current location of the file. - @param newpath: the new file name. - """ - return self._sendRequest(FXP_RENAME, NS(oldpath)+NS(newpath)) - - def makeDirectory(self, path, attrs): - """ - Make a directory. - - This method returns a Deferred that is called back when it is - created. - - @param path: the name of the directory to create as a string. - - @param attrs: a dictionary of attributes to create the directory - with. Its meaning is the same as the attrs in the openFile method. - """ - return self._sendRequest(FXP_MKDIR, NS(path)+self._packAttributes(attrs)) - - def removeDirectory(self, path): - """ - Remove a directory (non-recursively) - - It is an error to remove a directory that has files or directories in - it. - - This method returns a Deferred that is called back when it is removed. - - @param path: the directory to remove. - """ - return self._sendRequest(FXP_RMDIR, NS(path)) - - def openDirectory(self, path): - """ - Open a directory for scanning. - - This method returns a Deferred that is called back with an iterable - object that has a close() method. - - The close() method is called when the client is finished reading - from the directory. At this point, the iterable will no longer - be used. - - The iterable returns triples of the form (filename, longname, attrs) - or a Deferred that returns the same. The sequence must support - __getitem__, but otherwise may be any 'sequence-like' object. - - filename is the name of the file relative to the directory. - logname is an expanded format of the filename. The recommended format - is: - -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer - 1234567890 123 12345678 12345678 12345678 123456789012 - - The first line is sample output, the second is the length of the field. - The fields are: permissions, link count, user owner, group owner, - size in bytes, modification time. - - attrs is a dictionary in the format of the attrs argument to openFile. - - @param path: the directory to open. - """ - d = self._sendRequest(FXP_OPENDIR, NS(path)) - self.wasAFile[d] = (0, path) - return d - - def getAttrs(self, path, followLinks=0): - """ - Return the attributes for the given path. - - This method returns a dictionary in the same format as the attrs - argument to openFile or a Deferred that is called back with same. - - @param path: the path to return attributes for as a string. - @param followLinks: a boolean. if it is True, follow symbolic links - and return attributes for the real path at the base. if it is False, - return attributes for the specified path. - """ - if followLinks: m = FXP_STAT - else: m = FXP_LSTAT - return self._sendRequest(m, NS(path)) - - def setAttrs(self, path, attrs): - """ - Set the attributes for the path. - - This method returns when the attributes are set or a Deferred that is - called back when they are. - - @param path: the path to set attributes for as a string. - @param attrs: a dictionary in the same format as the attrs argument to - openFile. - """ - data = NS(path) + self._packAttributes(attrs) - return self._sendRequest(FXP_SETSTAT, data) - - def readLink(self, path): - """ - Find the root of a set of symbolic links. - - This method returns the target of the link, or a Deferred that - returns the same. - - @param path: the path of the symlink to read. - """ - d = self._sendRequest(FXP_READLINK, NS(path)) - return d.addCallback(self._cbRealPath) - - def makeLink(self, linkPath, targetPath): - """ - Create a symbolic link. - - This method returns when the link is made, or a Deferred that - returns the same. - - @param linkPath: the pathname of the symlink as a string - @param targetPath: the path of the target of the link as a string. - """ - return self._sendRequest(FXP_SYMLINK, NS(linkPath)+NS(targetPath)) - - def realPath(self, path): - """ - Convert any path to an absolute path. - - This method returns the absolute path as a string, or a Deferred - that returns the same. - - @param path: the path to convert as a string. - """ - d = self._sendRequest(FXP_REALPATH, NS(path)) - return d.addCallback(self._cbRealPath) - - def _cbRealPath(self, result): - name, longname, attrs = result[0] - return name - - def extendedRequest(self, request, data): - """ - Make an extended request of the server. - - The method returns a Deferred that is called back with - the result of the extended request. - - @param request: the name of the extended request to make. - @param data: any other data that goes along with the request. - """ - return self._sendRequest(FXP_EXTENDED, NS(request) + data) - - def packet_VERSION(self, data): - version, = struct.unpack('!L', data[:4]) - data = data[4:] - d = {} - while data: - k, data = getNS(data) - v, data = getNS(data) - d[k]=v - self.version = version - self.gotServerVersion(version, d) - - def packet_STATUS(self, data): - d, data = self._parseRequest(data) - code, = struct.unpack('!L', data[:4]) - data = data[4:] - if len(data) >= 4: - msg, data = getNS(data) - if len(data) >= 4: - lang, data = getNS(data) - else: - lang = '' - else: - msg = '' - lang = '' - if code == FX_OK: - d.callback((msg, lang)) - elif code == FX_EOF: - d.errback(EOFError(msg)) - elif code == FX_OP_UNSUPPORTED: - d.errback(NotImplementedError(msg)) - else: - d.errback(SFTPError(code, msg, lang)) - - def packet_HANDLE(self, data): - d, data = self._parseRequest(data) - isFile, name = self.wasAFile.pop(d) - if isFile: - cb = ClientFile(self, getNS(data)[0]) - else: - cb = ClientDirectory(self, getNS(data)[0]) - cb.name = name - d.callback(cb) - - def packet_DATA(self, data): - d, data = self._parseRequest(data) - d.callback(getNS(data)[0]) - - def packet_NAME(self, data): - d, data = self._parseRequest(data) - count, = struct.unpack('!L', data[:4]) - data = data[4:] - files = [] - for i in range(count): - filename, data = getNS(data) - longname, data = getNS(data) - attrs, data = self._parseAttributes(data) - files.append((filename, longname, attrs)) - d.callback(files) - - def packet_ATTRS(self, data): - d, data = self._parseRequest(data) - d.callback(self._parseAttributes(data)[0]) - - def packet_EXTENDED_REPLY(self, data): - d, data = self._parseRequest(data) - d.callback(data) - - def gotServerVersion(self, serverVersion, extData): - """ - Called when the client sends their version info. - - @param otherVersion: an integer representing the version of the SFTP - protocol they are claiming. - @param extData: a dictionary of extended_name : extended_data items. - These items are sent by the client to indicate additional features. - """ - -class ClientFile: - - interface.implements(ISFTPFile) - - def __init__(self, parent, handle): - self.parent = parent - self.handle = NS(handle) - - def close(self): - return self.parent._sendRequest(FXP_CLOSE, self.handle) - - def readChunk(self, offset, length): - data = self.handle + struct.pack("!QL", offset, length) - return self.parent._sendRequest(FXP_READ, data) - - def writeChunk(self, offset, chunk): - data = self.handle + struct.pack("!Q", offset) + NS(chunk) - return self.parent._sendRequest(FXP_WRITE, data) - - def getAttrs(self): - return self.parent._sendRequest(FXP_FSTAT, self.handle) - - def setAttrs(self, attrs): - data = self.handle + self.parent._packAttributes(attrs) - return self.parent._sendRequest(FXP_FSTAT, data) - -class ClientDirectory: - - def __init__(self, parent, handle): - self.parent = parent - self.handle = NS(handle) - self.filesCache = [] - - def read(self): - d = self.parent._sendRequest(FXP_READDIR, self.handle) - return d - - def close(self): - return self.parent._sendRequest(FXP_CLOSE, self.handle) - - def __iter__(self): - return self - - def next(self): - if self.filesCache: - return self.filesCache.pop(0) - d = self.read() - d.addCallback(self._cbReadDir) - d.addErrback(self._ebReadDir) - return d - - def _cbReadDir(self, names): - self.filesCache = names[1:] - return names[0] - - def _ebReadDir(self, reason): - reason.trap(EOFError) - def _(): - raise StopIteration - self.next = _ - return reason - - -class SFTPError(Exception): - - def __init__(self, errorCode, errorMessage, lang = ''): - Exception.__init__(self) - self.code = errorCode - self._message = errorMessage - self.lang = lang - - - def message(self): - """ - A string received over the network that explains the error to a human. - """ - # Python 2.6 deprecates assigning to the 'message' attribute of an - # exception. We define this read-only property here in order to - # prevent the warning about deprecation while maintaining backwards - # compatibility with object clients that rely on the 'message' - # attribute being set correctly. See bug #3897. - return self._message - message = property(message) - - - def __str__(self): - return 'SFTPError %s: %s' % (self.code, self.message) - -FXP_INIT = 1 -FXP_VERSION = 2 -FXP_OPEN = 3 -FXP_CLOSE = 4 -FXP_READ = 5 -FXP_WRITE = 6 -FXP_LSTAT = 7 -FXP_FSTAT = 8 -FXP_SETSTAT = 9 -FXP_FSETSTAT = 10 -FXP_OPENDIR = 11 -FXP_READDIR = 12 -FXP_REMOVE = 13 -FXP_MKDIR = 14 -FXP_RMDIR = 15 -FXP_REALPATH = 16 -FXP_STAT = 17 -FXP_RENAME = 18 -FXP_READLINK = 19 -FXP_SYMLINK = 20 -FXP_STATUS = 101 -FXP_HANDLE = 102 -FXP_DATA = 103 -FXP_NAME = 104 -FXP_ATTRS = 105 -FXP_EXTENDED = 200 -FXP_EXTENDED_REPLY = 201 - -FILEXFER_ATTR_SIZE = 0x00000001 -FILEXFER_ATTR_UIDGID = 0x00000002 -FILEXFER_ATTR_OWNERGROUP = FILEXFER_ATTR_UIDGID -FILEXFER_ATTR_PERMISSIONS = 0x00000004 -FILEXFER_ATTR_ACMODTIME = 0x00000008 -FILEXFER_ATTR_EXTENDED = 0x80000000L - -FILEXFER_TYPE_REGULAR = 1 -FILEXFER_TYPE_DIRECTORY = 2 -FILEXFER_TYPE_SYMLINK = 3 -FILEXFER_TYPE_SPECIAL = 4 -FILEXFER_TYPE_UNKNOWN = 5 - -FXF_READ = 0x00000001 -FXF_WRITE = 0x00000002 -FXF_APPEND = 0x00000004 -FXF_CREAT = 0x00000008 -FXF_TRUNC = 0x00000010 -FXF_EXCL = 0x00000020 -FXF_TEXT = 0x00000040 - -FX_OK = 0 -FX_EOF = 1 -FX_NO_SUCH_FILE = 2 -FX_PERMISSION_DENIED = 3 -FX_FAILURE = 4 -FX_BAD_MESSAGE = 5 -FX_NO_CONNECTION = 6 -FX_CONNECTION_LOST = 7 -FX_OP_UNSUPPORTED = 8 -FX_FILE_ALREADY_EXISTS = 11 -# http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/ defines more -# useful error codes, but so far OpenSSH doesn't implement them. We use them -# internally for clarity, but for now define them all as FX_FAILURE to be -# compatible with existing software. -FX_NOT_A_DIRECTORY = FX_FAILURE -FX_FILE_IS_A_DIRECTORY = FX_FAILURE - - -# initialize FileTransferBase.packetTypes: -g = globals() -for name in g.keys(): - if name.startswith('FXP_'): - value = g[name] - FileTransferBase.packetTypes[value] = name[4:] -del g, name, value diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py deleted file mode 100755 index 753f9946..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/forwarding.py +++ /dev/null @@ -1,181 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -""" -This module contains the implementation of the TCP forwarding, which allows -clients and servers to forward arbitrary TCP data across the connection. - -Maintainer: Paul Swartz -""" - -import struct - -from twisted.internet import protocol, reactor -from twisted.python import log - -import common, channel - -class SSHListenForwardingFactory(protocol.Factory): - def __init__(self, connection, hostport, klass): - self.conn = connection - self.hostport = hostport # tuple - self.klass = klass - - def buildProtocol(self, addr): - channel = self.klass(conn = self.conn) - client = SSHForwardingClient(channel) - channel.client = client - addrTuple = (addr.host, addr.port) - channelOpenData = packOpen_direct_tcpip(self.hostport, addrTuple) - self.conn.openChannel(channel, channelOpenData) - return client - -class SSHListenForwardingChannel(channel.SSHChannel): - - def channelOpen(self, specificData): - log.msg('opened forwarding channel %s' % self.id) - if len(self.client.buf)>1: - b = self.client.buf[1:] - self.write(b) - self.client.buf = '' - - def openFailed(self, reason): - self.closed() - - def dataReceived(self, data): - self.client.transport.write(data) - - def eofReceived(self): - self.client.transport.loseConnection() - - def closed(self): - if hasattr(self, 'client'): - log.msg('closing local forwarding channel %s' % self.id) - self.client.transport.loseConnection() - del self.client - -class SSHListenClientForwardingChannel(SSHListenForwardingChannel): - - name = 'direct-tcpip' - -class SSHListenServerForwardingChannel(SSHListenForwardingChannel): - - name = 'forwarded-tcpip' - -class SSHConnectForwardingChannel(channel.SSHChannel): - - def __init__(self, hostport, *args, **kw): - channel.SSHChannel.__init__(self, *args, **kw) - self.hostport = hostport - self.client = None - self.clientBuf = '' - - def channelOpen(self, specificData): - cc = protocol.ClientCreator(reactor, SSHForwardingClient, self) - log.msg("connecting to %s:%i" % self.hostport) - cc.connectTCP(*self.hostport).addCallbacks(self._setClient, self._close) - - def _setClient(self, client): - self.client = client - log.msg("connected to %s:%i" % self.hostport) - if self.clientBuf: - self.client.transport.write(self.clientBuf) - self.clientBuf = None - if self.client.buf[1:]: - self.write(self.client.buf[1:]) - self.client.buf = '' - - def _close(self, reason): - log.msg("failed to connect: %s" % reason) - self.loseConnection() - - def dataReceived(self, data): - if self.client: - self.client.transport.write(data) - else: - self.clientBuf += data - - def closed(self): - if self.client: - log.msg('closed remote forwarding channel %s' % self.id) - if self.client.channel: - self.loseConnection() - self.client.transport.loseConnection() - del self.client - -def openConnectForwardingClient(remoteWindow, remoteMaxPacket, data, avatar): - remoteHP, origHP = unpackOpen_direct_tcpip(data) - return SSHConnectForwardingChannel(remoteHP, - remoteWindow=remoteWindow, - remoteMaxPacket=remoteMaxPacket, - avatar=avatar) - -class SSHForwardingClient(protocol.Protocol): - - def __init__(self, channel): - self.channel = channel - self.buf = '\000' - - def dataReceived(self, data): - if self.buf: - self.buf += data - else: - self.channel.write(data) - - def connectionLost(self, reason): - if self.channel: - self.channel.loseConnection() - self.channel = None - - -def packOpen_direct_tcpip((connHost, connPort), (origHost, origPort)): - """Pack the data suitable for sending in a CHANNEL_OPEN packet. - """ - conn = common.NS(connHost) + struct.pack('>L', connPort) - orig = common.NS(origHost) + struct.pack('>L', origPort) - return conn + orig - -packOpen_forwarded_tcpip = packOpen_direct_tcpip - -def unpackOpen_direct_tcpip(data): - """Unpack the data to a usable format. - """ - connHost, rest = common.getNS(data) - connPort = int(struct.unpack('>L', rest[:4])[0]) - origHost, rest = common.getNS(rest[4:]) - origPort = int(struct.unpack('>L', rest[:4])[0]) - return (connHost, connPort), (origHost, origPort) - -unpackOpen_forwarded_tcpip = unpackOpen_direct_tcpip - -def packGlobal_tcpip_forward((host, port)): - return common.NS(host) + struct.pack('>L', port) - -def unpackGlobal_tcpip_forward(data): - host, rest = common.getNS(data) - port = int(struct.unpack('>L', rest[:4])[0]) - return host, port - -"""This is how the data -> eof -> close stuff /should/ work. - -debug3: channel 1: waiting for connection -debug1: channel 1: connected -debug1: channel 1: read<=0 rfd 7 len 0 -debug1: channel 1: read failed -debug1: channel 1: close_read -debug1: channel 1: input open -> drain -debug1: channel 1: ibuf empty -debug1: channel 1: send eof -debug1: channel 1: input drain -> closed -debug1: channel 1: rcvd eof -debug1: channel 1: output open -> drain -debug1: channel 1: obuf empty -debug1: channel 1: close_write -debug1: channel 1: output drain -> closed -debug1: channel 1: rcvd close -debug3: channel 1: will not send data after close -debug1: channel 1: send close -debug1: channel 1: is dead -""" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py deleted file mode 100755 index 1c223517..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/keys.py +++ /dev/null @@ -1,809 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_keys -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Handling of RSA and DSA keys. - -Maintainer: U{Paul Swartz} -""" - -# base library imports -import base64 -import itertools - -# external library imports -from Crypto.Cipher import DES3, AES -from Crypto.PublicKey import RSA, DSA -from Crypto import Util -from pyasn1.type import univ -from pyasn1.codec.ber import decoder as berDecoder -from pyasn1.codec.ber import encoder as berEncoder - -# twisted -from twisted.python import randbytes -from twisted.python.hashlib import md5, sha1 - -# sibling imports -from twisted.conch.ssh import common, sexpy - - -class BadKeyError(Exception): - """ - Raised when a key isn't what we expected from it. - - XXX: we really need to check for bad keys - """ - - -class EncryptedKeyError(Exception): - """ - Raised when an encrypted key is presented to fromString/fromFile without - a password. - """ - - -class Key(object): - """ - An object representing a key. A key can be either a public or - private key. A public key can verify a signature; a private key can - create or verify a signature. To generate a string that can be stored - on disk, use the toString method. If you have a private key, but want - the string representation of the public key, use Key.public().toString(). - - @ivar keyObject: The C{Crypto.PublicKey.pubkey.pubkey} object that - operations are performed with. - """ - - def fromFile(Class, filename, type=None, passphrase=None): - """ - Return a Key object corresponding to the data in filename. type - and passphrase function as they do in fromString. - """ - return Class.fromString(file(filename, 'rb').read(), type, passphrase) - fromFile = classmethod(fromFile) - - def fromString(Class, data, type=None, passphrase=None): - """ - Return a Key object corresponding to the string data. - type is optionally the type of string, matching a _fromString_* - method. Otherwise, the _guessStringType() classmethod will be used - to guess a type. If the key is encrypted, passphrase is used as - the decryption key. - - @type data: C{str} - @type type: C{None}/C{str} - @type passphrase: C{None}/C{str} - @rtype: C{Key} - """ - if type is None: - type = Class._guessStringType(data) - if type is None: - raise BadKeyError('cannot guess the type of %r' % data) - method = getattr(Class, '_fromString_%s' % type.upper(), None) - if method is None: - raise BadKeyError('no _fromString method for %s' % type) - if method.func_code.co_argcount == 2: # no passphrase - if passphrase: - raise BadKeyError('key not encrypted') - return method(data) - else: - return method(data, passphrase) - fromString = classmethod(fromString) - - def _fromString_BLOB(Class, blob): - """ - Return a public key object corresponding to this public key blob. - The format of a RSA public key blob is:: - string 'ssh-rsa' - integer e - integer n - - The format of a DSA public key blob is:: - string 'ssh-dss' - integer p - integer q - integer g - integer y - - @type blob: C{str} - @return: a C{Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the key type (the first string) is unknown. - """ - keyType, rest = common.getNS(blob) - if keyType == 'ssh-rsa': - e, n, rest = common.getMP(rest, 2) - return Class(RSA.construct((n, e))) - elif keyType == 'ssh-dss': - p, q, g, y, rest = common.getMP(rest, 4) - return Class(DSA.construct((y, g, p, q))) - else: - raise BadKeyError('unknown blob type: %s' % keyType) - _fromString_BLOB = classmethod(_fromString_BLOB) - - def _fromString_PRIVATE_BLOB(Class, blob): - """ - Return a private key object corresponding to this private key blob. - The blob formats are as follows: - - RSA keys:: - string 'ssh-rsa' - integer n - integer e - integer d - integer u - integer p - integer q - - DSA keys:: - string 'ssh-dss' - integer p - integer q - integer g - integer y - integer x - - @type blob: C{str} - @return: a C{Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the key type (the first string) is unknown. - """ - keyType, rest = common.getNS(blob) - - if keyType == 'ssh-rsa': - n, e, d, u, p, q, rest = common.getMP(rest, 6) - rsakey = Class(RSA.construct((n, e, d, p, q, u))) - return rsakey - elif keyType == 'ssh-dss': - p, q, g, y, x, rest = common.getMP(rest, 5) - dsakey = Class(DSA.construct((y, g, p, q, x))) - return dsakey - else: - raise BadKeyError('unknown blob type: %s' % keyType) - _fromString_PRIVATE_BLOB = classmethod(_fromString_PRIVATE_BLOB) - - def _fromString_PUBLIC_OPENSSH(Class, data): - """ - Return a public key object corresponding to this OpenSSH public key - string. The format of an OpenSSH public key string is:: - <key type> <base64-encoded public key blob> - - @type data: C{str} - @return: A {Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the blob type is unknown. - """ - blob = base64.decodestring(data.split()[1]) - return Class._fromString_BLOB(blob) - _fromString_PUBLIC_OPENSSH = classmethod(_fromString_PUBLIC_OPENSSH) - - def _fromString_PRIVATE_OPENSSH(Class, data, passphrase): - """ - Return a private key object corresponding to this OpenSSH private key - string. If the key is encrypted, passphrase MUST be provided. - Providing a passphrase for an unencrypted key is an error. - - The format of an OpenSSH private key string is:: - -----BEGIN <key type> PRIVATE KEY----- - [Proc-Type: 4,ENCRYPTED - DEK-Info: DES-EDE3-CBC,<initialization value>] - <base64-encoded ASN.1 structure> - ------END <key type> PRIVATE KEY------ - - The ASN.1 structure of a RSA key is:: - (0, n, e, d, p, q) - - The ASN.1 structure of a DSA key is:: - (0, p, q, g, y, x) - - @type data: C{str} - @type passphrase: C{str} - @return: a C{Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if - * a passphrase is provided for an unencrypted key - * a passphrase is not provided for an encrypted key - * the ASN.1 encoding is incorrect - """ - lines = data.strip().split('\n') - kind = lines[0][11:14] - if lines[1].startswith('Proc-Type: 4,ENCRYPTED'): # encrypted key - try: - _, cipher_iv_info = lines[2].split(' ', 1) - cipher, ivdata = cipher_iv_info.rstrip().split(',', 1) - except ValueError: - raise BadKeyError('invalid DEK-info %r' % lines[2]) - if cipher == 'AES-128-CBC': - CipherClass = AES - keySize = 16 - if len(ivdata) != 32: - raise BadKeyError('AES encrypted key with a bad IV') - elif cipher == 'DES-EDE3-CBC': - CipherClass = DES3 - keySize = 24 - if len(ivdata) != 16: - raise BadKeyError('DES encrypted key with a bad IV') - else: - raise BadKeyError('unknown encryption type %r' % cipher) - iv = ''.join([chr(int(ivdata[i:i + 2], 16)) - for i in range(0, len(ivdata), 2)]) - if not passphrase: - raise EncryptedKeyError('encrypted key with no passphrase') - ba = md5(passphrase + iv[:8]).digest() - bb = md5(ba + passphrase + iv[:8]).digest() - decKey = (ba + bb)[:keySize] - b64Data = base64.decodestring(''.join(lines[3:-1])) - keyData = CipherClass.new(decKey, - CipherClass.MODE_CBC, - iv).decrypt(b64Data) - removeLen = ord(keyData[-1]) - keyData = keyData[:-removeLen] - else: - b64Data = ''.join(lines[1:-1]) - keyData = base64.decodestring(b64Data) - try: - decodedKey = berDecoder.decode(keyData)[0] - except Exception: - raise BadKeyError('something wrong with decode') - if kind == 'RSA': - if len(decodedKey) == 2: # alternate RSA key - decodedKey = decodedKey[0] - if len(decodedKey) < 6: - raise BadKeyError('RSA key failed to decode properly') - n, e, d, p, q = [long(value) for value in decodedKey[1:6]] - if p > q: # make p smaller than q - p, q = q, p - return Class(RSA.construct((n, e, d, p, q))) - elif kind == 'DSA': - p, q, g, y, x = [long(value) for value in decodedKey[1: 6]] - if len(decodedKey) < 6: - raise BadKeyError('DSA key failed to decode properly') - return Class(DSA.construct((y, g, p, q, x))) - _fromString_PRIVATE_OPENSSH = classmethod(_fromString_PRIVATE_OPENSSH) - - def _fromString_PUBLIC_LSH(Class, data): - """ - Return a public key corresponding to this LSH public key string. - The LSH public key string format is:: - <s-expression: ('public-key', (<key type>, (<name, <value>)+))> - - The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e. - The names for a DSA (key type 'dsa') key are: y, g, p, q. - - @type data: C{str} - @return: a C{Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the key type is unknown - """ - sexp = sexpy.parse(base64.decodestring(data[1:-1])) - assert sexp[0] == 'public-key' - kd = {} - for name, data in sexp[1][1:]: - kd[name] = common.getMP(common.NS(data))[0] - if sexp[1][0] == 'dsa': - return Class(DSA.construct((kd['y'], kd['g'], kd['p'], kd['q']))) - elif sexp[1][0] == 'rsa-pkcs1-sha1': - return Class(RSA.construct((kd['n'], kd['e']))) - else: - raise BadKeyError('unknown lsh key type %s' % sexp[1][0]) - _fromString_PUBLIC_LSH = classmethod(_fromString_PUBLIC_LSH) - - def _fromString_PRIVATE_LSH(Class, data): - """ - Return a private key corresponding to this LSH private key string. - The LSH private key string format is:: - <s-expression: ('private-key', (<key type>, (<name>, <value>)+))> - - The names for a RSA (key type 'rsa-pkcs1-sha1') key are: n, e, d, p, q. - The names for a DSA (key type 'dsa') key are: y, g, p, q, x. - - @type data: C{str} - @return: a {Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the key type is unknown - """ - sexp = sexpy.parse(data) - assert sexp[0] == 'private-key' - kd = {} - for name, data in sexp[1][1:]: - kd[name] = common.getMP(common.NS(data))[0] - if sexp[1][0] == 'dsa': - assert len(kd) == 5, len(kd) - return Class(DSA.construct((kd['y'], kd['g'], kd['p'], - kd['q'], kd['x']))) - elif sexp[1][0] == 'rsa-pkcs1': - assert len(kd) == 8, len(kd) - if kd['p'] > kd['q']: # make p smaller than q - kd['p'], kd['q'] = kd['q'], kd['p'] - return Class(RSA.construct((kd['n'], kd['e'], kd['d'], - kd['p'], kd['q']))) - else: - raise BadKeyError('unknown lsh key type %s' % sexp[1][0]) - _fromString_PRIVATE_LSH = classmethod(_fromString_PRIVATE_LSH) - - def _fromString_AGENTV3(Class, data): - """ - Return a private key object corresponsing to the Secure Shell Key - Agent v3 format. - - The SSH Key Agent v3 format for a RSA key is:: - string 'ssh-rsa' - integer e - integer d - integer n - integer u - integer p - integer q - - The SSH Key Agent v3 format for a DSA key is:: - string 'ssh-dss' - integer p - integer q - integer g - integer y - integer x - - @type data: C{str} - @return: a C{Crypto.PublicKey.pubkey.pubkey} object - @raises BadKeyError: if the key type (the first string) is unknown - """ - keyType, data = common.getNS(data) - if keyType == 'ssh-dss': - p, data = common.getMP(data) - q, data = common.getMP(data) - g, data = common.getMP(data) - y, data = common.getMP(data) - x, data = common.getMP(data) - return Class(DSA.construct((y, g, p, q, x))) - elif keyType == 'ssh-rsa': - e, data = common.getMP(data) - d, data = common.getMP(data) - n, data = common.getMP(data) - u, data = common.getMP(data) - p, data = common.getMP(data) - q, data = common.getMP(data) - return Class(RSA.construct((n, e, d, p, q, u))) - else: - raise BadKeyError("unknown key type %s" % keyType) - _fromString_AGENTV3 = classmethod(_fromString_AGENTV3) - - def _guessStringType(Class, data): - """ - Guess the type of key in data. The types map to _fromString_* - methods. - """ - if data.startswith('ssh-'): - return 'public_openssh' - elif data.startswith('-----BEGIN'): - return 'private_openssh' - elif data.startswith('{'): - return 'public_lsh' - elif data.startswith('('): - return 'private_lsh' - elif data.startswith('\x00\x00\x00\x07ssh-'): - ignored, rest = common.getNS(data) - count = 0 - while rest: - count += 1 - ignored, rest = common.getMP(rest) - if count > 4: - return 'agentv3' - else: - return 'blob' - _guessStringType = classmethod(_guessStringType) - - def __init__(self, keyObject): - """ - Initialize a PublicKey with a C{Crypto.PublicKey.pubkey.pubkey} - object. - - @type keyObject: C{Crypto.PublicKey.pubkey.pubkey} - """ - self.keyObject = keyObject - - def __eq__(self, other): - """ - Return True if other represents an object with the same key. - """ - if type(self) == type(other): - return self.type() == other.type() and self.data() == other.data() - else: - return NotImplemented - - def __ne__(self, other): - """ - Return True if other represents anything other than this key. - """ - result = self.__eq__(other) - if result == NotImplemented: - return result - return not result - - def __repr__(self): - """ - Return a pretty representation of this object. - """ - lines = [ - '<%s %s (%s bits)' % ( - self.type(), - self.isPublic() and 'Public Key' or 'Private Key', - self.keyObject.size())] - for k, v in sorted(self.data().items()): - lines.append('attr %s:' % k) - by = common.MP(v)[4:] - while by: - m = by[:15] - by = by[15:] - o = '' - for c in m: - o = o + '%02x:' % ord(c) - if len(m) < 15: - o = o[:-1] - lines.append('\t' + o) - lines[-1] = lines[-1] + '>' - return '\n'.join(lines) - - def isPublic(self): - """ - Returns True if this Key is a public key. - """ - return not self.keyObject.has_private() - - def public(self): - """ - Returns a version of this key containing only the public key data. - If this is a public key, this may or may not be the same object - as self. - """ - return Key(self.keyObject.publickey()) - - def fingerprint(self): - """ - Get the user presentation of the fingerprint of this L{Key}. As - described by U{RFC 4716 section - 4<http://tools.ietf.org/html/rfc4716#section-4>}:: - - The fingerprint of a public key consists of the output of the MD5 - message-digest algorithm [RFC1321]. The input to the algorithm is - the public key data as specified by [RFC4253]. (...) The output - of the (MD5) algorithm is presented to the user as a sequence of 16 - octets printed as hexadecimal with lowercase letters and separated - by colons. - - @since: 8.2 - - @return: the user presentation of this L{Key}'s fingerprint, as a - string. - - @rtype: L{str} - """ - return ':'.join([x.encode('hex') for x in md5(self.blob()).digest()]) - - def type(self): - """ - Return the type of the object we wrap. Currently this can only be - 'RSA' or 'DSA'. - """ - # the class is Crypto.PublicKey.<type>.<stuff we don't care about> - mod = self.keyObject.__class__.__module__ - if mod.startswith('Crypto.PublicKey'): - type = mod.split('.')[2] - else: - raise RuntimeError('unknown type of object: %r' % self.keyObject) - if type in ('RSA', 'DSA'): - return type - else: - raise RuntimeError('unknown type of key: %s' % type) - - def sshType(self): - """ - Return the type of the object we wrap as defined in the ssh protocol. - Currently this can only be 'ssh-rsa' or 'ssh-dss'. - """ - return {'RSA': 'ssh-rsa', 'DSA': 'ssh-dss'}[self.type()] - - def data(self): - """ - Return the values of the public key as a dictionary. - - @rtype: C{dict} - """ - keyData = {} - for name in self.keyObject.keydata: - value = getattr(self.keyObject, name, None) - if value is not None: - keyData[name] = value - return keyData - - def blob(self): - """ - Return the public key blob for this key. The blob is the - over-the-wire format for public keys: - - RSA keys:: - string 'ssh-rsa' - integer e - integer n - - DSA keys:: - string 'ssh-dss' - integer p - integer q - integer g - integer y - - @rtype: C{str} - """ - type = self.type() - data = self.data() - if type == 'RSA': - return (common.NS('ssh-rsa') + common.MP(data['e']) + - common.MP(data['n'])) - elif type == 'DSA': - return (common.NS('ssh-dss') + common.MP(data['p']) + - common.MP(data['q']) + common.MP(data['g']) + - common.MP(data['y'])) - - def privateBlob(self): - """ - Return the private key blob for this key. The blob is the - over-the-wire format for private keys: - - RSA keys:: - string 'ssh-rsa' - integer n - integer e - integer d - integer u - integer p - integer q - - DSA keys:: - string 'ssh-dss' - integer p - integer q - integer g - integer y - integer x - """ - type = self.type() - data = self.data() - if type == 'RSA': - return (common.NS('ssh-rsa') + common.MP(data['n']) + - common.MP(data['e']) + common.MP(data['d']) + - common.MP(data['u']) + common.MP(data['p']) + - common.MP(data['q'])) - elif type == 'DSA': - return (common.NS('ssh-dss') + common.MP(data['p']) + - common.MP(data['q']) + common.MP(data['g']) + - common.MP(data['y']) + common.MP(data['x'])) - - def toString(self, type, extra=None): - """ - Create a string representation of this key. If the key is a private - key and you want the represenation of its public key, use - C{key.public().toString()}. type maps to a _toString_* method. - - @param type: The type of string to emit. Currently supported values - are C{'OPENSSH'}, C{'LSH'}, and C{'AGENTV3'}. - @type type: L{str} - - @param extra: Any extra data supported by the selected format which - is not part of the key itself. For public OpenSSH keys, this is - a comment. For private OpenSSH keys, this is a passphrase to - encrypt with. - @type extra: L{str} or L{NoneType} - - @rtype: L{str} - """ - method = getattr(self, '_toString_%s' % type.upper(), None) - if method is None: - raise BadKeyError('unknown type: %s' % type) - if method.func_code.co_argcount == 2: - return method(extra) - else: - return method() - - def _toString_OPENSSH(self, extra): - """ - Return a public or private OpenSSH string. See - _fromString_PUBLIC_OPENSSH and _fromString_PRIVATE_OPENSSH for the - string formats. If extra is present, it represents a comment for a - public key, or a passphrase for a private key. - - @type extra: C{str} - @rtype: C{str} - """ - data = self.data() - if self.isPublic(): - b64Data = base64.encodestring(self.blob()).replace('\n', '') - if not extra: - extra = '' - return ('%s %s %s' % (self.sshType(), b64Data, extra)).strip() - else: - lines = ['-----BEGIN %s PRIVATE KEY-----' % self.type()] - if self.type() == 'RSA': - p, q = data['p'], data['q'] - objData = (0, data['n'], data['e'], data['d'], q, p, - data['d'] % (q - 1), data['d'] % (p - 1), - data['u']) - else: - objData = (0, data['p'], data['q'], data['g'], data['y'], - data['x']) - asn1Sequence = univ.Sequence() - for index, value in itertools.izip(itertools.count(), objData): - asn1Sequence.setComponentByPosition(index, univ.Integer(value)) - asn1Data = berEncoder.encode(asn1Sequence) - if extra: - iv = randbytes.secureRandom(8) - hexiv = ''.join(['%02X' % ord(x) for x in iv]) - lines.append('Proc-Type: 4,ENCRYPTED') - lines.append('DEK-Info: DES-EDE3-CBC,%s\n' % hexiv) - ba = md5(extra + iv).digest() - bb = md5(ba + extra + iv).digest() - encKey = (ba + bb)[:24] - padLen = 8 - (len(asn1Data) % 8) - asn1Data += (chr(padLen) * padLen) - asn1Data = DES3.new(encKey, DES3.MODE_CBC, - iv).encrypt(asn1Data) - b64Data = base64.encodestring(asn1Data).replace('\n', '') - lines += [b64Data[i:i + 64] for i in range(0, len(b64Data), 64)] - lines.append('-----END %s PRIVATE KEY-----' % self.type()) - return '\n'.join(lines) - - def _toString_LSH(self): - """ - Return a public or private LSH key. See _fromString_PUBLIC_LSH and - _fromString_PRIVATE_LSH for the key formats. - - @rtype: C{str} - """ - data = self.data() - if self.isPublic(): - if self.type() == 'RSA': - keyData = sexpy.pack([['public-key', - ['rsa-pkcs1-sha1', - ['n', common.MP(data['n'])[4:]], - ['e', common.MP(data['e'])[4:]]]]]) - elif self.type() == 'DSA': - keyData = sexpy.pack([['public-key', - ['dsa', - ['p', common.MP(data['p'])[4:]], - ['q', common.MP(data['q'])[4:]], - ['g', common.MP(data['g'])[4:]], - ['y', common.MP(data['y'])[4:]]]]]) - return '{' + base64.encodestring(keyData).replace('\n', '') + '}' - else: - if self.type() == 'RSA': - p, q = data['p'], data['q'] - return sexpy.pack([['private-key', - ['rsa-pkcs1', - ['n', common.MP(data['n'])[4:]], - ['e', common.MP(data['e'])[4:]], - ['d', common.MP(data['d'])[4:]], - ['p', common.MP(q)[4:]], - ['q', common.MP(p)[4:]], - ['a', common.MP(data['d'] % (q - 1))[4:]], - ['b', common.MP(data['d'] % (p - 1))[4:]], - ['c', common.MP(data['u'])[4:]]]]]) - elif self.type() == 'DSA': - return sexpy.pack([['private-key', - ['dsa', - ['p', common.MP(data['p'])[4:]], - ['q', common.MP(data['q'])[4:]], - ['g', common.MP(data['g'])[4:]], - ['y', common.MP(data['y'])[4:]], - ['x', common.MP(data['x'])[4:]]]]]) - - def _toString_AGENTV3(self): - """ - Return a private Secure Shell Agent v3 key. See - _fromString_AGENTV3 for the key format. - - @rtype: C{str} - """ - data = self.data() - if not self.isPublic(): - if self.type() == 'RSA': - values = (data['e'], data['d'], data['n'], data['u'], - data['p'], data['q']) - elif self.type() == 'DSA': - values = (data['p'], data['q'], data['g'], data['y'], - data['x']) - return common.NS(self.sshType()) + ''.join(map(common.MP, values)) - - def sign(self, data): - """ - Returns a signature with this Key. - - @type data: C{str} - @rtype: C{str} - """ - if self.type() == 'RSA': - digest = pkcs1Digest(data, self.keyObject.size() / 8) - signature = self.keyObject.sign(digest, '')[0] - ret = common.NS(Util.number.long_to_bytes(signature)) - elif self.type() == 'DSA': - digest = sha1(data).digest() - randomBytes = randbytes.secureRandom(19) - sig = self.keyObject.sign(digest, randomBytes) - # SSH insists that the DSS signature blob be two 160-bit integers - # concatenated together. The sig[0], [1] numbers from obj.sign - # are just numbers, and could be any length from 0 to 160 bits. - # Make sure they are padded out to 160 bits (20 bytes each) - ret = common.NS(Util.number.long_to_bytes(sig[0], 20) + - Util.number.long_to_bytes(sig[1], 20)) - return common.NS(self.sshType()) + ret - - def verify(self, signature, data): - """ - Returns true if the signature for data is valid for this Key. - - @type signature: C{str} - @type data: C{str} - @rtype: C{bool} - """ - if len(signature) == 40: - # DSA key with no padding - signatureType, signature = 'ssh-dss', common.NS(signature) - else: - signatureType, signature = common.getNS(signature) - if signatureType != self.sshType(): - return False - if self.type() == 'RSA': - numbers = common.getMP(signature) - digest = pkcs1Digest(data, self.keyObject.size() / 8) - elif self.type() == 'DSA': - signature = common.getNS(signature)[0] - numbers = [Util.number.bytes_to_long(n) for n in signature[:20], - signature[20:]] - digest = sha1(data).digest() - return self.keyObject.verify(digest, numbers) - - -def objectType(obj): - """ - Return the SSH key type corresponding to a - C{Crypto.PublicKey.pubkey.pubkey} object. - - @type obj: C{Crypto.PublicKey.pubkey.pubkey} - @rtype: C{str} - """ - keyDataMapping = { - ('n', 'e', 'd', 'p', 'q'): 'ssh-rsa', - ('n', 'e', 'd', 'p', 'q', 'u'): 'ssh-rsa', - ('y', 'g', 'p', 'q', 'x'): 'ssh-dss' - } - try: - return keyDataMapping[tuple(obj.keydata)] - except (KeyError, AttributeError): - raise BadKeyError("invalid key object", obj) - - -def pkcs1Pad(data, messageLength): - """ - Pad out data to messageLength according to the PKCS#1 standard. - @type data: C{str} - @type messageLength: C{int} - """ - lenPad = messageLength - 2 - len(data) - return '\x01' + ('\xff' * lenPad) + '\x00' + data - - -def pkcs1Digest(data, messageLength): - """ - Create a message digest using the SHA1 hash algorithm according to the - PKCS#1 standard. - @type data: C{str} - @type messageLength: C{str} - """ - digest = sha1(data).digest() - return pkcs1Pad(ID_SHA1 + digest, messageLength) - - -def lenSig(obj): - """ - Return the length of the signature in bytes for a key object. - - @type obj: C{Crypto.PublicKey.pubkey.pubkey} - @rtype: C{long} - """ - return obj.size() / 8 - - -ID_SHA1 = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14' diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py deleted file mode 100755 index b5477c4f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/service.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -The parent class for all the SSH services. Currently implemented services -are ssh-userauth and ssh-connection. - -Maintainer: Paul Swartz -""" - - -from twisted.python import log - -class SSHService(log.Logger): - name = None # this is the ssh name for the service - protocolMessages = {} # these map #'s -> protocol names - transport = None # gets set later - - def serviceStarted(self): - """ - called when the service is active on the transport. - """ - - def serviceStopped(self): - """ - called when the service is stopped, either by the connection ending - or by another service being started - """ - - def logPrefix(self): - return "SSHService %s on %s" % (self.name, - self.transport.transport.logPrefix()) - - def packetReceived(self, messageNum, packet): - """ - called when we receive a packet on the transport - """ - #print self.protocolMessages - if messageNum in self.protocolMessages: - messageType = self.protocolMessages[messageNum] - f = getattr(self,'ssh_%s' % messageType[4:], - None) - if f is not None: - return f(packet) - log.msg("couldn't handle %r" % messageNum) - log.msg(repr(packet)) - self.transport.sendUnimplemented() - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py deleted file mode 100755 index e9eca3eb..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/session.py +++ /dev/null @@ -1,348 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_session -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -This module contains the implementation of SSHSession, which (by default) -allows access to a shell and a python interpreter over SSH. - -Maintainer: Paul Swartz -""" - -import struct -import signal -import sys -import os -from zope.interface import implements - -from twisted.internet import interfaces, protocol -from twisted.python import log -from twisted.conch.interfaces import ISession -from twisted.conch.ssh import common, channel - -class SSHSession(channel.SSHChannel): - - name = 'session' - def __init__(self, *args, **kw): - channel.SSHChannel.__init__(self, *args, **kw) - self.buf = '' - self.client = None - self.session = None - - def request_subsystem(self, data): - subsystem, ignored= common.getNS(data) - log.msg('asking for subsystem "%s"' % subsystem) - client = self.avatar.lookupSubsystem(subsystem, data) - if client: - pp = SSHSessionProcessProtocol(self) - proto = wrapProcessProtocol(pp) - client.makeConnection(proto) - pp.makeConnection(wrapProtocol(client)) - self.client = pp - return 1 - else: - log.msg('failed to get subsystem') - return 0 - - def request_shell(self, data): - log.msg('getting shell') - if not self.session: - self.session = ISession(self.avatar) - try: - pp = SSHSessionProcessProtocol(self) - self.session.openShell(pp) - except: - log.deferr() - return 0 - else: - self.client = pp - return 1 - - def request_exec(self, data): - if not self.session: - self.session = ISession(self.avatar) - f,data = common.getNS(data) - log.msg('executing command "%s"' % f) - try: - pp = SSHSessionProcessProtocol(self) - self.session.execCommand(pp, f) - except: - log.deferr() - return 0 - else: - self.client = pp - return 1 - - def request_pty_req(self, data): - if not self.session: - self.session = ISession(self.avatar) - term, windowSize, modes = parseRequest_pty_req(data) - log.msg('pty request: %s %s' % (term, windowSize)) - try: - self.session.getPty(term, windowSize, modes) - except: - log.err() - return 0 - else: - return 1 - - def request_window_change(self, data): - if not self.session: - self.session = ISession(self.avatar) - winSize = parseRequest_window_change(data) - try: - self.session.windowChanged(winSize) - except: - log.msg('error changing window size') - log.err() - return 0 - else: - return 1 - - def dataReceived(self, data): - if not self.client: - #self.conn.sendClose(self) - self.buf += data - return - self.client.transport.write(data) - - def extReceived(self, dataType, data): - if dataType == connection.EXTENDED_DATA_STDERR: - if self.client and hasattr(self.client.transport, 'writeErr'): - self.client.transport.writeErr(data) - else: - log.msg('weird extended data: %s'%dataType) - - def eofReceived(self): - if self.session: - self.session.eofReceived() - elif self.client: - self.conn.sendClose(self) - - def closed(self): - if self.session: - self.session.closed() - elif self.client: - self.client.transport.loseConnection() - - #def closeReceived(self): - # self.loseConnection() # don't know what to do with this - - def loseConnection(self): - if self.client: - self.client.transport.loseConnection() - channel.SSHChannel.loseConnection(self) - -class _ProtocolWrapper(protocol.ProcessProtocol): - """ - This class wraps a L{Protocol} instance in a L{ProcessProtocol} instance. - """ - def __init__(self, proto): - self.proto = proto - - def connectionMade(self): self.proto.connectionMade() - - def outReceived(self, data): self.proto.dataReceived(data) - - def processEnded(self, reason): self.proto.connectionLost(reason) - -class _DummyTransport: - - def __init__(self, proto): - self.proto = proto - - def dataReceived(self, data): - self.proto.transport.write(data) - - def write(self, data): - self.proto.dataReceived(data) - - def writeSequence(self, seq): - self.write(''.join(seq)) - - def loseConnection(self): - self.proto.connectionLost(protocol.connectionDone) - -def wrapProcessProtocol(inst): - if isinstance(inst, protocol.Protocol): - return _ProtocolWrapper(inst) - else: - return inst - -def wrapProtocol(proto): - return _DummyTransport(proto) - - - -# SUPPORTED_SIGNALS is a list of signals that every session channel is supposed -# to accept. See RFC 4254 -SUPPORTED_SIGNALS = ["ABRT", "ALRM", "FPE", "HUP", "ILL", "INT", "KILL", - "PIPE", "QUIT", "SEGV", "TERM", "USR1", "USR2"] - - - -class SSHSessionProcessProtocol(protocol.ProcessProtocol): - """I am both an L{IProcessProtocol} and an L{ITransport}. - - I am a transport to the remote endpoint and a process protocol to the - local subsystem. - """ - - implements(interfaces.ITransport) - - # once initialized, a dictionary mapping signal values to strings - # that follow RFC 4254. - _signalValuesToNames = None - - def __init__(self, session): - self.session = session - self.lostOutOrErrFlag = False - - def connectionMade(self): - if self.session.buf: - self.transport.write(self.session.buf) - self.session.buf = None - - def outReceived(self, data): - self.session.write(data) - - def errReceived(self, err): - self.session.writeExtended(connection.EXTENDED_DATA_STDERR, err) - - def outConnectionLost(self): - """ - EOF should only be sent when both STDOUT and STDERR have been closed. - """ - if self.lostOutOrErrFlag: - self.session.conn.sendEOF(self.session) - else: - self.lostOutOrErrFlag = True - - def errConnectionLost(self): - """ - See outConnectionLost(). - """ - self.outConnectionLost() - - def connectionLost(self, reason = None): - self.session.loseConnection() - - - def _getSignalName(self, signum): - """ - Get a signal name given a signal number. - """ - if self._signalValuesToNames is None: - self._signalValuesToNames = {} - # make sure that the POSIX ones are the defaults - for signame in SUPPORTED_SIGNALS: - signame = 'SIG' + signame - sigvalue = getattr(signal, signame, None) - if sigvalue is not None: - self._signalValuesToNames[sigvalue] = signame - for k, v in signal.__dict__.items(): - # Check for platform specific signals, ignoring Python specific - # SIG_DFL and SIG_IGN - if k.startswith('SIG') and not k.startswith('SIG_'): - if v not in self._signalValuesToNames: - self._signalValuesToNames[v] = k + '@' + sys.platform - return self._signalValuesToNames[signum] - - - def processEnded(self, reason=None): - """ - When we are told the process ended, try to notify the other side about - how the process ended using the exit-signal or exit-status requests. - Also, close the channel. - """ - if reason is not None: - err = reason.value - if err.signal is not None: - signame = self._getSignalName(err.signal) - if (getattr(os, 'WCOREDUMP', None) is not None and - os.WCOREDUMP(err.status)): - log.msg('exitSignal: %s (core dumped)' % (signame,)) - coreDumped = 1 - else: - log.msg('exitSignal: %s' % (signame,)) - coreDumped = 0 - self.session.conn.sendRequest(self.session, 'exit-signal', - common.NS(signame[3:]) + chr(coreDumped) + - common.NS('') + common.NS('')) - elif err.exitCode is not None: - log.msg('exitCode: %r' % (err.exitCode,)) - self.session.conn.sendRequest(self.session, 'exit-status', - struct.pack('>L', err.exitCode)) - self.session.loseConnection() - - - def getHost(self): - """ - Return the host from my session's transport. - """ - return self.session.conn.transport.getHost() - - - def getPeer(self): - """ - Return the peer from my session's transport. - """ - return self.session.conn.transport.getPeer() - - - def write(self, data): - self.session.write(data) - - - def writeSequence(self, seq): - self.session.write(''.join(seq)) - - - def loseConnection(self): - self.session.loseConnection() - - - -class SSHSessionClient(protocol.Protocol): - - def dataReceived(self, data): - if self.transport: - self.transport.write(data) - -# methods factored out to make live easier on server writers -def parseRequest_pty_req(data): - """Parse the data from a pty-req request into usable data. - - @returns: a tuple of (terminal type, (rows, cols, xpixel, ypixel), modes) - """ - term, rest = common.getNS(data) - cols, rows, xpixel, ypixel = struct.unpack('>4L', rest[: 16]) - modes, ignored= common.getNS(rest[16:]) - winSize = (rows, cols, xpixel, ypixel) - modes = [(ord(modes[i]), struct.unpack('>L', modes[i+1: i+5])[0]) for i in range(0, len(modes)-1, 5)] - return term, winSize, modes - -def packRequest_pty_req(term, (rows, cols, xpixel, ypixel), modes): - """Pack a pty-req request so that it is suitable for sending. - - NOTE: modes must be packed before being sent here. - """ - termPacked = common.NS(term) - winSizePacked = struct.pack('>4L', cols, rows, xpixel, ypixel) - modesPacked = common.NS(modes) # depend on the client packing modes - return termPacked + winSizePacked + modesPacked - -def parseRequest_window_change(data): - """Parse the data from a window-change request into usuable data. - - @returns: a tuple of (rows, cols, xpixel, ypixel) - """ - cols, rows, xpixel, ypixel = struct.unpack('>4L', data) - return rows, cols, xpixel, ypixel - -def packRequest_window_change((rows, cols, xpixel, ypixel)): - """Pack a window-change request so that it is suitable for sending. - """ - return struct.pack('>4L', cols, rows, xpixel, ypixel) - -import connection diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py deleted file mode 100755 index 60c43289..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/sexpy.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -def parse(s): - s = s.strip() - expr = [] - while s: - if s[0] == '(': - newSexp = [] - if expr: - expr[-1].append(newSexp) - expr.append(newSexp) - s = s[1:] - continue - if s[0] == ')': - aList = expr.pop() - s=s[1:] - if not expr: - assert not s - return aList - continue - i = 0 - while s[i].isdigit(): i+=1 - assert i - length = int(s[:i]) - data = s[i+1:i+1+length] - expr[-1].append(data) - s=s[i+1+length:] - assert 0, "this should not happen" - -def pack(sexp): - s = "" - for o in sexp: - if type(o) in (type(()), type([])): - s+='(' - s+=pack(o) - s+=')' - else: - s+='%i:%s' % (len(o), o) - return s diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py deleted file mode 100755 index 9e0c753f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/transport.py +++ /dev/null @@ -1,1617 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_transport -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -The lowest level SSH protocol. This handles the key negotiation, the -encryption and the compression. The transport layer is described in -RFC 4253. - -Maintainer: Paul Swartz -""" - -# base library imports -import struct -import zlib -import array - -# external library imports -from Crypto import Util -from Crypto.Cipher import XOR - -# twisted imports -from twisted.internet import protocol, defer - -from twisted.conch import error -from twisted.python import log, randbytes -from twisted.python.hashlib import md5, sha1 - - -# sibling imports -from twisted.conch.ssh import address, keys -from twisted.conch.ssh.common import NS, getNS, MP, getMP, _MPpow, ffs - - -def _getRandomNumber(random, bits): - """ - Generate a random number in the range [0, 2 ** bits). - - @param bits: The number of bits in the result. - @type bits: C{int} - - @rtype: C{int} or C{long} - @return: The newly generated random number. - - @raise ValueError: if C{bits} is not a multiple of 8. - """ - if bits % 8: - raise ValueError("bits (%d) must be a multiple of 8" % (bits,)) - bytes = random(bits / 8) - result = Util.number.bytes_to_long(bytes) - return result - - - -def _generateX(random, bits): - """ - Generate a new value for the private key x. - - From RFC 2631, section 2.2:: - - X9.42 requires that the private key x be in the interval - [2, (q - 2)]. x should be randomly generated in this interval. - """ - while True: - x = _getRandomNumber(random, bits) - if 2 <= x <= (2 ** bits) - 2: - return x - -class SSHTransportBase(protocol.Protocol): - """ - Protocol supporting basic SSH functionality: sending/receiving packets - and message dispatch. To connect to or run a server, you must use - SSHClientTransport or SSHServerTransport. - - @ivar protocolVersion: A string representing the version of the SSH - protocol we support. Currently defaults to '2.0'. - - @ivar version: A string representing the version of the server or client. - Currently defaults to 'Twisted'. - - @ivar comment: An optional string giving more information about the - server or client. - - @ivar supportedCiphers: A list of strings representing the encryption - algorithms supported, in order from most-preferred to least. - - @ivar supportedMACs: A list of strings representing the message - authentication codes (hashes) supported, in order from most-preferred - to least. Both this and supportedCiphers can include 'none' to use - no encryption or authentication, but that must be done manually, - - @ivar supportedKeyExchanges: A list of strings representing the - key exchanges supported, in order from most-preferred to least. - - @ivar supportedPublicKeys: A list of strings representing the - public key types supported, in order from most-preferred to least. - - @ivar supportedCompressions: A list of strings representing compression - types supported, from most-preferred to least. - - @ivar supportedLanguages: A list of strings representing languages - supported, from most-preferred to least. - - @ivar supportedVersions: A container of strings representing supported ssh - protocol version numbers. - - @ivar isClient: A boolean indicating whether this is a client or server. - - @ivar gotVersion: A boolean indicating whether we have receieved the - version string from the other side. - - @ivar buf: Data we've received but hasn't been parsed into a packet. - - @ivar outgoingPacketSequence: the sequence number of the next packet we - will send. - - @ivar incomingPacketSequence: the sequence number of the next packet we - are expecting from the other side. - - @ivar outgoingCompression: an object supporting the .compress(str) and - .flush() methods, or None if there is no outgoing compression. Used to - compress outgoing data. - - @ivar outgoingCompressionType: A string representing the outgoing - compression type. - - @ivar incomingCompression: an object supporting the .decompress(str) - method, or None if there is no incoming compression. Used to - decompress incoming data. - - @ivar incomingCompressionType: A string representing the incoming - compression type. - - @ivar ourVersionString: the version string that we sent to the other side. - Used in the key exchange. - - @ivar otherVersionString: the version string sent by the other side. Used - in the key exchange. - - @ivar ourKexInitPayload: the MSG_KEXINIT payload we sent. Used in the key - exchange. - - @ivar otherKexInitPayload: the MSG_KEXINIT payload we received. Used in - the key exchange - - @ivar sessionID: a string that is unique to this SSH session. Created as - part of the key exchange, sessionID is used to generate the various - encryption and authentication keys. - - @ivar service: an SSHService instance, or None. If it's set to an object, - it's the currently running service. - - @ivar kexAlg: the agreed-upon key exchange algorithm. - - @ivar keyAlg: the agreed-upon public key type for the key exchange. - - @ivar currentEncryptions: an SSHCiphers instance. It represents the - current encryption and authentication options for the transport. - - @ivar nextEncryptions: an SSHCiphers instance. Held here until the - MSG_NEWKEYS messages are exchanged, when nextEncryptions is - transitioned to currentEncryptions. - - @ivar first: the first bytes of the next packet. In order to avoid - decrypting data twice, the first bytes are decrypted and stored until - the whole packet is available. - - @ivar _keyExchangeState: The current protocol state with respect to key - exchange. This is either C{_KEY_EXCHANGE_NONE} if no key exchange is - in progress (and returns to this value after any key exchange - completqes), C{_KEY_EXCHANGE_REQUESTED} if this side of the connection - initiated a key exchange, and C{_KEY_EXCHANGE_PROGRESSING} if the other - side of the connection initiated a key exchange. C{_KEY_EXCHANGE_NONE} - is the initial value (however SSH connections begin with key exchange, - so it will quickly change to another state). - - @ivar _blockedByKeyExchange: Whenever C{_keyExchangeState} is not - C{_KEY_EXCHANGE_NONE}, this is a C{list} of pending messages which were - passed to L{sendPacket} but could not be sent because it is not legal - to send them while a key exchange is in progress. When the key - exchange completes, another attempt is made to send these messages. - """ - - - protocolVersion = '2.0' - version = 'Twisted' - comment = '' - ourVersionString = ('SSH-' + protocolVersion + '-' + version + ' ' - + comment).strip() - supportedCiphers = ['aes256-ctr', 'aes256-cbc', 'aes192-ctr', 'aes192-cbc', - 'aes128-ctr', 'aes128-cbc', 'cast128-ctr', - 'cast128-cbc', 'blowfish-ctr', 'blowfish-cbc', - '3des-ctr', '3des-cbc'] # ,'none'] - supportedMACs = ['hmac-sha1', 'hmac-md5'] # , 'none'] - # both of the above support 'none', but for security are disabled by - # default. to enable them, subclass this class and add it, or do: - # SSHTransportBase.supportedCiphers.append('none') - supportedKeyExchanges = ['diffie-hellman-group-exchange-sha1', - 'diffie-hellman-group1-sha1'] - supportedPublicKeys = ['ssh-rsa', 'ssh-dss'] - supportedCompressions = ['none', 'zlib'] - supportedLanguages = () - supportedVersions = ('1.99', '2.0') - isClient = False - gotVersion = False - buf = '' - outgoingPacketSequence = 0 - incomingPacketSequence = 0 - outgoingCompression = None - incomingCompression = None - sessionID = None - service = None - - # There is no key exchange activity in progress. - _KEY_EXCHANGE_NONE = '_KEY_EXCHANGE_NONE' - - # Key exchange is in progress and we started it. - _KEY_EXCHANGE_REQUESTED = '_KEY_EXCHANGE_REQUESTED' - - # Key exchange is in progress and both sides have sent KEXINIT messages. - _KEY_EXCHANGE_PROGRESSING = '_KEY_EXCHANGE_PROGRESSING' - - # There is a fourth conceptual state not represented here: KEXINIT received - # but not sent. Since we always send a KEXINIT as soon as we get it, we - # can't ever be in that state. - - # The current key exchange state. - _keyExchangeState = _KEY_EXCHANGE_NONE - _blockedByKeyExchange = None - - def connectionLost(self, reason): - if self.service: - self.service.serviceStopped() - if hasattr(self, 'avatar'): - self.logoutFunction() - log.msg('connection lost') - - - def connectionMade(self): - """ - Called when the connection is made to the other side. We sent our - version and the MSG_KEXINIT packet. - """ - self.transport.write('%s\r\n' % (self.ourVersionString,)) - self.currentEncryptions = SSHCiphers('none', 'none', 'none', 'none') - self.currentEncryptions.setKeys('', '', '', '', '', '') - self.sendKexInit() - - - def sendKexInit(self): - """ - Send a I{KEXINIT} message to initiate key exchange or to respond to a - key exchange initiated by the peer. - - @raise RuntimeError: If a key exchange has already been started and it - is not appropriate to send a I{KEXINIT} message at this time. - - @return: C{None} - """ - if self._keyExchangeState != self._KEY_EXCHANGE_NONE: - raise RuntimeError( - "Cannot send KEXINIT while key exchange state is %r" % ( - self._keyExchangeState,)) - - self.ourKexInitPayload = (chr(MSG_KEXINIT) + - randbytes.secureRandom(16) + - NS(','.join(self.supportedKeyExchanges)) + - NS(','.join(self.supportedPublicKeys)) + - NS(','.join(self.supportedCiphers)) + - NS(','.join(self.supportedCiphers)) + - NS(','.join(self.supportedMACs)) + - NS(','.join(self.supportedMACs)) + - NS(','.join(self.supportedCompressions)) + - NS(','.join(self.supportedCompressions)) + - NS(','.join(self.supportedLanguages)) + - NS(','.join(self.supportedLanguages)) + - '\000' + '\000\000\000\000') - self.sendPacket(MSG_KEXINIT, self.ourKexInitPayload[1:]) - self._keyExchangeState = self._KEY_EXCHANGE_REQUESTED - self._blockedByKeyExchange = [] - - - def _allowedKeyExchangeMessageType(self, messageType): - """ - Determine if the given message type may be sent while key exchange is - in progress. - - @param messageType: The type of message - @type messageType: C{int} - - @return: C{True} if the given type of message may be sent while key - exchange is in progress, C{False} if it may not. - @rtype: C{bool} - - @see: U{http://tools.ietf.org/html/rfc4253#section-7.1} - """ - # Written somewhat peculularly to reflect the way the specification - # defines the allowed message types. - if 1 <= messageType <= 19: - return messageType not in (MSG_SERVICE_REQUEST, MSG_SERVICE_ACCEPT) - if 20 <= messageType <= 29: - return messageType not in (MSG_KEXINIT,) - return 30 <= messageType <= 49 - - - def sendPacket(self, messageType, payload): - """ - Sends a packet. If it's been set up, compress the data, encrypt it, - and authenticate it before sending. If key exchange is in progress and - the message is not part of key exchange, queue it to be sent later. - - @param messageType: The type of the packet; generally one of the - MSG_* values. - @type messageType: C{int} - @param payload: The payload for the message. - @type payload: C{str} - """ - if self._keyExchangeState != self._KEY_EXCHANGE_NONE: - if not self._allowedKeyExchangeMessageType(messageType): - self._blockedByKeyExchange.append((messageType, payload)) - return - - payload = chr(messageType) + payload - if self.outgoingCompression: - payload = (self.outgoingCompression.compress(payload) - + self.outgoingCompression.flush(2)) - bs = self.currentEncryptions.encBlockSize - # 4 for the packet length and 1 for the padding length - totalSize = 5 + len(payload) - lenPad = bs - (totalSize % bs) - if lenPad < 4: - lenPad = lenPad + bs - packet = (struct.pack('!LB', - totalSize + lenPad - 4, lenPad) + - payload + randbytes.secureRandom(lenPad)) - encPacket = ( - self.currentEncryptions.encrypt(packet) + - self.currentEncryptions.makeMAC( - self.outgoingPacketSequence, packet)) - self.transport.write(encPacket) - self.outgoingPacketSequence += 1 - - - def getPacket(self): - """ - Try to return a decrypted, authenticated, and decompressed packet - out of the buffer. If there is not enough data, return None. - - @rtype: C{str}/C{None} - """ - bs = self.currentEncryptions.decBlockSize - ms = self.currentEncryptions.verifyDigestSize - if len(self.buf) < bs: return # not enough data - if not hasattr(self, 'first'): - first = self.currentEncryptions.decrypt(self.buf[:bs]) - else: - first = self.first - del self.first - packetLen, paddingLen = struct.unpack('!LB', first[:5]) - if packetLen > 1048576: # 1024 ** 2 - self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, - 'bad packet length %s' % packetLen) - return - if len(self.buf) < packetLen + 4 + ms: - self.first = first - return # not enough packet - if(packetLen + 4) % bs != 0: - self.sendDisconnect( - DISCONNECT_PROTOCOL_ERROR, - 'bad packet mod (%i%%%i == %i)' % (packetLen + 4, bs, - (packetLen + 4) % bs)) - return - encData, self.buf = self.buf[:4 + packetLen], self.buf[4 + packetLen:] - packet = first + self.currentEncryptions.decrypt(encData[bs:]) - if len(packet) != 4 + packetLen: - self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, - 'bad decryption') - return - if ms: - macData, self.buf = self.buf[:ms], self.buf[ms:] - if not self.currentEncryptions.verify(self.incomingPacketSequence, - packet, macData): - self.sendDisconnect(DISCONNECT_MAC_ERROR, 'bad MAC') - return - payload = packet[5:-paddingLen] - if self.incomingCompression: - try: - payload = self.incomingCompression.decompress(payload) - except: # bare except, because who knows what kind of errors - # decompression can raise - log.err() - self.sendDisconnect(DISCONNECT_COMPRESSION_ERROR, - 'compression error') - return - self.incomingPacketSequence += 1 - return payload - - - def _unsupportedVersionReceived(self, remoteVersion): - """ - Called when an unsupported version of the ssh protocol is received from - the remote endpoint. - - @param remoteVersion: remote ssh protocol version which is unsupported - by us. - @type remoteVersion: C{str} - """ - self.sendDisconnect(DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED, - 'bad version ' + remoteVersion) - - - def dataReceived(self, data): - """ - First, check for the version string (SSH-2.0-*). After that has been - received, this method adds data to the buffer, and pulls out any - packets. - - @type data: C{str} - """ - self.buf = self.buf + data - if not self.gotVersion: - if self.buf.find('\n', self.buf.find('SSH-')) == -1: - return - lines = self.buf.split('\n') - for p in lines: - if p.startswith('SSH-'): - self.gotVersion = True - self.otherVersionString = p.strip() - remoteVersion = p.split('-')[1] - if remoteVersion not in self.supportedVersions: - self._unsupportedVersionReceived(remoteVersion) - return - i = lines.index(p) - self.buf = '\n'.join(lines[i + 1:]) - packet = self.getPacket() - while packet: - messageNum = ord(packet[0]) - self.dispatchMessage(messageNum, packet[1:]) - packet = self.getPacket() - - - def dispatchMessage(self, messageNum, payload): - """ - Send a received message to the appropriate method. - - @type messageNum: C{int} - @type payload: c{str} - """ - if messageNum < 50 and messageNum in messages: - messageType = messages[messageNum][4:] - f = getattr(self, 'ssh_%s' % messageType, None) - if f is not None: - f(payload) - else: - log.msg("couldn't handle %s" % messageType) - log.msg(repr(payload)) - self.sendUnimplemented() - elif self.service: - log.callWithLogger(self.service, self.service.packetReceived, - messageNum, payload) - else: - log.msg("couldn't handle %s" % messageNum) - log.msg(repr(payload)) - self.sendUnimplemented() - - def getPeer(self): - """ - Returns an L{SSHTransportAddress} corresponding to the other (peer) - side of this transport. - - @return: L{SSHTransportAddress} for the peer - @rtype: L{SSHTransportAddress} - @since: 12.1 - """ - return address.SSHTransportAddress(self.transport.getPeer()) - - def getHost(self): - """ - Returns an L{SSHTransportAddress} corresponding to the this side of - transport. - - @return: L{SSHTransportAddress} for the peer - @rtype: L{SSHTransportAddress} - @since: 12.1 - """ - return address.SSHTransportAddress(self.transport.getHost()) - - - # Client-initiated rekeying looks like this: - # - # C> MSG_KEXINIT - # S> MSG_KEXINIT - # C> MSG_KEX_DH_GEX_REQUEST or MSG_KEXDH_INIT - # S> MSG_KEX_DH_GEX_GROUP or MSG_KEXDH_REPLY - # C> MSG_KEX_DH_GEX_INIT or -- - # S> MSG_KEX_DH_GEX_REPLY or -- - # C> MSG_NEWKEYS - # S> MSG_NEWKEYS - # - # Server-initiated rekeying is the same, only the first two messages are - # switched. - - def ssh_KEXINIT(self, packet): - """ - Called when we receive a MSG_KEXINIT message. Payload:: - bytes[16] cookie - string keyExchangeAlgorithms - string keyAlgorithms - string incomingEncryptions - string outgoingEncryptions - string incomingAuthentications - string outgoingAuthentications - string incomingCompressions - string outgoingCompressions - string incomingLanguages - string outgoingLanguages - bool firstPacketFollows - unit32 0 (reserved) - - Starts setting up the key exchange, keys, encryptions, and - authentications. Extended by ssh_KEXINIT in SSHServerTransport and - SSHClientTransport. - """ - self.otherKexInitPayload = chr(MSG_KEXINIT) + packet - #cookie = packet[: 16] # taking this is useless - k = getNS(packet[16:], 10) - strings, rest = k[:-1], k[-1] - (kexAlgs, keyAlgs, encCS, encSC, macCS, macSC, compCS, compSC, langCS, - langSC) = [s.split(',') for s in strings] - # these are the server directions - outs = [encSC, macSC, compSC] - ins = [encCS, macSC, compCS] - if self.isClient: - outs, ins = ins, outs # switch directions - server = (self.supportedKeyExchanges, self.supportedPublicKeys, - self.supportedCiphers, self.supportedCiphers, - self.supportedMACs, self.supportedMACs, - self.supportedCompressions, self.supportedCompressions) - client = (kexAlgs, keyAlgs, outs[0], ins[0], outs[1], ins[1], - outs[2], ins[2]) - if self.isClient: - server, client = client, server - self.kexAlg = ffs(client[0], server[0]) - self.keyAlg = ffs(client[1], server[1]) - self.nextEncryptions = SSHCiphers( - ffs(client[2], server[2]), - ffs(client[3], server[3]), - ffs(client[4], server[4]), - ffs(client[5], server[5])) - self.outgoingCompressionType = ffs(client[6], server[6]) - self.incomingCompressionType = ffs(client[7], server[7]) - if None in (self.kexAlg, self.keyAlg, self.outgoingCompressionType, - self.incomingCompressionType): - self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, - "couldn't match all kex parts") - return - if None in self.nextEncryptions.__dict__.values(): - self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, - "couldn't match all kex parts") - return - log.msg('kex alg, key alg: %s %s' % (self.kexAlg, self.keyAlg)) - log.msg('outgoing: %s %s %s' % (self.nextEncryptions.outCipType, - self.nextEncryptions.outMACType, - self.outgoingCompressionType)) - log.msg('incoming: %s %s %s' % (self.nextEncryptions.inCipType, - self.nextEncryptions.inMACType, - self.incomingCompressionType)) - - if self._keyExchangeState == self._KEY_EXCHANGE_REQUESTED: - self._keyExchangeState = self._KEY_EXCHANGE_PROGRESSING - else: - self.sendKexInit() - - return kexAlgs, keyAlgs, rest # for SSHServerTransport to use - - - def ssh_DISCONNECT(self, packet): - """ - Called when we receive a MSG_DISCONNECT message. Payload:: - long code - string description - - This means that the other side has disconnected. Pass the message up - and disconnect ourselves. - """ - reasonCode = struct.unpack('>L', packet[: 4])[0] - description, foo = getNS(packet[4:]) - self.receiveError(reasonCode, description) - self.transport.loseConnection() - - - def ssh_IGNORE(self, packet): - """ - Called when we receieve a MSG_IGNORE message. No payload. - This means nothing; we simply return. - """ - - - def ssh_UNIMPLEMENTED(self, packet): - """ - Called when we receieve a MSG_UNIMPLEMENTED message. Payload:: - long packet - - This means that the other side did not implement one of our packets. - """ - seqnum, = struct.unpack('>L', packet) - self.receiveUnimplemented(seqnum) - - - def ssh_DEBUG(self, packet): - """ - Called when we receieve a MSG_DEBUG message. Payload:: - bool alwaysDisplay - string message - string language - - This means the other side has passed along some debugging info. - """ - alwaysDisplay = bool(packet[0]) - message, lang, foo = getNS(packet[1:], 2) - self.receiveDebug(alwaysDisplay, message, lang) - - - def setService(self, service): - """ - Set our service to service and start it running. If we were - running a service previously, stop it first. - - @type service: C{SSHService} - """ - log.msg('starting service %s' % service.name) - if self.service: - self.service.serviceStopped() - self.service = service - service.transport = self - self.service.serviceStarted() - - - def sendDebug(self, message, alwaysDisplay=False, language=''): - """ - Send a debug message to the other side. - - @param message: the message to send. - @type message: C{str} - @param alwaysDisplay: if True, tell the other side to always - display this message. - @type alwaysDisplay: C{bool} - @param language: optionally, the language the message is in. - @type language: C{str} - """ - self.sendPacket(MSG_DEBUG, chr(alwaysDisplay) + NS(message) + - NS(language)) - - - def sendIgnore(self, message): - """ - Send a message that will be ignored by the other side. This is - useful to fool attacks based on guessing packet sizes in the - encrypted stream. - - @param message: data to send with the message - @type message: C{str} - """ - self.sendPacket(MSG_IGNORE, NS(message)) - - - def sendUnimplemented(self): - """ - Send a message to the other side that the last packet was not - understood. - """ - seqnum = self.incomingPacketSequence - self.sendPacket(MSG_UNIMPLEMENTED, struct.pack('!L', seqnum)) - - - def sendDisconnect(self, reason, desc): - """ - Send a disconnect message to the other side and then disconnect. - - @param reason: the reason for the disconnect. Should be one of the - DISCONNECT_* values. - @type reason: C{int} - @param desc: a descrption of the reason for the disconnection. - @type desc: C{str} - """ - self.sendPacket( - MSG_DISCONNECT, struct.pack('>L', reason) + NS(desc) + NS('')) - log.msg('Disconnecting with error, code %s\nreason: %s' % (reason, - desc)) - self.transport.loseConnection() - - - def _getKey(self, c, sharedSecret, exchangeHash): - """ - Get one of the keys for authentication/encryption. - - @type c: C{str} - @type sharedSecret: C{str} - @type exchangeHash: C{str} - """ - k1 = sha1(sharedSecret + exchangeHash + c + self.sessionID) - k1 = k1.digest() - k2 = sha1(sharedSecret + exchangeHash + k1).digest() - return k1 + k2 - - - def _keySetup(self, sharedSecret, exchangeHash): - """ - Set up the keys for the connection and sends MSG_NEWKEYS when - finished, - - @param sharedSecret: a secret string agreed upon using a Diffie- - Hellman exchange, so it is only shared between - the server and the client. - @type sharedSecret: C{str} - @param exchangeHash: A hash of various data known by both sides. - @type exchangeHash: C{str} - """ - if not self.sessionID: - self.sessionID = exchangeHash - initIVCS = self._getKey('A', sharedSecret, exchangeHash) - initIVSC = self._getKey('B', sharedSecret, exchangeHash) - encKeyCS = self._getKey('C', sharedSecret, exchangeHash) - encKeySC = self._getKey('D', sharedSecret, exchangeHash) - integKeyCS = self._getKey('E', sharedSecret, exchangeHash) - integKeySC = self._getKey('F', sharedSecret, exchangeHash) - outs = [initIVSC, encKeySC, integKeySC] - ins = [initIVCS, encKeyCS, integKeyCS] - if self.isClient: # reverse for the client - log.msg('REVERSE') - outs, ins = ins, outs - self.nextEncryptions.setKeys(outs[0], outs[1], ins[0], ins[1], - outs[2], ins[2]) - self.sendPacket(MSG_NEWKEYS, '') - - - def _newKeys(self): - """ - Called back by a subclass once a I{MSG_NEWKEYS} message has been - received. This indicates key exchange has completed and new encryption - and compression parameters should be adopted. Any messages which were - queued during key exchange will also be flushed. - """ - log.msg('NEW KEYS') - self.currentEncryptions = self.nextEncryptions - if self.outgoingCompressionType == 'zlib': - self.outgoingCompression = zlib.compressobj(6) - if self.incomingCompressionType == 'zlib': - self.incomingCompression = zlib.decompressobj() - - self._keyExchangeState = self._KEY_EXCHANGE_NONE - messages = self._blockedByKeyExchange - self._blockedByKeyExchange = None - for (messageType, payload) in messages: - self.sendPacket(messageType, payload) - - - def isEncrypted(self, direction="out"): - """ - Return True if the connection is encrypted in the given direction. - Direction must be one of ["out", "in", "both"]. - """ - if direction == "out": - return self.currentEncryptions.outCipType != 'none' - elif direction == "in": - return self.currentEncryptions.inCipType != 'none' - elif direction == "both": - return self.isEncrypted("in") and self.isEncrypted("out") - else: - raise TypeError('direction must be "out", "in", or "both"') - - - def isVerified(self, direction="out"): - """ - Return True if the connecction is verified/authenticated in the - given direction. Direction must be one of ["out", "in", "both"]. - """ - if direction == "out": - return self.currentEncryptions.outMACType != 'none' - elif direction == "in": - return self.currentEncryptions.inMACType != 'none' - elif direction == "both": - return self.isVerified("in")and self.isVerified("out") - else: - raise TypeError('direction must be "out", "in", or "both"') - - - def loseConnection(self): - """ - Lose the connection to the other side, sending a - DISCONNECT_CONNECTION_LOST message. - """ - self.sendDisconnect(DISCONNECT_CONNECTION_LOST, - "user closed connection") - - - # client methods - def receiveError(self, reasonCode, description): - """ - Called when we receive a disconnect error message from the other - side. - - @param reasonCode: the reason for the disconnect, one of the - DISCONNECT_ values. - @type reasonCode: C{int} - @param description: a human-readable description of the - disconnection. - @type description: C{str} - """ - log.msg('Got remote error, code %s\nreason: %s' % (reasonCode, - description)) - - - def receiveUnimplemented(self, seqnum): - """ - Called when we receive an unimplemented packet message from the other - side. - - @param seqnum: the sequence number that was not understood. - @type seqnum: C{int} - """ - log.msg('other side unimplemented packet #%s' % seqnum) - - - def receiveDebug(self, alwaysDisplay, message, lang): - """ - Called when we receive a debug message from the other side. - - @param alwaysDisplay: if True, this message should always be - displayed. - @type alwaysDisplay: C{bool} - @param message: the debug message - @type message: C{str} - @param lang: optionally the language the message is in. - @type lang: C{str} - """ - if alwaysDisplay: - log.msg('Remote Debug Message: %s' % message) - - - -class SSHServerTransport(SSHTransportBase): - """ - SSHServerTransport implements the server side of the SSH protocol. - - @ivar isClient: since we are never the client, this is always False. - - @ivar ignoreNextPacket: if True, ignore the next key exchange packet. This - is set when the client sends a guessed key exchange packet but with - an incorrect guess. - - @ivar dhGexRequest: the KEX_DH_GEX_REQUEST(_OLD) that the client sent. - The key generation needs this to be stored. - - @ivar g: the Diffie-Hellman group generator. - - @ivar p: the Diffie-Hellman group prime. - """ - isClient = False - ignoreNextPacket = 0 - - - def ssh_KEXINIT(self, packet): - """ - Called when we receive a MSG_KEXINIT message. For a description - of the packet, see SSHTransportBase.ssh_KEXINIT(). Additionally, - this method checks if a guessed key exchange packet was sent. If - it was sent, and it guessed incorrectly, the next key exchange - packet MUST be ignored. - """ - retval = SSHTransportBase.ssh_KEXINIT(self, packet) - if not retval: # disconnected - return - else: - kexAlgs, keyAlgs, rest = retval - if ord(rest[0]): # first_kex_packet_follows - if (kexAlgs[0] != self.supportedKeyExchanges[0] or - keyAlgs[0] != self.supportedPublicKeys[0]): - self.ignoreNextPacket = True # guess was wrong - - - def _ssh_KEXDH_INIT(self, packet): - """ - Called to handle the beginning of a diffie-hellman-group1-sha1 key - exchange. - - Unlike other message types, this is not dispatched automatically. It - is called from C{ssh_KEX_DH_GEX_REQUEST_OLD} because an extra check is - required to determine if this is really a KEXDH_INIT message or if it - is a KEX_DH_GEX_REQUEST_OLD message. - - The KEXDH_INIT (for diffie-hellman-group1-sha1 exchanges) payload:: - - integer e (the client's Diffie-Hellman public key) - - We send the KEXDH_REPLY with our host key and signature. - """ - clientDHpublicKey, foo = getMP(packet) - y = _getRandomNumber(randbytes.secureRandom, 512) - serverDHpublicKey = _MPpow(DH_GENERATOR, y, DH_PRIME) - sharedSecret = _MPpow(clientDHpublicKey, y, DH_PRIME) - h = sha1() - h.update(NS(self.otherVersionString)) - h.update(NS(self.ourVersionString)) - h.update(NS(self.otherKexInitPayload)) - h.update(NS(self.ourKexInitPayload)) - h.update(NS(self.factory.publicKeys[self.keyAlg].blob())) - h.update(MP(clientDHpublicKey)) - h.update(serverDHpublicKey) - h.update(sharedSecret) - exchangeHash = h.digest() - self.sendPacket( - MSG_KEXDH_REPLY, - NS(self.factory.publicKeys[self.keyAlg].blob()) + - serverDHpublicKey + - NS(self.factory.privateKeys[self.keyAlg].sign(exchangeHash))) - self._keySetup(sharedSecret, exchangeHash) - - - def ssh_KEX_DH_GEX_REQUEST_OLD(self, packet): - """ - This represents two different key exchange methods that share the same - integer value. If the message is determined to be a KEXDH_INIT, - C{_ssh_KEXDH_INIT} is called to handle it. Otherwise, for - KEX_DH_GEX_REQUEST_OLD (for diffie-hellman-group-exchange-sha1) - payload:: - - integer ideal (ideal size for the Diffie-Hellman prime) - - We send the KEX_DH_GEX_GROUP message with the group that is - closest in size to ideal. - - If we were told to ignore the next key exchange packet by ssh_KEXINIT, - drop it on the floor and return. - """ - if self.ignoreNextPacket: - self.ignoreNextPacket = 0 - return - - # KEXDH_INIT and KEX_DH_GEX_REQUEST_OLD have the same value, so use - # another cue to decide what kind of message the peer sent us. - if self.kexAlg == 'diffie-hellman-group1-sha1': - return self._ssh_KEXDH_INIT(packet) - elif self.kexAlg == 'diffie-hellman-group-exchange-sha1': - self.dhGexRequest = packet - ideal = struct.unpack('>L', packet)[0] - self.g, self.p = self.factory.getDHPrime(ideal) - self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p) + MP(self.g)) - else: - raise error.ConchError('bad kexalg: %s' % self.kexAlg) - - - def ssh_KEX_DH_GEX_REQUEST(self, packet): - """ - Called when we receive a MSG_KEX_DH_GEX_REQUEST message. Payload:: - integer minimum - integer ideal - integer maximum - - The client is asking for a Diffie-Hellman group between minimum and - maximum size, and close to ideal if possible. We reply with a - MSG_KEX_DH_GEX_GROUP message. - - If we were told to ignore the next key exchange packet by ssh_KEXINIT, - drop it on the floor and return. - """ - if self.ignoreNextPacket: - self.ignoreNextPacket = 0 - return - self.dhGexRequest = packet - min, ideal, max = struct.unpack('>3L', packet) - self.g, self.p = self.factory.getDHPrime(ideal) - self.sendPacket(MSG_KEX_DH_GEX_GROUP, MP(self.p) + MP(self.g)) - - - def ssh_KEX_DH_GEX_INIT(self, packet): - """ - Called when we get a MSG_KEX_DH_GEX_INIT message. Payload:: - integer e (client DH public key) - - We send the MSG_KEX_DH_GEX_REPLY message with our host key and - signature. - """ - clientDHpublicKey, foo = getMP(packet) - # TODO: we should also look at the value they send to us and reject - # insecure values of f (if g==2 and f has a single '1' bit while the - # rest are '0's, then they must have used a small y also). - - # TODO: This could be computed when self.p is set up - # or do as openssh does and scan f for a single '1' bit instead - - pSize = Util.number.size(self.p) - y = _getRandomNumber(randbytes.secureRandom, pSize) - - serverDHpublicKey = _MPpow(self.g, y, self.p) - sharedSecret = _MPpow(clientDHpublicKey, y, self.p) - h = sha1() - h.update(NS(self.otherVersionString)) - h.update(NS(self.ourVersionString)) - h.update(NS(self.otherKexInitPayload)) - h.update(NS(self.ourKexInitPayload)) - h.update(NS(self.factory.publicKeys[self.keyAlg].blob())) - h.update(self.dhGexRequest) - h.update(MP(self.p)) - h.update(MP(self.g)) - h.update(MP(clientDHpublicKey)) - h.update(serverDHpublicKey) - h.update(sharedSecret) - exchangeHash = h.digest() - self.sendPacket( - MSG_KEX_DH_GEX_REPLY, - NS(self.factory.publicKeys[self.keyAlg].blob()) + - serverDHpublicKey + - NS(self.factory.privateKeys[self.keyAlg].sign(exchangeHash))) - self._keySetup(sharedSecret, exchangeHash) - - - def ssh_NEWKEYS(self, packet): - """ - Called when we get a MSG_NEWKEYS message. No payload. - When we get this, the keys have been set on both sides, and we - start using them to encrypt and authenticate the connection. - """ - if packet != '': - self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, - "NEWKEYS takes no data") - return - self._newKeys() - - - def ssh_SERVICE_REQUEST(self, packet): - """ - Called when we get a MSG_SERVICE_REQUEST message. Payload:: - string serviceName - - The client has requested a service. If we can start the service, - start it; otherwise, disconnect with - DISCONNECT_SERVICE_NOT_AVAILABLE. - """ - service, rest = getNS(packet) - cls = self.factory.getService(self, service) - if not cls: - self.sendDisconnect(DISCONNECT_SERVICE_NOT_AVAILABLE, - "don't have service %s" % service) - return - else: - self.sendPacket(MSG_SERVICE_ACCEPT, NS(service)) - self.setService(cls()) - - - -class SSHClientTransport(SSHTransportBase): - """ - SSHClientTransport implements the client side of the SSH protocol. - - @ivar isClient: since we are always the client, this is always True. - - @ivar _gotNewKeys: if we receive a MSG_NEWKEYS message before we are - ready to transition to the new keys, this is set to True so we - can transition when the keys are ready locally. - - @ivar x: our Diffie-Hellman private key. - - @ivar e: our Diffie-Hellman public key. - - @ivar g: the Diffie-Hellman group generator. - - @ivar p: the Diffie-Hellman group prime - - @ivar instance: the SSHService object we are requesting. - """ - isClient = True - - def connectionMade(self): - """ - Called when the connection is started with the server. Just sets - up a private instance variable. - """ - SSHTransportBase.connectionMade(self) - self._gotNewKeys = 0 - - - def ssh_KEXINIT(self, packet): - """ - Called when we receive a MSG_KEXINIT message. For a description - of the packet, see SSHTransportBase.ssh_KEXINIT(). Additionally, - this method sends the first key exchange packet. If the agreed-upon - exchange is diffie-hellman-group1-sha1, generate a public key - and send it in a MSG_KEXDH_INIT message. If the exchange is - diffie-hellman-group-exchange-sha1, ask for a 2048 bit group with a - MSG_KEX_DH_GEX_REQUEST_OLD message. - """ - if SSHTransportBase.ssh_KEXINIT(self, packet) is None: - return # we disconnected - if self.kexAlg == 'diffie-hellman-group1-sha1': - self.x = _generateX(randbytes.secureRandom, 512) - self.e = _MPpow(DH_GENERATOR, self.x, DH_PRIME) - self.sendPacket(MSG_KEXDH_INIT, self.e) - elif self.kexAlg == 'diffie-hellman-group-exchange-sha1': - self.sendPacket(MSG_KEX_DH_GEX_REQUEST_OLD, '\x00\x00\x08\x00') - else: - raise error.ConchError("somehow, the kexAlg has been set " - "to something we don't support") - - - def _ssh_KEXDH_REPLY(self, packet): - """ - Called to handle a reply to a diffie-hellman-group1-sha1 key exchange - message (KEXDH_INIT). - - Like the handler for I{KEXDH_INIT}, this message type has an - overlapping value. This method is called from C{ssh_KEX_DH_GEX_GROUP} - if that method detects a diffie-hellman-group1-sha1 key exchange is in - progress. - - Payload:: - - string serverHostKey - integer f (server Diffie-Hellman public key) - string signature - - We verify the host key by calling verifyHostKey, then continue in - _continueKEXDH_REPLY. - """ - pubKey, packet = getNS(packet) - f, packet = getMP(packet) - signature, packet = getNS(packet) - fingerprint = ':'.join([ch.encode('hex') for ch in - md5(pubKey).digest()]) - d = self.verifyHostKey(pubKey, fingerprint) - d.addCallback(self._continueKEXDH_REPLY, pubKey, f, signature) - d.addErrback( - lambda unused: self.sendDisconnect( - DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key')) - return d - - - def ssh_KEX_DH_GEX_GROUP(self, packet): - """ - This handles two different message which share an integer value. - - If the key exchange is diffie-hellman-group-exchange-sha1, this is - MSG_KEX_DH_GEX_GROUP. Payload:: - string g (group generator) - string p (group prime) - - We generate a Diffie-Hellman public key and send it in a - MSG_KEX_DH_GEX_INIT message. - """ - if self.kexAlg == 'diffie-hellman-group1-sha1': - return self._ssh_KEXDH_REPLY(packet) - else: - self.p, rest = getMP(packet) - self.g, rest = getMP(rest) - self.x = _generateX(randbytes.secureRandom, 320) - self.e = _MPpow(self.g, self.x, self.p) - self.sendPacket(MSG_KEX_DH_GEX_INIT, self.e) - - - def _continueKEXDH_REPLY(self, ignored, pubKey, f, signature): - """ - The host key has been verified, so we generate the keys. - - @param pubKey: the public key blob for the server's public key. - @type pubKey: C{str} - @param f: the server's Diffie-Hellman public key. - @type f: C{long} - @param signature: the server's signature, verifying that it has the - correct private key. - @type signature: C{str} - """ - serverKey = keys.Key.fromString(pubKey) - sharedSecret = _MPpow(f, self.x, DH_PRIME) - h = sha1() - h.update(NS(self.ourVersionString)) - h.update(NS(self.otherVersionString)) - h.update(NS(self.ourKexInitPayload)) - h.update(NS(self.otherKexInitPayload)) - h.update(NS(pubKey)) - h.update(self.e) - h.update(MP(f)) - h.update(sharedSecret) - exchangeHash = h.digest() - if not serverKey.verify(signature, exchangeHash): - self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, - 'bad signature') - return - self._keySetup(sharedSecret, exchangeHash) - - - def ssh_KEX_DH_GEX_REPLY(self, packet): - """ - Called when we receieve a MSG_KEX_DH_GEX_REPLY message. Payload:: - string server host key - integer f (server DH public key) - - We verify the host key by calling verifyHostKey, then continue in - _continueGEX_REPLY. - """ - pubKey, packet = getNS(packet) - f, packet = getMP(packet) - signature, packet = getNS(packet) - fingerprint = ':'.join(map(lambda c: '%02x'%ord(c), - md5(pubKey).digest())) - d = self.verifyHostKey(pubKey, fingerprint) - d.addCallback(self._continueGEX_REPLY, pubKey, f, signature) - d.addErrback( - lambda unused: self.sendDisconnect( - DISCONNECT_HOST_KEY_NOT_VERIFIABLE, 'bad host key')) - return d - - - def _continueGEX_REPLY(self, ignored, pubKey, f, signature): - """ - The host key has been verified, so we generate the keys. - - @param pubKey: the public key blob for the server's public key. - @type pubKey: C{str} - @param f: the server's Diffie-Hellman public key. - @type f: C{long} - @param signature: the server's signature, verifying that it has the - correct private key. - @type signature: C{str} - """ - serverKey = keys.Key.fromString(pubKey) - sharedSecret = _MPpow(f, self.x, self.p) - h = sha1() - h.update(NS(self.ourVersionString)) - h.update(NS(self.otherVersionString)) - h.update(NS(self.ourKexInitPayload)) - h.update(NS(self.otherKexInitPayload)) - h.update(NS(pubKey)) - h.update('\x00\x00\x08\x00') - h.update(MP(self.p)) - h.update(MP(self.g)) - h.update(self.e) - h.update(MP(f)) - h.update(sharedSecret) - exchangeHash = h.digest() - if not serverKey.verify(signature, exchangeHash): - self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED, - 'bad signature') - return - self._keySetup(sharedSecret, exchangeHash) - - - def _keySetup(self, sharedSecret, exchangeHash): - """ - See SSHTransportBase._keySetup(). - """ - SSHTransportBase._keySetup(self, sharedSecret, exchangeHash) - if self._gotNewKeys: - self.ssh_NEWKEYS('') - - - def ssh_NEWKEYS(self, packet): - """ - Called when we receieve a MSG_NEWKEYS message. No payload. - If we've finished setting up our own keys, start using them. - Otherwise, remeber that we've receieved this message. - """ - if packet != '': - self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, - "NEWKEYS takes no data") - return - if not self.nextEncryptions.encBlockSize: - self._gotNewKeys = 1 - return - self._newKeys() - self.connectionSecure() - - - def ssh_SERVICE_ACCEPT(self, packet): - """ - Called when we receieve a MSG_SERVICE_ACCEPT message. Payload:: - string service name - - Start the service we requested. - """ - if packet == '': - log.msg('got SERVICE_ACCEPT without payload') - else: - name = getNS(packet)[0] - if name != self.instance.name: - self.sendDisconnect( - DISCONNECT_PROTOCOL_ERROR, - "received accept for service we did not request") - self.setService(self.instance) - - - def requestService(self, instance): - """ - Request that a service be run over this transport. - - @type instance: subclass of L{twisted.conch.ssh.service.SSHService} - """ - self.sendPacket(MSG_SERVICE_REQUEST, NS(instance.name)) - self.instance = instance - - - # client methods - def verifyHostKey(self, hostKey, fingerprint): - """ - Returns a Deferred that gets a callback if it is a valid key, or - an errback if not. - - @type hostKey: C{str} - @type fingerprint: C{str} - @rtype: L{twisted.internet.defer.Deferred} - """ - # return if it's good - return defer.fail(NotImplementedError()) - - - def connectionSecure(self): - """ - Called when the encryption has been set up. Generally, - requestService() is called to run another service over the transport. - """ - raise NotImplementedError() - - - -class _DummyCipher: - """ - A cipher for the none encryption method. - - @ivar block_size: the block size of the encryption. In the case of the - none cipher, this is 8 bytes. - """ - block_size = 8 - - - def encrypt(self, x): - return x - - - decrypt = encrypt - - -class SSHCiphers: - """ - SSHCiphers represents all the encryption operations that need to occur - to encrypt and authenticate the SSH connection. - - @cvar cipherMap: A dictionary mapping SSH encryption names to 3-tuples of - (<Crypto.Cipher.* name>, <block size>, <counter mode>) - @cvar macMap: A dictionary mapping SSH MAC names to hash modules. - - @ivar outCipType: the string type of the outgoing cipher. - @ivar inCipType: the string type of the incoming cipher. - @ivar outMACType: the string type of the incoming MAC. - @ivar inMACType: the string type of the incoming MAC. - @ivar encBlockSize: the block size of the outgoing cipher. - @ivar decBlockSize: the block size of the incoming cipher. - @ivar verifyDigestSize: the size of the incoming MAC. - @ivar outMAC: a tuple of (<hash module>, <inner key>, <outer key>, - <digest size>) representing the outgoing MAC. - @ivar inMAc: see outMAC, but for the incoming MAC. - """ - - - cipherMap = { - '3des-cbc':('DES3', 24, 0), - 'blowfish-cbc':('Blowfish', 16,0 ), - 'aes256-cbc':('AES', 32, 0), - 'aes192-cbc':('AES', 24, 0), - 'aes128-cbc':('AES', 16, 0), - 'cast128-cbc':('CAST', 16, 0), - 'aes128-ctr':('AES', 16, 1), - 'aes192-ctr':('AES', 24, 1), - 'aes256-ctr':('AES', 32, 1), - '3des-ctr':('DES3', 24, 1), - 'blowfish-ctr':('Blowfish', 16, 1), - 'cast128-ctr':('CAST', 16, 1), - 'none':(None, 0, 0), - } - macMap = { - 'hmac-sha1': sha1, - 'hmac-md5': md5, - 'none': None - } - - - def __init__(self, outCip, inCip, outMac, inMac): - self.outCipType = outCip - self.inCipType = inCip - self.outMACType = outMac - self.inMACType = inMac - self.encBlockSize = 0 - self.decBlockSize = 0 - self.verifyDigestSize = 0 - self.outMAC = (None, '', '', 0) - self.inMAC = (None, '', '', 0) - - - def setKeys(self, outIV, outKey, inIV, inKey, outInteg, inInteg): - """ - Set up the ciphers and hashes using the given keys, - - @param outIV: the outgoing initialization vector - @param outKey: the outgoing encryption key - @param inIV: the incoming initialization vector - @param inKey: the incoming encryption key - @param outInteg: the outgoing integrity key - @param inInteg: the incoming integrity key. - """ - o = self._getCipher(self.outCipType, outIV, outKey) - self.encrypt = o.encrypt - self.encBlockSize = o.block_size - o = self._getCipher(self.inCipType, inIV, inKey) - self.decrypt = o.decrypt - self.decBlockSize = o.block_size - self.outMAC = self._getMAC(self.outMACType, outInteg) - self.inMAC = self._getMAC(self.inMACType, inInteg) - if self.inMAC: - self.verifyDigestSize = self.inMAC[3] - - - def _getCipher(self, cip, iv, key): - """ - Creates an initialized cipher object. - - @param cip: the name of the cipher: maps into Crypto.Cipher.* - @param iv: the initialzation vector - @param key: the encryption key - """ - modName, keySize, counterMode = self.cipherMap[cip] - if not modName: # no cipher - return _DummyCipher() - mod = __import__('Crypto.Cipher.%s'%modName, {}, {}, 'x') - if counterMode: - return mod.new(key[:keySize], mod.MODE_CTR, iv[:mod.block_size], - counter=_Counter(iv, mod.block_size)) - else: - return mod.new(key[:keySize], mod.MODE_CBC, iv[:mod.block_size]) - - - def _getMAC(self, mac, key): - """ - Gets a 4-tuple representing the message authentication code. - (<hash module>, <inner hash value>, <outer hash value>, - <digest size>) - - @param mac: a key mapping into macMap - @type mac: C{str} - @param key: the MAC key. - @type key: C{str} - """ - mod = self.macMap[mac] - if not mod: - return (None, '', '', 0) - ds = mod().digest_size - key = key[:ds] + '\x00' * (64 - ds) - i = XOR.new('\x36').encrypt(key) - o = XOR.new('\x5c').encrypt(key) - return mod, i, o, ds - - - def encrypt(self, blocks): - """ - Encrypt blocks. Overridden by the encrypt method of a - Crypto.Cipher.* object in setKeys(). - - @type blocks: C{str} - """ - raise NotImplementedError() - - - def decrypt(self, blocks): - """ - Decrypt blocks. See encrypt(). - - @type blocks: C{str} - """ - raise NotImplementedError() - - - def makeMAC(self, seqid, data): - """ - Create a message authentication code (MAC) for the given packet using - the outgoing MAC values. - - @param seqid: the sequence ID of the outgoing packet - @type seqid: C{int} - @param data: the data to create a MAC for - @type data: C{str} - @rtype: C{str} - """ - if not self.outMAC[0]: - return '' - data = struct.pack('>L', seqid) + data - mod, i, o, ds = self.outMAC - inner = mod(i + data) - outer = mod(o + inner.digest()) - return outer.digest() - - - def verify(self, seqid, data, mac): - """ - Verify an incoming MAC using the incoming MAC values. Return True - if the MAC is valid. - - @param seqid: the sequence ID of the incoming packet - @type seqid: C{int} - @param data: the packet data to verify - @type data: C{str} - @param mac: the MAC sent with the packet - @type mac: C{str} - @rtype: C{bool} - """ - if not self.inMAC[0]: - return mac == '' - data = struct.pack('>L', seqid) + data - mod, i, o, ds = self.inMAC - inner = mod(i + data) - outer = mod(o + inner.digest()) - return mac == outer.digest() - - - -class _Counter: - """ - Stateful counter which returns results packed in a byte string - """ - - - def __init__(self, initialVector, blockSize): - """ - @type initialVector: C{str} - @param initialVector: A byte string representing the initial counter - value. - @type blockSize: C{int} - @param blockSize: The length of the output buffer, as well as the - number of bytes at the beginning of C{initialVector} to consider. - """ - initialVector = initialVector[:blockSize] - self.count = getMP('\xff\xff\xff\xff' + initialVector)[0] - self.blockSize = blockSize - self.count = Util.number.long_to_bytes(self.count - 1) - self.count = '\x00' * (self.blockSize - len(self.count)) + self.count - self.count = array.array('c', self.count) - self.len = len(self.count) - 1 - - - def __call__(self): - """ - Increment the counter and return the new value. - """ - i = self.len - while i > -1: - self.count[i] = n = chr((ord(self.count[i]) + 1) % 256) - if n == '\x00': - i -= 1 - else: - return self.count.tostring() - - self.count = array.array('c', '\x00' * self.blockSize) - return self.count.tostring() - - - -# Diffie-Hellman primes from Oakley Group 2 [RFC 2409] -DH_PRIME = long('17976931348623159077083915679378745319786029604875601170644' -'442368419718021615851936894783379586492554150218056548598050364644054819923' -'910005079287700335581663922955313623907650873575991482257486257500742530207' -'744771258955095793777842444242661733472762929938766870920560605027081084290' -'7692932019128194467627007L') -DH_GENERATOR = 2L - - - -MSG_DISCONNECT = 1 -MSG_IGNORE = 2 -MSG_UNIMPLEMENTED = 3 -MSG_DEBUG = 4 -MSG_SERVICE_REQUEST = 5 -MSG_SERVICE_ACCEPT = 6 -MSG_KEXINIT = 20 -MSG_NEWKEYS = 21 -MSG_KEXDH_INIT = 30 -MSG_KEXDH_REPLY = 31 -MSG_KEX_DH_GEX_REQUEST_OLD = 30 -MSG_KEX_DH_GEX_REQUEST = 34 -MSG_KEX_DH_GEX_GROUP = 31 -MSG_KEX_DH_GEX_INIT = 32 -MSG_KEX_DH_GEX_REPLY = 33 - - - -DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1 -DISCONNECT_PROTOCOL_ERROR = 2 -DISCONNECT_KEY_EXCHANGE_FAILED = 3 -DISCONNECT_RESERVED = 4 -DISCONNECT_MAC_ERROR = 5 -DISCONNECT_COMPRESSION_ERROR = 6 -DISCONNECT_SERVICE_NOT_AVAILABLE = 7 -DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8 -DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9 -DISCONNECT_CONNECTION_LOST = 10 -DISCONNECT_BY_APPLICATION = 11 -DISCONNECT_TOO_MANY_CONNECTIONS = 12 -DISCONNECT_AUTH_CANCELLED_BY_USER = 13 -DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14 -DISCONNECT_ILLEGAL_USER_NAME = 15 - - - -messages = {} -for name, value in globals().items(): - # Avoid legacy messages which overlap with never ones - if name.startswith('MSG_') and not name.startswith('MSG_KEXDH_'): - messages[value] = name -# Check for regressions (#5352) -if 'MSG_KEXDH_INIT' in messages or 'MSG_KEXDH_REPLY' in messages: - raise RuntimeError( - "legacy SSH mnemonics should not end up in messages dict") diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py deleted file mode 100755 index 65c0ef07..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ssh/userauth.py +++ /dev/null @@ -1,848 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_userauth -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Implementation of the ssh-userauth service. -Currently implemented authentication types are public-key and password. - -Maintainer: Paul Swartz -""" - -import struct, warnings -from twisted.conch import error, interfaces -from twisted.conch.ssh import keys, transport, service -from twisted.conch.ssh.common import NS, getNS -from twisted.cred import credentials -from twisted.cred.error import UnauthorizedLogin -from twisted.internet import defer, reactor -from twisted.python import failure, log - - - -class SSHUserAuthServer(service.SSHService): - """ - A service implementing the server side of the 'ssh-userauth' service. It - is used to authenticate the user on the other side as being able to access - this server. - - @ivar name: the name of this service: 'ssh-userauth' - @type name: C{str} - @ivar authenticatedWith: a list of authentication methods that have - already been used. - @type authenticatedWith: C{list} - @ivar loginTimeout: the number of seconds we wait before disconnecting - the user for taking too long to authenticate - @type loginTimeout: C{int} - @ivar attemptsBeforeDisconnect: the number of failed login attempts we - allow before disconnecting. - @type attemptsBeforeDisconnect: C{int} - @ivar loginAttempts: the number of login attempts that have been made - @type loginAttempts: C{int} - @ivar passwordDelay: the number of seconds to delay when the user gives - an incorrect password - @type passwordDelay: C{int} - @ivar interfaceToMethod: a C{dict} mapping credential interfaces to - authentication methods. The server checks to see which of the - cred interfaces have checkers and tells the client that those methods - are valid for authentication. - @type interfaceToMethod: C{dict} - @ivar supportedAuthentications: A list of the supported authentication - methods. - @type supportedAuthentications: C{list} of C{str} - @ivar user: the last username the client tried to authenticate with - @type user: C{str} - @ivar method: the current authentication method - @type method: C{str} - @ivar nextService: the service the user wants started after authentication - has been completed. - @type nextService: C{str} - @ivar portal: the L{twisted.cred.portal.Portal} we are using for - authentication - @type portal: L{twisted.cred.portal.Portal} - @ivar clock: an object with a callLater method. Stubbed out for testing. - """ - - - name = 'ssh-userauth' - loginTimeout = 10 * 60 * 60 - # 10 minutes before we disconnect them - attemptsBeforeDisconnect = 20 - # 20 login attempts before a disconnect - passwordDelay = 1 # number of seconds to delay on a failed password - clock = reactor - interfaceToMethod = { - credentials.ISSHPrivateKey : 'publickey', - credentials.IUsernamePassword : 'password', - credentials.IPluggableAuthenticationModules : 'keyboard-interactive', - } - - - def serviceStarted(self): - """ - Called when the userauth service is started. Set up instance - variables, check if we should allow password/keyboard-interactive - authentication (only allow if the outgoing connection is encrypted) and - set up a login timeout. - """ - self.authenticatedWith = [] - self.loginAttempts = 0 - self.user = None - self.nextService = None - self._pamDeferred = None - self.portal = self.transport.factory.portal - - self.supportedAuthentications = [] - for i in self.portal.listCredentialsInterfaces(): - if i in self.interfaceToMethod: - self.supportedAuthentications.append(self.interfaceToMethod[i]) - - if not self.transport.isEncrypted('in'): - # don't let us transport password in plaintext - if 'password' in self.supportedAuthentications: - self.supportedAuthentications.remove('password') - if 'keyboard-interactive' in self.supportedAuthentications: - self.supportedAuthentications.remove('keyboard-interactive') - self._cancelLoginTimeout = self.clock.callLater( - self.loginTimeout, - self.timeoutAuthentication) - - - def serviceStopped(self): - """ - Called when the userauth service is stopped. Cancel the login timeout - if it's still going. - """ - if self._cancelLoginTimeout: - self._cancelLoginTimeout.cancel() - self._cancelLoginTimeout = None - - - def timeoutAuthentication(self): - """ - Called when the user has timed out on authentication. Disconnect - with a DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE message. - """ - self._cancelLoginTimeout = None - self.transport.sendDisconnect( - transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, - 'you took too long') - - - def tryAuth(self, kind, user, data): - """ - Try to authenticate the user with the given method. Dispatches to a - auth_* method. - - @param kind: the authentication method to try. - @type kind: C{str} - @param user: the username the client is authenticating with. - @type user: C{str} - @param data: authentication specific data sent by the client. - @type data: C{str} - @return: A Deferred called back if the method succeeded, or erred back - if it failed. - @rtype: C{defer.Deferred} - """ - log.msg('%s trying auth %s' % (user, kind)) - if kind not in self.supportedAuthentications: - return defer.fail( - error.ConchError('unsupported authentication, failing')) - kind = kind.replace('-', '_') - f = getattr(self,'auth_%s'%kind, None) - if f: - ret = f(data) - if not ret: - return defer.fail( - error.ConchError('%s return None instead of a Deferred' - % kind)) - else: - return ret - return defer.fail(error.ConchError('bad auth type: %s' % kind)) - - - def ssh_USERAUTH_REQUEST(self, packet): - """ - The client has requested authentication. Payload:: - string user - string next service - string method - <authentication specific data> - - @type packet: C{str} - """ - user, nextService, method, rest = getNS(packet, 3) - if user != self.user or nextService != self.nextService: - self.authenticatedWith = [] # clear auth state - self.user = user - self.nextService = nextService - self.method = method - d = self.tryAuth(method, user, rest) - if not d: - self._ebBadAuth( - failure.Failure(error.ConchError('auth returned none'))) - return - d.addCallback(self._cbFinishedAuth) - d.addErrback(self._ebMaybeBadAuth) - d.addErrback(self._ebBadAuth) - return d - - - def _cbFinishedAuth(self, (interface, avatar, logout)): - """ - The callback when user has successfully been authenticated. For a - description of the arguments, see L{twisted.cred.portal.Portal.login}. - We start the service requested by the user. - """ - self.transport.avatar = avatar - self.transport.logoutFunction = logout - service = self.transport.factory.getService(self.transport, - self.nextService) - if not service: - raise error.ConchError('could not get next service: %s' - % self.nextService) - log.msg('%s authenticated with %s' % (self.user, self.method)) - self.transport.sendPacket(MSG_USERAUTH_SUCCESS, '') - self.transport.setService(service()) - - - def _ebMaybeBadAuth(self, reason): - """ - An intermediate errback. If the reason is - error.NotEnoughAuthentication, we send a MSG_USERAUTH_FAILURE, but - with the partial success indicator set. - - @type reason: L{twisted.python.failure.Failure} - """ - reason.trap(error.NotEnoughAuthentication) - self.transport.sendPacket(MSG_USERAUTH_FAILURE, - NS(','.join(self.supportedAuthentications)) + '\xff') - - - def _ebBadAuth(self, reason): - """ - The final errback in the authentication chain. If the reason is - error.IgnoreAuthentication, we simply return; the authentication - method has sent its own response. Otherwise, send a failure message - and (if the method is not 'none') increment the number of login - attempts. - - @type reason: L{twisted.python.failure.Failure} - """ - if reason.check(error.IgnoreAuthentication): - return - if self.method != 'none': - log.msg('%s failed auth %s' % (self.user, self.method)) - if reason.check(UnauthorizedLogin): - log.msg('unauthorized login: %s' % reason.getErrorMessage()) - elif reason.check(error.ConchError): - log.msg('reason: %s' % reason.getErrorMessage()) - else: - log.msg(reason.getTraceback()) - self.loginAttempts += 1 - if self.loginAttempts > self.attemptsBeforeDisconnect: - self.transport.sendDisconnect( - transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, - 'too many bad auths') - return - self.transport.sendPacket( - MSG_USERAUTH_FAILURE, - NS(','.join(self.supportedAuthentications)) + '\x00') - - - def auth_publickey(self, packet): - """ - Public key authentication. Payload:: - byte has signature - string algorithm name - string key blob - [string signature] (if has signature is True) - - Create a SSHPublicKey credential and verify it using our portal. - """ - hasSig = ord(packet[0]) - algName, blob, rest = getNS(packet[1:], 2) - pubKey = keys.Key.fromString(blob) - signature = hasSig and getNS(rest)[0] or None - if hasSig: - b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) + - NS(self.user) + NS(self.nextService) + NS('publickey') + - chr(hasSig) + NS(pubKey.sshType()) + NS(blob)) - c = credentials.SSHPrivateKey(self.user, algName, blob, b, - signature) - return self.portal.login(c, None, interfaces.IConchUser) - else: - c = credentials.SSHPrivateKey(self.user, algName, blob, None, None) - return self.portal.login(c, None, - interfaces.IConchUser).addErrback(self._ebCheckKey, - packet[1:]) - - - def _ebCheckKey(self, reason, packet): - """ - Called back if the user did not sent a signature. If reason is - error.ValidPublicKey then this key is valid for the user to - authenticate with. Send MSG_USERAUTH_PK_OK. - """ - reason.trap(error.ValidPublicKey) - # if we make it here, it means that the publickey is valid - self.transport.sendPacket(MSG_USERAUTH_PK_OK, packet) - return failure.Failure(error.IgnoreAuthentication()) - - - def auth_password(self, packet): - """ - Password authentication. Payload:: - string password - - Make a UsernamePassword credential and verify it with our portal. - """ - password = getNS(packet[1:])[0] - c = credentials.UsernamePassword(self.user, password) - return self.portal.login(c, None, interfaces.IConchUser).addErrback( - self._ebPassword) - - - def _ebPassword(self, f): - """ - If the password is invalid, wait before sending the failure in order - to delay brute-force password guessing. - """ - d = defer.Deferred() - self.clock.callLater(self.passwordDelay, d.callback, f) - return d - - - def auth_keyboard_interactive(self, packet): - """ - Keyboard interactive authentication. No payload. We create a - PluggableAuthenticationModules credential and authenticate with our - portal. - """ - if self._pamDeferred is not None: - self.transport.sendDisconnect( - transport.DISCONNECT_PROTOCOL_ERROR, - "only one keyboard interactive attempt at a time") - return defer.fail(error.IgnoreAuthentication()) - c = credentials.PluggableAuthenticationModules(self.user, - self._pamConv) - return self.portal.login(c, None, interfaces.IConchUser) - - - def _pamConv(self, items): - """ - Convert a list of PAM authentication questions into a - MSG_USERAUTH_INFO_REQUEST. Returns a Deferred that will be called - back when the user has responses to the questions. - - @param items: a list of 2-tuples (message, kind). We only care about - kinds 1 (password) and 2 (text). - @type items: C{list} - @rtype: L{defer.Deferred} - """ - resp = [] - for message, kind in items: - if kind == 1: # password - resp.append((message, 0)) - elif kind == 2: # text - resp.append((message, 1)) - elif kind in (3, 4): - return defer.fail(error.ConchError( - 'cannot handle PAM 3 or 4 messages')) - else: - return defer.fail(error.ConchError( - 'bad PAM auth kind %i' % kind)) - packet = NS('') + NS('') + NS('') - packet += struct.pack('>L', len(resp)) - for prompt, echo in resp: - packet += NS(prompt) - packet += chr(echo) - self.transport.sendPacket(MSG_USERAUTH_INFO_REQUEST, packet) - self._pamDeferred = defer.Deferred() - return self._pamDeferred - - - def ssh_USERAUTH_INFO_RESPONSE(self, packet): - """ - The user has responded with answers to PAMs authentication questions. - Parse the packet into a PAM response and callback self._pamDeferred. - Payload:: - uint32 numer of responses - string response 1 - ... - string response n - """ - d, self._pamDeferred = self._pamDeferred, None - - try: - resp = [] - numResps = struct.unpack('>L', packet[:4])[0] - packet = packet[4:] - while len(resp) < numResps: - response, packet = getNS(packet) - resp.append((response, 0)) - if packet: - raise error.ConchError("%i bytes of extra data" % len(packet)) - except: - d.errback(failure.Failure()) - else: - d.callback(resp) - - - -class SSHUserAuthClient(service.SSHService): - """ - A service implementing the client side of 'ssh-userauth'. - - @ivar name: the name of this service: 'ssh-userauth' - @type name: C{str} - @ivar preferredOrder: a list of authentication methods we support, in - order of preference. The client will try authentication methods in - this order, making callbacks for information when necessary. - @type preferredOrder: C{list} - @ivar user: the name of the user to authenticate as - @type user: C{str} - @ivar instance: the service to start after authentication has finished - @type instance: L{service.SSHService} - @ivar authenticatedWith: a list of strings of authentication methods we've tried - @type authenticatedWith: C{list} of C{str} - @ivar triedPublicKeys: a list of public key objects that we've tried to - authenticate with - @type triedPublicKeys: C{list} of L{Key} - @ivar lastPublicKey: the last public key object we've tried to authenticate - with - @type lastPublicKey: L{Key} - """ - - - name = 'ssh-userauth' - preferredOrder = ['publickey', 'password', 'keyboard-interactive'] - - - def __init__(self, user, instance): - self.user = user - self.instance = instance - - - def serviceStarted(self): - self.authenticatedWith = [] - self.triedPublicKeys = [] - self.lastPublicKey = None - self.askForAuth('none', '') - - - def askForAuth(self, kind, extraData): - """ - Send a MSG_USERAUTH_REQUEST. - - @param kind: the authentication method to try. - @type kind: C{str} - @param extraData: method-specific data to go in the packet - @type extraData: C{str} - """ - self.lastAuth = kind - self.transport.sendPacket(MSG_USERAUTH_REQUEST, NS(self.user) + - NS(self.instance.name) + NS(kind) + extraData) - - - def tryAuth(self, kind): - """ - Dispatch to an authentication method. - - @param kind: the authentication method - @type kind: C{str} - """ - kind = kind.replace('-', '_') - log.msg('trying to auth with %s' % (kind,)) - f = getattr(self,'auth_%s' % (kind,), None) - if f: - return f() - - - def _ebAuth(self, ignored, *args): - """ - Generic callback for a failed authentication attempt. Respond by - asking for the list of accepted methods (the 'none' method) - """ - self.askForAuth('none', '') - - - def ssh_USERAUTH_SUCCESS(self, packet): - """ - We received a MSG_USERAUTH_SUCCESS. The server has accepted our - authentication, so start the next service. - """ - self.transport.setService(self.instance) - - - def ssh_USERAUTH_FAILURE(self, packet): - """ - We received a MSG_USERAUTH_FAILURE. Payload:: - string methods - byte partial success - - If partial success is C{True}, then the previous method succeeded but is - not sufficent for authentication. C{methods} is a comma-separated list - of accepted authentication methods. - - We sort the list of methods by their position in C{self.preferredOrder}, - removing methods that have already succeeded. We then call - C{self.tryAuth} with the most preferred method. - - @param packet: the L{MSG_USERAUTH_FAILURE} payload. - @type packet: C{str} - - @return: a L{defer.Deferred} that will be callbacked with C{None} as - soon as all authentication methods have been tried, or C{None} if no - more authentication methods are available. - @rtype: C{defer.Deferred} or C{None} - """ - canContinue, partial = getNS(packet) - partial = ord(partial) - if partial: - self.authenticatedWith.append(self.lastAuth) - - def orderByPreference(meth): - """ - Invoked once per authentication method in order to extract a - comparison key which is then used for sorting. - - @param meth: the authentication method. - @type meth: C{str} - - @return: the comparison key for C{meth}. - @rtype: C{int} - """ - if meth in self.preferredOrder: - return self.preferredOrder.index(meth) - else: - # put the element at the end of the list. - return len(self.preferredOrder) - - canContinue = sorted([meth for meth in canContinue.split(',') - if meth not in self.authenticatedWith], - key=orderByPreference) - - log.msg('can continue with: %s' % canContinue) - return self._cbUserauthFailure(None, iter(canContinue)) - - - def _cbUserauthFailure(self, result, iterator): - if result: - return - try: - method = iterator.next() - except StopIteration: - self.transport.sendDisconnect( - transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, - 'no more authentication methods available') - else: - d = defer.maybeDeferred(self.tryAuth, method) - d.addCallback(self._cbUserauthFailure, iterator) - return d - - - def ssh_USERAUTH_PK_OK(self, packet): - """ - This message (number 60) can mean several different messages depending - on the current authentication type. We dispatch to individual methods - in order to handle this request. - """ - func = getattr(self, 'ssh_USERAUTH_PK_OK_%s' % - self.lastAuth.replace('-', '_'), None) - if func is not None: - return func(packet) - else: - self.askForAuth('none', '') - - - def ssh_USERAUTH_PK_OK_publickey(self, packet): - """ - This is MSG_USERAUTH_PK. Our public key is valid, so we create a - signature and try to authenticate with it. - """ - publicKey = self.lastPublicKey - b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) + - NS(self.user) + NS(self.instance.name) + NS('publickey') + - '\x01' + NS(publicKey.sshType()) + NS(publicKey.blob())) - d = self.signData(publicKey, b) - if not d: - self.askForAuth('none', '') - # this will fail, we'll move on - return - d.addCallback(self._cbSignedData) - d.addErrback(self._ebAuth) - - - def ssh_USERAUTH_PK_OK_password(self, packet): - """ - This is MSG_USERAUTH_PASSWD_CHANGEREQ. The password given has expired. - We ask for an old password and a new password, then send both back to - the server. - """ - prompt, language, rest = getNS(packet, 2) - self._oldPass = self._newPass = None - d = self.getPassword('Old Password: ') - d = d.addCallbacks(self._setOldPass, self._ebAuth) - d.addCallback(lambda ignored: self.getPassword(prompt)) - d.addCallbacks(self._setNewPass, self._ebAuth) - - - def ssh_USERAUTH_PK_OK_keyboard_interactive(self, packet): - """ - This is MSG_USERAUTH_INFO_RESPONSE. The server has sent us the - questions it wants us to answer, so we ask the user and sent the - responses. - """ - name, instruction, lang, data = getNS(packet, 3) - numPrompts = struct.unpack('!L', data[:4])[0] - data = data[4:] - prompts = [] - for i in range(numPrompts): - prompt, data = getNS(data) - echo = bool(ord(data[0])) - data = data[1:] - prompts.append((prompt, echo)) - d = self.getGenericAnswers(name, instruction, prompts) - d.addCallback(self._cbGenericAnswers) - d.addErrback(self._ebAuth) - - - def _cbSignedData(self, signedData): - """ - Called back out of self.signData with the signed data. Send the - authentication request with the signature. - - @param signedData: the data signed by the user's private key. - @type signedData: C{str} - """ - publicKey = self.lastPublicKey - self.askForAuth('publickey', '\x01' + NS(publicKey.sshType()) + - NS(publicKey.blob()) + NS(signedData)) - - - def _setOldPass(self, op): - """ - Called back when we are choosing a new password. Simply store the old - password for now. - - @param op: the old password as entered by the user - @type op: C{str} - """ - self._oldPass = op - - - def _setNewPass(self, np): - """ - Called back when we are choosing a new password. Get the old password - and send the authentication message with both. - - @param np: the new password as entered by the user - @type np: C{str} - """ - op = self._oldPass - self._oldPass = None - self.askForAuth('password', '\xff' + NS(op) + NS(np)) - - - def _cbGenericAnswers(self, responses): - """ - Called back when we are finished answering keyboard-interactive - questions. Send the info back to the server in a - MSG_USERAUTH_INFO_RESPONSE. - - @param responses: a list of C{str} responses - @type responses: C{list} - """ - data = struct.pack('!L', len(responses)) - for r in responses: - data += NS(r.encode('UTF8')) - self.transport.sendPacket(MSG_USERAUTH_INFO_RESPONSE, data) - - - def auth_publickey(self): - """ - Try to authenticate with a public key. Ask the user for a public key; - if the user has one, send the request to the server and return True. - Otherwise, return False. - - @rtype: C{bool} - """ - d = defer.maybeDeferred(self.getPublicKey) - d.addBoth(self._cbGetPublicKey) - return d - - - def _cbGetPublicKey(self, publicKey): - if isinstance(publicKey, str): - warnings.warn("Returning a string from " - "SSHUserAuthClient.getPublicKey() is deprecated " - "since Twisted 9.0. Return a keys.Key() instead.", - DeprecationWarning) - publicKey = keys.Key.fromString(publicKey) - if not isinstance(publicKey, keys.Key): # failure or None - publicKey = None - if publicKey is not None: - self.lastPublicKey = publicKey - self.triedPublicKeys.append(publicKey) - log.msg('using key of type %s' % publicKey.type()) - self.askForAuth('publickey', '\x00' + NS(publicKey.sshType()) + - NS(publicKey.blob())) - return True - else: - return False - - - def auth_password(self): - """ - Try to authenticate with a password. Ask the user for a password. - If the user will return a password, return True. Otherwise, return - False. - - @rtype: C{bool} - """ - d = self.getPassword() - if d: - d.addCallbacks(self._cbPassword, self._ebAuth) - return True - else: # returned None, don't do password auth - return False - - - def auth_keyboard_interactive(self): - """ - Try to authenticate with keyboard-interactive authentication. Send - the request to the server and return True. - - @rtype: C{bool} - """ - log.msg('authing with keyboard-interactive') - self.askForAuth('keyboard-interactive', NS('') + NS('')) - return True - - - def _cbPassword(self, password): - """ - Called back when the user gives a password. Send the request to the - server. - - @param password: the password the user entered - @type password: C{str} - """ - self.askForAuth('password', '\x00' + NS(password)) - - - def signData(self, publicKey, signData): - """ - Sign the given data with the given public key. - - By default, this will call getPrivateKey to get the private key, - then sign the data using Key.sign(). - - This method is factored out so that it can be overridden to use - alternate methods, such as a key agent. - - @param publicKey: The public key object returned from L{getPublicKey} - @type publicKey: L{keys.Key} - - @param signData: the data to be signed by the private key. - @type signData: C{str} - @return: a Deferred that's called back with the signature - @rtype: L{defer.Deferred} - """ - key = self.getPrivateKey() - if not key: - return - return key.addCallback(self._cbSignData, signData) - - - def _cbSignData(self, privateKey, signData): - """ - Called back when the private key is returned. Sign the data and - return the signature. - - @param privateKey: the private key object - @type publicKey: L{keys.Key} - @param signData: the data to be signed by the private key. - @type signData: C{str} - @return: the signature - @rtype: C{str} - """ - if not isinstance(privateKey, keys.Key): - warnings.warn("Returning a PyCrypto key object from " - "SSHUserAuthClient.getPrivateKey() is deprecated " - "since Twisted 9.0. Return a keys.Key() instead.", - DeprecationWarning) - privateKey = keys.Key(privateKey) - return privateKey.sign(signData) - - - def getPublicKey(self): - """ - Return a public key for the user. If no more public keys are - available, return C{None}. - - This implementation always returns C{None}. Override it in a - subclass to actually find and return a public key object. - - @rtype: L{Key} or L{NoneType} - """ - return None - - - def getPrivateKey(self): - """ - Return a L{Deferred} that will be called back with the private key - object corresponding to the last public key from getPublicKey(). - If the private key is not available, errback on the Deferred. - - @rtype: L{Deferred} called back with L{Key} - """ - return defer.fail(NotImplementedError()) - - - def getPassword(self, prompt = None): - """ - Return a L{Deferred} that will be called back with a password. - prompt is a string to display for the password, or None for a generic - 'user@hostname's password: '. - - @type prompt: C{str}/C{None} - @rtype: L{defer.Deferred} - """ - return defer.fail(NotImplementedError()) - - - def getGenericAnswers(self, name, instruction, prompts): - """ - Returns a L{Deferred} with the responses to the promopts. - - @param name: The name of the authentication currently in progress. - @param instruction: Describes what the authentication wants. - @param prompts: A list of (prompt, echo) pairs, where prompt is a - string to display and echo is a boolean indicating whether the - user's response should be echoed as they type it. - """ - return defer.fail(NotImplementedError()) - - -MSG_USERAUTH_REQUEST = 50 -MSG_USERAUTH_FAILURE = 51 -MSG_USERAUTH_SUCCESS = 52 -MSG_USERAUTH_BANNER = 53 -MSG_USERAUTH_INFO_RESPONSE = 61 -MSG_USERAUTH_PK_OK = 60 - -messages = {} -for k, v in locals().items(): - if k[:4]=='MSG_': - messages[v] = k - -SSHUserAuthServer.protocolMessages = messages -SSHUserAuthClient.protocolMessages = messages -del messages -del v - -# Doubles, not included in the protocols' mappings -MSG_USERAUTH_PASSWD_CHANGEREQ = 60 -MSG_USERAUTH_INFO_REQUEST = 60 diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py deleted file mode 100755 index c45fc3bf..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/stdio.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_manhole -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Asynchronous local terminal input handling - -@author: Jp Calderone -""" - -import os, tty, sys, termios - -from twisted.internet import reactor, stdio, protocol, defer -from twisted.python import failure, reflect, log - -from twisted.conch.insults.insults import ServerProtocol -from twisted.conch.manhole import ColoredManhole - -class UnexpectedOutputError(Exception): - pass - -class TerminalProcessProtocol(protocol.ProcessProtocol): - def __init__(self, proto): - self.proto = proto - self.onConnection = defer.Deferred() - - def connectionMade(self): - self.proto.makeConnection(self) - self.onConnection.callback(None) - self.onConnection = None - - def write(self, bytes): - self.transport.write(bytes) - - def outReceived(self, bytes): - self.proto.dataReceived(bytes) - - def errReceived(self, bytes): - self.transport.loseConnection() - if self.proto is not None: - self.proto.connectionLost(failure.Failure(UnexpectedOutputError(bytes))) - self.proto = None - - def childConnectionLost(self, childFD): - if self.proto is not None: - self.proto.childConnectionLost(childFD) - - def processEnded(self, reason): - if self.proto is not None: - self.proto.connectionLost(reason) - self.proto = None - - - -class ConsoleManhole(ColoredManhole): - """ - A manhole protocol specifically for use with L{stdio.StandardIO}. - """ - def connectionLost(self, reason): - """ - When the connection is lost, there is nothing more to do. Stop the - reactor so that the process can exit. - """ - reactor.stop() - - - -def runWithProtocol(klass): - fd = sys.__stdin__.fileno() - oldSettings = termios.tcgetattr(fd) - tty.setraw(fd) - try: - p = ServerProtocol(klass) - stdio.StandardIO(p) - reactor.run() - finally: - termios.tcsetattr(fd, termios.TCSANOW, oldSettings) - os.write(fd, "\r\x1bc\r") - - - -def main(argv=None): - log.startLogging(file('child.log', 'w')) - - if argv is None: - argv = sys.argv[1:] - if argv: - klass = reflect.namedClass(argv[0]) - else: - klass = ConsoleManhole - runWithProtocol(klass) - - -if __name__ == '__main__': - main() diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py deleted file mode 100755 index 7488cc02..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/tap.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_tap -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Support module for making SSH servers with twistd. -""" - -from twisted.conch import unix -from twisted.conch import checkers as conch_checkers -from twisted.conch.openssh_compat import factory -from twisted.cred import portal, checkers, strcred -from twisted.python import usage -from twisted.application import strports -try: - from twisted.cred import pamauth -except ImportError: - pamauth = None - - - -class Options(usage.Options, strcred.AuthOptionMixin): - synopsis = "[-i <interface>] [-p <port>] [-d <dir>] " - longdesc = ("Makes a Conch SSH server. If no authentication methods are " - "specified, the default authentication methods are UNIX passwords, " - "SSH public keys, and PAM if it is available. If --auth options are " - "passed, only the measures specified will be used.") - optParameters = [ - ["interface", "i", "", "local interface to which we listen"], - ["port", "p", "tcp:22", "Port on which to listen"], - ["data", "d", "/etc", "directory to look for host keys in"], - ["moduli", "", None, "directory to look for moduli in " - "(if different from --data)"] - ] - compData = usage.Completions( - optActions={"data": usage.CompleteDirs(descr="data directory"), - "moduli": usage.CompleteDirs(descr="moduli directory"), - "interface": usage.CompleteNetInterfaces()} - ) - - - def __init__(self, *a, **kw): - usage.Options.__init__(self, *a, **kw) - - # call the default addCheckers (for backwards compatibility) that will - # be used if no --auth option is provided - note that conch's - # UNIXPasswordDatabase is used, instead of twisted.plugins.cred_unix's - # checker - super(Options, self).addChecker(conch_checkers.UNIXPasswordDatabase()) - super(Options, self).addChecker(conch_checkers.SSHPublicKeyDatabase()) - if pamauth is not None: - super(Options, self).addChecker( - checkers.PluggableAuthenticationModulesChecker()) - - - def addChecker(self, checker): - """ - If addChecker is called, clear out the default checkers first - """ - self['credCheckers'] = [] - self['credInterfaces'] = {} - super(Options, self).addChecker(checker) - - - -def makeService(config): - """ - Construct a service for operating a SSH server. - - @param config: An L{Options} instance specifying server options, including - where server keys are stored and what authentication methods to use. - - @return: An L{IService} provider which contains the requested SSH server. - """ - - t = factory.OpenSSHFactory() - - r = unix.UnixSSHRealm() - t.portal = portal.Portal(r, config.get('credCheckers', [])) - t.dataRoot = config['data'] - t.moduliRoot = config['moduli'] or config['data'] - - port = config['port'] - if config['interface']: - # Add warning here - port += ':interface=' + config['interface'] - return strports.service(port, t) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py deleted file mode 100755 index c90fe1a2..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/telnet.py +++ /dev/null @@ -1,1086 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_telnet -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Telnet protocol implementation. - -@author: Jean-Paul Calderone -""" - -import struct - -from zope.interface import implements - -from twisted.internet import protocol, interfaces as iinternet, defer -from twisted.python import log - -MODE = chr(1) -EDIT = 1 -TRAPSIG = 2 -MODE_ACK = 4 -SOFT_TAB = 8 -LIT_ECHO = 16 - -# Characters gleaned from the various (and conflicting) RFCs. Not all of these are correct. - -NULL = chr(0) # No operation. -BEL = chr(7) # Produces an audible or - # visible signal (which does - # NOT move the print head). -BS = chr(8) # Moves the print head one - # character position towards - # the left margin. -HT = chr(9) # Moves the printer to the - # next horizontal tab stop. - # It remains unspecified how - # either party determines or - # establishes where such tab - # stops are located. -LF = chr(10) # Moves the printer to the - # next print line, keeping the - # same horizontal position. -VT = chr(11) # Moves the printer to the - # next vertical tab stop. It - # remains unspecified how - # either party determines or - # establishes where such tab - # stops are located. -FF = chr(12) # Moves the printer to the top - # of the next page, keeping - # the same horizontal position. -CR = chr(13) # Moves the printer to the left - # margin of the current line. - -ECHO = chr(1) # User-to-Server: Asks the server to send - # Echos of the transmitted data. -SGA = chr(3) # Suppress Go Ahead. Go Ahead is silly - # and most modern servers should suppress - # it. -NAWS = chr(31) # Negotiate About Window Size. Indicate that - # information about the size of the terminal - # can be communicated. -LINEMODE = chr(34) # Allow line buffering to be - # negotiated about. - -SE = chr(240) # End of subnegotiation parameters. -NOP = chr(241) # No operation. -DM = chr(242) # "Data Mark": The data stream portion - # of a Synch. This should always be - # accompanied by a TCP Urgent - # notification. -BRK = chr(243) # NVT character Break. -IP = chr(244) # The function Interrupt Process. -AO = chr(245) # The function Abort Output -AYT = chr(246) # The function Are You There. -EC = chr(247) # The function Erase Character. -EL = chr(248) # The function Erase Line -GA = chr(249) # The Go Ahead signal. -SB = chr(250) # Indicates that what follows is - # subnegotiation of the indicated - # option. -WILL = chr(251) # Indicates the desire to begin - # performing, or confirmation that - # you are now performing, the - # indicated option. -WONT = chr(252) # Indicates the refusal to perform, - # or continue performing, the - # indicated option. -DO = chr(253) # Indicates the request that the - # other party perform, or - # confirmation that you are expecting - # the other party to perform, the - # indicated option. -DONT = chr(254) # Indicates the demand that the - # other party stop performing, - # or confirmation that you are no - # longer expecting the other party - # to perform, the indicated option. -IAC = chr(255) # Data Byte 255. Introduces a - # telnet command. - -LINEMODE_MODE = chr(1) -LINEMODE_EDIT = chr(1) -LINEMODE_TRAPSIG = chr(2) -LINEMODE_MODE_ACK = chr(4) -LINEMODE_SOFT_TAB = chr(8) -LINEMODE_LIT_ECHO = chr(16) -LINEMODE_FORWARDMASK = chr(2) -LINEMODE_SLC = chr(3) -LINEMODE_SLC_SYNCH = chr(1) -LINEMODE_SLC_BRK = chr(2) -LINEMODE_SLC_IP = chr(3) -LINEMODE_SLC_AO = chr(4) -LINEMODE_SLC_AYT = chr(5) -LINEMODE_SLC_EOR = chr(6) -LINEMODE_SLC_ABORT = chr(7) -LINEMODE_SLC_EOF = chr(8) -LINEMODE_SLC_SUSP = chr(9) -LINEMODE_SLC_EC = chr(10) -LINEMODE_SLC_EL = chr(11) - -LINEMODE_SLC_EW = chr(12) -LINEMODE_SLC_RP = chr(13) -LINEMODE_SLC_LNEXT = chr(14) -LINEMODE_SLC_XON = chr(15) -LINEMODE_SLC_XOFF = chr(16) -LINEMODE_SLC_FORW1 = chr(17) -LINEMODE_SLC_FORW2 = chr(18) -LINEMODE_SLC_MCL = chr(19) -LINEMODE_SLC_MCR = chr(20) -LINEMODE_SLC_MCWL = chr(21) -LINEMODE_SLC_MCWR = chr(22) -LINEMODE_SLC_MCBOL = chr(23) -LINEMODE_SLC_MCEOL = chr(24) -LINEMODE_SLC_INSRT = chr(25) -LINEMODE_SLC_OVER = chr(26) -LINEMODE_SLC_ECR = chr(27) -LINEMODE_SLC_EWR = chr(28) -LINEMODE_SLC_EBOL = chr(29) -LINEMODE_SLC_EEOL = chr(30) - -LINEMODE_SLC_DEFAULT = chr(3) -LINEMODE_SLC_VALUE = chr(2) -LINEMODE_SLC_CANTCHANGE = chr(1) -LINEMODE_SLC_NOSUPPORT = chr(0) -LINEMODE_SLC_LEVELBITS = chr(3) - -LINEMODE_SLC_ACK = chr(128) -LINEMODE_SLC_FLUSHIN = chr(64) -LINEMODE_SLC_FLUSHOUT = chr(32) -LINEMODE_EOF = chr(236) -LINEMODE_SUSP = chr(237) -LINEMODE_ABORT = chr(238) - -class ITelnetProtocol(iinternet.IProtocol): - def unhandledCommand(command, argument): - """A command was received but not understood. - - @param command: the command received. - @type command: C{str}, a single character. - @param argument: the argument to the received command. - @type argument: C{str}, a single character, or None if the command that - was unhandled does not provide an argument. - """ - - def unhandledSubnegotiation(command, bytes): - """A subnegotiation command was received but not understood. - - @param command: the command being subnegotiated. That is, the first - byte after the SB command. - @type command: C{str}, a single character. - @param bytes: all other bytes of the subneogation. That is, all but the - first bytes between SB and SE, with IAC un-escaping applied. - @type bytes: C{list} of C{str}, each a single character - """ - - def enableLocal(option): - """Enable the given option locally. - - This should enable the given option on this side of the - telnet connection and return True. If False is returned, - the option will be treated as still disabled and the peer - will be notified. - - @param option: the option to be enabled. - @type option: C{str}, a single character. - """ - - def enableRemote(option): - """Indicate whether the peer should be allowed to enable this option. - - Returns True if the peer should be allowed to enable this option, - False otherwise. - - @param option: the option to be enabled. - @type option: C{str}, a single character. - """ - - def disableLocal(option): - """Disable the given option locally. - - Unlike enableLocal, this method cannot fail. The option must be - disabled. - - @param option: the option to be disabled. - @type option: C{str}, a single character. - """ - - def disableRemote(option): - """Indicate that the peer has disabled this option. - - @param option: the option to be disabled. - @type option: C{str}, a single character. - """ - - - -class ITelnetTransport(iinternet.ITransport): - def do(option): - """ - Indicate a desire for the peer to begin performing the given option. - - Returns a Deferred that fires with True when the peer begins performing - the option, or fails with L{OptionRefused} when the peer refuses to - perform it. If the peer is already performing the given option, the - Deferred will fail with L{AlreadyEnabled}. If a negotiation regarding - this option is already in progress, the Deferred will fail with - L{AlreadyNegotiating}. - - Note: It is currently possible that this Deferred will never fire, - if the peer never responds, or if the peer believes the option to - already be enabled. - """ - - - def dont(option): - """ - Indicate a desire for the peer to cease performing the given option. - - Returns a Deferred that fires with True when the peer ceases performing - the option. If the peer is not performing the given option, the - Deferred will fail with L{AlreadyDisabled}. If negotiation regarding - this option is already in progress, the Deferred will fail with - L{AlreadyNegotiating}. - - Note: It is currently possible that this Deferred will never fire, - if the peer never responds, or if the peer believes the option to - already be disabled. - """ - - - def will(option): - """ - Indicate our willingness to begin performing this option locally. - - Returns a Deferred that fires with True when the peer agrees to allow us - to begin performing this option, or fails with L{OptionRefused} if the - peer refuses to allow us to begin performing it. If the option is - already enabled locally, the Deferred will fail with L{AlreadyEnabled}. - If negotiation regarding this option is already in progress, the - Deferred will fail with L{AlreadyNegotiating}. - - Note: It is currently possible that this Deferred will never fire, - if the peer never responds, or if the peer believes the option to - already be enabled. - """ - - - def wont(option): - """ - Indicate that we will stop performing the given option. - - Returns a Deferred that fires with True when the peer acknowledges - we have stopped performing this option. If the option is already - disabled locally, the Deferred will fail with L{AlreadyDisabled}. - If negotiation regarding this option is already in progress, - the Deferred will fail with L{AlreadyNegotiating}. - - Note: It is currently possible that this Deferred will never fire, - if the peer never responds, or if the peer believes the option to - already be disabled. - """ - - - def requestNegotiation(about, bytes): - """ - Send a subnegotiation request. - - @param about: A byte indicating the feature being negotiated. - @param bytes: Any number of bytes containing specific information - about the negotiation being requested. No values in this string - need to be escaped, as this function will escape any value which - requires it. - """ - - - -class TelnetError(Exception): - pass - -class NegotiationError(TelnetError): - def __str__(self): - return self.__class__.__module__ + '.' + self.__class__.__name__ + ':' + repr(self.args[0]) - -class OptionRefused(NegotiationError): - pass - -class AlreadyEnabled(NegotiationError): - pass - -class AlreadyDisabled(NegotiationError): - pass - -class AlreadyNegotiating(NegotiationError): - pass - -class TelnetProtocol(protocol.Protocol): - implements(ITelnetProtocol) - - def unhandledCommand(self, command, argument): - pass - - def unhandledSubnegotiation(self, command, bytes): - pass - - def enableLocal(self, option): - pass - - def enableRemote(self, option): - pass - - def disableLocal(self, option): - pass - - def disableRemote(self, option): - pass - - -class Telnet(protocol.Protocol): - """ - @ivar commandMap: A mapping of bytes to callables. When a - telnet command is received, the command byte (the first byte - after IAC) is looked up in this dictionary. If a callable is - found, it is invoked with the argument of the command, or None - if the command takes no argument. Values should be added to - this dictionary if commands wish to be handled. By default, - only WILL, WONT, DO, and DONT are handled. These should not - be overridden, as this class handles them correctly and - provides an API for interacting with them. - - @ivar negotiationMap: A mapping of bytes to callables. When - a subnegotiation command is received, the command byte (the - first byte after SB) is looked up in this dictionary. If - a callable is found, it is invoked with the argument of the - subnegotiation. Values should be added to this dictionary if - subnegotiations are to be handled. By default, no values are - handled. - - @ivar options: A mapping of option bytes to their current - state. This state is likely of little use to user code. - Changes should not be made to it. - - @ivar state: A string indicating the current parse state. It - can take on the values "data", "escaped", "command", "newline", - "subnegotiation", and "subnegotiation-escaped". Changes - should not be made to it. - - @ivar transport: This protocol's transport object. - """ - - # One of a lot of things - state = 'data' - - def __init__(self): - self.options = {} - self.negotiationMap = {} - self.commandMap = { - WILL: self.telnet_WILL, - WONT: self.telnet_WONT, - DO: self.telnet_DO, - DONT: self.telnet_DONT} - - def _write(self, bytes): - self.transport.write(bytes) - - class _OptionState: - """ - Represents the state of an option on both sides of a telnet - connection. - - @ivar us: The state of the option on this side of the connection. - - @ivar him: The state of the option on the other side of the - connection. - """ - class _Perspective: - """ - Represents the state of an option on side of the telnet - connection. Some options can be enabled on a particular side of - the connection (RFC 1073 for example: only the client can have - NAWS enabled). Other options can be enabled on either or both - sides (such as RFC 1372: each side can have its own flow control - state). - - @ivar state: C{'yes'} or C{'no'} indicating whether or not this - option is enabled on one side of the connection. - - @ivar negotiating: A boolean tracking whether negotiation about - this option is in progress. - - @ivar onResult: When negotiation about this option has been - initiated by this side of the connection, a L{Deferred} - which will fire with the result of the negotiation. C{None} - at other times. - """ - state = 'no' - negotiating = False - onResult = None - - def __str__(self): - return self.state + ('*' * self.negotiating) - - def __init__(self): - self.us = self._Perspective() - self.him = self._Perspective() - - def __repr__(self): - return '<_OptionState us=%s him=%s>' % (self.us, self.him) - - def getOptionState(self, opt): - return self.options.setdefault(opt, self._OptionState()) - - def _do(self, option): - self._write(IAC + DO + option) - - def _dont(self, option): - self._write(IAC + DONT + option) - - def _will(self, option): - self._write(IAC + WILL + option) - - def _wont(self, option): - self._write(IAC + WONT + option) - - def will(self, option): - """Indicate our willingness to enable an option. - """ - s = self.getOptionState(option) - if s.us.negotiating or s.him.negotiating: - return defer.fail(AlreadyNegotiating(option)) - elif s.us.state == 'yes': - return defer.fail(AlreadyEnabled(option)) - else: - s.us.negotiating = True - s.us.onResult = d = defer.Deferred() - self._will(option) - return d - - def wont(self, option): - """Indicate we are not willing to enable an option. - """ - s = self.getOptionState(option) - if s.us.negotiating or s.him.negotiating: - return defer.fail(AlreadyNegotiating(option)) - elif s.us.state == 'no': - return defer.fail(AlreadyDisabled(option)) - else: - s.us.negotiating = True - s.us.onResult = d = defer.Deferred() - self._wont(option) - return d - - def do(self, option): - s = self.getOptionState(option) - if s.us.negotiating or s.him.negotiating: - return defer.fail(AlreadyNegotiating(option)) - elif s.him.state == 'yes': - return defer.fail(AlreadyEnabled(option)) - else: - s.him.negotiating = True - s.him.onResult = d = defer.Deferred() - self._do(option) - return d - - def dont(self, option): - s = self.getOptionState(option) - if s.us.negotiating or s.him.negotiating: - return defer.fail(AlreadyNegotiating(option)) - elif s.him.state == 'no': - return defer.fail(AlreadyDisabled(option)) - else: - s.him.negotiating = True - s.him.onResult = d = defer.Deferred() - self._dont(option) - return d - - - def requestNegotiation(self, about, bytes): - """ - Send a negotiation message for the option C{about} with C{bytes} as the - payload. - - @see: L{ITelnetTransport.requestNegotiation} - """ - bytes = bytes.replace(IAC, IAC * 2) - self._write(IAC + SB + about + bytes + IAC + SE) - - - def dataReceived(self, data): - appDataBuffer = [] - - for b in data: - if self.state == 'data': - if b == IAC: - self.state = 'escaped' - elif b == '\r': - self.state = 'newline' - else: - appDataBuffer.append(b) - elif self.state == 'escaped': - if b == IAC: - appDataBuffer.append(b) - self.state = 'data' - elif b == SB: - self.state = 'subnegotiation' - self.commands = [] - elif b in (NOP, DM, BRK, IP, AO, AYT, EC, EL, GA): - self.state = 'data' - if appDataBuffer: - self.applicationDataReceived(''.join(appDataBuffer)) - del appDataBuffer[:] - self.commandReceived(b, None) - elif b in (WILL, WONT, DO, DONT): - self.state = 'command' - self.command = b - else: - raise ValueError("Stumped", b) - elif self.state == 'command': - self.state = 'data' - command = self.command - del self.command - if appDataBuffer: - self.applicationDataReceived(''.join(appDataBuffer)) - del appDataBuffer[:] - self.commandReceived(command, b) - elif self.state == 'newline': - self.state = 'data' - if b == '\n': - appDataBuffer.append('\n') - elif b == '\0': - appDataBuffer.append('\r') - elif b == IAC: - # IAC isn't really allowed after \r, according to the - # RFC, but handling it this way is less surprising than - # delivering the IAC to the app as application data. - # The purpose of the restriction is to allow terminals - # to unambiguously interpret the behavior of the CR - # after reading only one more byte. CR LF is supposed - # to mean one thing (cursor to next line, first column), - # CR NUL another (cursor to first column). Absent the - # NUL, it still makes sense to interpret this as CR and - # then apply all the usual interpretation to the IAC. - appDataBuffer.append('\r') - self.state = 'escaped' - else: - appDataBuffer.append('\r' + b) - elif self.state == 'subnegotiation': - if b == IAC: - self.state = 'subnegotiation-escaped' - else: - self.commands.append(b) - elif self.state == 'subnegotiation-escaped': - if b == SE: - self.state = 'data' - commands = self.commands - del self.commands - if appDataBuffer: - self.applicationDataReceived(''.join(appDataBuffer)) - del appDataBuffer[:] - self.negotiate(commands) - else: - self.state = 'subnegotiation' - self.commands.append(b) - else: - raise ValueError("How'd you do this?") - - if appDataBuffer: - self.applicationDataReceived(''.join(appDataBuffer)) - - - def connectionLost(self, reason): - for state in self.options.values(): - if state.us.onResult is not None: - d = state.us.onResult - state.us.onResult = None - d.errback(reason) - if state.him.onResult is not None: - d = state.him.onResult - state.him.onResult = None - d.errback(reason) - - def applicationDataReceived(self, bytes): - """Called with application-level data. - """ - - def unhandledCommand(self, command, argument): - """Called for commands for which no handler is installed. - """ - - def commandReceived(self, command, argument): - cmdFunc = self.commandMap.get(command) - if cmdFunc is None: - self.unhandledCommand(command, argument) - else: - cmdFunc(argument) - - def unhandledSubnegotiation(self, command, bytes): - """Called for subnegotiations for which no handler is installed. - """ - - def negotiate(self, bytes): - command, bytes = bytes[0], bytes[1:] - cmdFunc = self.negotiationMap.get(command) - if cmdFunc is None: - self.unhandledSubnegotiation(command, bytes) - else: - cmdFunc(bytes) - - def telnet_WILL(self, option): - s = self.getOptionState(option) - self.willMap[s.him.state, s.him.negotiating](self, s, option) - - def will_no_false(self, state, option): - # He is unilaterally offering to enable an option. - if self.enableRemote(option): - state.him.state = 'yes' - self._do(option) - else: - self._dont(option) - - def will_no_true(self, state, option): - # Peer agreed to enable an option in response to our request. - state.him.state = 'yes' - state.him.negotiating = False - d = state.him.onResult - state.him.onResult = None - d.callback(True) - assert self.enableRemote(option), "enableRemote must return True in this context (for option %r)" % (option,) - - def will_yes_false(self, state, option): - # He is unilaterally offering to enable an already-enabled option. - # Ignore this. - pass - - def will_yes_true(self, state, option): - # This is a bogus state. It is here for completeness. It will - # never be entered. - assert False, "will_yes_true can never be entered, but was called with %r, %r" % (state, option) - - willMap = {('no', False): will_no_false, ('no', True): will_no_true, - ('yes', False): will_yes_false, ('yes', True): will_yes_true} - - def telnet_WONT(self, option): - s = self.getOptionState(option) - self.wontMap[s.him.state, s.him.negotiating](self, s, option) - - def wont_no_false(self, state, option): - # He is unilaterally demanding that an already-disabled option be/remain disabled. - # Ignore this (although we could record it and refuse subsequent enable attempts - # from our side - he can always refuse them again though, so we won't) - pass - - def wont_no_true(self, state, option): - # Peer refused to enable an option in response to our request. - state.him.negotiating = False - d = state.him.onResult - state.him.onResult = None - d.errback(OptionRefused(option)) - - def wont_yes_false(self, state, option): - # Peer is unilaterally demanding that an option be disabled. - state.him.state = 'no' - self.disableRemote(option) - self._dont(option) - - def wont_yes_true(self, state, option): - # Peer agreed to disable an option at our request. - state.him.state = 'no' - state.him.negotiating = False - d = state.him.onResult - state.him.onResult = None - d.callback(True) - self.disableRemote(option) - - wontMap = {('no', False): wont_no_false, ('no', True): wont_no_true, - ('yes', False): wont_yes_false, ('yes', True): wont_yes_true} - - def telnet_DO(self, option): - s = self.getOptionState(option) - self.doMap[s.us.state, s.us.negotiating](self, s, option) - - def do_no_false(self, state, option): - # Peer is unilaterally requesting that we enable an option. - if self.enableLocal(option): - state.us.state = 'yes' - self._will(option) - else: - self._wont(option) - - def do_no_true(self, state, option): - # Peer agreed to allow us to enable an option at our request. - state.us.state = 'yes' - state.us.negotiating = False - d = state.us.onResult - state.us.onResult = None - d.callback(True) - self.enableLocal(option) - - def do_yes_false(self, state, option): - # Peer is unilaterally requesting us to enable an already-enabled option. - # Ignore this. - pass - - def do_yes_true(self, state, option): - # This is a bogus state. It is here for completeness. It will never be - # entered. - assert False, "do_yes_true can never be entered, but was called with %r, %r" % (state, option) - - doMap = {('no', False): do_no_false, ('no', True): do_no_true, - ('yes', False): do_yes_false, ('yes', True): do_yes_true} - - def telnet_DONT(self, option): - s = self.getOptionState(option) - self.dontMap[s.us.state, s.us.negotiating](self, s, option) - - def dont_no_false(self, state, option): - # Peer is unilaterally demanding us to disable an already-disabled option. - # Ignore this. - pass - - def dont_no_true(self, state, option): - # Offered option was refused. Fail the Deferred returned by the - # previous will() call. - state.us.negotiating = False - d = state.us.onResult - state.us.onResult = None - d.errback(OptionRefused(option)) - - def dont_yes_false(self, state, option): - # Peer is unilaterally demanding we disable an option. - state.us.state = 'no' - self.disableLocal(option) - self._wont(option) - - def dont_yes_true(self, state, option): - # Peer acknowledged our notice that we will disable an option. - state.us.state = 'no' - state.us.negotiating = False - d = state.us.onResult - state.us.onResult = None - d.callback(True) - self.disableLocal(option) - - dontMap = {('no', False): dont_no_false, ('no', True): dont_no_true, - ('yes', False): dont_yes_false, ('yes', True): dont_yes_true} - - def enableLocal(self, option): - """ - Reject all attempts to enable options. - """ - return False - - - def enableRemote(self, option): - """ - Reject all attempts to enable options. - """ - return False - - - def disableLocal(self, option): - """ - Signal a programming error by raising an exception. - - L{enableLocal} must return true for the given value of C{option} in - order for this method to be called. If a subclass of L{Telnet} - overrides enableLocal to allow certain options to be enabled, it must - also override disableLocal to disable those options. - - @raise NotImplementedError: Always raised. - """ - raise NotImplementedError( - "Don't know how to disable local telnet option %r" % (option,)) - - - def disableRemote(self, option): - """ - Signal a programming error by raising an exception. - - L{enableRemote} must return true for the given value of C{option} in - order for this method to be called. If a subclass of L{Telnet} - overrides enableRemote to allow certain options to be enabled, it must - also override disableRemote tto disable those options. - - @raise NotImplementedError: Always raised. - """ - raise NotImplementedError( - "Don't know how to disable remote telnet option %r" % (option,)) - - - -class ProtocolTransportMixin: - def write(self, bytes): - self.transport.write(bytes.replace('\n', '\r\n')) - - def writeSequence(self, seq): - self.transport.writeSequence(seq) - - def loseConnection(self): - self.transport.loseConnection() - - def getHost(self): - return self.transport.getHost() - - def getPeer(self): - return self.transport.getPeer() - -class TelnetTransport(Telnet, ProtocolTransportMixin): - """ - @ivar protocol: An instance of the protocol to which this - transport is connected, or None before the connection is - established and after it is lost. - - @ivar protocolFactory: A callable which returns protocol instances - which provide L{ITelnetProtocol}. This will be invoked when a - connection is established. It is passed *protocolArgs and - **protocolKwArgs. - - @ivar protocolArgs: A tuple of additional arguments to - pass to protocolFactory. - - @ivar protocolKwArgs: A dictionary of additional arguments - to pass to protocolFactory. - """ - - disconnecting = False - - protocolFactory = None - protocol = None - - def __init__(self, protocolFactory=None, *a, **kw): - Telnet.__init__(self) - if protocolFactory is not None: - self.protocolFactory = protocolFactory - self.protocolArgs = a - self.protocolKwArgs = kw - - def connectionMade(self): - if self.protocolFactory is not None: - self.protocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs) - assert ITelnetProtocol.providedBy(self.protocol) - try: - factory = self.factory - except AttributeError: - pass - else: - self.protocol.factory = factory - self.protocol.makeConnection(self) - - def connectionLost(self, reason): - Telnet.connectionLost(self, reason) - if self.protocol is not None: - try: - self.protocol.connectionLost(reason) - finally: - del self.protocol - - def enableLocal(self, option): - return self.protocol.enableLocal(option) - - def enableRemote(self, option): - return self.protocol.enableRemote(option) - - def disableLocal(self, option): - return self.protocol.disableLocal(option) - - def disableRemote(self, option): - return self.protocol.disableRemote(option) - - def unhandledSubnegotiation(self, command, bytes): - self.protocol.unhandledSubnegotiation(command, bytes) - - def unhandledCommand(self, command, argument): - self.protocol.unhandledCommand(command, argument) - - def applicationDataReceived(self, bytes): - self.protocol.dataReceived(bytes) - - def write(self, data): - ProtocolTransportMixin.write(self, data.replace('\xff','\xff\xff')) - - -class TelnetBootstrapProtocol(TelnetProtocol, ProtocolTransportMixin): - implements() - - protocol = None - - def __init__(self, protocolFactory, *args, **kw): - self.protocolFactory = protocolFactory - self.protocolArgs = args - self.protocolKwArgs = kw - - def connectionMade(self): - self.transport.negotiationMap[NAWS] = self.telnet_NAWS - self.transport.negotiationMap[LINEMODE] = self.telnet_LINEMODE - - for opt in (LINEMODE, NAWS, SGA): - self.transport.do(opt).addErrback(log.err) - for opt in (ECHO,): - self.transport.will(opt).addErrback(log.err) - - self.protocol = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs) - - try: - factory = self.factory - except AttributeError: - pass - else: - self.protocol.factory = factory - - self.protocol.makeConnection(self) - - def connectionLost(self, reason): - if self.protocol is not None: - try: - self.protocol.connectionLost(reason) - finally: - del self.protocol - - def dataReceived(self, data): - self.protocol.dataReceived(data) - - def enableLocal(self, opt): - if opt == ECHO: - return True - elif opt == SGA: - return True - else: - return False - - def enableRemote(self, opt): - if opt == LINEMODE: - self.transport.requestNegotiation(LINEMODE, MODE + chr(TRAPSIG)) - return True - elif opt == NAWS: - return True - elif opt == SGA: - return True - else: - return False - - def telnet_NAWS(self, bytes): - # NAWS is client -> server *only*. self.protocol will - # therefore be an ITerminalTransport, the `.protocol' - # attribute of which will be an ITerminalProtocol. Maybe. - # You know what, XXX TODO clean this up. - if len(bytes) == 4: - width, height = struct.unpack('!HH', ''.join(bytes)) - self.protocol.terminalProtocol.terminalSize(width, height) - else: - log.msg("Wrong number of NAWS bytes") - - - linemodeSubcommands = { - LINEMODE_SLC: 'SLC'} - def telnet_LINEMODE(self, bytes): - revmap = {} - linemodeSubcommand = bytes[0] - if 0: - # XXX TODO: This should be enabled to parse linemode subnegotiation. - getattr(self, 'linemode_' + self.linemodeSubcommands[linemodeSubcommand])(bytes[1:]) - - def linemode_SLC(self, bytes): - chunks = zip(*[iter(bytes)]*3) - for slcFunction, slcValue, slcWhat in chunks: - # Later, we should parse stuff. - 'SLC', ord(slcFunction), ord(slcValue), ord(slcWhat) - -from twisted.protocols import basic - -class StatefulTelnetProtocol(basic.LineReceiver, TelnetProtocol): - delimiter = '\n' - - state = 'Discard' - - def connectionLost(self, reason): - basic.LineReceiver.connectionLost(self, reason) - TelnetProtocol.connectionLost(self, reason) - - def lineReceived(self, line): - oldState = self.state - newState = getattr(self, "telnet_" + oldState)(line) - if newState is not None: - if self.state == oldState: - self.state = newState - else: - log.msg("Warning: state changed and new state returned") - - def telnet_Discard(self, line): - pass - -from twisted.cred import credentials - -class AuthenticatingTelnetProtocol(StatefulTelnetProtocol): - """A protocol which prompts for credentials and attempts to authenticate them. - - Username and password prompts are given (the password is obscured). When the - information is collected, it is passed to a portal and an avatar implementing - L{ITelnetProtocol} is requested. If an avatar is returned, it connected to this - protocol's transport, and this protocol's transport is connected to it. - Otherwise, the user is re-prompted for credentials. - """ - - state = "User" - protocol = None - - def __init__(self, portal): - self.portal = portal - - def connectionMade(self): - self.transport.write("Username: ") - - def connectionLost(self, reason): - StatefulTelnetProtocol.connectionLost(self, reason) - if self.protocol is not None: - try: - self.protocol.connectionLost(reason) - self.logout() - finally: - del self.protocol, self.logout - - def telnet_User(self, line): - self.username = line - self.transport.will(ECHO) - self.transport.write("Password: ") - return 'Password' - - def telnet_Password(self, line): - username, password = self.username, line - del self.username - def login(ignored): - creds = credentials.UsernamePassword(username, password) - d = self.portal.login(creds, None, ITelnetProtocol) - d.addCallback(self._cbLogin) - d.addErrback(self._ebLogin) - self.transport.wont(ECHO).addCallback(login) - return 'Discard' - - def _cbLogin(self, ial): - interface, protocol, logout = ial - assert interface is ITelnetProtocol - self.protocol = protocol - self.logout = logout - self.state = 'Command' - - protocol.makeConnection(self.transport) - self.transport.protocol = protocol - - def _ebLogin(self, failure): - self.transport.write("\nAuthentication failed\n") - self.transport.write("Username: ") - self.state = "User" - -__all__ = [ - # Exceptions - 'TelnetError', 'NegotiationError', 'OptionRefused', - 'AlreadyNegotiating', 'AlreadyEnabled', 'AlreadyDisabled', - - # Interfaces - 'ITelnetProtocol', 'ITelnetTransport', - - # Other stuff, protocols, etc. - 'Telnet', 'TelnetProtocol', 'TelnetTransport', - 'TelnetBootstrapProtocol', - - ] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py deleted file mode 100755 index d09b4122..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/__init__.py +++ /dev/null @@ -1 +0,0 @@ -'conch tests' diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py deleted file mode 100755 index 9417ec57..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/keydata.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_keys -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Data used by test_keys as well as others. -""" -RSAData = { - 'n':long('1062486685755247411169438309495398947372127791189432809481' - '382072971106157632182084539383569281493520117634129557550415277' - '516685881326038852354459895734875625093273594925884531272867425' - '864910490065695876046999646807138717162833156501L'), - 'e':35L, - 'd':long('6678487739032983727350755088256793383481946116047863373882' - '973030104095847973715959961839578340816412167985957218887914482' - '713602371850869127033494910375212470664166001439410214474266799' - '85974425203903884190893469297150446322896587555L'), - 'q':long('3395694744258061291019136154000709371890447462086362702627' - '9704149412726577280741108645721676968699696898960891593323L'), - 'p':long('3128922844292337321766351031842562691837301298995834258844' - '4720539204069737532863831050930719431498338835415515173887L')} - -DSAData = { - 'y':long('2300663509295750360093768159135720439490120577534296730713' - '348508834878775464483169644934425336771277908527130096489120714' - '610188630979820723924744291603865L'), - 'g':long('4451569990409370769930903934104221766858515498655655091803' - '866645719060300558655677517139568505649468378587802312867198352' - '1161998270001677664063945776405L'), - 'p':long('7067311773048598659694590252855127633397024017439939353776' - '608320410518694001356789646664502838652272205440894335303988504' - '978724817717069039110940675621677L'), - 'q':1184501645189849666738820838619601267690550087703L, - 'x':863951293559205482820041244219051653999559962819L} - -publicRSA_openssh = ("ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBE" -"vLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYL" -"h5KmRpslkYHRivcJSkbh/C+BR3utDS555mV comment") - -privateRSA_openssh = """-----BEGIN RSA PRIVATE KEY----- -MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW -4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw -vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb -Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1 -xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8 -PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2 -gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu -DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML -pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP -EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg== ------END RSA PRIVATE KEY-----""" - -# some versions of OpenSSH generate these (slightly different keys) -privateRSA_openssh_alternate = """-----BEGIN RSA PRIVATE KEY----- -MIIBzjCCAcgCAQACYQCvMnHw5g6cmbN/i18ES8uLwNU+snf9z2TYj8DPrh/GMd/2 -KbJEluLG1CGUf2V82NQjH7guaskflA1GwWmitwcMo5PBNNguHkqZGmyWRgdGK9wl -KRuH8L4FHe60NLnnmZUCASMCYG4ftVWX6+1n7SuZbuzB7ahNUtbz1mUGBN/lVJ/M -iQA8m2eH7GWgq81vZZCKl5BNxiGPqI3YWYZDtYGxtNdfLCIKYcElikcStJr4ehEc -SqiLdcSRCTu+BMpF2VeKDSfLIwIxANyfa9mYIVYRjelfA50K05NuE3dBPIVPAHD9 -BVT/vD0Jv4P2l39kEJEE/qJnR1RCawIxAMtKS9BAR+hFUvfHrwwgbUMNtjmU+dql -5QMGdoMk64ihVaKo3hI7d0mSiqlx0gKT/wIwS6Rffc3CSWUatmm4GJX/Zb9XIZK1 -qgx1Lg2bbZmCXhH4hQQWr1WCBdXTpWU9BvIzAjAXO7DkmaHRZwIq8j/kIPaLUgYy -d20DC6Uk6su3N2tgEnAv2MjsJA2iAh55w918ozMCMQC0c5dLUBCjF7OoR/E6FHZS -0TgqzxIUNMGoVEwpNYCgOLjw+kzEwoWr24eCutzr2yowAA== -------END RSA PRIVATE KEY------""" - -# encrypted with the passphrase 'encrypted' -privateRSA_openssh_encrypted = """-----BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,FFFFFFFFFFFFFFFF - -30qUR7DYY/rpVJu159paRM1mUqt/IMibfEMTKWSjNhCVD21hskftZCJROw/WgIFt -ncusHpJMkjgwEpho0KyKilcC7zxjpunTex24Meb5pCdXCrYft8AyUkRdq3dugMqT -4nuWuWxziluBhKQ2M9tPGcEOeulU4vVjceZt2pZhZQVBf08o3XUv5/7RYd24M9md -WIo+5zdj2YQkI6xMFTP954O/X32ME1KQt98wgNEy6mxhItbvf00mH3woALwEKP3v -PSMxxtx3VKeDKd9YTOm1giKkXZUf91vZWs0378tUBrU4U5qJxgryTjvvVKOtofj6 -4qQy6+r6M6wtwVlXBgeRm2gBPvL3nv6MsROp3E6ztBd/e7A8fSec+UTq3ko/EbGP -0QG+IG5tg8FsdITxQ9WAIITZL3Rc6hA5Ymx1VNhySp3iSiso8Jof27lku4pyuvRV -ko/B3N2H7LnQrGV0GyrjeYocW/qZh/PCsY48JBFhlNQexn2mn44AJW3y5xgbhvKA -3mrmMD1hD17ZvZxi4fPHjbuAyM1vFqhQx63eT9ijbwJ91svKJl5O5MIv41mCRonm -hxvOXw8S0mjSasyofptzzQCtXxFLQigXbpQBltII+Ys= ------END RSA PRIVATE KEY-----""" - -# encrypted with the passphrase 'testxp'. NB: this key was generated by -# OpenSSH, so it doesn't use the same key data as the other keys here. -privateRSA_openssh_encrypted_aes = """-----BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,0673309A6ACCAB4B77DEE1C1E536AC26 - -4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n -T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H -g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB -sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 -9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV -gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW -0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE -vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS -hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk -2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf -qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk -4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY -EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n -8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 -fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P -V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ -0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 -xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI -dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup -VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk -gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c -8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw -SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 -CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE -xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P ------END RSA PRIVATE KEY-----""" - -publicRSA_lsh = ("{KDEwOnB1YmxpYy1rZXkoMTQ6cnNhLXBrY3MxLXNoYTEoMTpuOTc6AK8yc" -"fDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW4sbUIZR/ZXzY1CMfuC5qyR+UDUbB" -"aaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fwvgUd7rQ0ueeZlSkoMTplMTojKSkp}") - -privateRSA_lsh = ("(11:private-key(9:rsa-pkcs1(1:n97:\x00\xaf2q\xf0\xe6\x0e" -"\x9c\x99\xb3\x7f\x8b_\x04K\xcb\x8b\xc0\xd5>\xb2w\xfd\xcfd\xd8\x8f\xc0\xcf" -"\xae\x1f\xc61\xdf\xf6)\xb2D\x96\xe2\xc6\xd4!\x94\x7fe|\xd8\xd4#\x1f\xb8.j" -"\xc9\x1f\x94\rF\xc1i\xa2\xb7\x07\x0c\xa3\x93\xc14\xd8.\x1eJ\x99\x1al\x96F" -"\x07F+\xdc%)\x1b\x87\xf0\xbe\x05\x1d\xee\xb44\xb9\xe7\x99\x95)(1:e1:#)(1:d9" -"6:n\x1f\xb5U\x97\xeb\xedg\xed+\x99n\xec\xc1\xed\xa8MR\xd6\xf3\xd6e\x06\x04" -"\xdf\xe5T\x9f\xcc\x89\x00<\x9bg\x87\xece\xa0\xab\xcdoe\x90\x8a\x97\x90M\xc6" -'!\x8f\xa8\x8d\xd8Y\x86C\xb5\x81\xb1\xb4\xd7_,"\na\xc1%\x8aG\x12\xb4\x9a\xf8' -"z\x11\x1cJ\xa8\x8bu\xc4\x91\t;\xbe\x04\xcaE\xd9W\x8a\r\'\xcb#)(1:p49:\x00" -"\xdc\x9fk\xd9\x98!V\x11\x8d\xe9_\x03\x9d\n\xd3\x93n\x13wA<\x85O\x00p\xfd" -"\x05T\xff\xbc=\t\xbf\x83\xf6\x97\x7fd\x10\x91\x04\xfe\xa2gGTBk)(1:q49:\x00" -"\xcbJK\xd0@G\xe8ER\xf7\xc7\xaf\x0c mC\r\xb69\x94\xf9\xda\xa5\xe5\x03\x06v" -"\x83$\xeb\x88\xa1U\xa2\xa8\xde\x12;wI\x92\x8a\xa9q\xd2\x02\x93\xff)(1:a48:K" -"\xa4_}\xcd\xc2Ie\x1a\xb6i\xb8\x18\x95\xffe\xbfW!\x92\xb5\xaa\x0cu.\r\x9bm" -"\x99\x82^\x11\xf8\x85\x04\x16\xafU\x82\x05\xd5\xd3\xa5e=\x06\xf23)(1:b48:" -"\x17;\xb0\xe4\x99\xa1\xd1g\x02*\xf2?\xe4 \xf6\x8bR\x062wm\x03\x0b\xa5$\xea" -"\xcb\xb77k`\x12p/\xd8\xc8\xec$\r\xa2\x02\x1ey\xc3\xdd|\xa33)(1:c49:\x00\xb4" -"s\x97KP\x10\xa3\x17\xb3\xa8G\xf1:\x14vR\xd18*\xcf\x12\x144\xc1\xa8TL)5\x80" -"\xa08\xb8\xf0\xfaL\xc4\xc2\x85\xab\xdb\x87\x82\xba\xdc\xeb\xdb*)))") - -privateRSA_agentv3 = ("\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00`" -"n\x1f\xb5U\x97\xeb\xedg\xed+\x99n\xec\xc1\xed\xa8MR\xd6\xf3\xd6e\x06\x04" -"\xdf\xe5T\x9f\xcc\x89\x00<\x9bg\x87\xece\xa0\xab\xcdoe\x90\x8a\x97\x90M\xc6" -'!\x8f\xa8\x8d\xd8Y\x86C\xb5\x81\xb1\xb4\xd7_,"\na\xc1%\x8aG\x12\xb4\x9a\xf8' -"z\x11\x1cJ\xa8\x8bu\xc4\x91\t;\xbe\x04\xcaE\xd9W\x8a\r\'\xcb#\x00\x00\x00a" -"\x00\xaf2q\xf0\xe6\x0e\x9c\x99\xb3\x7f\x8b_\x04K\xcb\x8b\xc0\xd5>\xb2w\xfd" -"\xcfd\xd8\x8f\xc0\xcf\xae\x1f\xc61\xdf\xf6)\xb2D\x96\xe2\xc6\xd4!\x94\x7fe|" -"\xd8\xd4#\x1f\xb8.j\xc9\x1f\x94\rF\xc1i\xa2\xb7\x07\x0c\xa3\x93\xc14\xd8." -"\x1eJ\x99\x1al\x96F\x07F+\xdc%)\x1b\x87\xf0\xbe\x05\x1d\xee\xb44\xb9\xe7" -"\x99\x95\x00\x00\x001\x00\xb4s\x97KP\x10\xa3\x17\xb3\xa8G\xf1:\x14vR\xd18*" -"\xcf\x12\x144\xc1\xa8TL)5\x80\xa08\xb8\xf0\xfaL\xc4\xc2\x85\xab\xdb\x87\x82" -"\xba\xdc\xeb\xdb*\x00\x00\x001\x00\xcbJK\xd0@G\xe8ER\xf7\xc7\xaf\x0c mC\r" -"\xb69\x94\xf9\xda\xa5\xe5\x03\x06v\x83$\xeb\x88\xa1U\xa2\xa8\xde\x12;wI\x92" -"\x8a\xa9q\xd2\x02\x93\xff\x00\x00\x001\x00\xdc\x9fk\xd9\x98!V\x11\x8d\xe9_" -"\x03\x9d\n\xd3\x93n\x13wA<\x85O\x00p\xfd\x05T\xff\xbc=\t\xbf\x83\xf6\x97" -"\x7fd\x10\x91\x04\xfe\xa2gGTBk") - -publicDSA_openssh = ("ssh-dss AAAAB3NzaC1kc3MAAABBAIbwTOSsZ7Bl7U1KyMNqV13Tu7" -"yRAtTr70PVI3QnfrPumf2UzCgpL1ljbKxSfAi05XvrE/1vfCFAsFYXRZLhQy0AAAAVAM965Akmo" -"6eAi7K+k9qDR4TotFAXAAAAQADZlpTW964haQWS4vC063NGdldT6xpUGDcDRqbm90CoPEa2RmNO" -"uOqi8lnbhYraEzypYH3K4Gzv/bxCBnKtHRUAAABAK+1osyWBS0+P90u/rAuko6chZ98thUSY2kL" -"SHp6hLKyy2bjnT29h7haELE+XHfq2bM9fckDx2FLOSIJzy83VmQ== comment") - -privateDSA_openssh = """-----BEGIN DSA PRIVATE KEY----- -MIH4AgEAAkEAhvBM5KxnsGXtTUrIw2pXXdO7vJEC1OvvQ9UjdCd+s+6Z/ZTMKCkv -WWNsrFJ8CLTle+sT/W98IUCwVhdFkuFDLQIVAM965Akmo6eAi7K+k9qDR4TotFAX -AkAA2ZaU1veuIWkFkuLwtOtzRnZXU+saVBg3A0am5vdAqDxGtkZjTrjqovJZ24WK -2hM8qWB9yuBs7/28QgZyrR0VAkAr7WizJYFLT4/3S7+sC6SjpyFn3y2FRJjaQtIe -nqEsrLLZuOdPb2HuFoQsT5cd+rZsz19yQPHYUs5IgnPLzdWZAhUAl1TqdmlAG/b4 -nnVchGiO9sML8MM= ------END DSA PRIVATE KEY-----""" - -publicDSA_lsh = ("{KDEwOnB1YmxpYy1rZXkoMzpkc2EoMTpwNjU6AIbwTOSsZ7Bl7U1KyMNqV" -"13Tu7yRAtTr70PVI3QnfrPumf2UzCgpL1ljbKxSfAi05XvrE/1vfCFAsFYXRZLhQy0pKDE6cTIx" -"OgDPeuQJJqOngIuyvpPag0eE6LRQFykoMTpnNjQ6ANmWlNb3riFpBZLi8LTrc0Z2V1PrGlQYNwN" -"Gpub3QKg8RrZGY0646qLyWduFitoTPKlgfcrgbO/9vEIGcq0dFSkoMTp5NjQ6K+1osyWBS0+P90" -"u/rAuko6chZ98thUSY2kLSHp6hLKyy2bjnT29h7haELE+XHfq2bM9fckDx2FLOSIJzy83VmSkpK" -"Q==}") - -privateDSA_lsh = ("(11:private-key(3:dsa(1:p65:\x00\x86\xf0L\xe4\xacg\xb0e" -"\xedMJ\xc8\xc3jW]\xd3\xbb\xbc\x91\x02\xd4\xeb\xefC\xd5#t'~\xb3\xee\x99\xfd" -"\x94\xcc()/Ycl\xacR|\x08\xb4\xe5{\xeb\x13\xfdo|!@\xb0V\x17E\x92\xe1C-)(1:q2" -"1:\x00\xcfz\xe4\t&\xa3\xa7\x80\x8b\xb2\xbe\x93\xda\x83G\x84\xe8\xb4P\x17)(1" -":g64:\x00\xd9\x96\x94\xd6\xf7\xae!i\x05\x92\xe2\xf0\xb4\xebsFvWS\xeb\x1aT" -"\x187\x03F\xa6\xe6\xf7@\xa8<F\xb6FcN\xb8\xea\xa2\xf2Y\xdb\x85\x8a\xda\x13<" -"\xa9`}\xca\xe0l\xef\xfd\xbcB\x06r\xad\x1d\x15)(1:y64:+\xedh\xb3%\x81KO\x8f" -"\xf7K\xbf\xac\x0b\xa4\xa3\xa7!g\xdf-\x85D\x98\xdaB\xd2\x1e\x9e\xa1,\xac\xb2" -"\xd9\xb8\xe7Ooa\xee\x16\x84,O\x97\x1d\xfa\xb6l\xcf_r@\xf1\xd8R\xceH\x82s" -"\xcb\xcd\xd5\x99)(1:x21:\x00\x97T\xeavi@\x1b\xf6\xf8\x9eu\\\x84h\x8e\xf6" -"\xc3\x0b\xf0\xc3)))") - -privateDSA_agentv3 = ("\x00\x00\x00\x07ssh-dss\x00\x00\x00A\x00\x86\xf0L\xe4" -"\xacg\xb0e\xedMJ\xc8\xc3jW]\xd3\xbb\xbc\x91\x02\xd4\xeb\xefC\xd5#t'~\xb3" -"\xee\x99\xfd\x94\xcc()/Ycl\xacR|\x08\xb4\xe5{\xeb\x13\xfdo|!@\xb0V\x17E\x92" -"\xe1C-\x00\x00\x00\x15\x00\xcfz\xe4\t&\xa3\xa7\x80\x8b\xb2\xbe\x93\xda\x83G" -"\x84\xe8\xb4P\x17\x00\x00\x00@\x00\xd9\x96\x94\xd6\xf7\xae!i\x05\x92\xe2" -"\xf0\xb4\xebsFvWS\xeb\x1aT\x187\x03F\xa6\xe6\xf7@\xa8<F\xb6FcN\xb8\xea\xa2" -"\xf2Y\xdb\x85\x8a\xda\x13<\xa9`}\xca\xe0l\xef\xfd\xbcB\x06r\xad\x1d\x15\x00" -"\x00\x00@+\xedh\xb3%\x81KO\x8f\xf7K\xbf\xac\x0b\xa4\xa3\xa7!g\xdf-\x85D\x98" -"\xdaB\xd2\x1e\x9e\xa1,\xac\xb2\xd9\xb8\xe7Ooa\xee\x16\x84,O\x97\x1d\xfa\xb6" -"l\xcf_r@\xf1\xd8R\xceH\x82s\xcb\xcd\xd5\x99\x00\x00\x00\x15\x00\x97T\xeavi@" -"\x1b\xf6\xf8\x9eu\\\x84h\x8e\xf6\xc3\x0b\xf0\xc3") - -__all__ = ['DSAData', 'RSAData', 'privateDSA_agentv3', 'privateDSA_lsh', - 'privateDSA_openssh', 'privateRSA_agentv3', 'privateRSA_lsh', - 'privateRSA_openssh', 'publicDSA_lsh', 'publicDSA_openssh', - 'publicRSA_lsh', 'publicRSA_openssh', 'privateRSA_openssh_alternate'] - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py deleted file mode 100755 index cf02275b..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_address.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{SSHTransportAddrress} in ssh/address.py -""" - -from twisted.trial import unittest -from twisted.internet.address import IPv4Address -from twisted.internet.test.test_address import AddressTestCaseMixin - -from twisted.conch.ssh.address import SSHTransportAddress - - - -class SSHTransportAddressTestCase(unittest.TestCase, AddressTestCaseMixin): - """ - L{twisted.conch.ssh.address.SSHTransportAddress} is what Conch transports - use to represent the other side of the SSH connection. This tests the - basic functionality of that class (string representation, comparison, &c). - """ - - - def _stringRepresentation(self, stringFunction): - """ - The string representation of C{SSHTransportAddress} should be - "SSHTransportAddress(<stringFunction on address>)". - """ - addr = self.buildAddress() - stringValue = stringFunction(addr) - addressValue = stringFunction(addr.address) - self.assertEqual(stringValue, - "SSHTransportAddress(%s)" % addressValue) - - - def buildAddress(self): - """ - Create an arbitrary new C{SSHTransportAddress}. A new instance is - created for each call, but always for the same address. - """ - return SSHTransportAddress(IPv4Address("TCP", "127.0.0.1", 22)) - - - def buildDifferentAddress(self): - """ - Like C{buildAddress}, but with a different fixed address. - """ - return SSHTransportAddress(IPv4Address("TCP", "127.0.0.2", 22)) - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py deleted file mode 100755 index 532a0e51..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_agent.py +++ /dev/null @@ -1,399 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.ssh.agent}. -""" - -import struct - -from twisted.trial import unittest - -try: - import OpenSSL -except ImportError: - iosim = None -else: - from twisted.test import iosim - -try: - import Crypto.Cipher.DES3 -except ImportError: - Crypto = None - -try: - import pyasn1 -except ImportError: - pyasn1 = None - -if Crypto and pyasn1: - from twisted.conch.ssh import keys, agent -else: - keys = agent = None - -from twisted.conch.test import keydata -from twisted.conch.error import ConchError, MissingKeyStoreError - - -class StubFactory(object): - """ - Mock factory that provides the keys attribute required by the - SSHAgentServerProtocol - """ - def __init__(self): - self.keys = {} - - - -class AgentTestBase(unittest.TestCase): - """ - Tests for SSHAgentServer/Client. - """ - if iosim is None: - skip = "iosim requires SSL, but SSL is not available" - elif agent is None or keys is None: - skip = "Cannot run without PyCrypto or PyASN1" - - def setUp(self): - # wire up our client <-> server - self.client, self.server, self.pump = iosim.connectedServerAndClient( - agent.SSHAgentServer, agent.SSHAgentClient) - - # the server's end of the protocol is stateful and we store it on the - # factory, for which we only need a mock - self.server.factory = StubFactory() - - # pub/priv keys of each kind - self.rsaPrivate = keys.Key.fromString(keydata.privateRSA_openssh) - self.dsaPrivate = keys.Key.fromString(keydata.privateDSA_openssh) - - self.rsaPublic = keys.Key.fromString(keydata.publicRSA_openssh) - self.dsaPublic = keys.Key.fromString(keydata.publicDSA_openssh) - - - -class TestServerProtocolContractWithFactory(AgentTestBase): - """ - The server protocol is stateful and so uses its factory to track state - across requests. This test asserts that the protocol raises if its factory - doesn't provide the necessary storage for that state. - """ - def test_factorySuppliesKeyStorageForServerProtocol(self): - # need a message to send into the server - msg = struct.pack('!LB',1, agent.AGENTC_REQUEST_IDENTITIES) - del self.server.factory.__dict__['keys'] - self.assertRaises(MissingKeyStoreError, - self.server.dataReceived, msg) - - - -class TestUnimplementedVersionOneServer(AgentTestBase): - """ - Tests for methods with no-op implementations on the server. We need these - for clients, such as openssh, that try v1 methods before going to v2. - - Because the client doesn't expose these operations with nice method names, - we invoke sendRequest directly with an op code. - """ - - def test_agentc_REQUEST_RSA_IDENTITIES(self): - """ - assert that we get the correct op code for an RSA identities request - """ - d = self.client.sendRequest(agent.AGENTC_REQUEST_RSA_IDENTITIES, '') - self.pump.flush() - def _cb(packet): - self.assertEqual( - agent.AGENT_RSA_IDENTITIES_ANSWER, ord(packet[0])) - return d.addCallback(_cb) - - - def test_agentc_REMOVE_RSA_IDENTITY(self): - """ - assert that we get the correct op code for an RSA remove identity request - """ - d = self.client.sendRequest(agent.AGENTC_REMOVE_RSA_IDENTITY, '') - self.pump.flush() - return d.addCallback(self.assertEqual, '') - - - def test_agentc_REMOVE_ALL_RSA_IDENTITIES(self): - """ - assert that we get the correct op code for an RSA remove all identities - request. - """ - d = self.client.sendRequest(agent.AGENTC_REMOVE_ALL_RSA_IDENTITIES, '') - self.pump.flush() - return d.addCallback(self.assertEqual, '') - - - -if agent is not None: - class CorruptServer(agent.SSHAgentServer): - """ - A misbehaving server that returns bogus response op codes so that we can - verify that our callbacks that deal with these op codes handle such - miscreants. - """ - def agentc_REQUEST_IDENTITIES(self, data): - self.sendResponse(254, '') - - - def agentc_SIGN_REQUEST(self, data): - self.sendResponse(254, '') - - - -class TestClientWithBrokenServer(AgentTestBase): - """ - verify error handling code in the client using a misbehaving server - """ - - def setUp(self): - AgentTestBase.setUp(self) - self.client, self.server, self.pump = iosim.connectedServerAndClient( - CorruptServer, agent.SSHAgentClient) - # the server's end of the protocol is stateful and we store it on the - # factory, for which we only need a mock - self.server.factory = StubFactory() - - - def test_signDataCallbackErrorHandling(self): - """ - Assert that L{SSHAgentClient.signData} raises a ConchError - if we get a response from the server whose opcode doesn't match - the protocol for data signing requests. - """ - d = self.client.signData(self.rsaPublic.blob(), "John Hancock") - self.pump.flush() - return self.assertFailure(d, ConchError) - - - def test_requestIdentitiesCallbackErrorHandling(self): - """ - Assert that L{SSHAgentClient.requestIdentities} raises a ConchError - if we get a response from the server whose opcode doesn't match - the protocol for identity requests. - """ - d = self.client.requestIdentities() - self.pump.flush() - return self.assertFailure(d, ConchError) - - - -class TestAgentKeyAddition(AgentTestBase): - """ - Test adding different flavors of keys to an agent. - """ - - def test_addRSAIdentityNoComment(self): - """ - L{SSHAgentClient.addIdentity} adds the private key it is called - with to the SSH agent server to which it is connected, associating - it with the comment it is called with. - - This test asserts that ommitting the comment produces an - empty string for the comment on the server. - """ - d = self.client.addIdentity(self.rsaPrivate.privateBlob()) - self.pump.flush() - def _check(ignored): - serverKey = self.server.factory.keys[self.rsaPrivate.blob()] - self.assertEqual(self.rsaPrivate, serverKey[0]) - self.assertEqual('', serverKey[1]) - return d.addCallback(_check) - - - def test_addDSAIdentityNoComment(self): - """ - L{SSHAgentClient.addIdentity} adds the private key it is called - with to the SSH agent server to which it is connected, associating - it with the comment it is called with. - - This test asserts that ommitting the comment produces an - empty string for the comment on the server. - """ - d = self.client.addIdentity(self.dsaPrivate.privateBlob()) - self.pump.flush() - def _check(ignored): - serverKey = self.server.factory.keys[self.dsaPrivate.blob()] - self.assertEqual(self.dsaPrivate, serverKey[0]) - self.assertEqual('', serverKey[1]) - return d.addCallback(_check) - - - def test_addRSAIdentityWithComment(self): - """ - L{SSHAgentClient.addIdentity} adds the private key it is called - with to the SSH agent server to which it is connected, associating - it with the comment it is called with. - - This test asserts that the server receives/stores the comment - as sent by the client. - """ - d = self.client.addIdentity( - self.rsaPrivate.privateBlob(), comment='My special key') - self.pump.flush() - def _check(ignored): - serverKey = self.server.factory.keys[self.rsaPrivate.blob()] - self.assertEqual(self.rsaPrivate, serverKey[0]) - self.assertEqual('My special key', serverKey[1]) - return d.addCallback(_check) - - - def test_addDSAIdentityWithComment(self): - """ - L{SSHAgentClient.addIdentity} adds the private key it is called - with to the SSH agent server to which it is connected, associating - it with the comment it is called with. - - This test asserts that the server receives/stores the comment - as sent by the client. - """ - d = self.client.addIdentity( - self.dsaPrivate.privateBlob(), comment='My special key') - self.pump.flush() - def _check(ignored): - serverKey = self.server.factory.keys[self.dsaPrivate.blob()] - self.assertEqual(self.dsaPrivate, serverKey[0]) - self.assertEqual('My special key', serverKey[1]) - return d.addCallback(_check) - - - -class TestAgentClientFailure(AgentTestBase): - def test_agentFailure(self): - """ - verify that the client raises ConchError on AGENT_FAILURE - """ - d = self.client.sendRequest(254, '') - self.pump.flush() - return self.assertFailure(d, ConchError) - - - -class TestAgentIdentityRequests(AgentTestBase): - """ - Test operations against a server with identities already loaded. - """ - - def setUp(self): - AgentTestBase.setUp(self) - self.server.factory.keys[self.dsaPrivate.blob()] = ( - self.dsaPrivate, 'a comment') - self.server.factory.keys[self.rsaPrivate.blob()] = ( - self.rsaPrivate, 'another comment') - - - def test_signDataRSA(self): - """ - Sign data with an RSA private key and then verify it with the public - key. - """ - d = self.client.signData(self.rsaPublic.blob(), "John Hancock") - self.pump.flush() - def _check(sig): - expected = self.rsaPrivate.sign("John Hancock") - self.assertEqual(expected, sig) - self.assertTrue(self.rsaPublic.verify(sig, "John Hancock")) - return d.addCallback(_check) - - - def test_signDataDSA(self): - """ - Sign data with a DSA private key and then verify it with the public - key. - """ - d = self.client.signData(self.dsaPublic.blob(), "John Hancock") - self.pump.flush() - def _check(sig): - # Cannot do this b/c DSA uses random numbers when signing - # expected = self.dsaPrivate.sign("John Hancock") - # self.assertEqual(expected, sig) - self.assertTrue(self.dsaPublic.verify(sig, "John Hancock")) - return d.addCallback(_check) - - - def test_signDataRSAErrbackOnUnknownBlob(self): - """ - Assert that we get an errback if we try to sign data using a key that - wasn't added. - """ - del self.server.factory.keys[self.rsaPublic.blob()] - d = self.client.signData(self.rsaPublic.blob(), "John Hancock") - self.pump.flush() - return self.assertFailure(d, ConchError) - - - def test_requestIdentities(self): - """ - Assert that we get all of the keys/comments that we add when we issue a - request for all identities. - """ - d = self.client.requestIdentities() - self.pump.flush() - def _check(keyt): - expected = {} - expected[self.dsaPublic.blob()] = 'a comment' - expected[self.rsaPublic.blob()] = 'another comment' - - received = {} - for k in keyt: - received[keys.Key.fromString(k[0], type='blob').blob()] = k[1] - self.assertEqual(expected, received) - return d.addCallback(_check) - - - -class TestAgentKeyRemoval(AgentTestBase): - """ - Test support for removing keys in a remote server. - """ - - def setUp(self): - AgentTestBase.setUp(self) - self.server.factory.keys[self.dsaPrivate.blob()] = ( - self.dsaPrivate, 'a comment') - self.server.factory.keys[self.rsaPrivate.blob()] = ( - self.rsaPrivate, 'another comment') - - - def test_removeRSAIdentity(self): - """ - Assert that we can remove an RSA identity. - """ - # only need public key for this - d = self.client.removeIdentity(self.rsaPrivate.blob()) - self.pump.flush() - - def _check(ignored): - self.assertEqual(1, len(self.server.factory.keys)) - self.assertIn(self.dsaPrivate.blob(), self.server.factory.keys) - self.assertNotIn(self.rsaPrivate.blob(), self.server.factory.keys) - return d.addCallback(_check) - - - def test_removeDSAIdentity(self): - """ - Assert that we can remove a DSA identity. - """ - # only need public key for this - d = self.client.removeIdentity(self.dsaPrivate.blob()) - self.pump.flush() - - def _check(ignored): - self.assertEqual(1, len(self.server.factory.keys)) - self.assertIn(self.rsaPrivate.blob(), self.server.factory.keys) - return d.addCallback(_check) - - - def test_removeAllIdentities(self): - """ - Assert that we can remove all identities. - """ - d = self.client.removeAllIdentities() - self.pump.flush() - - def _check(ignored): - self.assertEqual(0, len(self.server.factory.keys)) - return d.addCallback(_check) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py deleted file mode 100755 index 03e327a6..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_cftp.py +++ /dev/null @@ -1,975 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_cftp -*- -# Copyright (c) 2001-2009 Twisted Matrix Laboratories. -# See LICENSE file for details. - -""" -Tests for L{twisted.conch.scripts.cftp}. -""" - -import locale -import time, sys, os, operator, getpass, struct -from StringIO import StringIO - -from twisted.conch.test.test_ssh import Crypto, pyasn1 - -_reason = None -if Crypto and pyasn1: - try: - from twisted.conch import unix - from twisted.conch.scripts import cftp - from twisted.conch.test.test_filetransfer import FileTransferForTestAvatar - except ImportError, e: - # Python 2.3 compatibility fix - sys.modules.pop("twisted.conch.unix", None) - unix = None - _reason = str(e) - del e -else: - unix = None - - -from twisted.python.fakepwd import UserDatabase -from twisted.trial.unittest import TestCase -from twisted.cred import portal -from twisted.internet import reactor, protocol, interfaces, defer, error -from twisted.internet.utils import getProcessOutputAndValue -from twisted.python import log -from twisted.conch import ls -from twisted.test.proto_helpers import StringTransport -from twisted.internet.task import Clock - -from twisted.conch.test import test_ssh, test_conch -from twisted.conch.test.test_filetransfer import SFTPTestBase -from twisted.conch.test.test_filetransfer import FileTransferTestAvatar - - - -class ListingTests(TestCase): - """ - Tests for L{lsLine}, the function which generates an entry for a file or - directory in an SFTP I{ls} command's output. - """ - if getattr(time, 'tzset', None) is None: - skip = "Cannot test timestamp formatting code without time.tzset" - - def setUp(self): - """ - Patch the L{ls} module's time function so the results of L{lsLine} are - deterministic. - """ - self.now = 123456789 - def fakeTime(): - return self.now - self.patch(ls, 'time', fakeTime) - - # Make sure that the timezone ends up the same after these tests as - # it was before. - if 'TZ' in os.environ: - self.addCleanup(operator.setitem, os.environ, 'TZ', os.environ['TZ']) - self.addCleanup(time.tzset) - else: - def cleanup(): - # os.environ.pop is broken! Don't use it! Ever! Or die! - try: - del os.environ['TZ'] - except KeyError: - pass - time.tzset() - self.addCleanup(cleanup) - - - def _lsInTimezone(self, timezone, stat): - """ - Call L{ls.lsLine} after setting the timezone to C{timezone} and return - the result. - """ - # Set the timezone to a well-known value so the timestamps are - # predictable. - os.environ['TZ'] = timezone - time.tzset() - return ls.lsLine('foo', stat) - - - def test_oldFile(self): - """ - A file with an mtime six months (approximately) or more in the past has - a listing including a low-resolution timestamp. - """ - # Go with 7 months. That's more than 6 months. - then = self.now - (60 * 60 * 24 * 31 * 7) - stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0)) - - self.assertEqual( - self._lsInTimezone('America/New_York', stat), - '!--------- 0 0 0 0 Apr 26 1973 foo') - self.assertEqual( - self._lsInTimezone('Pacific/Auckland', stat), - '!--------- 0 0 0 0 Apr 27 1973 foo') - - - def test_oldSingleDigitDayOfMonth(self): - """ - A file with a high-resolution timestamp which falls on a day of the - month which can be represented by one decimal digit is formatted with - one padding 0 to preserve the columns which come after it. - """ - # A point about 7 months in the past, tweaked to fall on the first of a - # month so we test the case we want to test. - then = self.now - (60 * 60 * 24 * 31 * 7) + (60 * 60 * 24 * 5) - stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0)) - - self.assertEqual( - self._lsInTimezone('America/New_York', stat), - '!--------- 0 0 0 0 May 01 1973 foo') - self.assertEqual( - self._lsInTimezone('Pacific/Auckland', stat), - '!--------- 0 0 0 0 May 02 1973 foo') - - - def test_newFile(self): - """ - A file with an mtime fewer than six months (approximately) in the past - has a listing including a high-resolution timestamp excluding the year. - """ - # A point about three months in the past. - then = self.now - (60 * 60 * 24 * 31 * 3) - stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0)) - - self.assertEqual( - self._lsInTimezone('America/New_York', stat), - '!--------- 0 0 0 0 Aug 28 17:33 foo') - self.assertEqual( - self._lsInTimezone('Pacific/Auckland', stat), - '!--------- 0 0 0 0 Aug 29 09:33 foo') - - - def test_localeIndependent(self): - """ - The month name in the date is locale independent. - """ - # A point about three months in the past. - then = self.now - (60 * 60 * 24 * 31 * 3) - stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0)) - - # Fake that we're in a language where August is not Aug (e.g.: Spanish) - currentLocale = locale.getlocale() - locale.setlocale(locale.LC_ALL, "es_AR.UTF8") - self.addCleanup(locale.setlocale, locale.LC_ALL, currentLocale) - - self.assertEqual( - self._lsInTimezone('America/New_York', stat), - '!--------- 0 0 0 0 Aug 28 17:33 foo') - self.assertEqual( - self._lsInTimezone('Pacific/Auckland', stat), - '!--------- 0 0 0 0 Aug 29 09:33 foo') - - # if alternate locale is not available, the previous test will be - # skipped, please install this locale for it to run - currentLocale = locale.getlocale() - try: - try: - locale.setlocale(locale.LC_ALL, "es_AR.UTF8") - except locale.Error: - test_localeIndependent.skip = "The es_AR.UTF8 locale is not installed." - finally: - locale.setlocale(locale.LC_ALL, currentLocale) - - - def test_newSingleDigitDayOfMonth(self): - """ - A file with a high-resolution timestamp which falls on a day of the - month which can be represented by one decimal digit is formatted with - one padding 0 to preserve the columns which come after it. - """ - # A point about three months in the past, tweaked to fall on the first - # of a month so we test the case we want to test. - then = self.now - (60 * 60 * 24 * 31 * 3) + (60 * 60 * 24 * 4) - stat = os.stat_result((0, 0, 0, 0, 0, 0, 0, 0, then, 0)) - - self.assertEqual( - self._lsInTimezone('America/New_York', stat), - '!--------- 0 0 0 0 Sep 01 17:33 foo') - self.assertEqual( - self._lsInTimezone('Pacific/Auckland', stat), - '!--------- 0 0 0 0 Sep 02 09:33 foo') - - - -class StdioClientTests(TestCase): - """ - Tests for L{cftp.StdioClient}. - """ - def setUp(self): - """ - Create a L{cftp.StdioClient} hooked up to dummy transport and a fake - user database. - """ - class Connection: - pass - - conn = Connection() - conn.transport = StringTransport() - conn.transport.localClosed = False - - self.client = cftp.StdioClient(conn) - self.database = self.client._pwd = UserDatabase() - - # Intentionally bypassing makeConnection - that triggers some code - # which uses features not provided by our dumb Connection fake. - self.client.transport = StringTransport() - - - def test_exec(self): - """ - The I{exec} command runs its arguments locally in a child process - using the user's shell. - """ - self.database.addUser( - getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar', - sys.executable) - - d = self.client._dispatchCommand("exec print 1 + 2") - d.addCallback(self.assertEqual, "3\n") - return d - - - def test_execWithoutShell(self): - """ - If the local user has no shell, the I{exec} command runs its arguments - using I{/bin/sh}. - """ - self.database.addUser( - getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar', '') - - d = self.client._dispatchCommand("exec echo hello") - d.addCallback(self.assertEqual, "hello\n") - return d - - - def test_bang(self): - """ - The I{exec} command is run for lines which start with C{"!"}. - """ - self.database.addUser( - getpass.getuser(), 'secret', os.getuid(), 1234, 'foo', 'bar', - '/bin/sh') - - d = self.client._dispatchCommand("!echo hello") - d.addCallback(self.assertEqual, "hello\n") - return d - - - def setKnownConsoleSize(self, width, height): - """ - For the duration of this test, patch C{cftp}'s C{fcntl} module to return - a fixed width and height. - - @param width: the width in characters - @type width: C{int} - @param height: the height in characters - @type height: C{int} - """ - import tty # local import to avoid win32 issues - class FakeFcntl(object): - def ioctl(self, fd, opt, mutate): - if opt != tty.TIOCGWINSZ: - self.fail("Only window-size queries supported.") - return struct.pack("4H", height, width, 0, 0) - self.patch(cftp, "fcntl", FakeFcntl()) - - - def test_progressReporting(self): - """ - L{StdioClient._printProgressBar} prints a progress description, - including percent done, amount transferred, transfer rate, and time - remaining, all based the given start time, the given L{FileWrapper}'s - progress information and the reactor's current time. - """ - # Use a short, known console width because this simple test doesn't need - # to test the console padding. - self.setKnownConsoleSize(10, 34) - clock = self.client.reactor = Clock() - wrapped = StringIO("x") - wrapped.name = "sample" - wrapper = cftp.FileWrapper(wrapped) - wrapper.size = 1024 * 10 - startTime = clock.seconds() - clock.advance(2.0) - wrapper.total += 4096 - self.client._printProgressBar(wrapper, startTime) - self.assertEqual(self.client.transport.value(), - "\rsample 40% 4.0kB 2.0kBps 00:03 ") - - - def test_reportNoProgress(self): - """ - L{StdioClient._printProgressBar} prints a progress description that - indicates 0 bytes transferred if no bytes have been transferred and no - time has passed. - """ - self.setKnownConsoleSize(10, 34) - clock = self.client.reactor = Clock() - wrapped = StringIO("x") - wrapped.name = "sample" - wrapper = cftp.FileWrapper(wrapped) - startTime = clock.seconds() - self.client._printProgressBar(wrapper, startTime) - self.assertEqual(self.client.transport.value(), - "\rsample 0% 0.0B 0.0Bps 00:00 ") - - - -class FileTransferTestRealm: - def __init__(self, testDir): - self.testDir = testDir - - def requestAvatar(self, avatarID, mind, *interfaces): - a = FileTransferTestAvatar(self.testDir) - return interfaces[0], a, lambda: None - - -class SFTPTestProcess(protocol.ProcessProtocol): - """ - Protocol for testing cftp. Provides an interface between Python (where all - the tests are) and the cftp client process (which does the work that is - being tested). - """ - - def __init__(self, onOutReceived): - """ - @param onOutReceived: A L{Deferred} to be fired as soon as data is - received from stdout. - """ - self.clearBuffer() - self.onOutReceived = onOutReceived - self.onProcessEnd = None - self._expectingCommand = None - self._processEnded = False - - def clearBuffer(self): - """ - Clear any buffered data received from stdout. Should be private. - """ - self.buffer = '' - self._linesReceived = [] - self._lineBuffer = '' - - def outReceived(self, data): - """ - Called by Twisted when the cftp client prints data to stdout. - """ - log.msg('got %s' % data) - lines = (self._lineBuffer + data).split('\n') - self._lineBuffer = lines.pop(-1) - self._linesReceived.extend(lines) - # XXX - not strictly correct. - # We really want onOutReceived to fire after the first 'cftp>' prompt - # has been received. (See use in TestOurServerCmdLineClient.setUp) - if self.onOutReceived is not None: - d, self.onOutReceived = self.onOutReceived, None - d.callback(data) - self.buffer += data - self._checkForCommand() - - def _checkForCommand(self): - prompt = 'cftp> ' - if self._expectingCommand and self._lineBuffer == prompt: - buf = '\n'.join(self._linesReceived) - if buf.startswith(prompt): - buf = buf[len(prompt):] - self.clearBuffer() - d, self._expectingCommand = self._expectingCommand, None - d.callback(buf) - - def errReceived(self, data): - """ - Called by Twisted when the cftp client prints data to stderr. - """ - log.msg('err: %s' % data) - - def getBuffer(self): - """ - Return the contents of the buffer of data received from stdout. - """ - return self.buffer - - def runCommand(self, command): - """ - Issue the given command via the cftp client. Return a C{Deferred} that - fires when the server returns a result. Note that the C{Deferred} will - callback even if the server returns some kind of error. - - @param command: A string containing an sftp command. - - @return: A C{Deferred} that fires when the sftp server returns a - result. The payload is the server's response string. - """ - self._expectingCommand = defer.Deferred() - self.clearBuffer() - self.transport.write(command + '\n') - return self._expectingCommand - - def runScript(self, commands): - """ - Run each command in sequence and return a Deferred that fires when all - commands are completed. - - @param commands: A list of strings containing sftp commands. - - @return: A C{Deferred} that fires when all commands are completed. The - payload is a list of response strings from the server, in the same - order as the commands. - """ - sem = defer.DeferredSemaphore(1) - dl = [sem.run(self.runCommand, command) for command in commands] - return defer.gatherResults(dl) - - def killProcess(self): - """ - Kill the process if it is still running. - - If the process is still running, sends a KILL signal to the transport - and returns a C{Deferred} which fires when L{processEnded} is called. - - @return: a C{Deferred}. - """ - if self._processEnded: - return defer.succeed(None) - self.onProcessEnd = defer.Deferred() - self.transport.signalProcess('KILL') - return self.onProcessEnd - - def processEnded(self, reason): - """ - Called by Twisted when the cftp client process ends. - """ - self._processEnded = True - if self.onProcessEnd: - d, self.onProcessEnd = self.onProcessEnd, None - d.callback(None) - - -class CFTPClientTestBase(SFTPTestBase): - def setUp(self): - f = open('dsa_test.pub','w') - f.write(test_ssh.publicDSA_openssh) - f.close() - f = open('dsa_test','w') - f.write(test_ssh.privateDSA_openssh) - f.close() - os.chmod('dsa_test', 33152) - f = open('kh_test','w') - f.write('127.0.0.1 ' + test_ssh.publicRSA_openssh) - f.close() - return SFTPTestBase.setUp(self) - - def startServer(self): - realm = FileTransferTestRealm(self.testDir) - p = portal.Portal(realm) - p.registerChecker(test_ssh.ConchTestPublicKeyChecker()) - fac = test_ssh.ConchTestServerFactory() - fac.portal = p - self.server = reactor.listenTCP(0, fac, interface="127.0.0.1") - - def stopServer(self): - if not hasattr(self.server.factory, 'proto'): - return self._cbStopServer(None) - self.server.factory.proto.expectedLoseConnection = 1 - d = defer.maybeDeferred( - self.server.factory.proto.transport.loseConnection) - d.addCallback(self._cbStopServer) - return d - - def _cbStopServer(self, ignored): - return defer.maybeDeferred(self.server.stopListening) - - def tearDown(self): - for f in ['dsa_test.pub', 'dsa_test', 'kh_test']: - try: - os.remove(f) - except: - pass - return SFTPTestBase.tearDown(self) - - - -class TestOurServerCmdLineClient(CFTPClientTestBase): - - def setUp(self): - CFTPClientTestBase.setUp(self) - - self.startServer() - cmds = ('-p %i -l testuser ' - '--known-hosts kh_test ' - '--user-authentications publickey ' - '--host-key-algorithms ssh-rsa ' - '-i dsa_test ' - '-a ' - '-v ' - '127.0.0.1') - port = self.server.getHost().port - cmds = test_conch._makeArgs((cmds % port).split(), mod='cftp') - log.msg('running %s %s' % (sys.executable, cmds)) - d = defer.Deferred() - self.processProtocol = SFTPTestProcess(d) - d.addCallback(lambda _: self.processProtocol.clearBuffer()) - env = os.environ.copy() - env['PYTHONPATH'] = os.pathsep.join(sys.path) - reactor.spawnProcess(self.processProtocol, sys.executable, cmds, - env=env) - return d - - def tearDown(self): - d = self.stopServer() - d.addCallback(lambda _: self.processProtocol.killProcess()) - return d - - def _killProcess(self, ignored): - try: - self.processProtocol.transport.signalProcess('KILL') - except error.ProcessExitedAlready: - pass - - def runCommand(self, command): - """ - Run the given command with the cftp client. Return a C{Deferred} that - fires when the command is complete. Payload is the server's output for - that command. - """ - return self.processProtocol.runCommand(command) - - def runScript(self, *commands): - """ - Run the given commands with the cftp client. Returns a C{Deferred} - that fires when the commands are all complete. The C{Deferred}'s - payload is a list of output for each command. - """ - return self.processProtocol.runScript(commands) - - def testCdPwd(self): - """ - Test that 'pwd' reports the current remote directory, that 'lpwd' - reports the current local directory, and that changing to a - subdirectory then changing to its parent leaves you in the original - remote directory. - """ - # XXX - not actually a unit test, see docstring. - homeDir = os.path.join(os.getcwd(), self.testDir) - d = self.runScript('pwd', 'lpwd', 'cd testDirectory', 'cd ..', 'pwd') - d.addCallback(lambda xs: xs[:3] + xs[4:]) - d.addCallback(self.assertEqual, - [homeDir, os.getcwd(), '', homeDir]) - return d - - def testChAttrs(self): - """ - Check that 'ls -l' output includes the access permissions and that - this output changes appropriately with 'chmod'. - """ - def _check(results): - self.flushLoggedErrors() - self.assertTrue(results[0].startswith('-rw-r--r--')) - self.assertEqual(results[1], '') - self.assertTrue(results[2].startswith('----------'), results[2]) - self.assertEqual(results[3], '') - - d = self.runScript('ls -l testfile1', 'chmod 0 testfile1', - 'ls -l testfile1', 'chmod 644 testfile1') - return d.addCallback(_check) - # XXX test chgrp/own - - - def testList(self): - """ - Check 'ls' works as expected. Checks for wildcards, hidden files, - listing directories and listing empty directories. - """ - def _check(results): - self.assertEqual(results[0], ['testDirectory', 'testRemoveFile', - 'testRenameFile', 'testfile1']) - self.assertEqual(results[1], ['testDirectory', 'testRemoveFile', - 'testRenameFile', 'testfile1']) - self.assertEqual(results[2], ['testRemoveFile', 'testRenameFile']) - self.assertEqual(results[3], ['.testHiddenFile', 'testRemoveFile', - 'testRenameFile']) - self.assertEqual(results[4], ['']) - d = self.runScript('ls', 'ls ../' + os.path.basename(self.testDir), - 'ls *File', 'ls -a *File', 'ls -l testDirectory') - d.addCallback(lambda xs: [x.split('\n') for x in xs]) - return d.addCallback(_check) - - - def testHelp(self): - """ - Check that running the '?' command returns help. - """ - d = self.runCommand('?') - d.addCallback(self.assertEqual, - cftp.StdioClient(None).cmd_HELP('').strip()) - return d - - def assertFilesEqual(self, name1, name2, msg=None): - """ - Assert that the files at C{name1} and C{name2} contain exactly the - same data. - """ - f1 = file(name1).read() - f2 = file(name2).read() - self.assertEqual(f1, f2, msg) - - - def testGet(self): - """ - Test that 'get' saves the remote file to the correct local location, - that the output of 'get' is correct and that 'rm' actually removes - the file. - """ - # XXX - not actually a unit test - expectedOutput = ("Transferred %s/%s/testfile1 to %s/test file2" - % (os.getcwd(), self.testDir, self.testDir)) - def _checkGet(result): - self.assertTrue(result.endswith(expectedOutput)) - self.assertFilesEqual(self.testDir + '/testfile1', - self.testDir + '/test file2', - "get failed") - return self.runCommand('rm "test file2"') - - d = self.runCommand('get testfile1 "%s/test file2"' % (self.testDir,)) - d.addCallback(_checkGet) - d.addCallback(lambda _: self.failIf( - os.path.exists(self.testDir + '/test file2'))) - return d - - - def testWildcardGet(self): - """ - Test that 'get' works correctly when given wildcard parameters. - """ - def _check(ignored): - self.assertFilesEqual(self.testDir + '/testRemoveFile', - 'testRemoveFile', - 'testRemoveFile get failed') - self.assertFilesEqual(self.testDir + '/testRenameFile', - 'testRenameFile', - 'testRenameFile get failed') - - d = self.runCommand('get testR*') - return d.addCallback(_check) - - - def testPut(self): - """ - Check that 'put' uploads files correctly and that they can be - successfully removed. Also check the output of the put command. - """ - # XXX - not actually a unit test - expectedOutput = ('Transferred %s/testfile1 to %s/%s/test"file2' - % (self.testDir, os.getcwd(), self.testDir)) - def _checkPut(result): - self.assertFilesEqual(self.testDir + '/testfile1', - self.testDir + '/test"file2') - self.failUnless(result.endswith(expectedOutput)) - return self.runCommand('rm "test\\"file2"') - - d = self.runCommand('put %s/testfile1 "test\\"file2"' - % (self.testDir,)) - d.addCallback(_checkPut) - d.addCallback(lambda _: self.failIf( - os.path.exists(self.testDir + '/test"file2'))) - return d - - - def test_putOverLongerFile(self): - """ - Check that 'put' uploads files correctly when overwriting a longer - file. - """ - # XXX - not actually a unit test - f = file(os.path.join(self.testDir, 'shorterFile'), 'w') - f.write("a") - f.close() - f = file(os.path.join(self.testDir, 'longerFile'), 'w') - f.write("bb") - f.close() - def _checkPut(result): - self.assertFilesEqual(self.testDir + '/shorterFile', - self.testDir + '/longerFile') - - d = self.runCommand('put %s/shorterFile longerFile' - % (self.testDir,)) - d.addCallback(_checkPut) - return d - - - def test_putMultipleOverLongerFile(self): - """ - Check that 'put' uploads files correctly when overwriting a longer - file and you use a wildcard to specify the files to upload. - """ - # XXX - not actually a unit test - os.mkdir(os.path.join(self.testDir, 'dir')) - f = file(os.path.join(self.testDir, 'dir', 'file'), 'w') - f.write("a") - f.close() - f = file(os.path.join(self.testDir, 'file'), 'w') - f.write("bb") - f.close() - def _checkPut(result): - self.assertFilesEqual(self.testDir + '/dir/file', - self.testDir + '/file') - - d = self.runCommand('put %s/dir/*' - % (self.testDir,)) - d.addCallback(_checkPut) - return d - - - def testWildcardPut(self): - """ - What happens if you issue a 'put' command and include a wildcard (i.e. - '*') in parameter? Check that all files matching the wildcard are - uploaded to the correct directory. - """ - def check(results): - self.assertEqual(results[0], '') - self.assertEqual(results[2], '') - self.assertFilesEqual(self.testDir + '/testRemoveFile', - self.testDir + '/../testRemoveFile', - 'testRemoveFile get failed') - self.assertFilesEqual(self.testDir + '/testRenameFile', - self.testDir + '/../testRenameFile', - 'testRenameFile get failed') - - d = self.runScript('cd ..', - 'put %s/testR*' % (self.testDir,), - 'cd %s' % os.path.basename(self.testDir)) - d.addCallback(check) - return d - - - def testLink(self): - """ - Test that 'ln' creates a file which appears as a link in the output of - 'ls'. Check that removing the new file succeeds without output. - """ - def _check(results): - self.flushLoggedErrors() - self.assertEqual(results[0], '') - self.assertTrue(results[1].startswith('l'), 'link failed') - return self.runCommand('rm testLink') - - d = self.runScript('ln testLink testfile1', 'ls -l testLink') - d.addCallback(_check) - d.addCallback(self.assertEqual, '') - return d - - - def testRemoteDirectory(self): - """ - Test that we can create and remove directories with the cftp client. - """ - def _check(results): - self.assertEqual(results[0], '') - self.assertTrue(results[1].startswith('d')) - return self.runCommand('rmdir testMakeDirectory') - - d = self.runScript('mkdir testMakeDirectory', - 'ls -l testMakeDirector?') - d.addCallback(_check) - d.addCallback(self.assertEqual, '') - return d - - - def test_existingRemoteDirectory(self): - """ - Test that a C{mkdir} on an existing directory fails with the - appropriate error, and doesn't log an useless error server side. - """ - def _check(results): - self.assertEqual(results[0], '') - self.assertEqual(results[1], - 'remote error 11: mkdir failed') - - d = self.runScript('mkdir testMakeDirectory', - 'mkdir testMakeDirectory') - d.addCallback(_check) - return d - - - def testLocalDirectory(self): - """ - Test that we can create a directory locally and remove it with the - cftp client. This test works because the 'remote' server is running - out of a local directory. - """ - d = self.runCommand('lmkdir %s/testLocalDirectory' % (self.testDir,)) - d.addCallback(self.assertEqual, '') - d.addCallback(lambda _: self.runCommand('rmdir testLocalDirectory')) - d.addCallback(self.assertEqual, '') - return d - - - def testRename(self): - """ - Test that we can rename a file. - """ - def _check(results): - self.assertEqual(results[0], '') - self.assertEqual(results[1], 'testfile2') - return self.runCommand('rename testfile2 testfile1') - - d = self.runScript('rename testfile1 testfile2', 'ls testfile?') - d.addCallback(_check) - d.addCallback(self.assertEqual, '') - return d - - - -class TestOurServerBatchFile(CFTPClientTestBase): - def setUp(self): - CFTPClientTestBase.setUp(self) - self.startServer() - - def tearDown(self): - CFTPClientTestBase.tearDown(self) - return self.stopServer() - - def _getBatchOutput(self, f): - fn = self.mktemp() - open(fn, 'w').write(f) - port = self.server.getHost().port - cmds = ('-p %i -l testuser ' - '--known-hosts kh_test ' - '--user-authentications publickey ' - '--host-key-algorithms ssh-rsa ' - '-i dsa_test ' - '-a ' - '-v -b %s 127.0.0.1') % (port, fn) - cmds = test_conch._makeArgs(cmds.split(), mod='cftp')[1:] - log.msg('running %s %s' % (sys.executable, cmds)) - env = os.environ.copy() - env['PYTHONPATH'] = os.pathsep.join(sys.path) - - self.server.factory.expectedLoseConnection = 1 - - d = getProcessOutputAndValue(sys.executable, cmds, env=env) - - def _cleanup(res): - os.remove(fn) - return res - - d.addCallback(lambda res: res[0]) - d.addBoth(_cleanup) - - return d - - def testBatchFile(self): - """Test whether batch file function of cftp ('cftp -b batchfile'). - This works by treating the file as a list of commands to be run. - """ - cmds = """pwd -ls -exit -""" - def _cbCheckResult(res): - res = res.split('\n') - log.msg('RES %s' % str(res)) - self.failUnless(res[1].find(self.testDir) != -1, repr(res)) - self.assertEqual(res[3:-2], ['testDirectory', 'testRemoveFile', - 'testRenameFile', 'testfile1']) - - d = self._getBatchOutput(cmds) - d.addCallback(_cbCheckResult) - return d - - def testError(self): - """Test that an error in the batch file stops running the batch. - """ - cmds = """chown 0 missingFile -pwd -exit -""" - def _cbCheckResult(res): - self.failIf(res.find(self.testDir) != -1) - - d = self._getBatchOutput(cmds) - d.addCallback(_cbCheckResult) - return d - - def testIgnoredError(self): - """Test that a minus sign '-' at the front of a line ignores - any errors. - """ - cmds = """-chown 0 missingFile -pwd -exit -""" - def _cbCheckResult(res): - self.failIf(res.find(self.testDir) == -1) - - d = self._getBatchOutput(cmds) - d.addCallback(_cbCheckResult) - return d - - - -class TestOurServerSftpClient(CFTPClientTestBase): - """ - Test the sftp server against sftp command line client. - """ - - def setUp(self): - CFTPClientTestBase.setUp(self) - return self.startServer() - - - def tearDown(self): - return self.stopServer() - - - def test_extendedAttributes(self): - """ - Test the return of extended attributes by the server: the sftp client - should ignore them, but still be able to parse the response correctly. - - This test is mainly here to check that - L{filetransfer.FILEXFER_ATTR_EXTENDED} has the correct value. - """ - fn = self.mktemp() - open(fn, 'w').write("ls .\nexit") - port = self.server.getHost().port - - oldGetAttr = FileTransferForTestAvatar._getAttrs - def _getAttrs(self, s): - attrs = oldGetAttr(self, s) - attrs["ext_foo"] = "bar" - return attrs - - self.patch(FileTransferForTestAvatar, "_getAttrs", _getAttrs) - - self.server.factory.expectedLoseConnection = True - cmds = ('-o', 'IdentityFile=dsa_test', - '-o', 'UserKnownHostsFile=kh_test', - '-o', 'HostKeyAlgorithms=ssh-rsa', - '-o', 'Port=%i' % (port,), '-b', fn, 'testuser@127.0.0.1') - d = getProcessOutputAndValue("sftp", cmds) - def check(result): - self.assertEqual(result[2], 0) - for i in ['testDirectory', 'testRemoveFile', - 'testRenameFile', 'testfile1']: - self.assertIn(i, result[0]) - return d.addCallback(check) - - - -if unix is None or Crypto is None or pyasn1 is None or interfaces.IReactorProcess(reactor, None) is None: - if _reason is None: - _reason = "don't run w/o spawnProcess or PyCrypto or pyasn1" - TestOurServerCmdLineClient.skip = _reason - TestOurServerBatchFile.skip = _reason - TestOurServerSftpClient.skip = _reason - StdioClientTests.skip = _reason -else: - from twisted.python.procutils import which - if not which('sftp'): - TestOurServerSftpClient.skip = "no sftp command-line client available" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py deleted file mode 100755 index a46596dd..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_channel.py +++ /dev/null @@ -1,279 +0,0 @@ -# Copyright (C) 2007-2008 Twisted Matrix Laboratories -# See LICENSE for details - -""" -Test ssh/channel.py. -""" -from twisted.conch.ssh import channel -from twisted.trial import unittest - - -class MockTransport(object): - """ - A mock Transport. All we use is the getPeer() and getHost() methods. - Channels implement the ITransport interface, and their getPeer() and - getHost() methods return ('SSH', <transport's getPeer/Host value>) so - we need to implement these methods so they have something to draw - from. - """ - def getPeer(self): - return ('MockPeer',) - - def getHost(self): - return ('MockHost',) - - -class MockConnection(object): - """ - A mock for twisted.conch.ssh.connection.SSHConnection. Record the data - that channels send, and when they try to close the connection. - - @ivar data: a C{dict} mapping channel id #s to lists of data sent by that - channel. - @ivar extData: a C{dict} mapping channel id #s to lists of 2-tuples - (extended data type, data) sent by that channel. - @ivar closes: a C{dict} mapping channel id #s to True if that channel sent - a close message. - """ - transport = MockTransport() - - def __init__(self): - self.data = {} - self.extData = {} - self.closes = {} - - def logPrefix(self): - """ - Return our logging prefix. - """ - return "MockConnection" - - def sendData(self, channel, data): - """ - Record the sent data. - """ - self.data.setdefault(channel, []).append(data) - - def sendExtendedData(self, channel, type, data): - """ - Record the sent extended data. - """ - self.extData.setdefault(channel, []).append((type, data)) - - def sendClose(self, channel): - """ - Record that the channel sent a close message. - """ - self.closes[channel] = True - - -class ChannelTestCase(unittest.TestCase): - - def setUp(self): - """ - Initialize the channel. remoteMaxPacket is 10 so that data is able - to be sent (the default of 0 means no data is sent because no packets - are made). - """ - self.conn = MockConnection() - self.channel = channel.SSHChannel(conn=self.conn, - remoteMaxPacket=10) - self.channel.name = 'channel' - - def test_init(self): - """ - Test that SSHChannel initializes correctly. localWindowSize defaults - to 131072 (2**17) and localMaxPacket to 32768 (2**15) as reasonable - defaults (what OpenSSH uses for those variables). - - The values in the second set of assertions are meaningless; they serve - only to verify that the instance variables are assigned in the correct - order. - """ - c = channel.SSHChannel(conn=self.conn) - self.assertEqual(c.localWindowSize, 131072) - self.assertEqual(c.localWindowLeft, 131072) - self.assertEqual(c.localMaxPacket, 32768) - self.assertEqual(c.remoteWindowLeft, 0) - self.assertEqual(c.remoteMaxPacket, 0) - self.assertEqual(c.conn, self.conn) - self.assertEqual(c.data, None) - self.assertEqual(c.avatar, None) - - c2 = channel.SSHChannel(1, 2, 3, 4, 5, 6, 7) - self.assertEqual(c2.localWindowSize, 1) - self.assertEqual(c2.localWindowLeft, 1) - self.assertEqual(c2.localMaxPacket, 2) - self.assertEqual(c2.remoteWindowLeft, 3) - self.assertEqual(c2.remoteMaxPacket, 4) - self.assertEqual(c2.conn, 5) - self.assertEqual(c2.data, 6) - self.assertEqual(c2.avatar, 7) - - def test_str(self): - """ - Test that str(SSHChannel) works gives the channel name and local and - remote windows at a glance.. - """ - self.assertEqual(str(self.channel), '<SSHChannel channel (lw 131072 ' - 'rw 0)>') - - def test_logPrefix(self): - """ - Test that SSHChannel.logPrefix gives the name of the channel, the - local channel ID and the underlying connection. - """ - self.assertEqual(self.channel.logPrefix(), 'SSHChannel channel ' - '(unknown) on MockConnection') - - def test_addWindowBytes(self): - """ - Test that addWindowBytes adds bytes to the window and resumes writing - if it was paused. - """ - cb = [False] - def stubStartWriting(): - cb[0] = True - self.channel.startWriting = stubStartWriting - self.channel.write('test') - self.channel.writeExtended(1, 'test') - self.channel.addWindowBytes(50) - self.assertEqual(self.channel.remoteWindowLeft, 50 - 4 - 4) - self.assertTrue(self.channel.areWriting) - self.assertTrue(cb[0]) - self.assertEqual(self.channel.buf, '') - self.assertEqual(self.conn.data[self.channel], ['test']) - self.assertEqual(self.channel.extBuf, []) - self.assertEqual(self.conn.extData[self.channel], [(1, 'test')]) - - cb[0] = False - self.channel.addWindowBytes(20) - self.assertFalse(cb[0]) - - self.channel.write('a'*80) - self.channel.loseConnection() - self.channel.addWindowBytes(20) - self.assertFalse(cb[0]) - - def test_requestReceived(self): - """ - Test that requestReceived handles requests by dispatching them to - request_* methods. - """ - self.channel.request_test_method = lambda data: data == '' - self.assertTrue(self.channel.requestReceived('test-method', '')) - self.assertFalse(self.channel.requestReceived('test-method', 'a')) - self.assertFalse(self.channel.requestReceived('bad-method', '')) - - def test_closeReceieved(self): - """ - Test that the default closeReceieved closes the connection. - """ - self.assertFalse(self.channel.closing) - self.channel.closeReceived() - self.assertTrue(self.channel.closing) - - def test_write(self): - """ - Test that write handles data correctly. Send data up to the size - of the remote window, splitting the data into packets of length - remoteMaxPacket. - """ - cb = [False] - def stubStopWriting(): - cb[0] = True - # no window to start with - self.channel.stopWriting = stubStopWriting - self.channel.write('d') - self.channel.write('a') - self.assertFalse(self.channel.areWriting) - self.assertTrue(cb[0]) - # regular write - self.channel.addWindowBytes(20) - self.channel.write('ta') - data = self.conn.data[self.channel] - self.assertEqual(data, ['da', 'ta']) - self.assertEqual(self.channel.remoteWindowLeft, 16) - # larger than max packet - self.channel.write('12345678901') - self.assertEqual(data, ['da', 'ta', '1234567890', '1']) - self.assertEqual(self.channel.remoteWindowLeft, 5) - # running out of window - cb[0] = False - self.channel.write('123456') - self.assertFalse(self.channel.areWriting) - self.assertTrue(cb[0]) - self.assertEqual(data, ['da', 'ta', '1234567890', '1', '12345']) - self.assertEqual(self.channel.buf, '6') - self.assertEqual(self.channel.remoteWindowLeft, 0) - - def test_writeExtended(self): - """ - Test that writeExtended handles data correctly. Send extended data - up to the size of the window, splitting the extended data into packets - of length remoteMaxPacket. - """ - cb = [False] - def stubStopWriting(): - cb[0] = True - # no window to start with - self.channel.stopWriting = stubStopWriting - self.channel.writeExtended(1, 'd') - self.channel.writeExtended(1, 'a') - self.channel.writeExtended(2, 't') - self.assertFalse(self.channel.areWriting) - self.assertTrue(cb[0]) - # regular write - self.channel.addWindowBytes(20) - self.channel.writeExtended(2, 'a') - data = self.conn.extData[self.channel] - self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a')]) - self.assertEqual(self.channel.remoteWindowLeft, 16) - # larger than max packet - self.channel.writeExtended(3, '12345678901') - self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a'), - (3, '1234567890'), (3, '1')]) - self.assertEqual(self.channel.remoteWindowLeft, 5) - # running out of window - cb[0] = False - self.channel.writeExtended(4, '123456') - self.assertFalse(self.channel.areWriting) - self.assertTrue(cb[0]) - self.assertEqual(data, [(1, 'da'), (2, 't'), (2, 'a'), - (3, '1234567890'), (3, '1'), (4, '12345')]) - self.assertEqual(self.channel.extBuf, [[4, '6']]) - self.assertEqual(self.channel.remoteWindowLeft, 0) - - def test_writeSequence(self): - """ - Test that writeSequence is equivalent to write(''.join(sequece)). - """ - self.channel.addWindowBytes(20) - self.channel.writeSequence(map(str, range(10))) - self.assertEqual(self.conn.data[self.channel], ['0123456789']) - - def test_loseConnection(self): - """ - Tesyt that loseConnection() doesn't close the channel until all - the data is sent. - """ - self.channel.write('data') - self.channel.writeExtended(1, 'datadata') - self.channel.loseConnection() - self.assertEqual(self.conn.closes.get(self.channel), None) - self.channel.addWindowBytes(4) # send regular data - self.assertEqual(self.conn.closes.get(self.channel), None) - self.channel.addWindowBytes(8) # send extended data - self.assertTrue(self.conn.closes.get(self.channel)) - - def test_getPeer(self): - """ - Test that getPeer() returns ('SSH', <connection transport peer>). - """ - self.assertEqual(self.channel.getPeer(), ('SSH', 'MockPeer')) - - def test_getHost(self): - """ - Test that getHost() returns ('SSH', <connection transport host>). - """ - self.assertEqual(self.channel.getHost(), ('SSH', 'MockHost')) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py deleted file mode 100755 index 9c85050b..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_checkers.py +++ /dev/null @@ -1,609 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.checkers}. -""" - -try: - import crypt -except ImportError: - cryptSkip = 'cannot run without crypt module' -else: - cryptSkip = None - -import os, base64 - -from twisted.python import util -from twisted.python.failure import Failure -from twisted.trial.unittest import TestCase -from twisted.python.filepath import FilePath -from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse -from twisted.cred.credentials import UsernamePassword, IUsernamePassword, \ - SSHPrivateKey, ISSHPrivateKey -from twisted.cred.error import UnhandledCredentials, UnauthorizedLogin -from twisted.python.fakepwd import UserDatabase, ShadowDatabase -from twisted.test.test_process import MockOS - -try: - import Crypto.Cipher.DES3 - import pyasn1 -except ImportError: - dependencySkip = "can't run without Crypto and PyASN1" -else: - dependencySkip = None - from twisted.conch.ssh import keys - from twisted.conch import checkers - from twisted.conch.error import NotEnoughAuthentication, ValidPublicKey - from twisted.conch.test import keydata - -if getattr(os, 'geteuid', None) is None: - euidSkip = "Cannot run without effective UIDs (questionable)" -else: - euidSkip = None - - -class HelperTests(TestCase): - """ - Tests for helper functions L{verifyCryptedPassword}, L{_pwdGetByName} and - L{_shadowGetByName}. - """ - skip = cryptSkip or dependencySkip - - def setUp(self): - self.mockos = MockOS() - - - def test_verifyCryptedPassword(self): - """ - L{verifyCryptedPassword} returns C{True} if the plaintext password - passed to it matches the encrypted password passed to it. - """ - password = 'secret string' - salt = 'salty' - crypted = crypt.crypt(password, salt) - self.assertTrue( - checkers.verifyCryptedPassword(crypted, password), - '%r supposed to be valid encrypted password for %r' % ( - crypted, password)) - - - def test_verifyCryptedPasswordMD5(self): - """ - L{verifyCryptedPassword} returns True if the provided cleartext password - matches the provided MD5 password hash. - """ - password = 'password' - salt = '$1$salt' - crypted = crypt.crypt(password, salt) - self.assertTrue( - checkers.verifyCryptedPassword(crypted, password), - '%r supposed to be valid encrypted password for %s' % ( - crypted, password)) - - - def test_refuteCryptedPassword(self): - """ - L{verifyCryptedPassword} returns C{False} if the plaintext password - passed to it does not match the encrypted password passed to it. - """ - password = 'string secret' - wrong = 'secret string' - crypted = crypt.crypt(password, password) - self.assertFalse( - checkers.verifyCryptedPassword(crypted, wrong), - '%r not supposed to be valid encrypted password for %s' % ( - crypted, wrong)) - - - def test_pwdGetByName(self): - """ - L{_pwdGetByName} returns a tuple of items from the UNIX /etc/passwd - database if the L{pwd} module is present. - """ - userdb = UserDatabase() - userdb.addUser( - 'alice', 'secrit', 1, 2, 'first last', '/foo', '/bin/sh') - self.patch(checkers, 'pwd', userdb) - self.assertEquals( - checkers._pwdGetByName('alice'), userdb.getpwnam('alice')) - - - def test_pwdGetByNameWithoutPwd(self): - """ - If the C{pwd} module isn't present, L{_pwdGetByName} returns C{None}. - """ - self.patch(checkers, 'pwd', None) - self.assertIdentical(checkers._pwdGetByName('alice'), None) - - - def test_shadowGetByName(self): - """ - L{_shadowGetByName} returns a tuple of items from the UNIX /etc/shadow - database if the L{spwd} is present. - """ - userdb = ShadowDatabase() - userdb.addUser('bob', 'passphrase', 1, 2, 3, 4, 5, 6, 7) - self.patch(checkers, 'spwd', userdb) - - self.mockos.euid = 2345 - self.mockos.egid = 1234 - self.patch(checkers, 'os', self.mockos) - self.patch(util, 'os', self.mockos) - - self.assertEquals( - checkers._shadowGetByName('bob'), userdb.getspnam('bob')) - self.assertEquals(self.mockos.seteuidCalls, [0, 2345]) - self.assertEquals(self.mockos.setegidCalls, [0, 1234]) - - - def test_shadowGetByNameWithoutSpwd(self): - """ - L{_shadowGetByName} uses the C{shadow} module to return a tuple of items - from the UNIX /etc/shadow database if the C{spwd} module is not present - and the C{shadow} module is. - """ - userdb = ShadowDatabase() - userdb.addUser('bob', 'passphrase', 1, 2, 3, 4, 5, 6, 7) - self.patch(checkers, 'spwd', None) - self.patch(checkers, 'shadow', userdb) - self.patch(checkers, 'os', self.mockos) - self.patch(util, 'os', self.mockos) - - self.mockos.euid = 2345 - self.mockos.egid = 1234 - - self.assertEquals( - checkers._shadowGetByName('bob'), userdb.getspnam('bob')) - self.assertEquals(self.mockos.seteuidCalls, [0, 2345]) - self.assertEquals(self.mockos.setegidCalls, [0, 1234]) - - - def test_shadowGetByNameWithoutEither(self): - """ - L{_shadowGetByName} returns C{None} if neither C{spwd} nor C{shadow} is - present. - """ - self.patch(checkers, 'spwd', None) - self.patch(checkers, 'shadow', None) - self.patch(checkers, 'os', self.mockos) - - self.assertIdentical(checkers._shadowGetByName('bob'), None) - self.assertEquals(self.mockos.seteuidCalls, []) - self.assertEquals(self.mockos.setegidCalls, []) - - - -class SSHPublicKeyDatabaseTestCase(TestCase): - """ - Tests for L{SSHPublicKeyDatabase}. - """ - skip = euidSkip or dependencySkip - - def setUp(self): - self.checker = checkers.SSHPublicKeyDatabase() - self.key1 = base64.encodestring("foobar") - self.key2 = base64.encodestring("eggspam") - self.content = "t1 %s foo\nt2 %s egg\n" % (self.key1, self.key2) - - self.mockos = MockOS() - self.mockos.path = FilePath(self.mktemp()) - self.mockos.path.makedirs() - self.patch(checkers, 'os', self.mockos) - self.patch(util, 'os', self.mockos) - self.sshDir = self.mockos.path.child('.ssh') - self.sshDir.makedirs() - - userdb = UserDatabase() - userdb.addUser( - 'user', 'password', 1, 2, 'first last', - self.mockos.path.path, '/bin/shell') - self.checker._userdb = userdb - - - def _testCheckKey(self, filename): - self.sshDir.child(filename).setContent(self.content) - user = UsernamePassword("user", "password") - user.blob = "foobar" - self.assertTrue(self.checker.checkKey(user)) - user.blob = "eggspam" - self.assertTrue(self.checker.checkKey(user)) - user.blob = "notallowed" - self.assertFalse(self.checker.checkKey(user)) - - - def test_checkKey(self): - """ - L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the - authorized_keys file and check the keys against that file. - """ - self._testCheckKey("authorized_keys") - self.assertEqual(self.mockos.seteuidCalls, []) - self.assertEqual(self.mockos.setegidCalls, []) - - - def test_checkKey2(self): - """ - L{SSHPublicKeyDatabase.checkKey} should retrieve the content of the - authorized_keys2 file and check the keys against that file. - """ - self._testCheckKey("authorized_keys2") - self.assertEqual(self.mockos.seteuidCalls, []) - self.assertEqual(self.mockos.setegidCalls, []) - - - def test_checkKeyAsRoot(self): - """ - If the key file is readable, L{SSHPublicKeyDatabase.checkKey} should - switch its uid/gid to the ones of the authenticated user. - """ - keyFile = self.sshDir.child("authorized_keys") - keyFile.setContent(self.content) - # Fake permission error by changing the mode - keyFile.chmod(0000) - self.addCleanup(keyFile.chmod, 0777) - # And restore the right mode when seteuid is called - savedSeteuid = self.mockos.seteuid - def seteuid(euid): - keyFile.chmod(0777) - return savedSeteuid(euid) - self.mockos.euid = 2345 - self.mockos.egid = 1234 - self.patch(self.mockos, "seteuid", seteuid) - self.patch(checkers, 'os', self.mockos) - self.patch(util, 'os', self.mockos) - user = UsernamePassword("user", "password") - user.blob = "foobar" - self.assertTrue(self.checker.checkKey(user)) - self.assertEqual(self.mockos.seteuidCalls, [0, 1, 0, 2345]) - self.assertEqual(self.mockos.setegidCalls, [2, 1234]) - - - def test_requestAvatarId(self): - """ - L{SSHPublicKeyDatabase.requestAvatarId} should return the avatar id - passed in if its C{_checkKey} method returns True. - """ - def _checkKey(ignored): - return True - self.patch(self.checker, 'checkKey', _checkKey) - credentials = SSHPrivateKey( - 'test', 'ssh-rsa', keydata.publicRSA_openssh, 'foo', - keys.Key.fromString(keydata.privateRSA_openssh).sign('foo')) - d = self.checker.requestAvatarId(credentials) - def _verify(avatarId): - self.assertEqual(avatarId, 'test') - return d.addCallback(_verify) - - - def test_requestAvatarIdWithoutSignature(self): - """ - L{SSHPublicKeyDatabase.requestAvatarId} should raise L{ValidPublicKey} - if the credentials represent a valid key without a signature. This - tells the user that the key is valid for login, but does not actually - allow that user to do so without a signature. - """ - def _checkKey(ignored): - return True - self.patch(self.checker, 'checkKey', _checkKey) - credentials = SSHPrivateKey( - 'test', 'ssh-rsa', keydata.publicRSA_openssh, None, None) - d = self.checker.requestAvatarId(credentials) - return self.assertFailure(d, ValidPublicKey) - - - def test_requestAvatarIdInvalidKey(self): - """ - If L{SSHPublicKeyDatabase.checkKey} returns False, - C{_cbRequestAvatarId} should raise L{UnauthorizedLogin}. - """ - def _checkKey(ignored): - return False - self.patch(self.checker, 'checkKey', _checkKey) - d = self.checker.requestAvatarId(None); - return self.assertFailure(d, UnauthorizedLogin) - - - def test_requestAvatarIdInvalidSignature(self): - """ - Valid keys with invalid signatures should cause - L{SSHPublicKeyDatabase.requestAvatarId} to return a {UnauthorizedLogin} - failure - """ - def _checkKey(ignored): - return True - self.patch(self.checker, 'checkKey', _checkKey) - credentials = SSHPrivateKey( - 'test', 'ssh-rsa', keydata.publicRSA_openssh, 'foo', - keys.Key.fromString(keydata.privateDSA_openssh).sign('foo')) - d = self.checker.requestAvatarId(credentials) - return self.assertFailure(d, UnauthorizedLogin) - - - def test_requestAvatarIdNormalizeException(self): - """ - Exceptions raised while verifying the key should be normalized into an - C{UnauthorizedLogin} failure. - """ - def _checkKey(ignored): - return True - self.patch(self.checker, 'checkKey', _checkKey) - credentials = SSHPrivateKey('test', None, 'blob', 'sigData', 'sig') - d = self.checker.requestAvatarId(credentials) - def _verifyLoggedException(failure): - errors = self.flushLoggedErrors(keys.BadKeyError) - self.assertEqual(len(errors), 1) - return failure - d.addErrback(_verifyLoggedException) - return self.assertFailure(d, UnauthorizedLogin) - - - -class SSHProtocolCheckerTestCase(TestCase): - """ - Tests for L{SSHProtocolChecker}. - """ - - skip = dependencySkip - - def test_registerChecker(self): - """ - L{SSHProcotolChecker.registerChecker} should add the given checker to - the list of registered checkers. - """ - checker = checkers.SSHProtocolChecker() - self.assertEqual(checker.credentialInterfaces, []) - checker.registerChecker(checkers.SSHPublicKeyDatabase(), ) - self.assertEqual(checker.credentialInterfaces, [ISSHPrivateKey]) - self.assertIsInstance(checker.checkers[ISSHPrivateKey], - checkers.SSHPublicKeyDatabase) - - - def test_registerCheckerWithInterface(self): - """ - If a apecific interface is passed into - L{SSHProtocolChecker.registerChecker}, that interface should be - registered instead of what the checker specifies in - credentialIntefaces. - """ - checker = checkers.SSHProtocolChecker() - self.assertEqual(checker.credentialInterfaces, []) - checker.registerChecker(checkers.SSHPublicKeyDatabase(), - IUsernamePassword) - self.assertEqual(checker.credentialInterfaces, [IUsernamePassword]) - self.assertIsInstance(checker.checkers[IUsernamePassword], - checkers.SSHPublicKeyDatabase) - - - def test_requestAvatarId(self): - """ - L{SSHProtocolChecker.requestAvatarId} should defer to one if its - registered checkers to authenticate a user. - """ - checker = checkers.SSHProtocolChecker() - passwordDatabase = InMemoryUsernamePasswordDatabaseDontUse() - passwordDatabase.addUser('test', 'test') - checker.registerChecker(passwordDatabase) - d = checker.requestAvatarId(UsernamePassword('test', 'test')) - def _callback(avatarId): - self.assertEqual(avatarId, 'test') - return d.addCallback(_callback) - - - def test_requestAvatarIdWithNotEnoughAuthentication(self): - """ - If the client indicates that it is never satisfied, by always returning - False from _areDone, then L{SSHProtocolChecker} should raise - L{NotEnoughAuthentication}. - """ - checker = checkers.SSHProtocolChecker() - def _areDone(avatarId): - return False - self.patch(checker, 'areDone', _areDone) - - passwordDatabase = InMemoryUsernamePasswordDatabaseDontUse() - passwordDatabase.addUser('test', 'test') - checker.registerChecker(passwordDatabase) - d = checker.requestAvatarId(UsernamePassword('test', 'test')) - return self.assertFailure(d, NotEnoughAuthentication) - - - def test_requestAvatarIdInvalidCredential(self): - """ - If the passed credentials aren't handled by any registered checker, - L{SSHProtocolChecker} should raise L{UnhandledCredentials}. - """ - checker = checkers.SSHProtocolChecker() - d = checker.requestAvatarId(UsernamePassword('test', 'test')) - return self.assertFailure(d, UnhandledCredentials) - - - def test_areDone(self): - """ - The default L{SSHProcotolChecker.areDone} should simply return True. - """ - self.assertEquals(checkers.SSHProtocolChecker().areDone(None), True) - - - -class UNIXPasswordDatabaseTests(TestCase): - """ - Tests for L{UNIXPasswordDatabase}. - """ - skip = cryptSkip or dependencySkip - - def assertLoggedIn(self, d, username): - """ - Assert that the L{Deferred} passed in is called back with the value - 'username'. This represents a valid login for this TestCase. - - NOTE: To work, this method's return value must be returned from the - test method, or otherwise hooked up to the test machinery. - - @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method. - @type d: L{Deferred} - @rtype: L{Deferred} - """ - result = [] - d.addBoth(result.append) - self.assertEquals(len(result), 1, "login incomplete") - if isinstance(result[0], Failure): - result[0].raiseException() - self.assertEquals(result[0], username) - - - def test_defaultCheckers(self): - """ - L{UNIXPasswordDatabase} with no arguments has checks the C{pwd} database - and then the C{spwd} database. - """ - checker = checkers.UNIXPasswordDatabase() - - def crypted(username, password): - salt = crypt.crypt(password, username) - crypted = crypt.crypt(password, '$1$' + salt) - return crypted - - pwd = UserDatabase() - pwd.addUser('alice', crypted('alice', 'password'), - 1, 2, 'foo', '/foo', '/bin/sh') - # x and * are convention for "look elsewhere for the password" - pwd.addUser('bob', 'x', 1, 2, 'bar', '/bar', '/bin/sh') - spwd = ShadowDatabase() - spwd.addUser('alice', 'wrong', 1, 2, 3, 4, 5, 6, 7) - spwd.addUser('bob', crypted('bob', 'password'), - 8, 9, 10, 11, 12, 13, 14) - - self.patch(checkers, 'pwd', pwd) - self.patch(checkers, 'spwd', spwd) - - mockos = MockOS() - self.patch(checkers, 'os', mockos) - self.patch(util, 'os', mockos) - - mockos.euid = 2345 - mockos.egid = 1234 - - cred = UsernamePassword("alice", "password") - self.assertLoggedIn(checker.requestAvatarId(cred), 'alice') - self.assertEquals(mockos.seteuidCalls, []) - self.assertEquals(mockos.setegidCalls, []) - cred.username = "bob" - self.assertLoggedIn(checker.requestAvatarId(cred), 'bob') - self.assertEquals(mockos.seteuidCalls, [0, 2345]) - self.assertEquals(mockos.setegidCalls, [0, 1234]) - - - def assertUnauthorizedLogin(self, d): - """ - Asserts that the L{Deferred} passed in is erred back with an - L{UnauthorizedLogin} L{Failure}. This reprsents an invalid login for - this TestCase. - - NOTE: To work, this method's return value must be returned from the - test method, or otherwise hooked up to the test machinery. - - @param d: a L{Deferred} from an L{IChecker.requestAvatarId} method. - @type d: L{Deferred} - @rtype: L{None} - """ - self.assertRaises( - checkers.UnauthorizedLogin, self.assertLoggedIn, d, 'bogus value') - - - def test_passInCheckers(self): - """ - L{UNIXPasswordDatabase} takes a list of functions to check for UNIX - user information. - """ - password = crypt.crypt('secret', 'secret') - userdb = UserDatabase() - userdb.addUser('anybody', password, 1, 2, 'foo', '/bar', '/bin/sh') - checker = checkers.UNIXPasswordDatabase([userdb.getpwnam]) - self.assertLoggedIn( - checker.requestAvatarId(UsernamePassword('anybody', 'secret')), - 'anybody') - - - def test_verifyPassword(self): - """ - If the encrypted password provided by the getpwnam function is valid - (verified by the L{verifyCryptedPassword} function), we callback the - C{requestAvatarId} L{Deferred} with the username. - """ - def verifyCryptedPassword(crypted, pw): - return crypted == pw - def getpwnam(username): - return [username, username] - self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword) - checker = checkers.UNIXPasswordDatabase([getpwnam]) - credential = UsernamePassword('username', 'username') - self.assertLoggedIn(checker.requestAvatarId(credential), 'username') - - - def test_failOnKeyError(self): - """ - If the getpwnam function raises a KeyError, the login fails with an - L{UnauthorizedLogin} exception. - """ - def getpwnam(username): - raise KeyError(username) - checker = checkers.UNIXPasswordDatabase([getpwnam]) - credential = UsernamePassword('username', 'username') - self.assertUnauthorizedLogin(checker.requestAvatarId(credential)) - - - def test_failOnBadPassword(self): - """ - If the verifyCryptedPassword function doesn't verify the password, the - login fails with an L{UnauthorizedLogin} exception. - """ - def verifyCryptedPassword(crypted, pw): - return False - def getpwnam(username): - return [username, username] - self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword) - checker = checkers.UNIXPasswordDatabase([getpwnam]) - credential = UsernamePassword('username', 'username') - self.assertUnauthorizedLogin(checker.requestAvatarId(credential)) - - - def test_loopThroughFunctions(self): - """ - UNIXPasswordDatabase.requestAvatarId loops through each getpwnam - function associated with it and returns a L{Deferred} which fires with - the result of the first one which returns a value other than None. - ones do not verify the password. - """ - def verifyCryptedPassword(crypted, pw): - return crypted == pw - def getpwnam1(username): - return [username, 'not the password'] - def getpwnam2(username): - return [username, username] - self.patch(checkers, 'verifyCryptedPassword', verifyCryptedPassword) - checker = checkers.UNIXPasswordDatabase([getpwnam1, getpwnam2]) - credential = UsernamePassword('username', 'username') - self.assertLoggedIn(checker.requestAvatarId(credential), 'username') - - - def test_failOnSpecial(self): - """ - If the password returned by any function is C{""}, C{"x"}, or C{"*"} it - is not compared against the supplied password. Instead it is skipped. - """ - pwd = UserDatabase() - pwd.addUser('alice', '', 1, 2, '', 'foo', 'bar') - pwd.addUser('bob', 'x', 1, 2, '', 'foo', 'bar') - pwd.addUser('carol', '*', 1, 2, '', 'foo', 'bar') - self.patch(checkers, 'pwd', pwd) - - checker = checkers.UNIXPasswordDatabase([checkers._pwdGetByName]) - cred = UsernamePassword('alice', '') - self.assertUnauthorizedLogin(checker.requestAvatarId(cred)) - - cred = UsernamePassword('bob', 'x') - self.assertUnauthorizedLogin(checker.requestAvatarId(cred)) - - cred = UsernamePassword('carol', '*') - self.assertUnauthorizedLogin(checker.requestAvatarId(cred)) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py deleted file mode 100755 index df437e2d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ckeygen.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.scripts.ckeygen}. -""" - -import sys -from StringIO import StringIO - -try: - import Crypto - import pyasn1 -except ImportError: - skip = "PyCrypto and pyasn1 required for twisted.conch.scripts.ckeygen." -else: - from twisted.conch.ssh.keys import Key - from twisted.conch.scripts.ckeygen import printFingerprint, _saveKey - -from twisted.python.filepath import FilePath -from twisted.trial.unittest import TestCase -from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh - - - -class KeyGenTests(TestCase): - """ - Tests for various functions used to implement the I{ckeygen} script. - """ - def setUp(self): - """ - Patch C{sys.stdout} with a L{StringIO} instance to tests can make - assertions about what's printed. - """ - self.stdout = StringIO() - self.patch(sys, 'stdout', self.stdout) - - - def test_printFingerprint(self): - """ - L{printFingerprint} writes a line to standard out giving the number of - bits of the key, its fingerprint, and the basename of the file from it - was read. - """ - filename = self.mktemp() - FilePath(filename).setContent(publicRSA_openssh) - printFingerprint({'filename': filename}) - self.assertEqual( - self.stdout.getvalue(), - '768 3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af temp\n') - - - def test_saveKey(self): - """ - L{_saveKey} writes the private and public parts of a key to two - different files and writes a report of this to standard out. - """ - base = FilePath(self.mktemp()) - base.makedirs() - filename = base.child('id_rsa').path - key = Key.fromString(privateRSA_openssh) - _saveKey( - key.keyObject, - {'filename': filename, 'pass': 'passphrase'}) - self.assertEqual( - self.stdout.getvalue(), - "Your identification has been saved in %s\n" - "Your public key has been saved in %s.pub\n" - "The key fingerprint is:\n" - "3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af\n" % ( - filename, - filename)) - self.assertEqual( - key.fromString( - base.child('id_rsa').getContent(), None, 'passphrase'), - key) - self.assertEqual( - Key.fromString(base.child('id_rsa.pub').getContent()), - key.public()) - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py deleted file mode 100755 index 95219d4d..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_conch.py +++ /dev/null @@ -1,552 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_conch -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -import os, sys, socket -from itertools import count - -from zope.interface import implements - -from twisted.cred import portal -from twisted.internet import reactor, defer, protocol -from twisted.internet.error import ProcessExitedAlready -from twisted.internet.task import LoopingCall -from twisted.python import log, runtime -from twisted.trial import unittest -from twisted.conch.error import ConchError -from twisted.conch.avatar import ConchUser -from twisted.conch.ssh.session import ISession, SSHSession, wrapProtocol - -try: - from twisted.conch.scripts.conch import SSHSession as StdioInteractingSession -except ImportError, e: - StdioInteractingSession = None - _reason = str(e) - del e - -from twisted.conch.test.test_ssh import ConchTestRealm -from twisted.python.procutils import which - -from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh -from twisted.conch.test.keydata import publicDSA_openssh, privateDSA_openssh - -from twisted.conch.test.test_ssh import Crypto, pyasn1 -try: - from twisted.conch.test.test_ssh import ConchTestServerFactory, \ - ConchTestPublicKeyChecker -except ImportError: - pass - - - -class StdioInteractingSessionTests(unittest.TestCase): - """ - Tests for L{twisted.conch.scripts.conch.SSHSession}. - """ - if StdioInteractingSession is None: - skip = _reason - - def test_eofReceived(self): - """ - L{twisted.conch.scripts.conch.SSHSession.eofReceived} loses the - write half of its stdio connection. - """ - class FakeStdio: - writeConnLost = False - - def loseWriteConnection(self): - self.writeConnLost = True - - stdio = FakeStdio() - channel = StdioInteractingSession() - channel.stdio = stdio - channel.eofReceived() - self.assertTrue(stdio.writeConnLost) - - - -class Echo(protocol.Protocol): - def connectionMade(self): - log.msg('ECHO CONNECTION MADE') - - - def connectionLost(self, reason): - log.msg('ECHO CONNECTION DONE') - - - def dataReceived(self, data): - self.transport.write(data) - if '\n' in data: - self.transport.loseConnection() - - - -class EchoFactory(protocol.Factory): - protocol = Echo - - - -class ConchTestOpenSSHProcess(protocol.ProcessProtocol): - """ - Test protocol for launching an OpenSSH client process. - - @ivar deferred: Set by whatever uses this object. Accessed using - L{_getDeferred}, which destroys the value so the Deferred is not - fired twice. Fires when the process is terminated. - """ - - deferred = None - buf = '' - - def _getDeferred(self): - d, self.deferred = self.deferred, None - return d - - - def outReceived(self, data): - self.buf += data - - - def processEnded(self, reason): - """ - Called when the process has ended. - - @param reason: a Failure giving the reason for the process' end. - """ - if reason.value.exitCode != 0: - self._getDeferred().errback( - ConchError("exit code was not 0: %s" % - reason.value.exitCode)) - else: - buf = self.buf.replace('\r\n', '\n') - self._getDeferred().callback(buf) - - - -class ConchTestForwardingProcess(protocol.ProcessProtocol): - """ - Manages a third-party process which launches a server. - - Uses L{ConchTestForwardingPort} to connect to the third-party server. - Once L{ConchTestForwardingPort} has disconnected, kill the process and fire - a Deferred with the data received by the L{ConchTestForwardingPort}. - - @ivar deferred: Set by whatever uses this object. Accessed using - L{_getDeferred}, which destroys the value so the Deferred is not - fired twice. Fires when the process is terminated. - """ - - deferred = None - - def __init__(self, port, data): - """ - @type port: C{int} - @param port: The port on which the third-party server is listening. - (it is assumed that the server is running on localhost). - - @type data: C{str} - @param data: This is sent to the third-party server. Must end with '\n' - in order to trigger a disconnect. - """ - self.port = port - self.buffer = None - self.data = data - - - def _getDeferred(self): - d, self.deferred = self.deferred, None - return d - - - def connectionMade(self): - self._connect() - - - def _connect(self): - """ - Connect to the server, which is often a third-party process. - Tries to reconnect if it fails because we have no way of determining - exactly when the port becomes available for listening -- we can only - know when the process starts. - """ - cc = protocol.ClientCreator(reactor, ConchTestForwardingPort, self, - self.data) - d = cc.connectTCP('127.0.0.1', self.port) - d.addErrback(self._ebConnect) - return d - - - def _ebConnect(self, f): - reactor.callLater(.1, self._connect) - - - def forwardingPortDisconnected(self, buffer): - """ - The network connection has died; save the buffer of output - from the network and attempt to quit the process gracefully, - and then (after the reactor has spun) send it a KILL signal. - """ - self.buffer = buffer - self.transport.write('\x03') - self.transport.loseConnection() - reactor.callLater(0, self._reallyDie) - - - def _reallyDie(self): - try: - self.transport.signalProcess('KILL') - except ProcessExitedAlready: - pass - - - def processEnded(self, reason): - """ - Fire the Deferred at self.deferred with the data collected - from the L{ConchTestForwardingPort} connection, if any. - """ - self._getDeferred().callback(self.buffer) - - - -class ConchTestForwardingPort(protocol.Protocol): - """ - Connects to server launched by a third-party process (managed by - L{ConchTestForwardingProcess}) sends data, then reports whatever it - received back to the L{ConchTestForwardingProcess} once the connection - is ended. - """ - - - def __init__(self, protocol, data): - """ - @type protocol: L{ConchTestForwardingProcess} - @param protocol: The L{ProcessProtocol} which made this connection. - - @type data: str - @param data: The data to be sent to the third-party server. - """ - self.protocol = protocol - self.data = data - - - def connectionMade(self): - self.buffer = '' - self.transport.write(self.data) - - - def dataReceived(self, data): - self.buffer += data - - - def connectionLost(self, reason): - self.protocol.forwardingPortDisconnected(self.buffer) - - - -def _makeArgs(args, mod="conch"): - start = [sys.executable, '-c' -""" -### Twisted Preamble -import sys, os -path = os.path.abspath(sys.argv[0]) -while os.path.dirname(path) != path: - if os.path.basename(path).startswith('Twisted'): - sys.path.insert(0, path) - break - path = os.path.dirname(path) - -from twisted.conch.scripts.%s import run -run()""" % mod] - return start + list(args) - - - -class ConchServerSetupMixin: - if not Crypto: - skip = "can't run w/o PyCrypto" - - if not pyasn1: - skip = "Cannot run without PyASN1" - - realmFactory = staticmethod(lambda: ConchTestRealm('testuser')) - - def _createFiles(self): - for f in ['rsa_test','rsa_test.pub','dsa_test','dsa_test.pub', - 'kh_test']: - if os.path.exists(f): - os.remove(f) - open('rsa_test','w').write(privateRSA_openssh) - open('rsa_test.pub','w').write(publicRSA_openssh) - open('dsa_test.pub','w').write(publicDSA_openssh) - open('dsa_test','w').write(privateDSA_openssh) - os.chmod('dsa_test', 33152) - os.chmod('rsa_test', 33152) - open('kh_test','w').write('127.0.0.1 '+publicRSA_openssh) - - - def _getFreePort(self): - s = socket.socket() - s.bind(('', 0)) - port = s.getsockname()[1] - s.close() - return port - - - def _makeConchFactory(self): - """ - Make a L{ConchTestServerFactory}, which allows us to start a - L{ConchTestServer} -- i.e. an actually listening conch. - """ - realm = self.realmFactory() - p = portal.Portal(realm) - p.registerChecker(ConchTestPublicKeyChecker()) - factory = ConchTestServerFactory() - factory.portal = p - return factory - - - def setUp(self): - self._createFiles() - self.conchFactory = self._makeConchFactory() - self.conchFactory.expectedLoseConnection = 1 - self.conchServer = reactor.listenTCP(0, self.conchFactory, - interface="127.0.0.1") - self.echoServer = reactor.listenTCP(0, EchoFactory()) - self.echoPort = self.echoServer.getHost().port - - - def tearDown(self): - try: - self.conchFactory.proto.done = 1 - except AttributeError: - pass - else: - self.conchFactory.proto.transport.loseConnection() - return defer.gatherResults([ - defer.maybeDeferred(self.conchServer.stopListening), - defer.maybeDeferred(self.echoServer.stopListening)]) - - - -class ForwardingMixin(ConchServerSetupMixin): - """ - Template class for tests of the Conch server's ability to forward arbitrary - protocols over SSH. - - These tests are integration tests, not unit tests. They launch a Conch - server, a custom TCP server (just an L{EchoProtocol}) and then call - L{execute}. - - L{execute} is implemented by subclasses of L{ForwardingMixin}. It should - cause an SSH client to connect to the Conch server, asking it to forward - data to the custom TCP server. - """ - - def test_exec(self): - """ - Test that we can use whatever client to send the command "echo goodbye" - to the Conch server. Make sure we receive "goodbye" back from the - server. - """ - d = self.execute('echo goodbye', ConchTestOpenSSHProcess()) - return d.addCallback(self.assertEqual, 'goodbye\n') - - - def test_localToRemoteForwarding(self): - """ - Test that we can use whatever client to forward a local port to a - specified port on the server. - """ - localPort = self._getFreePort() - process = ConchTestForwardingProcess(localPort, 'test\n') - d = self.execute('', process, - sshArgs='-N -L%i:127.0.0.1:%i' - % (localPort, self.echoPort)) - d.addCallback(self.assertEqual, 'test\n') - return d - - - def test_remoteToLocalForwarding(self): - """ - Test that we can use whatever client to forward a port from the server - to a port locally. - """ - localPort = self._getFreePort() - process = ConchTestForwardingProcess(localPort, 'test\n') - d = self.execute('', process, - sshArgs='-N -R %i:127.0.0.1:%i' - % (localPort, self.echoPort)) - d.addCallback(self.assertEqual, 'test\n') - return d - - - -class RekeyAvatar(ConchUser): - """ - This avatar implements a shell which sends 60 numbered lines to whatever - connects to it, then closes the session with a 0 exit status. - - 60 lines is selected as being enough to send more than 2kB of traffic, the - amount the client is configured to initiate a rekey after. - """ - # Conventionally there is a separate adapter object which provides ISession - # for the user, but making the user provide ISession directly works too. - # This isn't a full implementation of ISession though, just enough to make - # these tests pass. - implements(ISession) - - def __init__(self): - ConchUser.__init__(self) - self.channelLookup['session'] = SSHSession - - - def openShell(self, transport): - """ - Write 60 lines of data to the transport, then exit. - """ - proto = protocol.Protocol() - proto.makeConnection(transport) - transport.makeConnection(wrapProtocol(proto)) - - # Send enough bytes to the connection so that a rekey is triggered in - # the client. - def write(counter): - i = counter() - if i == 60: - call.stop() - transport.session.conn.sendRequest( - transport.session, 'exit-status', '\x00\x00\x00\x00') - transport.loseConnection() - else: - transport.write("line #%02d\n" % (i,)) - - # The timing for this loop is an educated guess (and/or the result of - # experimentation) to exercise the case where a packet is generated - # mid-rekey. Since the other side of the connection is (so far) the - # OpenSSH command line client, there's no easy way to determine when the - # rekey has been initiated. If there were, then generating a packet - # immediately at that time would be a better way to test the - # functionality being tested here. - call = LoopingCall(write, count().next) - call.start(0.01) - - - def closed(self): - """ - Ignore the close of the session. - """ - - - -class RekeyRealm: - """ - This realm gives out new L{RekeyAvatar} instances for any avatar request. - """ - def requestAvatar(self, avatarID, mind, *interfaces): - return interfaces[0], RekeyAvatar(), lambda: None - - - -class RekeyTestsMixin(ConchServerSetupMixin): - """ - TestCase mixin which defines tests exercising L{SSHTransportBase}'s handling - of rekeying messages. - """ - realmFactory = RekeyRealm - - def test_clientRekey(self): - """ - After a client-initiated rekey is completed, application data continues - to be passed over the SSH connection. - """ - process = ConchTestOpenSSHProcess() - d = self.execute("", process, '-o RekeyLimit=2K') - def finished(result): - self.assertEqual( - result, - '\n'.join(['line #%02d' % (i,) for i in range(60)]) + '\n') - d.addCallback(finished) - return d - - - -class OpenSSHClientMixin: - if not which('ssh'): - skip = "no ssh command-line client available" - - def execute(self, remoteCommand, process, sshArgs=''): - """ - Connects to the SSH server started in L{ConchServerSetupMixin.setUp} by - running the 'ssh' command line tool. - - @type remoteCommand: str - @param remoteCommand: The command (with arguments) to run on the - remote end. - - @type process: L{ConchTestOpenSSHProcess} - - @type sshArgs: str - @param sshArgs: Arguments to pass to the 'ssh' process. - - @return: L{defer.Deferred} - """ - process.deferred = defer.Deferred() - cmdline = ('ssh -2 -l testuser -p %i ' - '-oUserKnownHostsFile=kh_test ' - '-oPasswordAuthentication=no ' - # Always use the RSA key, since that's the one in kh_test. - '-oHostKeyAlgorithms=ssh-rsa ' - '-a ' - '-i dsa_test ') + sshArgs + \ - ' 127.0.0.1 ' + remoteCommand - port = self.conchServer.getHost().port - cmds = (cmdline % port).split() - reactor.spawnProcess(process, "ssh", cmds) - return process.deferred - - - -class OpenSSHClientForwardingTestCase(ForwardingMixin, OpenSSHClientMixin, - unittest.TestCase): - """ - Connection forwarding tests run against the OpenSSL command line client. - """ - - - -class OpenSSHClientRekeyTestCase(RekeyTestsMixin, OpenSSHClientMixin, - unittest.TestCase): - """ - Rekeying tests run against the OpenSSL command line client. - """ - - - -class CmdLineClientTestCase(ForwardingMixin, unittest.TestCase): - """ - Connection forwarding tests run against the Conch command line client. - """ - if runtime.platformType == 'win32': - skip = "can't run cmdline client on win32" - - def execute(self, remoteCommand, process, sshArgs=''): - """ - As for L{OpenSSHClientTestCase.execute}, except it runs the 'conch' - command line tool, not 'ssh'. - """ - process.deferred = defer.Deferred() - port = self.conchServer.getHost().port - cmd = ('-p %i -l testuser ' - '--known-hosts kh_test ' - '--user-authentications publickey ' - '--host-key-algorithms ssh-rsa ' - '-a ' - '-i dsa_test ' - '-v ') % port + sshArgs + \ - ' 127.0.0.1 ' + remoteCommand - cmds = _makeArgs(cmd.split()) - log.msg(str(cmds)) - env = os.environ.copy() - env['PYTHONPATH'] = os.pathsep.join(sys.path) - reactor.spawnProcess(process, sys.executable, cmds, env=env) - return process.deferred diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py deleted file mode 100755 index 85a8e6a7..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_connection.py +++ /dev/null @@ -1,730 +0,0 @@ -# Copyright (c) 2007-2010 Twisted Matrix Laboratories. -# See LICENSE for details - -""" -This module tests twisted.conch.ssh.connection. -""" - -import struct - -from twisted.conch import error -from twisted.conch.ssh import channel, common, connection -from twisted.trial import unittest -from twisted.conch.test import test_userauth - - -class TestChannel(channel.SSHChannel): - """ - A mocked-up version of twisted.conch.ssh.channel.SSHChannel. - - @ivar gotOpen: True if channelOpen has been called. - @type gotOpen: C{bool} - @ivar specificData: the specific channel open data passed to channelOpen. - @type specificData: C{str} - @ivar openFailureReason: the reason passed to openFailed. - @type openFailed: C{error.ConchError} - @ivar inBuffer: a C{list} of strings received by the channel. - @type inBuffer: C{list} - @ivar extBuffer: a C{list} of 2-tuples (type, extended data) of received by - the channel. - @type extBuffer: C{list} - @ivar numberRequests: the number of requests that have been made to this - channel. - @type numberRequests: C{int} - @ivar gotEOF: True if the other side sent EOF. - @type gotEOF: C{bool} - @ivar gotOneClose: True if the other side closed the connection. - @type gotOneClose: C{bool} - @ivar gotClosed: True if the channel is closed. - @type gotClosed: C{bool} - """ - name = "TestChannel" - gotOpen = False - - def logPrefix(self): - return "TestChannel %i" % self.id - - def channelOpen(self, specificData): - """ - The channel is open. Set up the instance variables. - """ - self.gotOpen = True - self.specificData = specificData - self.inBuffer = [] - self.extBuffer = [] - self.numberRequests = 0 - self.gotEOF = False - self.gotOneClose = False - self.gotClosed = False - - def openFailed(self, reason): - """ - Opening the channel failed. Store the reason why. - """ - self.openFailureReason = reason - - def request_test(self, data): - """ - A test request. Return True if data is 'data'. - - @type data: C{str} - """ - self.numberRequests += 1 - return data == 'data' - - def dataReceived(self, data): - """ - Data was received. Store it in the buffer. - """ - self.inBuffer.append(data) - - def extReceived(self, code, data): - """ - Extended data was received. Store it in the buffer. - """ - self.extBuffer.append((code, data)) - - def eofReceived(self): - """ - EOF was received. Remember it. - """ - self.gotEOF = True - - def closeReceived(self): - """ - Close was received. Remember it. - """ - self.gotOneClose = True - - def closed(self): - """ - The channel is closed. Rembember it. - """ - self.gotClosed = True - -class TestAvatar: - """ - A mocked-up version of twisted.conch.avatar.ConchUser - """ - _ARGS_ERROR_CODE = 123 - - def lookupChannel(self, channelType, windowSize, maxPacket, data): - """ - The server wants us to return a channel. If the requested channel is - our TestChannel, return it, otherwise return None. - """ - if channelType == TestChannel.name: - return TestChannel(remoteWindow=windowSize, - remoteMaxPacket=maxPacket, - data=data, avatar=self) - elif channelType == "conch-error-args": - # Raise a ConchError with backwards arguments to make sure the - # connection fixes it for us. This case should be deprecated and - # deleted eventually, but only after all of Conch gets the argument - # order right. - raise error.ConchError( - self._ARGS_ERROR_CODE, "error args in wrong order") - - - def gotGlobalRequest(self, requestType, data): - """ - The client has made a global request. If the global request is - 'TestGlobal', return True. If the global request is 'TestData', - return True and the request-specific data we received. Otherwise, - return False. - """ - if requestType == 'TestGlobal': - return True - elif requestType == 'TestData': - return True, data - else: - return False - - - -class TestConnection(connection.SSHConnection): - """ - A subclass of SSHConnection for testing. - - @ivar channel: the current channel. - @type channel. C{TestChannel} - """ - - def logPrefix(self): - return "TestConnection" - - def global_TestGlobal(self, data): - """ - The other side made the 'TestGlobal' global request. Return True. - """ - return True - - def global_Test_Data(self, data): - """ - The other side made the 'Test-Data' global request. Return True and - the data we received. - """ - return True, data - - def channel_TestChannel(self, windowSize, maxPacket, data): - """ - The other side is requesting the TestChannel. Create a C{TestChannel} - instance, store it, and return it. - """ - self.channel = TestChannel(remoteWindow=windowSize, - remoteMaxPacket=maxPacket, data=data) - return self.channel - - def channel_ErrorChannel(self, windowSize, maxPacket, data): - """ - The other side is requesting the ErrorChannel. Raise an exception. - """ - raise AssertionError('no such thing') - - - -class ConnectionTestCase(unittest.TestCase): - - if test_userauth.transport is None: - skip = "Cannot run without both PyCrypto and pyasn1" - - def setUp(self): - self.transport = test_userauth.FakeTransport(None) - self.transport.avatar = TestAvatar() - self.conn = TestConnection() - self.conn.transport = self.transport - self.conn.serviceStarted() - - def _openChannel(self, channel): - """ - Open the channel with the default connection. - """ - self.conn.openChannel(channel) - self.transport.packets = self.transport.packets[:-1] - self.conn.ssh_CHANNEL_OPEN_CONFIRMATION(struct.pack('>2L', - channel.id, 255) + '\x00\x02\x00\x00\x00\x00\x80\x00') - - def tearDown(self): - self.conn.serviceStopped() - - def test_linkAvatar(self): - """ - Test that the connection links itself to the avatar in the - transport. - """ - self.assertIdentical(self.transport.avatar.conn, self.conn) - - def test_serviceStopped(self): - """ - Test that serviceStopped() closes any open channels. - """ - channel1 = TestChannel() - channel2 = TestChannel() - self.conn.openChannel(channel1) - self.conn.openChannel(channel2) - self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00' * 4) - self.assertTrue(channel1.gotOpen) - self.assertFalse(channel2.gotOpen) - self.conn.serviceStopped() - self.assertTrue(channel1.gotClosed) - - def test_GLOBAL_REQUEST(self): - """ - Test that global request packets are dispatched to the global_* - methods and the return values are translated into success or failure - messages. - """ - self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\xff') - self.assertEqual(self.transport.packets, - [(connection.MSG_REQUEST_SUCCESS, '')]) - self.transport.packets = [] - self.conn.ssh_GLOBAL_REQUEST(common.NS('TestData') + '\xff' + - 'test data') - self.assertEqual(self.transport.packets, - [(connection.MSG_REQUEST_SUCCESS, 'test data')]) - self.transport.packets = [] - self.conn.ssh_GLOBAL_REQUEST(common.NS('TestBad') + '\xff') - self.assertEqual(self.transport.packets, - [(connection.MSG_REQUEST_FAILURE, '')]) - self.transport.packets = [] - self.conn.ssh_GLOBAL_REQUEST(common.NS('TestGlobal') + '\x00') - self.assertEqual(self.transport.packets, []) - - def test_REQUEST_SUCCESS(self): - """ - Test that global request success packets cause the Deferred to be - called back. - """ - d = self.conn.sendGlobalRequest('request', 'data', True) - self.conn.ssh_REQUEST_SUCCESS('data') - def check(data): - self.assertEqual(data, 'data') - d.addCallback(check) - d.addErrback(self.fail) - return d - - def test_REQUEST_FAILURE(self): - """ - Test that global request failure packets cause the Deferred to be - erred back. - """ - d = self.conn.sendGlobalRequest('request', 'data', True) - self.conn.ssh_REQUEST_FAILURE('data') - def check(f): - self.assertEqual(f.value.data, 'data') - d.addCallback(self.fail) - d.addErrback(check) - return d - - def test_CHANNEL_OPEN(self): - """ - Test that open channel packets cause a channel to be created and - opened or a failure message to be returned. - """ - del self.transport.avatar - self.conn.ssh_CHANNEL_OPEN(common.NS('TestChannel') + - '\x00\x00\x00\x01' * 4) - self.assertTrue(self.conn.channel.gotOpen) - self.assertEqual(self.conn.channel.conn, self.conn) - self.assertEqual(self.conn.channel.data, '\x00\x00\x00\x01') - self.assertEqual(self.conn.channel.specificData, '\x00\x00\x00\x01') - self.assertEqual(self.conn.channel.remoteWindowLeft, 1) - self.assertEqual(self.conn.channel.remoteMaxPacket, 1) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_OPEN_CONFIRMATION, - '\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00' - '\x00\x00\x80\x00')]) - self.transport.packets = [] - self.conn.ssh_CHANNEL_OPEN(common.NS('BadChannel') + - '\x00\x00\x00\x02' * 4) - self.flushLoggedErrors() - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_OPEN_FAILURE, - '\x00\x00\x00\x02\x00\x00\x00\x03' + common.NS( - 'unknown channel') + common.NS(''))]) - self.transport.packets = [] - self.conn.ssh_CHANNEL_OPEN(common.NS('ErrorChannel') + - '\x00\x00\x00\x02' * 4) - self.flushLoggedErrors() - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_OPEN_FAILURE, - '\x00\x00\x00\x02\x00\x00\x00\x02' + common.NS( - 'unknown failure') + common.NS(''))]) - - - def _lookupChannelErrorTest(self, code): - """ - Deliver a request for a channel open which will result in an exception - being raised during channel lookup. Assert that an error response is - delivered as a result. - """ - self.transport.avatar._ARGS_ERROR_CODE = code - self.conn.ssh_CHANNEL_OPEN( - common.NS('conch-error-args') + '\x00\x00\x00\x01' * 4) - errors = self.flushLoggedErrors(error.ConchError) - self.assertEqual( - len(errors), 1, "Expected one error, got: %r" % (errors,)) - self.assertEqual(errors[0].value.args, (123, "error args in wrong order")) - self.assertEqual( - self.transport.packets, - [(connection.MSG_CHANNEL_OPEN_FAILURE, - # The response includes some bytes which identifying the - # associated request, as well as the error code (7b in hex) and - # the error message. - '\x00\x00\x00\x01\x00\x00\x00\x7b' + common.NS( - 'error args in wrong order') + common.NS(''))]) - - - def test_lookupChannelError(self): - """ - If a C{lookupChannel} implementation raises L{error.ConchError} with the - arguments in the wrong order, a C{MSG_CHANNEL_OPEN} failure is still - sent in response to the message. - - This is a temporary work-around until L{error.ConchError} is given - better attributes and all of the Conch code starts constructing - instances of it properly. Eventually this functionality should be - deprecated and then removed. - """ - self._lookupChannelErrorTest(123) - - - def test_lookupChannelErrorLongCode(self): - """ - Like L{test_lookupChannelError}, but for the case where the failure code - is represented as a C{long} instead of a C{int}. - """ - self._lookupChannelErrorTest(123L) - - - def test_CHANNEL_OPEN_CONFIRMATION(self): - """ - Test that channel open confirmation packets cause the channel to be - notified that it's open. - """ - channel = TestChannel() - self.conn.openChannel(channel) - self.conn.ssh_CHANNEL_OPEN_CONFIRMATION('\x00\x00\x00\x00'*5) - self.assertEqual(channel.remoteWindowLeft, 0) - self.assertEqual(channel.remoteMaxPacket, 0) - self.assertEqual(channel.specificData, '\x00\x00\x00\x00') - self.assertEqual(self.conn.channelsToRemoteChannel[channel], - 0) - self.assertEqual(self.conn.localToRemoteChannel[0], 0) - - def test_CHANNEL_OPEN_FAILURE(self): - """ - Test that channel open failure packets cause the channel to be - notified that its opening failed. - """ - channel = TestChannel() - self.conn.openChannel(channel) - self.conn.ssh_CHANNEL_OPEN_FAILURE('\x00\x00\x00\x00\x00\x00\x00' - '\x01' + common.NS('failure!')) - self.assertEqual(channel.openFailureReason.args, ('failure!', 1)) - self.assertEqual(self.conn.channels.get(channel), None) - - - def test_CHANNEL_WINDOW_ADJUST(self): - """ - Test that channel window adjust messages add bytes to the channel - window. - """ - channel = TestChannel() - self._openChannel(channel) - oldWindowSize = channel.remoteWindowLeft - self.conn.ssh_CHANNEL_WINDOW_ADJUST('\x00\x00\x00\x00\x00\x00\x00' - '\x01') - self.assertEqual(channel.remoteWindowLeft, oldWindowSize + 1) - - def test_CHANNEL_DATA(self): - """ - Test that channel data messages are passed up to the channel, or - cause the channel to be closed if the data is too large. - """ - channel = TestChannel(localWindow=6, localMaxPacket=5) - self._openChannel(channel) - self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS('data')) - self.assertEqual(channel.inBuffer, ['data']) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff' - '\x00\x00\x00\x04')]) - self.transport.packets = [] - longData = 'a' * (channel.localWindowLeft + 1) - self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x00' + common.NS(longData)) - self.assertEqual(channel.inBuffer, ['data']) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - channel = TestChannel() - self._openChannel(channel) - bigData = 'a' * (channel.localMaxPacket + 1) - self.transport.packets = [] - self.conn.ssh_CHANNEL_DATA('\x00\x00\x00\x01' + common.NS(bigData)) - self.assertEqual(channel.inBuffer, []) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - - def test_CHANNEL_EXTENDED_DATA(self): - """ - Test that channel extended data messages are passed up to the channel, - or cause the channel to be closed if they're too big. - """ - channel = TestChannel(localWindow=6, localMaxPacket=5) - self._openChannel(channel) - self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00' - '\x00' + common.NS('data')) - self.assertEqual(channel.extBuffer, [(0, 'data')]) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff' - '\x00\x00\x00\x04')]) - self.transport.packets = [] - longData = 'a' * (channel.localWindowLeft + 1) - self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x00\x00\x00\x00' - '\x00' + common.NS(longData)) - self.assertEqual(channel.extBuffer, [(0, 'data')]) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - channel = TestChannel() - self._openChannel(channel) - bigData = 'a' * (channel.localMaxPacket + 1) - self.transport.packets = [] - self.conn.ssh_CHANNEL_EXTENDED_DATA('\x00\x00\x00\x01\x00\x00\x00' - '\x00' + common.NS(bigData)) - self.assertEqual(channel.extBuffer, []) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - - def test_CHANNEL_EOF(self): - """ - Test that channel eof messages are passed up to the channel. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.ssh_CHANNEL_EOF('\x00\x00\x00\x00') - self.assertTrue(channel.gotEOF) - - def test_CHANNEL_CLOSE(self): - """ - Test that channel close messages are passed up to the channel. Also, - test that channel.close() is called if both sides are closed when this - message is received. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.sendClose(channel) - self.conn.ssh_CHANNEL_CLOSE('\x00\x00\x00\x00') - self.assertTrue(channel.gotOneClose) - self.assertTrue(channel.gotClosed) - - def test_CHANNEL_REQUEST_success(self): - """ - Test that channel requests that succeed send MSG_CHANNEL_SUCCESS. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS('test') - + '\x00') - self.assertEqual(channel.numberRequests, 1) - d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS( - 'test') + '\xff' + 'data') - def check(result): - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_SUCCESS, '\x00\x00\x00\xff')]) - d.addCallback(check) - return d - - def test_CHANNEL_REQUEST_failure(self): - """ - Test that channel requests that fail send MSG_CHANNEL_FAILURE. - """ - channel = TestChannel() - self._openChannel(channel) - d = self.conn.ssh_CHANNEL_REQUEST('\x00\x00\x00\x00' + common.NS( - 'test') + '\xff') - def check(result): - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_FAILURE, '\x00\x00\x00\xff' - )]) - d.addCallback(self.fail) - d.addErrback(check) - return d - - def test_CHANNEL_REQUEST_SUCCESS(self): - """ - Test that channel request success messages cause the Deferred to be - called back. - """ - channel = TestChannel() - self._openChannel(channel) - d = self.conn.sendRequest(channel, 'test', 'data', True) - self.conn.ssh_CHANNEL_SUCCESS('\x00\x00\x00\x00') - def check(result): - self.assertTrue(result) - return d - - def test_CHANNEL_REQUEST_FAILURE(self): - """ - Test that channel request failure messages cause the Deferred to be - erred back. - """ - channel = TestChannel() - self._openChannel(channel) - d = self.conn.sendRequest(channel, 'test', '', True) - self.conn.ssh_CHANNEL_FAILURE('\x00\x00\x00\x00') - def check(result): - self.assertEqual(result.value.value, 'channel request failed') - d.addCallback(self.fail) - d.addErrback(check) - return d - - def test_sendGlobalRequest(self): - """ - Test that global request messages are sent in the right format. - """ - d = self.conn.sendGlobalRequest('wantReply', 'data', True) - # must be added to prevent errbacking during teardown - d.addErrback(lambda failure: None) - self.conn.sendGlobalRequest('noReply', '', False) - self.assertEqual(self.transport.packets, - [(connection.MSG_GLOBAL_REQUEST, common.NS('wantReply') + - '\xffdata'), - (connection.MSG_GLOBAL_REQUEST, common.NS('noReply') + - '\x00')]) - self.assertEqual(self.conn.deferreds, {'global':[d]}) - - def test_openChannel(self): - """ - Test that open channel messages are sent in the right format. - """ - channel = TestChannel() - self.conn.openChannel(channel, 'aaaa') - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_OPEN, common.NS('TestChannel') + - '\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x80\x00aaaa')]) - self.assertEqual(channel.id, 0) - self.assertEqual(self.conn.localChannelID, 1) - - def test_sendRequest(self): - """ - Test that channel request messages are sent in the right format. - """ - channel = TestChannel() - self._openChannel(channel) - d = self.conn.sendRequest(channel, 'test', 'test', True) - # needed to prevent errbacks during teardown. - d.addErrback(lambda failure: None) - self.conn.sendRequest(channel, 'test2', '', False) - channel.localClosed = True # emulate sending a close message - self.conn.sendRequest(channel, 'test3', '', True) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' + - common.NS('test') + '\x01test'), - (connection.MSG_CHANNEL_REQUEST, '\x00\x00\x00\xff' + - common.NS('test2') + '\x00')]) - self.assertEqual(self.conn.deferreds[0], [d]) - - def test_adjustWindow(self): - """ - Test that channel window adjust messages cause bytes to be added - to the window. - """ - channel = TestChannel(localWindow=5) - self._openChannel(channel) - channel.localWindowLeft = 0 - self.conn.adjustWindow(channel, 1) - self.assertEqual(channel.localWindowLeft, 1) - channel.localClosed = True - self.conn.adjustWindow(channel, 2) - self.assertEqual(channel.localWindowLeft, 1) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_WINDOW_ADJUST, '\x00\x00\x00\xff' - '\x00\x00\x00\x01')]) - - def test_sendData(self): - """ - Test that channel data messages are sent in the right format. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.sendData(channel, 'a') - channel.localClosed = True - self.conn.sendData(channel, 'b') - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_DATA, '\x00\x00\x00\xff' + - common.NS('a'))]) - - def test_sendExtendedData(self): - """ - Test that channel extended data messages are sent in the right format. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.sendExtendedData(channel, 1, 'test') - channel.localClosed = True - self.conn.sendExtendedData(channel, 2, 'test2') - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_EXTENDED_DATA, '\x00\x00\x00\xff' + - '\x00\x00\x00\x01' + common.NS('test'))]) - - def test_sendEOF(self): - """ - Test that channel EOF messages are sent in the right format. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.sendEOF(channel) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')]) - channel.localClosed = True - self.conn.sendEOF(channel) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_EOF, '\x00\x00\x00\xff')]) - - def test_sendClose(self): - """ - Test that channel close messages are sent in the right format. - """ - channel = TestChannel() - self._openChannel(channel) - self.conn.sendClose(channel) - self.assertTrue(channel.localClosed) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - self.conn.sendClose(channel) - self.assertEqual(self.transport.packets, - [(connection.MSG_CHANNEL_CLOSE, '\x00\x00\x00\xff')]) - - channel2 = TestChannel() - self._openChannel(channel2) - channel2.remoteClosed = True - self.conn.sendClose(channel2) - self.assertTrue(channel2.gotClosed) - - def test_getChannelWithAvatar(self): - """ - Test that getChannel dispatches to the avatar when an avatar is - present. Correct functioning without the avatar is verified in - test_CHANNEL_OPEN. - """ - channel = self.conn.getChannel('TestChannel', 50, 30, 'data') - self.assertEqual(channel.data, 'data') - self.assertEqual(channel.remoteWindowLeft, 50) - self.assertEqual(channel.remoteMaxPacket, 30) - self.assertRaises(error.ConchError, self.conn.getChannel, - 'BadChannel', 50, 30, 'data') - - def test_gotGlobalRequestWithoutAvatar(self): - """ - Test that gotGlobalRequests dispatches to global_* without an avatar. - """ - del self.transport.avatar - self.assertTrue(self.conn.gotGlobalRequest('TestGlobal', 'data')) - self.assertEqual(self.conn.gotGlobalRequest('Test-Data', 'data'), - (True, 'data')) - self.assertFalse(self.conn.gotGlobalRequest('BadGlobal', 'data')) - - - def test_channelClosedCausesLeftoverChannelDeferredsToErrback(self): - """ - Whenever an SSH channel gets closed any Deferred that was returned by a - sendRequest() on its parent connection must be errbacked. - """ - channel = TestChannel() - self._openChannel(channel) - - d = self.conn.sendRequest( - channel, "dummyrequest", "dummydata", wantReply=1) - d = self.assertFailure(d, error.ConchError) - self.conn.channelClosed(channel) - return d - - - -class TestCleanConnectionShutdown(unittest.TestCase): - """ - Check whether correct cleanup is performed on connection shutdown. - """ - if test_userauth.transport is None: - skip = "Cannot run without both PyCrypto and pyasn1" - - def setUp(self): - self.transport = test_userauth.FakeTransport(None) - self.transport.avatar = TestAvatar() - self.conn = TestConnection() - self.conn.transport = self.transport - - - def test_serviceStoppedCausesLeftoverGlobalDeferredsToErrback(self): - """ - Once the service is stopped any leftover global deferred returned by - a sendGlobalRequest() call must be errbacked. - """ - self.conn.serviceStarted() - - d = self.conn.sendGlobalRequest( - "dummyrequest", "dummydata", wantReply=1) - d = self.assertFailure(d, error.ConchError) - self.conn.serviceStopped() - return d - - diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py deleted file mode 100755 index 109f23d2..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_default.py +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.client.default}. -""" -try: - import Crypto.Cipher.DES3 - import pyasn1 -except ImportError: - skip = "PyCrypto and PyASN1 required for twisted.conch.client.default." -else: - from twisted.conch.client.agent import SSHAgentClient - from twisted.conch.client.default import SSHUserAuthClient - from twisted.conch.client.options import ConchOptions - from twisted.conch.ssh.keys import Key - - -from twisted.trial.unittest import TestCase -from twisted.python.filepath import FilePath -from twisted.conch.test import keydata -from twisted.test.proto_helpers import StringTransport - - - -class SSHUserAuthClientTest(TestCase): - """ - Tests for L{SSHUserAuthClient}. - - @type rsaPublic: L{Key} - @ivar rsaPublic: A public RSA key. - """ - - def setUp(self): - self.rsaPublic = Key.fromString(keydata.publicRSA_openssh) - self.tmpdir = FilePath(self.mktemp()) - self.tmpdir.makedirs() - self.rsaFile = self.tmpdir.child('id_rsa') - self.rsaFile.setContent(keydata.privateRSA_openssh) - self.tmpdir.child('id_rsa.pub').setContent(keydata.publicRSA_openssh) - - - def test_signDataWithAgent(self): - """ - When connected to an agent, L{SSHUserAuthClient} can use it to - request signatures of particular data with a particular L{Key}. - """ - client = SSHUserAuthClient("user", ConchOptions(), None) - agent = SSHAgentClient() - transport = StringTransport() - agent.makeConnection(transport) - client.keyAgent = agent - cleartext = "Sign here" - client.signData(self.rsaPublic, cleartext) - self.assertEqual( - transport.value(), - "\x00\x00\x00\x8b\r\x00\x00\x00u" + self.rsaPublic.blob() + - "\x00\x00\x00\t" + cleartext + - "\x00\x00\x00\x00") - - - def test_agentGetPublicKey(self): - """ - L{SSHUserAuthClient} looks up public keys from the agent using the - L{SSHAgentClient} class. That L{SSHAgentClient.getPublicKey} returns a - L{Key} object with one of the public keys in the agent. If no more - keys are present, it returns C{None}. - """ - agent = SSHAgentClient() - agent.blobs = [self.rsaPublic.blob()] - key = agent.getPublicKey() - self.assertEqual(key.isPublic(), True) - self.assertEqual(key, self.rsaPublic) - self.assertEqual(agent.getPublicKey(), None) - - - def test_getPublicKeyFromFile(self): - """ - L{SSHUserAuthClient.getPublicKey()} is able to get a public key from - the first file described by its options' C{identitys} list, and return - the corresponding public L{Key} object. - """ - options = ConchOptions() - options.identitys = [self.rsaFile.path] - client = SSHUserAuthClient("user", options, None) - key = client.getPublicKey() - self.assertEqual(key.isPublic(), True) - self.assertEqual(key, self.rsaPublic) - - - def test_getPublicKeyAgentFallback(self): - """ - If an agent is present, but doesn't return a key, - L{SSHUserAuthClient.getPublicKey} continue with the normal key lookup. - """ - options = ConchOptions() - options.identitys = [self.rsaFile.path] - agent = SSHAgentClient() - client = SSHUserAuthClient("user", options, None) - client.keyAgent = agent - key = client.getPublicKey() - self.assertEqual(key.isPublic(), True) - self.assertEqual(key, self.rsaPublic) - - - def test_getPublicKeyBadKeyError(self): - """ - If L{keys.Key.fromFile} raises a L{keys.BadKeyError}, the - L{SSHUserAuthClient.getPublicKey} tries again to get a public key by - calling itself recursively. - """ - options = ConchOptions() - self.tmpdir.child('id_dsa.pub').setContent(keydata.publicDSA_openssh) - dsaFile = self.tmpdir.child('id_dsa') - dsaFile.setContent(keydata.privateDSA_openssh) - options.identitys = [self.rsaFile.path, dsaFile.path] - self.tmpdir.child('id_rsa.pub').setContent('not a key!') - client = SSHUserAuthClient("user", options, None) - key = client.getPublicKey() - self.assertEqual(key.isPublic(), True) - self.assertEqual(key, Key.fromString(keydata.publicDSA_openssh)) - self.assertEqual(client.usedFiles, [self.rsaFile.path, dsaFile.path]) - - - def test_getPrivateKey(self): - """ - L{SSHUserAuthClient.getPrivateKey} will load a private key from the - last used file populated by L{SSHUserAuthClient.getPublicKey}, and - return a L{Deferred} which fires with the corresponding private L{Key}. - """ - rsaPrivate = Key.fromString(keydata.privateRSA_openssh) - options = ConchOptions() - options.identitys = [self.rsaFile.path] - client = SSHUserAuthClient("user", options, None) - # Populate the list of used files - client.getPublicKey() - - def _cbGetPrivateKey(key): - self.assertEqual(key.isPublic(), False) - self.assertEqual(key, rsaPrivate) - - return client.getPrivateKey().addCallback(_cbGetPrivateKey) - - - def test_getPrivateKeyPassphrase(self): - """ - L{SSHUserAuthClient} can get a private key from a file, and return a - Deferred called back with a private L{Key} object, even if the key is - encrypted. - """ - rsaPrivate = Key.fromString(keydata.privateRSA_openssh) - passphrase = 'this is the passphrase' - self.rsaFile.setContent(rsaPrivate.toString('openssh', passphrase)) - options = ConchOptions() - options.identitys = [self.rsaFile.path] - client = SSHUserAuthClient("user", options, None) - # Populate the list of used files - client.getPublicKey() - - def _getPassword(prompt): - self.assertEqual(prompt, - "Enter passphrase for key '%s': " % ( - self.rsaFile.path,)) - return passphrase - - def _cbGetPrivateKey(key): - self.assertEqual(key.isPublic(), False) - self.assertEqual(key, rsaPrivate) - - self.patch(client, '_getPassword', _getPassword) - return client.getPrivateKey().addCallback(_cbGetPrivateKey) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py deleted file mode 100755 index 38493317..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_filetransfer.py +++ /dev/null @@ -1,765 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_filetransfer -*- -# Copyright (c) 2001-2008 Twisted Matrix Laboratories. -# See LICENSE file for details. - - -import os -import re -import struct -import sys - -from twisted.trial import unittest -try: - from twisted.conch import unix - unix # shut up pyflakes -except ImportError: - unix = None - try: - del sys.modules['twisted.conch.unix'] # remove the bad import - except KeyError: - # In Python 2.4, the bad import has already been cleaned up for us. - # Hooray. - pass - -from twisted.conch import avatar -from twisted.conch.ssh import common, connection, filetransfer, session -from twisted.internet import defer -from twisted.protocols import loopback -from twisted.python import components - - -class TestAvatar(avatar.ConchUser): - def __init__(self): - avatar.ConchUser.__init__(self) - self.channelLookup['session'] = session.SSHSession - self.subsystemLookup['sftp'] = filetransfer.FileTransferServer - - def _runAsUser(self, f, *args, **kw): - try: - f = iter(f) - except TypeError: - f = [(f, args, kw)] - for i in f: - func = i[0] - args = len(i)>1 and i[1] or () - kw = len(i)>2 and i[2] or {} - r = func(*args, **kw) - return r - - -class FileTransferTestAvatar(TestAvatar): - - def __init__(self, homeDir): - TestAvatar.__init__(self) - self.homeDir = homeDir - - def getHomeDir(self): - return os.path.join(os.getcwd(), self.homeDir) - - -class ConchSessionForTestAvatar: - - def __init__(self, avatar): - self.avatar = avatar - -if unix: - if not hasattr(unix, 'SFTPServerForUnixConchUser'): - # unix should either be a fully working module, or None. I'm not sure - # how this happens, but on win32 it does. Try to cope. --spiv. - import warnings - warnings.warn(("twisted.conch.unix imported %r, " - "but doesn't define SFTPServerForUnixConchUser'") - % (unix,)) - unix = None - else: - class FileTransferForTestAvatar(unix.SFTPServerForUnixConchUser): - - def gotVersion(self, version, otherExt): - return {'conchTest' : 'ext data'} - - def extendedRequest(self, extName, extData): - if extName == 'testExtendedRequest': - return 'bar' - raise NotImplementedError - - components.registerAdapter(FileTransferForTestAvatar, - TestAvatar, - filetransfer.ISFTPServer) - -class SFTPTestBase(unittest.TestCase): - - def setUp(self): - self.testDir = self.mktemp() - # Give the testDir another level so we can safely "cd .." from it in - # tests. - self.testDir = os.path.join(self.testDir, 'extra') - os.makedirs(os.path.join(self.testDir, 'testDirectory')) - - f = file(os.path.join(self.testDir, 'testfile1'),'w') - f.write('a'*10+'b'*10) - f.write(file('/dev/urandom').read(1024*64)) # random data - os.chmod(os.path.join(self.testDir, 'testfile1'), 0644) - file(os.path.join(self.testDir, 'testRemoveFile'), 'w').write('a') - file(os.path.join(self.testDir, 'testRenameFile'), 'w').write('a') - file(os.path.join(self.testDir, '.testHiddenFile'), 'w').write('a') - - -class TestOurServerOurClient(SFTPTestBase): - - if not unix: - skip = "can't run on non-posix computers" - - def setUp(self): - SFTPTestBase.setUp(self) - - self.avatar = FileTransferTestAvatar(self.testDir) - self.server = filetransfer.FileTransferServer(avatar=self.avatar) - clientTransport = loopback.LoopbackRelay(self.server) - - self.client = filetransfer.FileTransferClient() - self._serverVersion = None - self._extData = None - def _(serverVersion, extData): - self._serverVersion = serverVersion - self._extData = extData - self.client.gotServerVersion = _ - serverTransport = loopback.LoopbackRelay(self.client) - self.client.makeConnection(clientTransport) - self.server.makeConnection(serverTransport) - - self.clientTransport = clientTransport - self.serverTransport = serverTransport - - self._emptyBuffers() - - - def _emptyBuffers(self): - while self.serverTransport.buffer or self.clientTransport.buffer: - self.serverTransport.clearBuffer() - self.clientTransport.clearBuffer() - - - def tearDown(self): - self.serverTransport.loseConnection() - self.clientTransport.loseConnection() - self.serverTransport.clearBuffer() - self.clientTransport.clearBuffer() - - - def testServerVersion(self): - self.assertEqual(self._serverVersion, 3) - self.assertEqual(self._extData, {'conchTest' : 'ext data'}) - - - def test_openedFileClosedWithConnection(self): - """ - A file opened with C{openFile} is close when the connection is lost. - """ - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {}) - self._emptyBuffers() - - oldClose = os.close - closed = [] - def close(fd): - closed.append(fd) - oldClose(fd) - - self.patch(os, "close", close) - - def _fileOpened(openFile): - fd = self.server.openFiles[openFile.handle[4:]].fd - self.serverTransport.loseConnection() - self.clientTransport.loseConnection() - self.serverTransport.clearBuffer() - self.clientTransport.clearBuffer() - self.assertEqual(self.server.openFiles, {}) - self.assertIn(fd, closed) - - d.addCallback(_fileOpened) - return d - - - def test_openedDirectoryClosedWithConnection(self): - """ - A directory opened with C{openDirectory} is close when the connection - is lost. - """ - d = self.client.openDirectory('') - self._emptyBuffers() - - def _getFiles(openDir): - self.serverTransport.loseConnection() - self.clientTransport.loseConnection() - self.serverTransport.clearBuffer() - self.clientTransport.clearBuffer() - self.assertEqual(self.server.openDirs, {}) - - d.addCallback(_getFiles) - return d - - - def testOpenFileIO(self): - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {}) - self._emptyBuffers() - - def _fileOpened(openFile): - self.assertEqual(openFile, filetransfer.ISFTPFile(openFile)) - d = _readChunk(openFile) - d.addCallback(_writeChunk, openFile) - return d - - def _readChunk(openFile): - d = openFile.readChunk(0, 20) - self._emptyBuffers() - d.addCallback(self.assertEqual, 'a'*10 + 'b'*10) - return d - - def _writeChunk(_, openFile): - d = openFile.writeChunk(20, 'c'*10) - self._emptyBuffers() - d.addCallback(_readChunk2, openFile) - return d - - def _readChunk2(_, openFile): - d = openFile.readChunk(0, 30) - self._emptyBuffers() - d.addCallback(self.assertEqual, 'a'*10 + 'b'*10 + 'c'*10) - return d - - d.addCallback(_fileOpened) - return d - - def testClosedFileGetAttrs(self): - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {}) - self._emptyBuffers() - - def _getAttrs(_, openFile): - d = openFile.getAttrs() - self._emptyBuffers() - return d - - def _err(f): - self.flushLoggedErrors() - return f - - def _close(openFile): - d = openFile.close() - self._emptyBuffers() - d.addCallback(_getAttrs, openFile) - d.addErrback(_err) - return self.assertFailure(d, filetransfer.SFTPError) - - d.addCallback(_close) - return d - - def testOpenFileAttributes(self): - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {}) - self._emptyBuffers() - - def _getAttrs(openFile): - d = openFile.getAttrs() - self._emptyBuffers() - d.addCallback(_getAttrs2) - return d - - def _getAttrs2(attrs1): - d = self.client.getAttrs('testfile1') - self._emptyBuffers() - d.addCallback(self.assertEqual, attrs1) - return d - - return d.addCallback(_getAttrs) - - - def testOpenFileSetAttrs(self): - # XXX test setAttrs - # Ok, how about this for a start? It caught a bug :) -- spiv. - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {}) - self._emptyBuffers() - - def _getAttrs(openFile): - d = openFile.getAttrs() - self._emptyBuffers() - d.addCallback(_setAttrs) - return d - - def _setAttrs(attrs): - attrs['atime'] = 0 - d = self.client.setAttrs('testfile1', attrs) - self._emptyBuffers() - d.addCallback(_getAttrs2) - d.addCallback(self.assertEqual, attrs) - return d - - def _getAttrs2(_): - d = self.client.getAttrs('testfile1') - self._emptyBuffers() - return d - - d.addCallback(_getAttrs) - return d - - - def test_openFileExtendedAttributes(self): - """ - Check that L{filetransfer.FileTransferClient.openFile} can send - extended attributes, that should be extracted server side. By default, - they are ignored, so we just verify they are correctly parsed. - """ - savedAttributes = {} - oldOpenFile = self.server.client.openFile - def openFile(filename, flags, attrs): - savedAttributes.update(attrs) - return oldOpenFile(filename, flags, attrs) - self.server.client.openFile = openFile - - d = self.client.openFile("testfile1", filetransfer.FXF_READ | - filetransfer.FXF_WRITE, {"ext_foo": "bar"}) - self._emptyBuffers() - - def check(ign): - self.assertEqual(savedAttributes, {"ext_foo": "bar"}) - - return d.addCallback(check) - - - def testRemoveFile(self): - d = self.client.getAttrs("testRemoveFile") - self._emptyBuffers() - def _removeFile(ignored): - d = self.client.removeFile("testRemoveFile") - self._emptyBuffers() - return d - d.addCallback(_removeFile) - d.addCallback(_removeFile) - return self.assertFailure(d, filetransfer.SFTPError) - - def testRenameFile(self): - d = self.client.getAttrs("testRenameFile") - self._emptyBuffers() - def _rename(attrs): - d = self.client.renameFile("testRenameFile", "testRenamedFile") - self._emptyBuffers() - d.addCallback(_testRenamed, attrs) - return d - def _testRenamed(_, attrs): - d = self.client.getAttrs("testRenamedFile") - self._emptyBuffers() - d.addCallback(self.assertEqual, attrs) - return d.addCallback(_rename) - - def testDirectoryBad(self): - d = self.client.getAttrs("testMakeDirectory") - self._emptyBuffers() - return self.assertFailure(d, filetransfer.SFTPError) - - def testDirectoryCreation(self): - d = self.client.makeDirectory("testMakeDirectory", {}) - self._emptyBuffers() - - def _getAttrs(_): - d = self.client.getAttrs("testMakeDirectory") - self._emptyBuffers() - return d - - # XXX not until version 4/5 - # self.assertEqual(filetransfer.FILEXFER_TYPE_DIRECTORY&attrs['type'], - # filetransfer.FILEXFER_TYPE_DIRECTORY) - - def _removeDirectory(_): - d = self.client.removeDirectory("testMakeDirectory") - self._emptyBuffers() - return d - - d.addCallback(_getAttrs) - d.addCallback(_removeDirectory) - d.addCallback(_getAttrs) - return self.assertFailure(d, filetransfer.SFTPError) - - def testOpenDirectory(self): - d = self.client.openDirectory('') - self._emptyBuffers() - files = [] - - def _getFiles(openDir): - def append(f): - files.append(f) - return openDir - d = defer.maybeDeferred(openDir.next) - self._emptyBuffers() - d.addCallback(append) - d.addCallback(_getFiles) - d.addErrback(_close, openDir) - return d - - def _checkFiles(ignored): - fs = list(zip(*files)[0]) - fs.sort() - self.assertEqual(fs, - ['.testHiddenFile', 'testDirectory', - 'testRemoveFile', 'testRenameFile', - 'testfile1']) - - def _close(_, openDir): - d = openDir.close() - self._emptyBuffers() - return d - - d.addCallback(_getFiles) - d.addCallback(_checkFiles) - return d - - def testLinkDoesntExist(self): - d = self.client.getAttrs('testLink') - self._emptyBuffers() - return self.assertFailure(d, filetransfer.SFTPError) - - def testLinkSharesAttrs(self): - d = self.client.makeLink('testLink', 'testfile1') - self._emptyBuffers() - def _getFirstAttrs(_): - d = self.client.getAttrs('testLink', 1) - self._emptyBuffers() - return d - def _getSecondAttrs(firstAttrs): - d = self.client.getAttrs('testfile1') - self._emptyBuffers() - d.addCallback(self.assertEqual, firstAttrs) - return d - d.addCallback(_getFirstAttrs) - return d.addCallback(_getSecondAttrs) - - def testLinkPath(self): - d = self.client.makeLink('testLink', 'testfile1') - self._emptyBuffers() - def _readLink(_): - d = self.client.readLink('testLink') - self._emptyBuffers() - d.addCallback(self.assertEqual, - os.path.join(os.getcwd(), self.testDir, 'testfile1')) - return d - def _realPath(_): - d = self.client.realPath('testLink') - self._emptyBuffers() - d.addCallback(self.assertEqual, - os.path.join(os.getcwd(), self.testDir, 'testfile1')) - return d - d.addCallback(_readLink) - d.addCallback(_realPath) - return d - - def testExtendedRequest(self): - d = self.client.extendedRequest('testExtendedRequest', 'foo') - self._emptyBuffers() - d.addCallback(self.assertEqual, 'bar') - d.addCallback(self._cbTestExtendedRequest) - return d - - def _cbTestExtendedRequest(self, ignored): - d = self.client.extendedRequest('testBadRequest', '') - self._emptyBuffers() - return self.assertFailure(d, NotImplementedError) - - -class FakeConn: - def sendClose(self, channel): - pass - - -class TestFileTransferClose(unittest.TestCase): - - if not unix: - skip = "can't run on non-posix computers" - - def setUp(self): - self.avatar = TestAvatar() - - def buildServerConnection(self): - # make a server connection - conn = connection.SSHConnection() - # server connections have a 'self.transport.avatar'. - class DummyTransport: - def __init__(self): - self.transport = self - def sendPacket(self, kind, data): - pass - def logPrefix(self): - return 'dummy transport' - conn.transport = DummyTransport() - conn.transport.avatar = self.avatar - return conn - - def interceptConnectionLost(self, sftpServer): - self.connectionLostFired = False - origConnectionLost = sftpServer.connectionLost - def connectionLost(reason): - self.connectionLostFired = True - origConnectionLost(reason) - sftpServer.connectionLost = connectionLost - - def assertSFTPConnectionLost(self): - self.assertTrue(self.connectionLostFired, - "sftpServer's connectionLost was not called") - - def test_sessionClose(self): - """ - Closing a session should notify an SFTP subsystem launched by that - session. - """ - # make a session - testSession = session.SSHSession(conn=FakeConn(), avatar=self.avatar) - - # start an SFTP subsystem on the session - testSession.request_subsystem(common.NS('sftp')) - sftpServer = testSession.client.transport.proto - - # intercept connectionLost so we can check that it's called - self.interceptConnectionLost(sftpServer) - - # close session - testSession.closeReceived() - - self.assertSFTPConnectionLost() - - def test_clientClosesChannelOnConnnection(self): - """ - A client sending CHANNEL_CLOSE should trigger closeReceived on the - associated channel instance. - """ - conn = self.buildServerConnection() - - # somehow get a session - packet = common.NS('session') + struct.pack('>L', 0) * 3 - conn.ssh_CHANNEL_OPEN(packet) - sessionChannel = conn.channels[0] - - sessionChannel.request_subsystem(common.NS('sftp')) - sftpServer = sessionChannel.client.transport.proto - self.interceptConnectionLost(sftpServer) - - # intercept closeReceived - self.interceptConnectionLost(sftpServer) - - # close the connection - conn.ssh_CHANNEL_CLOSE(struct.pack('>L', 0)) - - self.assertSFTPConnectionLost() - - - def test_stopConnectionServiceClosesChannel(self): - """ - Closing an SSH connection should close all sessions within it. - """ - conn = self.buildServerConnection() - - # somehow get a session - packet = common.NS('session') + struct.pack('>L', 0) * 3 - conn.ssh_CHANNEL_OPEN(packet) - sessionChannel = conn.channels[0] - - sessionChannel.request_subsystem(common.NS('sftp')) - sftpServer = sessionChannel.client.transport.proto - self.interceptConnectionLost(sftpServer) - - # close the connection - conn.serviceStopped() - - self.assertSFTPConnectionLost() - - - -class TestConstants(unittest.TestCase): - """ - Tests for the constants used by the SFTP protocol implementation. - - @ivar filexferSpecExcerpts: Excerpts from the - draft-ietf-secsh-filexfer-02.txt (draft) specification of the SFTP - protocol. There are more recent drafts of the specification, but this - one describes version 3, which is what conch (and OpenSSH) implements. - """ - - - filexferSpecExcerpts = [ - """ - The following values are defined for packet types. - - #define SSH_FXP_INIT 1 - #define SSH_FXP_VERSION 2 - #define SSH_FXP_OPEN 3 - #define SSH_FXP_CLOSE 4 - #define SSH_FXP_READ 5 - #define SSH_FXP_WRITE 6 - #define SSH_FXP_LSTAT 7 - #define SSH_FXP_FSTAT 8 - #define SSH_FXP_SETSTAT 9 - #define SSH_FXP_FSETSTAT 10 - #define SSH_FXP_OPENDIR 11 - #define SSH_FXP_READDIR 12 - #define SSH_FXP_REMOVE 13 - #define SSH_FXP_MKDIR 14 - #define SSH_FXP_RMDIR 15 - #define SSH_FXP_REALPATH 16 - #define SSH_FXP_STAT 17 - #define SSH_FXP_RENAME 18 - #define SSH_FXP_READLINK 19 - #define SSH_FXP_SYMLINK 20 - #define SSH_FXP_STATUS 101 - #define SSH_FXP_HANDLE 102 - #define SSH_FXP_DATA 103 - #define SSH_FXP_NAME 104 - #define SSH_FXP_ATTRS 105 - #define SSH_FXP_EXTENDED 200 - #define SSH_FXP_EXTENDED_REPLY 201 - - Additional packet types should only be defined if the protocol - version number (see Section ``Protocol Initialization'') is - incremented, and their use MUST be negotiated using the version - number. However, the SSH_FXP_EXTENDED and SSH_FXP_EXTENDED_REPLY - packets can be used to implement vendor-specific extensions. See - Section ``Vendor-Specific-Extensions'' for more details. - """, - """ - The flags bits are defined to have the following values: - - #define SSH_FILEXFER_ATTR_SIZE 0x00000001 - #define SSH_FILEXFER_ATTR_UIDGID 0x00000002 - #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004 - #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008 - #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000 - - """, - """ - The `pflags' field is a bitmask. The following bits have been - defined. - - #define SSH_FXF_READ 0x00000001 - #define SSH_FXF_WRITE 0x00000002 - #define SSH_FXF_APPEND 0x00000004 - #define SSH_FXF_CREAT 0x00000008 - #define SSH_FXF_TRUNC 0x00000010 - #define SSH_FXF_EXCL 0x00000020 - """, - """ - Currently, the following values are defined (other values may be - defined by future versions of this protocol): - - #define SSH_FX_OK 0 - #define SSH_FX_EOF 1 - #define SSH_FX_NO_SUCH_FILE 2 - #define SSH_FX_PERMISSION_DENIED 3 - #define SSH_FX_FAILURE 4 - #define SSH_FX_BAD_MESSAGE 5 - #define SSH_FX_NO_CONNECTION 6 - #define SSH_FX_CONNECTION_LOST 7 - #define SSH_FX_OP_UNSUPPORTED 8 - """] - - - def test_constantsAgainstSpec(self): - """ - The constants used by the SFTP protocol implementation match those - found by searching through the spec. - """ - constants = {} - for excerpt in self.filexferSpecExcerpts: - for line in excerpt.splitlines(): - m = re.match('^\s*#define SSH_([A-Z_]+)\s+([0-9x]*)\s*$', line) - if m: - constants[m.group(1)] = long(m.group(2), 0) - self.assertTrue( - len(constants) > 0, "No constants found (the test must be buggy).") - for k, v in constants.items(): - self.assertEqual(v, getattr(filetransfer, k)) - - - -class TestRawPacketData(unittest.TestCase): - """ - Tests for L{filetransfer.FileTransferClient} which explicitly craft certain - less common protocol messages to exercise their handling. - """ - def setUp(self): - self.ftc = filetransfer.FileTransferClient() - - - def test_packetSTATUS(self): - """ - A STATUS packet containing a result code, a message, and a language is - parsed to produce the result of an outstanding request L{Deferred}. - - @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>} - of the SFTP Internet-Draft. - """ - d = defer.Deferred() - d.addCallback(self._cbTestPacketSTATUS) - self.ftc.openRequests[1] = d - data = struct.pack('!LL', 1, filetransfer.FX_OK) + common.NS('msg') + common.NS('lang') - self.ftc.packet_STATUS(data) - return d - - - def _cbTestPacketSTATUS(self, result): - """ - Assert that the result is a two-tuple containing the message and - language from the STATUS packet. - """ - self.assertEqual(result[0], 'msg') - self.assertEqual(result[1], 'lang') - - - def test_packetSTATUSShort(self): - """ - A STATUS packet containing only a result code can also be parsed to - produce the result of an outstanding request L{Deferred}. Such packets - are sent by some SFTP implementations, though not strictly legal. - - @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>} - of the SFTP Internet-Draft. - """ - d = defer.Deferred() - d.addCallback(self._cbTestPacketSTATUSShort) - self.ftc.openRequests[1] = d - data = struct.pack('!LL', 1, filetransfer.FX_OK) - self.ftc.packet_STATUS(data) - return d - - - def _cbTestPacketSTATUSShort(self, result): - """ - Assert that the result is a two-tuple containing empty strings, since - the STATUS packet had neither a message nor a language. - """ - self.assertEqual(result[0], '') - self.assertEqual(result[1], '') - - - def test_packetSTATUSWithoutLang(self): - """ - A STATUS packet containing a result code and a message but no language - can also be parsed to produce the result of an outstanding request - L{Deferred}. Such packets are sent by some SFTP implementations, though - not strictly legal. - - @see: U{section 9.1<http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1>} - of the SFTP Internet-Draft. - """ - d = defer.Deferred() - d.addCallback(self._cbTestPacketSTATUSWithoutLang) - self.ftc.openRequests[1] = d - data = struct.pack('!LL', 1, filetransfer.FX_OK) + common.NS('msg') - self.ftc.packet_STATUS(data) - return d - - - def _cbTestPacketSTATUSWithoutLang(self, result): - """ - Assert that the result is a two-tuple containing the message from the - STATUS packet and an empty string, since the language was missing. - """ - self.assertEqual(result[0], 'msg') - self.assertEqual(result[1], '') diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py deleted file mode 100755 index 7064d03b..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_helper.py +++ /dev/null @@ -1,560 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_helper -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -from twisted.conch.insults import helper -from twisted.conch.insults.insults import G0, G1, G2, G3 -from twisted.conch.insults.insults import modes, privateModes -from twisted.conch.insults.insults import NORMAL, BOLD, UNDERLINE, BLINK, REVERSE_VIDEO - -from twisted.trial import unittest - -WIDTH = 80 -HEIGHT = 24 - -class BufferTestCase(unittest.TestCase): - def setUp(self): - self.term = helper.TerminalBuffer() - self.term.connectionMade() - - def testInitialState(self): - self.assertEqual(self.term.width, WIDTH) - self.assertEqual(self.term.height, HEIGHT) - self.assertEqual(str(self.term), - '\n' * (HEIGHT - 1)) - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - - - def test_initialPrivateModes(self): - """ - Verify that only DEC Auto Wrap Mode (DECAWM) and DEC Text Cursor Enable - Mode (DECTCEM) are initially in the Set Mode (SM) state. - """ - self.assertEqual( - {privateModes.AUTO_WRAP: True, - privateModes.CURSOR_MODE: True}, - self.term.privateModes) - - - def test_carriageReturn(self): - """ - C{"\r"} moves the cursor to the first column in the current row. - """ - self.term.cursorForward(5) - self.term.cursorDown(3) - self.assertEqual(self.term.reportCursorPosition(), (5, 3)) - self.term.insertAtCursor("\r") - self.assertEqual(self.term.reportCursorPosition(), (0, 3)) - - - def test_linefeed(self): - """ - C{"\n"} moves the cursor to the next row without changing the column. - """ - self.term.cursorForward(5) - self.assertEqual(self.term.reportCursorPosition(), (5, 0)) - self.term.insertAtCursor("\n") - self.assertEqual(self.term.reportCursorPosition(), (5, 1)) - - - def test_newline(self): - """ - C{write} transforms C{"\n"} into C{"\r\n"}. - """ - self.term.cursorForward(5) - self.term.cursorDown(3) - self.assertEqual(self.term.reportCursorPosition(), (5, 3)) - self.term.write("\n") - self.assertEqual(self.term.reportCursorPosition(), (0, 4)) - - - def test_setPrivateModes(self): - """ - Verify that L{helper.TerminalBuffer.setPrivateModes} changes the Set - Mode (SM) state to "set" for the private modes it is passed. - """ - expected = self.term.privateModes.copy() - self.term.setPrivateModes([privateModes.SCROLL, privateModes.SCREEN]) - expected[privateModes.SCROLL] = True - expected[privateModes.SCREEN] = True - self.assertEqual(expected, self.term.privateModes) - - - def test_resetPrivateModes(self): - """ - Verify that L{helper.TerminalBuffer.resetPrivateModes} changes the Set - Mode (SM) state to "reset" for the private modes it is passed. - """ - expected = self.term.privateModes.copy() - self.term.resetPrivateModes([privateModes.AUTO_WRAP, privateModes.CURSOR_MODE]) - del expected[privateModes.AUTO_WRAP] - del expected[privateModes.CURSOR_MODE] - self.assertEqual(expected, self.term.privateModes) - - - def testCursorDown(self): - self.term.cursorDown(3) - self.assertEqual(self.term.reportCursorPosition(), (0, 3)) - self.term.cursorDown() - self.assertEqual(self.term.reportCursorPosition(), (0, 4)) - self.term.cursorDown(HEIGHT) - self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1)) - - def testCursorUp(self): - self.term.cursorUp(5) - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - - self.term.cursorDown(20) - self.term.cursorUp(1) - self.assertEqual(self.term.reportCursorPosition(), (0, 19)) - - self.term.cursorUp(19) - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - - def testCursorForward(self): - self.term.cursorForward(2) - self.assertEqual(self.term.reportCursorPosition(), (2, 0)) - self.term.cursorForward(2) - self.assertEqual(self.term.reportCursorPosition(), (4, 0)) - self.term.cursorForward(WIDTH) - self.assertEqual(self.term.reportCursorPosition(), (WIDTH, 0)) - - def testCursorBackward(self): - self.term.cursorForward(10) - self.term.cursorBackward(2) - self.assertEqual(self.term.reportCursorPosition(), (8, 0)) - self.term.cursorBackward(7) - self.assertEqual(self.term.reportCursorPosition(), (1, 0)) - self.term.cursorBackward(1) - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - self.term.cursorBackward(1) - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - - def testCursorPositioning(self): - self.term.cursorPosition(3, 9) - self.assertEqual(self.term.reportCursorPosition(), (3, 9)) - - def testSimpleWriting(self): - s = "Hello, world." - self.term.write(s) - self.assertEqual( - str(self.term), - s + '\n' + - '\n' * (HEIGHT - 2)) - - def testOvertype(self): - s = "hello, world." - self.term.write(s) - self.term.cursorBackward(len(s)) - self.term.resetModes([modes.IRM]) - self.term.write("H") - self.assertEqual( - str(self.term), - ("H" + s[1:]) + '\n' + - '\n' * (HEIGHT - 2)) - - def testInsert(self): - s = "ello, world." - self.term.write(s) - self.term.cursorBackward(len(s)) - self.term.setModes([modes.IRM]) - self.term.write("H") - self.assertEqual( - str(self.term), - ("H" + s) + '\n' + - '\n' * (HEIGHT - 2)) - - def testWritingInTheMiddle(self): - s = "Hello, world." - self.term.cursorDown(5) - self.term.cursorForward(5) - self.term.write(s) - self.assertEqual( - str(self.term), - '\n' * 5 + - (self.term.fill * 5) + s + '\n' + - '\n' * (HEIGHT - 7)) - - def testWritingWrappedAtEndOfLine(self): - s = "Hello, world." - self.term.cursorForward(WIDTH - 5) - self.term.write(s) - self.assertEqual( - str(self.term), - s[:5].rjust(WIDTH) + '\n' + - s[5:] + '\n' + - '\n' * (HEIGHT - 3)) - - def testIndex(self): - self.term.index() - self.assertEqual(self.term.reportCursorPosition(), (0, 1)) - self.term.cursorDown(HEIGHT) - self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1)) - self.term.index() - self.assertEqual(self.term.reportCursorPosition(), (0, HEIGHT - 1)) - - def testReverseIndex(self): - self.term.reverseIndex() - self.assertEqual(self.term.reportCursorPosition(), (0, 0)) - self.term.cursorDown(2) - self.assertEqual(self.term.reportCursorPosition(), (0, 2)) - self.term.reverseIndex() - self.assertEqual(self.term.reportCursorPosition(), (0, 1)) - - def test_nextLine(self): - """ - C{nextLine} positions the cursor at the beginning of the row below the - current row. - """ - self.term.nextLine() - self.assertEqual(self.term.reportCursorPosition(), (0, 1)) - self.term.cursorForward(5) - self.assertEqual(self.term.reportCursorPosition(), (5, 1)) - self.term.nextLine() - self.assertEqual(self.term.reportCursorPosition(), (0, 2)) - - def testSaveCursor(self): - self.term.cursorDown(5) - self.term.cursorForward(7) - self.assertEqual(self.term.reportCursorPosition(), (7, 5)) - self.term.saveCursor() - self.term.cursorDown(7) - self.term.cursorBackward(3) - self.assertEqual(self.term.reportCursorPosition(), (4, 12)) - self.term.restoreCursor() - self.assertEqual(self.term.reportCursorPosition(), (7, 5)) - - def testSingleShifts(self): - self.term.singleShift2() - self.term.write('Hi') - - ch = self.term.getCharacter(0, 0) - self.assertEqual(ch[0], 'H') - self.assertEqual(ch[1].charset, G2) - - ch = self.term.getCharacter(1, 0) - self.assertEqual(ch[0], 'i') - self.assertEqual(ch[1].charset, G0) - - self.term.singleShift3() - self.term.write('!!') - - ch = self.term.getCharacter(2, 0) - self.assertEqual(ch[0], '!') - self.assertEqual(ch[1].charset, G3) - - ch = self.term.getCharacter(3, 0) - self.assertEqual(ch[0], '!') - self.assertEqual(ch[1].charset, G0) - - def testShifting(self): - s1 = "Hello" - s2 = "World" - s3 = "Bye!" - self.term.write("Hello\n") - self.term.shiftOut() - self.term.write("World\n") - self.term.shiftIn() - self.term.write("Bye!\n") - - g = G0 - h = 0 - for s in (s1, s2, s3): - for i in range(len(s)): - ch = self.term.getCharacter(i, h) - self.assertEqual(ch[0], s[i]) - self.assertEqual(ch[1].charset, g) - g = g == G0 and G1 or G0 - h += 1 - - def testGraphicRendition(self): - self.term.selectGraphicRendition(BOLD, UNDERLINE, BLINK, REVERSE_VIDEO) - self.term.write('W') - self.term.selectGraphicRendition(NORMAL) - self.term.write('X') - self.term.selectGraphicRendition(BLINK) - self.term.write('Y') - self.term.selectGraphicRendition(BOLD) - self.term.write('Z') - - ch = self.term.getCharacter(0, 0) - self.assertEqual(ch[0], 'W') - self.failUnless(ch[1].bold) - self.failUnless(ch[1].underline) - self.failUnless(ch[1].blink) - self.failUnless(ch[1].reverseVideo) - - ch = self.term.getCharacter(1, 0) - self.assertEqual(ch[0], 'X') - self.failIf(ch[1].bold) - self.failIf(ch[1].underline) - self.failIf(ch[1].blink) - self.failIf(ch[1].reverseVideo) - - ch = self.term.getCharacter(2, 0) - self.assertEqual(ch[0], 'Y') - self.failUnless(ch[1].blink) - self.failIf(ch[1].bold) - self.failIf(ch[1].underline) - self.failIf(ch[1].reverseVideo) - - ch = self.term.getCharacter(3, 0) - self.assertEqual(ch[0], 'Z') - self.failUnless(ch[1].blink) - self.failUnless(ch[1].bold) - self.failIf(ch[1].underline) - self.failIf(ch[1].reverseVideo) - - def testColorAttributes(self): - s1 = "Merry xmas" - s2 = "Just kidding" - self.term.selectGraphicRendition(helper.FOREGROUND + helper.RED, - helper.BACKGROUND + helper.GREEN) - self.term.write(s1 + "\n") - self.term.selectGraphicRendition(NORMAL) - self.term.write(s2 + "\n") - - for i in range(len(s1)): - ch = self.term.getCharacter(i, 0) - self.assertEqual(ch[0], s1[i]) - self.assertEqual(ch[1].charset, G0) - self.assertEqual(ch[1].bold, False) - self.assertEqual(ch[1].underline, False) - self.assertEqual(ch[1].blink, False) - self.assertEqual(ch[1].reverseVideo, False) - self.assertEqual(ch[1].foreground, helper.RED) - self.assertEqual(ch[1].background, helper.GREEN) - - for i in range(len(s2)): - ch = self.term.getCharacter(i, 1) - self.assertEqual(ch[0], s2[i]) - self.assertEqual(ch[1].charset, G0) - self.assertEqual(ch[1].bold, False) - self.assertEqual(ch[1].underline, False) - self.assertEqual(ch[1].blink, False) - self.assertEqual(ch[1].reverseVideo, False) - self.assertEqual(ch[1].foreground, helper.WHITE) - self.assertEqual(ch[1].background, helper.BLACK) - - def testEraseLine(self): - s1 = 'line 1' - s2 = 'line 2' - s3 = 'line 3' - self.term.write('\n'.join((s1, s2, s3)) + '\n') - self.term.cursorPosition(1, 1) - self.term.eraseLine() - - self.assertEqual( - str(self.term), - s1 + '\n' + - '\n' + - s3 + '\n' + - '\n' * (HEIGHT - 4)) - - def testEraseToLineEnd(self): - s = 'Hello, world.' - self.term.write(s) - self.term.cursorBackward(5) - self.term.eraseToLineEnd() - self.assertEqual( - str(self.term), - s[:-5] + '\n' + - '\n' * (HEIGHT - 2)) - - def testEraseToLineBeginning(self): - s = 'Hello, world.' - self.term.write(s) - self.term.cursorBackward(5) - self.term.eraseToLineBeginning() - self.assertEqual( - str(self.term), - s[-4:].rjust(len(s)) + '\n' + - '\n' * (HEIGHT - 2)) - - def testEraseDisplay(self): - self.term.write('Hello world\n') - self.term.write('Goodbye world\n') - self.term.eraseDisplay() - - self.assertEqual( - str(self.term), - '\n' * (HEIGHT - 1)) - - def testEraseToDisplayEnd(self): - s1 = "Hello world" - s2 = "Goodbye world" - self.term.write('\n'.join((s1, s2, ''))) - self.term.cursorPosition(5, 1) - self.term.eraseToDisplayEnd() - - self.assertEqual( - str(self.term), - s1 + '\n' + - s2[:5] + '\n' + - '\n' * (HEIGHT - 3)) - - def testEraseToDisplayBeginning(self): - s1 = "Hello world" - s2 = "Goodbye world" - self.term.write('\n'.join((s1, s2))) - self.term.cursorPosition(5, 1) - self.term.eraseToDisplayBeginning() - - self.assertEqual( - str(self.term), - '\n' + - s2[6:].rjust(len(s2)) + '\n' + - '\n' * (HEIGHT - 3)) - - def testLineInsertion(self): - s1 = "Hello world" - s2 = "Goodbye world" - self.term.write('\n'.join((s1, s2))) - self.term.cursorPosition(7, 1) - self.term.insertLine() - - self.assertEqual( - str(self.term), - s1 + '\n' + - '\n' + - s2 + '\n' + - '\n' * (HEIGHT - 4)) - - def testLineDeletion(self): - s1 = "Hello world" - s2 = "Middle words" - s3 = "Goodbye world" - self.term.write('\n'.join((s1, s2, s3))) - self.term.cursorPosition(9, 1) - self.term.deleteLine() - - self.assertEqual( - str(self.term), - s1 + '\n' + - s3 + '\n' + - '\n' * (HEIGHT - 3)) - -class FakeDelayedCall: - called = False - cancelled = False - def __init__(self, fs, timeout, f, a, kw): - self.fs = fs - self.timeout = timeout - self.f = f - self.a = a - self.kw = kw - - def active(self): - return not (self.cancelled or self.called) - - def cancel(self): - self.cancelled = True -# self.fs.calls.remove(self) - - def call(self): - self.called = True - self.f(*self.a, **self.kw) - -class FakeScheduler: - def __init__(self): - self.calls = [] - - def callLater(self, timeout, f, *a, **kw): - self.calls.append(FakeDelayedCall(self, timeout, f, a, kw)) - return self.calls[-1] - -class ExpectTestCase(unittest.TestCase): - def setUp(self): - self.term = helper.ExpectableBuffer() - self.term.connectionMade() - self.fs = FakeScheduler() - - def testSimpleString(self): - result = [] - d = self.term.expect("hello world", timeout=1, scheduler=self.fs) - d.addCallback(result.append) - - self.term.write("greeting puny earthlings\n") - self.failIf(result) - self.term.write("hello world\n") - self.failUnless(result) - self.assertEqual(result[0].group(), "hello world") - self.assertEqual(len(self.fs.calls), 1) - self.failIf(self.fs.calls[0].active()) - - def testBrokenUpString(self): - result = [] - d = self.term.expect("hello world") - d.addCallback(result.append) - - self.failIf(result) - self.term.write("hello ") - self.failIf(result) - self.term.write("worl") - self.failIf(result) - self.term.write("d") - self.failUnless(result) - self.assertEqual(result[0].group(), "hello world") - - - def testMultiple(self): - result = [] - d1 = self.term.expect("hello ") - d1.addCallback(result.append) - d2 = self.term.expect("world") - d2.addCallback(result.append) - - self.failIf(result) - self.term.write("hello") - self.failIf(result) - self.term.write(" ") - self.assertEqual(len(result), 1) - self.term.write("world") - self.assertEqual(len(result), 2) - self.assertEqual(result[0].group(), "hello ") - self.assertEqual(result[1].group(), "world") - - def testSynchronous(self): - self.term.write("hello world") - - result = [] - d = self.term.expect("hello world") - d.addCallback(result.append) - self.failUnless(result) - self.assertEqual(result[0].group(), "hello world") - - def testMultipleSynchronous(self): - self.term.write("goodbye world") - - result = [] - d1 = self.term.expect("bye") - d1.addCallback(result.append) - d2 = self.term.expect("world") - d2.addCallback(result.append) - - self.assertEqual(len(result), 2) - self.assertEqual(result[0].group(), "bye") - self.assertEqual(result[1].group(), "world") - - def _cbTestTimeoutFailure(self, res): - self.assert_(hasattr(res, 'type')) - self.assertEqual(res.type, helper.ExpectationTimeout) - - def testTimeoutFailure(self): - d = self.term.expect("hello world", timeout=1, scheduler=self.fs) - d.addBoth(self._cbTestTimeoutFailure) - self.fs.calls[0].call() - - def testOverlappingTimeout(self): - self.term.write("not zoomtastic") - - result = [] - d1 = self.term.expect("hello world", timeout=1, scheduler=self.fs) - d1.addBoth(self._cbTestTimeoutFailure) - d2 = self.term.expect("zoom") - d2.addCallback(result.append) - - self.fs.calls[0].call() - - self.assertEqual(len(result), 1) - self.assertEqual(result[0].group(), "zoom") diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py deleted file mode 100755 index f313b5ec..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_insults.py +++ /dev/null @@ -1,496 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_insults -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -from twisted.trial import unittest -from twisted.test.proto_helpers import StringTransport - -from twisted.conch.insults.insults import ServerProtocol, ClientProtocol -from twisted.conch.insults.insults import CS_UK, CS_US, CS_DRAWING, CS_ALTERNATE, CS_ALTERNATE_SPECIAL -from twisted.conch.insults.insults import G0, G1 -from twisted.conch.insults.insults import modes - -def _getattr(mock, name): - return super(Mock, mock).__getattribute__(name) - -def occurrences(mock): - return _getattr(mock, 'occurrences') - -def methods(mock): - return _getattr(mock, 'methods') - -def _append(mock, obj): - occurrences(mock).append(obj) - -default = object() - -class Mock(object): - callReturnValue = default - - def __init__(self, methods=None, callReturnValue=default): - """ - @param methods: Mapping of names to return values - @param callReturnValue: object __call__ should return - """ - self.occurrences = [] - if methods is None: - methods = {} - self.methods = methods - if callReturnValue is not default: - self.callReturnValue = callReturnValue - - def __call__(self, *a, **kw): - returnValue = _getattr(self, 'callReturnValue') - if returnValue is default: - returnValue = Mock() - # _getattr(self, 'occurrences').append(('__call__', returnValue, a, kw)) - _append(self, ('__call__', returnValue, a, kw)) - return returnValue - - def __getattribute__(self, name): - methods = _getattr(self, 'methods') - if name in methods: - attrValue = Mock(callReturnValue=methods[name]) - else: - attrValue = Mock() - # _getattr(self, 'occurrences').append((name, attrValue)) - _append(self, (name, attrValue)) - return attrValue - -class MockMixin: - def assertCall(self, occurrence, methodName, expectedPositionalArgs=(), - expectedKeywordArgs={}): - attr, mock = occurrence - self.assertEqual(attr, methodName) - self.assertEqual(len(occurrences(mock)), 1) - [(call, result, args, kw)] = occurrences(mock) - self.assertEqual(call, "__call__") - self.assertEqual(args, expectedPositionalArgs) - self.assertEqual(kw, expectedKeywordArgs) - return result - - -_byteGroupingTestTemplate = """\ -def testByte%(groupName)s(self): - transport = StringTransport() - proto = Mock() - parser = self.protocolFactory(lambda: proto) - parser.factory = self - parser.makeConnection(transport) - - bytes = self.TEST_BYTES - while bytes: - chunk = bytes[:%(bytesPer)d] - bytes = bytes[%(bytesPer)d:] - parser.dataReceived(chunk) - - self.verifyResults(transport, proto, parser) -""" -class ByteGroupingsMixin(MockMixin): - protocolFactory = None - - for word, n in [('Pairs', 2), ('Triples', 3), ('Quads', 4), ('Quints', 5), ('Sexes', 6)]: - exec _byteGroupingTestTemplate % {'groupName': word, 'bytesPer': n} - del word, n - - def verifyResults(self, transport, proto, parser): - result = self.assertCall(occurrences(proto).pop(0), "makeConnection", (parser,)) - self.assertEqual(occurrences(result), []) - -del _byteGroupingTestTemplate - -class ServerArrowKeys(ByteGroupingsMixin, unittest.TestCase): - protocolFactory = ServerProtocol - - # All the arrow keys once - TEST_BYTES = '\x1b[A\x1b[B\x1b[C\x1b[D' - - def verifyResults(self, transport, proto, parser): - ByteGroupingsMixin.verifyResults(self, transport, proto, parser) - - for arrow in (parser.UP_ARROW, parser.DOWN_ARROW, - parser.RIGHT_ARROW, parser.LEFT_ARROW): - result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (arrow, None)) - self.assertEqual(occurrences(result), []) - self.failIf(occurrences(proto)) - - -class PrintableCharacters(ByteGroupingsMixin, unittest.TestCase): - protocolFactory = ServerProtocol - - # Some letters and digits, first on their own, then capitalized, - # then modified with alt - - TEST_BYTES = 'abc123ABC!@#\x1ba\x1bb\x1bc\x1b1\x1b2\x1b3' - - def verifyResults(self, transport, proto, parser): - ByteGroupingsMixin.verifyResults(self, transport, proto, parser) - - for char in 'abc123ABC!@#': - result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (char, None)) - self.assertEqual(occurrences(result), []) - - for char in 'abc123': - result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (char, parser.ALT)) - self.assertEqual(occurrences(result), []) - - occs = occurrences(proto) - self.failIf(occs, "%r should have been []" % (occs,)) - -class ServerFunctionKeys(ByteGroupingsMixin, unittest.TestCase): - """Test for parsing and dispatching function keys (F1 - F12) - """ - protocolFactory = ServerProtocol - - byteList = [] - for bytes in ('OP', 'OQ', 'OR', 'OS', # F1 - F4 - '15~', '17~', '18~', '19~', # F5 - F8 - '20~', '21~', '23~', '24~'): # F9 - F12 - byteList.append('\x1b[' + bytes) - TEST_BYTES = ''.join(byteList) - del byteList, bytes - - def verifyResults(self, transport, proto, parser): - ByteGroupingsMixin.verifyResults(self, transport, proto, parser) - for funcNum in range(1, 13): - funcArg = getattr(parser, 'F%d' % (funcNum,)) - result = self.assertCall(occurrences(proto).pop(0), "keystrokeReceived", (funcArg, None)) - self.assertEqual(occurrences(result), []) - self.failIf(occurrences(proto)) - -class ClientCursorMovement(ByteGroupingsMixin, unittest.TestCase): - protocolFactory = ClientProtocol - - d2 = "\x1b[2B" - r4 = "\x1b[4C" - u1 = "\x1b[A" - l2 = "\x1b[2D" - # Move the cursor down two, right four, up one, left two, up one, left two - TEST_BYTES = d2 + r4 + u1 + l2 + u1 + l2 - del d2, r4, u1, l2 - - def verifyResults(self, transport, proto, parser): - ByteGroupingsMixin.verifyResults(self, transport, proto, parser) - - for (method, count) in [('Down', 2), ('Forward', 4), ('Up', 1), - ('Backward', 2), ('Up', 1), ('Backward', 2)]: - result = self.assertCall(occurrences(proto).pop(0), "cursor" + method, (count,)) - self.assertEqual(occurrences(result), []) - self.failIf(occurrences(proto)) - -class ClientControlSequences(unittest.TestCase, MockMixin): - def setUp(self): - self.transport = StringTransport() - self.proto = Mock() - self.parser = ClientProtocol(lambda: self.proto) - self.parser.factory = self - self.parser.makeConnection(self.transport) - result = self.assertCall(occurrences(self.proto).pop(0), "makeConnection", (self.parser,)) - self.failIf(occurrences(result)) - - def testSimpleCardinals(self): - self.parser.dataReceived( - ''.join([''.join(['\x1b[' + str(n) + ch for n in ('', 2, 20, 200)]) for ch in 'BACD'])) - occs = occurrences(self.proto) - - for meth in ("Down", "Up", "Forward", "Backward"): - for count in (1, 2, 20, 200): - result = self.assertCall(occs.pop(0), "cursor" + meth, (count,)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testScrollRegion(self): - self.parser.dataReceived('\x1b[5;22r\x1b[r') - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "setScrollRegion", (5, 22)) - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "setScrollRegion", (None, None)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testHeightAndWidth(self): - self.parser.dataReceived("\x1b#3\x1b#4\x1b#5\x1b#6") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "doubleHeightLine", (True,)) - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "doubleHeightLine", (False,)) - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "singleWidthLine") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "doubleWidthLine") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testCharacterSet(self): - self.parser.dataReceived( - ''.join([''.join(['\x1b' + g + n for n in 'AB012']) for g in '()'])) - occs = occurrences(self.proto) - - for which in (G0, G1): - for charset in (CS_UK, CS_US, CS_DRAWING, CS_ALTERNATE, CS_ALTERNATE_SPECIAL): - result = self.assertCall(occs.pop(0), "selectCharacterSet", (charset, which)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testShifting(self): - self.parser.dataReceived("\x15\x14") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "shiftIn") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "shiftOut") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testSingleShifts(self): - self.parser.dataReceived("\x1bN\x1bO") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "singleShift2") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "singleShift3") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testKeypadMode(self): - self.parser.dataReceived("\x1b=\x1b>") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "applicationKeypadMode") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "numericKeypadMode") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testCursor(self): - self.parser.dataReceived("\x1b7\x1b8") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "saveCursor") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "restoreCursor") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testReset(self): - self.parser.dataReceived("\x1bc") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "reset") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testIndex(self): - self.parser.dataReceived("\x1bD\x1bM\x1bE") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "index") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "reverseIndex") - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "nextLine") - self.failIf(occurrences(result)) - self.failIf(occs) - - def testModes(self): - self.parser.dataReceived( - "\x1b[" + ';'.join(map(str, [modes.KAM, modes.IRM, modes.LNM])) + "h") - self.parser.dataReceived( - "\x1b[" + ';'.join(map(str, [modes.KAM, modes.IRM, modes.LNM])) + "l") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "setModes", ([modes.KAM, modes.IRM, modes.LNM],)) - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "resetModes", ([modes.KAM, modes.IRM, modes.LNM],)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testErasure(self): - self.parser.dataReceived( - "\x1b[K\x1b[1K\x1b[2K\x1b[J\x1b[1J\x1b[2J\x1b[3P") - occs = occurrences(self.proto) - - for meth in ("eraseToLineEnd", "eraseToLineBeginning", "eraseLine", - "eraseToDisplayEnd", "eraseToDisplayBeginning", - "eraseDisplay"): - result = self.assertCall(occs.pop(0), meth) - self.failIf(occurrences(result)) - - result = self.assertCall(occs.pop(0), "deleteCharacter", (3,)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testLineDeletion(self): - self.parser.dataReceived("\x1b[M\x1b[3M") - occs = occurrences(self.proto) - - for arg in (1, 3): - result = self.assertCall(occs.pop(0), "deleteLine", (arg,)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testLineInsertion(self): - self.parser.dataReceived("\x1b[L\x1b[3L") - occs = occurrences(self.proto) - - for arg in (1, 3): - result = self.assertCall(occs.pop(0), "insertLine", (arg,)) - self.failIf(occurrences(result)) - self.failIf(occs) - - def testCursorPosition(self): - methods(self.proto)['reportCursorPosition'] = (6, 7) - self.parser.dataReceived("\x1b[6n") - self.assertEqual(self.transport.value(), "\x1b[7;8R") - occs = occurrences(self.proto) - - result = self.assertCall(occs.pop(0), "reportCursorPosition") - # This isn't really an interesting assert, since it only tests that - # our mock setup is working right, but I'll include it anyway. - self.assertEqual(result, (6, 7)) - - - def test_applicationDataBytes(self): - """ - Contiguous non-control bytes are passed to a single call to the - C{write} method of the terminal to which the L{ClientProtocol} is - connected. - """ - occs = occurrences(self.proto) - self.parser.dataReceived('a') - self.assertCall(occs.pop(0), "write", ("a",)) - self.parser.dataReceived('bc') - self.assertCall(occs.pop(0), "write", ("bc",)) - - - def _applicationDataTest(self, data, calls): - occs = occurrences(self.proto) - self.parser.dataReceived(data) - while calls: - self.assertCall(occs.pop(0), *calls.pop(0)) - self.assertFalse(occs, "No other calls should happen: %r" % (occs,)) - - - def test_shiftInAfterApplicationData(self): - """ - Application data bytes followed by a shift-in command are passed to a - call to C{write} before the terminal's C{shiftIn} method is called. - """ - self._applicationDataTest( - 'ab\x15', [ - ("write", ("ab",)), - ("shiftIn",)]) - - - def test_shiftOutAfterApplicationData(self): - """ - Application data bytes followed by a shift-out command are passed to a - call to C{write} before the terminal's C{shiftOut} method is called. - """ - self._applicationDataTest( - 'ab\x14', [ - ("write", ("ab",)), - ("shiftOut",)]) - - - def test_cursorBackwardAfterApplicationData(self): - """ - Application data bytes followed by a cursor-backward command are passed - to a call to C{write} before the terminal's C{cursorBackward} method is - called. - """ - self._applicationDataTest( - 'ab\x08', [ - ("write", ("ab",)), - ("cursorBackward",)]) - - - def test_escapeAfterApplicationData(self): - """ - Application data bytes followed by an escape character are passed to a - call to C{write} before the terminal's handler method for the escape is - called. - """ - # Test a short escape - self._applicationDataTest( - 'ab\x1bD', [ - ("write", ("ab",)), - ("index",)]) - - # And a long escape - self._applicationDataTest( - 'ab\x1b[4h', [ - ("write", ("ab",)), - ("setModes", ([4],))]) - - # There's some other cases too, but they're all handled by the same - # codepaths as above. - - - -class ServerProtocolOutputTests(unittest.TestCase): - """ - Tests for the bytes L{ServerProtocol} writes to its transport when its - methods are called. - """ - def test_nextLine(self): - """ - L{ServerProtocol.nextLine} writes C{"\r\n"} to its transport. - """ - # Why doesn't it write ESC E? Because ESC E is poorly supported. For - # example, gnome-terminal (many different versions) fails to scroll if - # it receives ESC E and the cursor is already on the last row. - protocol = ServerProtocol() - transport = StringTransport() - protocol.makeConnection(transport) - protocol.nextLine() - self.assertEqual(transport.value(), "\r\n") - - - -class Deprecations(unittest.TestCase): - """ - Tests to ensure deprecation of L{insults.colors} and L{insults.client} - """ - - def ensureDeprecated(self, message): - """ - Ensures that the correct deprecation warning was issued. - """ - warnings = self.flushWarnings() - self.assertIdentical(warnings[0]['category'], DeprecationWarning) - self.assertEqual(warnings[0]['message'], message) - self.assertEqual(len(warnings), 1) - - - def test_colors(self): - """ - The L{insults.colors} module is deprecated - """ - from twisted.conch.insults import colors - self.ensureDeprecated("twisted.conch.insults.colors was deprecated " - "in Twisted 10.1.0: Please use " - "twisted.conch.insults.helper instead.") - - - def test_client(self): - """ - The L{insults.client} module is deprecated - """ - from twisted.conch.insults import client - self.ensureDeprecated("twisted.conch.insults.client was deprecated " - "in Twisted 10.1.0: Please use " - "twisted.conch.insults.insults instead.") diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py deleted file mode 100755 index 8403e1e5..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_keys.py +++ /dev/null @@ -1,644 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.ssh.keys}. -""" - -try: - import Crypto.Cipher.DES3 -except ImportError: - # we'll have to skip these tests without PyCypto and pyasn1 - Crypto = None - -try: - import pyasn1 -except ImportError: - pyasn1 = None - -if Crypto and pyasn1: - from twisted.conch.ssh import keys, common, sexpy - -import os, base64 -from twisted.conch.test import keydata -from twisted.python import randbytes -from twisted.python.hashlib import sha1 -from twisted.trial import unittest - - -class HelpersTestCase(unittest.TestCase): - - if Crypto is None: - skip = "cannot run w/o PyCrypto" - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - def setUp(self): - self._secureRandom = randbytes.secureRandom - randbytes.secureRandom = lambda x: '\x55' * x - - def tearDown(self): - randbytes.secureRandom = self._secureRandom - self._secureRandom = None - - def test_pkcs1(self): - """ - Test Public Key Cryptographic Standard #1 functions. - """ - data = 'ABC' - messageSize = 6 - self.assertEqual(keys.pkcs1Pad(data, messageSize), - '\x01\xff\x00ABC') - hash = sha1().digest() - messageSize = 40 - self.assertEqual(keys.pkcs1Digest('', messageSize), - '\x01\xff\xff\xff\x00' + keys.ID_SHA1 + hash) - - def _signRSA(self, data): - key = keys.Key.fromString(keydata.privateRSA_openssh) - sig = key.sign(data) - return key.keyObject, sig - - def _signDSA(self, data): - key = keys.Key.fromString(keydata.privateDSA_openssh) - sig = key.sign(data) - return key.keyObject, sig - - def test_signRSA(self): - """ - Test that RSA keys return appropriate signatures. - """ - data = 'data' - key, sig = self._signRSA(data) - sigData = keys.pkcs1Digest(data, keys.lenSig(key)) - v = key.sign(sigData, '')[0] - self.assertEqual(sig, common.NS('ssh-rsa') + common.MP(v)) - return key, sig - - def test_signDSA(self): - """ - Test that DSA keys return appropriate signatures. - """ - data = 'data' - key, sig = self._signDSA(data) - sigData = sha1(data).digest() - v = key.sign(sigData, '\x55' * 19) - self.assertEqual(sig, common.NS('ssh-dss') + common.NS( - Crypto.Util.number.long_to_bytes(v[0], 20) + - Crypto.Util.number.long_to_bytes(v[1], 20))) - return key, sig - - - def test_objectType(self): - """ - Test that objectType, returns the correct type for objects. - """ - self.assertEqual(keys.objectType(keys.Key.fromString( - keydata.privateRSA_openssh).keyObject), 'ssh-rsa') - self.assertEqual(keys.objectType(keys.Key.fromString( - keydata.privateDSA_openssh).keyObject), 'ssh-dss') - self.assertRaises(keys.BadKeyError, keys.objectType, None) - - -class KeyTestCase(unittest.TestCase): - - if Crypto is None: - skip = "cannot run w/o PyCrypto" - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - def setUp(self): - self.rsaObj = Crypto.PublicKey.RSA.construct((1L, 2L, 3L, 4L, 5L)) - self.dsaObj = Crypto.PublicKey.DSA.construct((1L, 2L, 3L, 4L, 5L)) - self.rsaSignature = ('\x00\x00\x00\x07ssh-rsa\x00' - '\x00\x00`N\xac\xb4@qK\xa0(\xc3\xf2h \xd3\xdd\xee6Np\x9d_' - '\xb0>\xe3\x0c(L\x9d{\txUd|!\xf6m\x9c\xd3\x93\x842\x7fU' - '\x05\xf4\xf7\xfaD\xda\xce\x81\x8ea\x7f=Y\xed*\xb7\xba\x81' - '\xf2\xad\xda\xeb(\x97\x03S\x08\x81\xc7\xb1\xb7\xe6\xe3' - '\xcd*\xd4\xbd\xc0wt\xf7y\xcd\xf0\xb7\x7f\xfb\x1e>\xf9r' - '\x8c\xba') - self.dsaSignature = ('\x00\x00\x00\x07ssh-dss\x00\x00' - '\x00(\x18z)H\x8a\x1b\xc6\r\xbbq\xa2\xd7f\x7f$\xa7\xbf' - '\xe8\x87\x8c\x88\xef\xd9k\x1a\x98\xdd{=\xdec\x18\t\xe3' - '\x87\xa9\xc72h\x95') - self.oldSecureRandom = randbytes.secureRandom - randbytes.secureRandom = lambda x: '\xff' * x - self.keyFile = self.mktemp() - file(self.keyFile, 'wb').write(keydata.privateRSA_lsh) - - def tearDown(self): - randbytes.secureRandom = self.oldSecureRandom - del self.oldSecureRandom - os.unlink(self.keyFile) - - def test__guessStringType(self): - """ - Test that the _guessStringType method guesses string types - correctly. - """ - self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_openssh), - 'public_openssh') - self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_openssh), - 'public_openssh') - self.assertEqual(keys.Key._guessStringType( - keydata.privateRSA_openssh), 'private_openssh') - self.assertEqual(keys.Key._guessStringType( - keydata.privateDSA_openssh), 'private_openssh') - self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_lsh), - 'public_lsh') - self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_lsh), - 'public_lsh') - self.assertEqual(keys.Key._guessStringType(keydata.privateRSA_lsh), - 'private_lsh') - self.assertEqual(keys.Key._guessStringType(keydata.privateDSA_lsh), - 'private_lsh') - self.assertEqual(keys.Key._guessStringType( - keydata.privateRSA_agentv3), 'agentv3') - self.assertEqual(keys.Key._guessStringType( - keydata.privateDSA_agentv3), 'agentv3') - self.assertEqual(keys.Key._guessStringType( - '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x01'), - 'blob') - self.assertEqual(keys.Key._guessStringType( - '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x01'), - 'blob') - self.assertEqual(keys.Key._guessStringType('not a key'), - None) - - def _testPublicPrivateFromString(self, public, private, type, data): - self._testPublicFromString(public, type, data) - self._testPrivateFromString(private, type, data) - - def _testPublicFromString(self, public, type, data): - publicKey = keys.Key.fromString(public) - self.assertTrue(publicKey.isPublic()) - self.assertEqual(publicKey.type(), type) - for k, v in publicKey.data().items(): - self.assertEqual(data[k], v) - - def _testPrivateFromString(self, private, type, data): - privateKey = keys.Key.fromString(private) - self.assertFalse(privateKey.isPublic()) - self.assertEqual(privateKey.type(), type) - for k, v in data.items(): - self.assertEqual(privateKey.data()[k], v) - - def test_fromOpenSSH(self): - """ - Test that keys are correctly generated from OpenSSH strings. - """ - self._testPublicPrivateFromString(keydata.publicRSA_openssh, - keydata.privateRSA_openssh, 'RSA', keydata.RSAData) - self.assertEqual(keys.Key.fromString( - keydata.privateRSA_openssh_encrypted, - passphrase='encrypted'), - keys.Key.fromString(keydata.privateRSA_openssh)) - self.assertEqual(keys.Key.fromString( - keydata.privateRSA_openssh_alternate), - keys.Key.fromString(keydata.privateRSA_openssh)) - self._testPublicPrivateFromString(keydata.publicDSA_openssh, - keydata.privateDSA_openssh, 'DSA', keydata.DSAData) - - def test_fromOpenSSH_with_whitespace(self): - """ - If key strings have trailing whitespace, it should be ignored. - """ - # from bug #3391, since our test key data doesn't have - # an issue with appended newlines - privateDSAData = """-----BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQDylESNuc61jq2yatCzZbenlr9llG+p9LhIpOLUbXhhHcwC6hrh -EZIdCKqTO0USLrGoP5uS9UHAUoeN62Z0KXXWTwOWGEQn/syyPzNJtnBorHpNUT9D -Qzwl1yUa53NNgEctpo4NoEFOx8PuU6iFLyvgHCjNn2MsuGuzkZm7sI9ZpQIVAJiR -9dPc08KLdpJyRxz8T74b4FQRAoGAGBc4Z5Y6R/HZi7AYM/iNOM8su6hrk8ypkBwR -a3Dbhzk97fuV3SF1SDrcQu4zF7c4CtH609N5nfZs2SUjLLGPWln83Ysb8qhh55Em -AcHXuROrHS/sDsnqu8FQp86MaudrqMExCOYyVPE7jaBWW+/JWFbKCxmgOCSdViUJ -esJpBFsCgYEA7+jtVvSt9yrwsS/YU1QGP5wRAiDYB+T5cK4HytzAqJKRdC5qS4zf -C7R0eKcDHHLMYO39aPnCwXjscisnInEhYGNblTDyPyiyNxAOXuC8x7luTmwzMbNJ -/ow0IqSj0VF72VJN9uSoPpFd4lLT0zN8v42RWja0M8ohWNf+YNJluPgCFE0PT4Vm -SUrCyZXsNh6VXwjs3gKQ ------END DSA PRIVATE KEY-----""" - self.assertEqual(keys.Key.fromString(privateDSAData), - keys.Key.fromString(privateDSAData + '\n')) - - def test_fromNewerOpenSSH(self): - """ - Newer versions of OpenSSH generate encrypted keys which have a longer - IV than the older versions. These newer keys are also loaded. - """ - key = keys.Key.fromString(keydata.privateRSA_openssh_encrypted_aes, - passphrase='testxp') - self.assertEqual(key.type(), 'RSA') - key2 = keys.Key.fromString( - keydata.privateRSA_openssh_encrypted_aes + '\n', - passphrase='testxp') - self.assertEqual(key, key2) - - - def test_fromLSH(self): - """ - Test that keys are correctly generated from LSH strings. - """ - self._testPublicPrivateFromString(keydata.publicRSA_lsh, - keydata.privateRSA_lsh, 'RSA', keydata.RSAData) - self._testPublicPrivateFromString(keydata.publicDSA_lsh, - keydata.privateDSA_lsh, 'DSA', keydata.DSAData) - sexp = sexpy.pack([['public-key', ['bad-key', ['p', '2']]]]) - self.assertRaises(keys.BadKeyError, keys.Key.fromString, - data='{'+base64.encodestring(sexp)+'}') - sexp = sexpy.pack([['private-key', ['bad-key', ['p', '2']]]]) - self.assertRaises(keys.BadKeyError, keys.Key.fromString, - sexp) - - def test_fromAgentv3(self): - """ - Test that keys are correctly generated from Agent v3 strings. - """ - self._testPrivateFromString(keydata.privateRSA_agentv3, 'RSA', - keydata.RSAData) - self._testPrivateFromString(keydata.privateDSA_agentv3, 'DSA', - keydata.DSAData) - self.assertRaises(keys.BadKeyError, keys.Key.fromString, - '\x00\x00\x00\x07ssh-foo'+'\x00\x00\x00\x01\x01'*5) - - def test_fromStringErrors(self): - """ - keys.Key.fromString should raise BadKeyError when the key is invalid. - """ - self.assertRaises(keys.BadKeyError, keys.Key.fromString, '') - # no key data with a bad key type - self.assertRaises(keys.BadKeyError, keys.Key.fromString, '', - 'bad_type') - # trying to decrypt a key which doesn't support encryption - self.assertRaises(keys.BadKeyError, keys.Key.fromString, - keydata.publicRSA_lsh, passphrase = 'unencrypted') - # trying to decrypt an unencrypted key - self.assertRaises(keys.EncryptedKeyError, keys.Key.fromString, - keys.Key(self.rsaObj).toString('openssh', 'encrypted')) - # key with no key data - self.assertRaises(keys.BadKeyError, keys.Key.fromString, - '-----BEGIN RSA KEY-----\nwA==\n') - # key with invalid DEK Info - self.assertRaises( - keys.BadKeyError, keys.Key.fromString, - """-----BEGIN ENCRYPTED RSA KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: weird type - -4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n -T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H -g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB -sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 -9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV -gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW -0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE -vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS -hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk -2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf -qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk -4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY -EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n -8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 -fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P -V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ -0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 -xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI -dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup -VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk -gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c -8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw -SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 -CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE -xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P ------END RSA PRIVATE KEY-----""") - # key with invalid encryption type - self.assertRaises( - keys.BadKeyError, keys.Key.fromString, - """-----BEGIN ENCRYPTED RSA KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: FOO-123-BAR,01234567 - -4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n -T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H -g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB -sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 -9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV -gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW -0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE -vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS -hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk -2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf -qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk -4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY -EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n -8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 -fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P -V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ -0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 -xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI -dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup -VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk -gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c -8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw -SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 -CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE -xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P ------END RSA PRIVATE KEY-----""") - # key with bad IV (AES) - self.assertRaises( - keys.BadKeyError, keys.Key.fromString, - """-----BEGIN ENCRYPTED RSA KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,01234 - -4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n -T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H -g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB -sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 -9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV -gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW -0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE -vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS -hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk -2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf -qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk -4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY -EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n -8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 -fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P -V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ -0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 -xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI -dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup -VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk -gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c -8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw -SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 -CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE -xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P ------END RSA PRIVATE KEY-----""") - # key with bad IV (DES3) - self.assertRaises( - keys.BadKeyError, keys.Key.fromString, - """-----BEGIN ENCRYPTED RSA KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,01234 - -4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n -T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H -g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB -sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 -9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV -gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW -0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE -vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS -hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk -2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf -qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk -4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY -EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n -8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 -fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P -V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ -0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 -xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI -dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup -VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk -gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c -8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw -SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 -CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE -xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P ------END RSA PRIVATE KEY-----""") - - def test_fromFile(self): - """ - Test that fromFile works correctly. - """ - self.assertEqual(keys.Key.fromFile(self.keyFile), - keys.Key.fromString(keydata.privateRSA_lsh)) - self.assertRaises(keys.BadKeyError, keys.Key.fromFile, - self.keyFile, 'bad_type') - self.assertRaises(keys.BadKeyError, keys.Key.fromFile, - self.keyFile, passphrase='unencrypted') - - def test_init(self): - """ - Test that the PublicKey object is initialized correctly. - """ - obj = Crypto.PublicKey.RSA.construct((1L, 2L)) - key = keys.Key(obj) - self.assertEqual(key.keyObject, obj) - - def test_equal(self): - """ - Test that Key objects are compared correctly. - """ - rsa1 = keys.Key(self.rsaObj) - rsa2 = keys.Key(self.rsaObj) - rsa3 = keys.Key(Crypto.PublicKey.RSA.construct((1L, 2L))) - dsa = keys.Key(self.dsaObj) - self.assertTrue(rsa1 == rsa2) - self.assertFalse(rsa1 == rsa3) - self.assertFalse(rsa1 == dsa) - self.assertFalse(rsa1 == object) - self.assertFalse(rsa1 == None) - - def test_notEqual(self): - """ - Test that Key objects are not-compared correctly. - """ - rsa1 = keys.Key(self.rsaObj) - rsa2 = keys.Key(self.rsaObj) - rsa3 = keys.Key(Crypto.PublicKey.RSA.construct((1L, 2L))) - dsa = keys.Key(self.dsaObj) - self.assertFalse(rsa1 != rsa2) - self.assertTrue(rsa1 != rsa3) - self.assertTrue(rsa1 != dsa) - self.assertTrue(rsa1 != object) - self.assertTrue(rsa1 != None) - - def test_type(self): - """ - Test that the type method returns the correct type for an object. - """ - self.assertEqual(keys.Key(self.rsaObj).type(), 'RSA') - self.assertEqual(keys.Key(self.rsaObj).sshType(), 'ssh-rsa') - self.assertEqual(keys.Key(self.dsaObj).type(), 'DSA') - self.assertEqual(keys.Key(self.dsaObj).sshType(), 'ssh-dss') - self.assertRaises(RuntimeError, keys.Key(None).type) - self.assertRaises(RuntimeError, keys.Key(None).sshType) - self.assertRaises(RuntimeError, keys.Key(self).type) - self.assertRaises(RuntimeError, keys.Key(self).sshType) - - def test_fromBlob(self): - """ - Test that a public key is correctly generated from a public key blob. - """ - rsaBlob = common.NS('ssh-rsa') + common.MP(2) + common.MP(3) - rsaKey = keys.Key.fromString(rsaBlob) - dsaBlob = (common.NS('ssh-dss') + common.MP(2) + common.MP(3) + - common.MP(4) + common.MP(5)) - dsaKey = keys.Key.fromString(dsaBlob) - badBlob = common.NS('ssh-bad') - self.assertTrue(rsaKey.isPublic()) - self.assertEqual(rsaKey.data(), {'e':2L, 'n':3L}) - self.assertTrue(dsaKey.isPublic()) - self.assertEqual(dsaKey.data(), {'p':2L, 'q':3L, 'g':4L, 'y':5L}) - self.assertRaises(keys.BadKeyError, - keys.Key.fromString, badBlob) - - - def test_fromPrivateBlob(self): - """ - Test that a private key is correctly generated from a private key blob. - """ - rsaBlob = (common.NS('ssh-rsa') + common.MP(2) + common.MP(3) + - common.MP(4) + common.MP(5) + common.MP(6) + common.MP(7)) - rsaKey = keys.Key._fromString_PRIVATE_BLOB(rsaBlob) - dsaBlob = (common.NS('ssh-dss') + common.MP(2) + common.MP(3) + - common.MP(4) + common.MP(5) + common.MP(6)) - dsaKey = keys.Key._fromString_PRIVATE_BLOB(dsaBlob) - badBlob = common.NS('ssh-bad') - self.assertFalse(rsaKey.isPublic()) - self.assertEqual( - rsaKey.data(), {'n':2L, 'e':3L, 'd':4L, 'u':5L, 'p':6L, 'q':7L}) - self.assertFalse(dsaKey.isPublic()) - self.assertEqual(dsaKey.data(), {'p':2L, 'q':3L, 'g':4L, 'y':5L, 'x':6L}) - self.assertRaises( - keys.BadKeyError, keys.Key._fromString_PRIVATE_BLOB, badBlob) - - - def test_blob(self): - """ - Test that the Key object generates blobs correctly. - """ - self.assertEqual(keys.Key(self.rsaObj).blob(), - '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x02' - '\x00\x00\x00\x01\x01') - self.assertEqual(keys.Key(self.dsaObj).blob(), - '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x03' - '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x02' - '\x00\x00\x00\x01\x01') - - badKey = keys.Key(None) - self.assertRaises(RuntimeError, badKey.blob) - - - def test_privateBlob(self): - """ - L{Key.privateBlob} returns the SSH protocol-level format of the private - key and raises L{RuntimeError} if the underlying key object is invalid. - """ - self.assertEqual(keys.Key(self.rsaObj).privateBlob(), - '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x01' - '\x00\x00\x00\x01\x02\x00\x00\x00\x01\x03\x00' - '\x00\x00\x01\x04\x00\x00\x00\x01\x04\x00\x00' - '\x00\x01\x05') - self.assertEqual(keys.Key(self.dsaObj).privateBlob(), - '\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x03' - '\x00\x00\x00\x01\x04\x00\x00\x00\x01\x02\x00' - '\x00\x00\x01\x01\x00\x00\x00\x01\x05') - - badKey = keys.Key(None) - self.assertRaises(RuntimeError, badKey.privateBlob) - - - def test_toOpenSSH(self): - """ - Test that the Key object generates OpenSSH keys correctly. - """ - key = keys.Key.fromString(keydata.privateRSA_lsh) - self.assertEqual(key.toString('openssh'), keydata.privateRSA_openssh) - self.assertEqual(key.toString('openssh', 'encrypted'), - keydata.privateRSA_openssh_encrypted) - self.assertEqual(key.public().toString('openssh'), - keydata.publicRSA_openssh[:-8]) # no comment - self.assertEqual(key.public().toString('openssh', 'comment'), - keydata.publicRSA_openssh) - key = keys.Key.fromString(keydata.privateDSA_lsh) - self.assertEqual(key.toString('openssh'), keydata.privateDSA_openssh) - self.assertEqual(key.public().toString('openssh', 'comment'), - keydata.publicDSA_openssh) - self.assertEqual(key.public().toString('openssh'), - keydata.publicDSA_openssh[:-8]) # no comment - - def test_toLSH(self): - """ - Test that the Key object generates LSH keys correctly. - """ - key = keys.Key.fromString(keydata.privateRSA_openssh) - self.assertEqual(key.toString('lsh'), keydata.privateRSA_lsh) - self.assertEqual(key.public().toString('lsh'), - keydata.publicRSA_lsh) - key = keys.Key.fromString(keydata.privateDSA_openssh) - self.assertEqual(key.toString('lsh'), keydata.privateDSA_lsh) - self.assertEqual(key.public().toString('lsh'), - keydata.publicDSA_lsh) - - def test_toAgentv3(self): - """ - Test that the Key object generates Agent v3 keys correctly. - """ - key = keys.Key.fromString(keydata.privateRSA_openssh) - self.assertEqual(key.toString('agentv3'), keydata.privateRSA_agentv3) - key = keys.Key.fromString(keydata.privateDSA_openssh) - self.assertEqual(key.toString('agentv3'), keydata.privateDSA_agentv3) - - def test_toStringErrors(self): - """ - Test that toString raises errors appropriately. - """ - self.assertRaises(keys.BadKeyError, keys.Key(self.rsaObj).toString, - 'bad_type') - - def test_sign(self): - """ - Test that the Key object generates correct signatures. - """ - key = keys.Key.fromString(keydata.privateRSA_openssh) - self.assertEqual(key.sign(''), self.rsaSignature) - key = keys.Key.fromString(keydata.privateDSA_openssh) - self.assertEqual(key.sign(''), self.dsaSignature) - - - def test_verify(self): - """ - Test that the Key object correctly verifies signatures. - """ - key = keys.Key.fromString(keydata.publicRSA_openssh) - self.assertTrue(key.verify(self.rsaSignature, '')) - self.assertFalse(key.verify(self.rsaSignature, 'a')) - self.assertFalse(key.verify(self.dsaSignature, '')) - key = keys.Key.fromString(keydata.publicDSA_openssh) - self.assertTrue(key.verify(self.dsaSignature, '')) - self.assertFalse(key.verify(self.dsaSignature, 'a')) - self.assertFalse(key.verify(self.rsaSignature, '')) - - - def test_verifyDSANoPrefix(self): - """ - Some commercial SSH servers send DSA keys as 2 20-byte numbers; - they are still verified as valid keys. - """ - key = keys.Key.fromString(keydata.publicDSA_openssh) - self.assertTrue(key.verify(self.dsaSignature[-40:], '')) - - - def test_repr(self): - """ - Test the pretty representation of Key. - """ - self.assertEqual(repr(keys.Key(self.rsaObj)), -"""<RSA Private Key (0 bits) -attr d: -\t03 -attr e: -\t02 -attr n: -\t01 -attr p: -\t04 -attr q: -\t05 -attr u: -\t04>""") diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py deleted file mode 100755 index d7fdacf0..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_knownhosts.py +++ /dev/null @@ -1,1037 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.client.knownhosts}. -""" - -import os -from binascii import Error as BinasciiError, b2a_base64, a2b_base64 - -try: - import Crypto - import pyasn1 -except ImportError: - skip = "PyCrypto and PyASN1 required for twisted.conch.knownhosts." -else: - from twisted.conch.ssh.keys import Key, BadKeyError - from twisted.conch.client.knownhosts import \ - PlainEntry, HashedEntry, KnownHostsFile, UnparsedEntry, ConsoleUI - from twisted.conch.client import default - -from zope.interface.verify import verifyObject - -from twisted.python.filepath import FilePath -from twisted.trial.unittest import TestCase -from twisted.internet.defer import Deferred -from twisted.conch.interfaces import IKnownHostEntry -from twisted.conch.error import HostKeyChanged, UserRejectedKey, InvalidEntry - - -sampleEncodedKey = ( - 'AAAAB3NzaC1yc2EAAAABIwAAAQEAsV0VMRbGmzhqxxayLRHmvnFvtyNqgbNKV46dU1bVFB+3y' - 'tNvue4Riqv/SVkPRNwMb7eWH29SviXaBxUhYyzKkDoNUq3rTNnH1Vnif6d6X4JCrUb5d3W+Dm' - 'YClyJrZ5HgD/hUpdSkTRqdbQ2TrvSAxRacj+vHHT4F4dm1bJSewm3B2D8HVOoi/CbVh3dsIiC' - 'dp8VltdZx4qYVfYe2LwVINCbAa3d3tj9ma7RVfw3OH2Mfb+toLd1N5tBQFb7oqTt2nC6I/6Bd' - '4JwPUld+IEitw/suElq/AIJVQXXujeyiZlea90HE65U2mF1ytr17HTAIT2ySokJWyuBANGACk' - '6iIaw==') - -otherSampleEncodedKey = ( - 'AAAAB3NzaC1yc2EAAAABIwAAAIEAwaeCZd3UCuPXhX39+/p9qO028jTF76DMVd9mPvYVDVXuf' - 'WckKZauF7+0b7qm+ChT7kan6BzRVo4++gCVNfAlMzLysSt3ylmOR48tFpAfygg9UCX3DjHz0E' - 'lOOUKh3iifc9aUShD0OPaK3pR5JJ8jfiBfzSYWt/hDi/iZ4igsSs8=') - -thirdSampleEncodedKey = ( - 'AAAAB3NzaC1yc2EAAAABIwAAAQEAl/TQakPkePlnwCBRPitIVUTg6Z8VzN1en+DGkyo/evkmLw' - '7o4NWR5qbysk9A9jXW332nxnEuAnbcCam9SHe1su1liVfyIK0+3bdn0YRB0sXIbNEtMs2LtCho' - '/aV3cXPS+Cf1yut3wvIpaRnAzXxuKPCTXQ7/y0IXa8TwkRBH58OJa3RqfQ/NsSp5SAfdsrHyH2' - 'aitiVKm2jfbTKzSEqOQG/zq4J9GXTkq61gZugory/Tvl5/yPgSnOR6C9jVOMHf27ZPoRtyj9SY' - '343Hd2QHiIE0KPZJEgCynKeWoKz8v6eTSK8n4rBnaqWdp8MnGZK1WGy05MguXbyCDuTC8AmJXQ' - '==') - -sampleKey = a2b_base64(sampleEncodedKey) -otherSampleKey = a2b_base64(otherSampleEncodedKey) -thirdSampleKey = a2b_base64(thirdSampleEncodedKey) - -samplePlaintextLine = ( - "www.twistedmatrix.com ssh-rsa " + sampleEncodedKey + "\n") - -otherSamplePlaintextLine = ( - "divmod.com ssh-rsa " + otherSampleEncodedKey + "\n") - -sampleHostIPLine = ( - "www.twistedmatrix.com,198.49.126.131 ssh-rsa " + sampleEncodedKey + "\n") - -sampleHashedLine = ( - "|1|gJbSEPBG9ZSBoZpHNtZBD1bHKBA=|bQv+0Xa0dByrwkA1EB0E7Xop/Fo= ssh-rsa " + - sampleEncodedKey + "\n") - - - -class EntryTestsMixin: - """ - Tests for implementations of L{IKnownHostEntry}. Subclasses must set the - 'entry' attribute to a provider of that interface, the implementation of - that interface under test. - - @ivar entry: a provider of L{IKnownHostEntry} with a hostname of - www.twistedmatrix.com and an RSA key of sampleKey. - """ - - def test_providesInterface(self): - """ - The given entry should provide IKnownHostEntry. - """ - verifyObject(IKnownHostEntry, self.entry) - - - def test_fromString(self): - """ - Constructing a plain text entry from an unhashed known_hosts entry will - result in an L{IKnownHostEntry} provider with 'keyString', 'hostname', - and 'keyType' attributes. While outside the interface in question, - these attributes are held in common by L{PlainEntry} and L{HashedEntry} - implementations; other implementations should override this method in - subclasses. - """ - entry = self.entry - self.assertEqual(entry.publicKey, Key.fromString(sampleKey)) - self.assertEqual(entry.keyType, "ssh-rsa") - - - def test_matchesKey(self): - """ - L{IKnownHostEntry.matchesKey} checks to see if an entry matches a given - SSH key. - """ - twistedmatrixDotCom = Key.fromString(sampleKey) - divmodDotCom = Key.fromString(otherSampleKey) - self.assertEqual( - True, - self.entry.matchesKey(twistedmatrixDotCom)) - self.assertEqual( - False, - self.entry.matchesKey(divmodDotCom)) - - - def test_matchesHost(self): - """ - L{IKnownHostEntry.matchesHost} checks to see if an entry matches a - given hostname. - """ - self.assertEqual(True, self.entry.matchesHost( - "www.twistedmatrix.com")) - self.assertEqual(False, self.entry.matchesHost( - "www.divmod.com")) - - - -class PlainEntryTests(EntryTestsMixin, TestCase): - """ - Test cases for L{PlainEntry}. - """ - plaintextLine = samplePlaintextLine - hostIPLine = sampleHostIPLine - - def setUp(self): - """ - Set 'entry' to a sample plain-text entry with sampleKey as its key. - """ - self.entry = PlainEntry.fromString(self.plaintextLine) - - - def test_matchesHostIP(self): - """ - A "hostname,ip" formatted line will match both the host and the IP. - """ - self.entry = PlainEntry.fromString(self.hostIPLine) - self.assertEqual(True, self.entry.matchesHost("198.49.126.131")) - self.test_matchesHost() - - - def test_toString(self): - """ - L{PlainEntry.toString} generates the serialized OpenSSL format string - for the entry, sans newline. - """ - self.assertEqual(self.entry.toString(), self.plaintextLine.rstrip("\n")) - multiHostEntry = PlainEntry.fromString(self.hostIPLine) - self.assertEqual(multiHostEntry.toString(), - self.hostIPLine.rstrip("\n")) - - - -class PlainTextWithCommentTests(PlainEntryTests): - """ - Test cases for L{PlainEntry} when parsed from a line with a comment. - """ - - plaintextLine = samplePlaintextLine[:-1] + " plain text comment.\n" - hostIPLine = sampleHostIPLine[:-1] + " text following host/IP line\n" - - - -class HashedEntryTests(EntryTestsMixin, TestCase): - """ - Tests for L{HashedEntry}. - - This suite doesn't include any tests for host/IP pairs because hashed - entries store IP addresses the same way as hostnames and does not support - comma-separated lists. (If you hash the IP and host together you can't - tell if you've got the key already for one or the other.) - """ - hashedLine = sampleHashedLine - - def setUp(self): - """ - Set 'entry' to a sample hashed entry for twistedmatrix.com with - sampleKey as its key. - """ - self.entry = HashedEntry.fromString(self.hashedLine) - - - def test_toString(self): - """ - L{HashedEntry.toString} generates the serialized OpenSSL format string - for the entry, sans the newline. - """ - self.assertEqual(self.entry.toString(), self.hashedLine.rstrip("\n")) - - - -class HashedEntryWithCommentTests(HashedEntryTests): - """ - Test cases for L{PlainEntry} when parsed from a line with a comment. - """ - - hashedLine = sampleHashedLine[:-1] + " plain text comment.\n" - - - -class UnparsedEntryTests(TestCase, EntryTestsMixin): - """ - Tests for L{UnparsedEntry} - """ - def setUp(self): - """ - Set up the 'entry' to be an unparsed entry for some random text. - """ - self.entry = UnparsedEntry(" This is a bogus entry. \n") - - - def test_fromString(self): - """ - Creating an L{UnparsedEntry} should simply record the string it was - passed. - """ - self.assertEqual(" This is a bogus entry. \n", - self.entry._string) - - - def test_matchesHost(self): - """ - An unparsed entry can't match any hosts. - """ - self.assertEqual(False, self.entry.matchesHost("www.twistedmatrix.com")) - - - def test_matchesKey(self): - """ - An unparsed entry can't match any keys. - """ - self.assertEqual(False, self.entry.matchesKey(Key.fromString(sampleKey))) - - - def test_toString(self): - """ - L{UnparsedEntry.toString} returns its input string, sans trailing - newline. - """ - self.assertEqual(" This is a bogus entry. ", self.entry.toString()) - - - -class ParseErrorTests(TestCase): - """ - L{HashedEntry.fromString} and L{PlainEntry.fromString} can raise a variety - of errors depending on misformattings of certain strings. These tests make - sure those errors are caught. Since many of the ways that this can go - wrong are in the lower-level APIs being invoked by the parsing logic, - several of these are integration tests with the C{base64} and - L{twisted.conch.ssh.keys} modules. - """ - - def invalidEntryTest(self, cls): - """ - If there are fewer than three elements, C{fromString} should raise - L{InvalidEntry}. - """ - self.assertRaises(InvalidEntry, cls.fromString, "invalid") - - - def notBase64Test(self, cls): - """ - If the key is not base64, C{fromString} should raise L{BinasciiError}. - """ - self.assertRaises(BinasciiError, cls.fromString, "x x x") - - - def badKeyTest(self, cls, prefix): - """ - If the key portion of the entry is valid base64, but is not actually an - SSH key, C{fromString} should raise L{BadKeyError}. - """ - self.assertRaises(BadKeyError, cls.fromString, ' '.join( - [prefix, "ssh-rsa", b2a_base64( - "Hey, this isn't an SSH key!").strip()])) - - - def test_invalidPlainEntry(self): - """ - If there are fewer than three whitespace-separated elements in an - entry, L{PlainEntry.fromString} should raise L{InvalidEntry}. - """ - self.invalidEntryTest(PlainEntry) - - - def test_invalidHashedEntry(self): - """ - If there are fewer than three whitespace-separated elements in an - entry, or the hostname salt/hash portion has more than two elements, - L{HashedEntry.fromString} should raise L{InvalidEntry}. - """ - self.invalidEntryTest(HashedEntry) - a, b, c = sampleHashedLine.split() - self.assertRaises(InvalidEntry, HashedEntry.fromString, ' '.join( - [a + "||", b, c])) - - - def test_plainNotBase64(self): - """ - If the key portion of a plain entry is not decodable as base64, - C{fromString} should raise L{BinasciiError}. - """ - self.notBase64Test(PlainEntry) - - - def test_hashedNotBase64(self): - """ - If the key, host salt, or host hash portion of a hashed entry is not - encoded, it will raise L{BinasciiError}. - """ - self.notBase64Test(HashedEntry) - a, b, c = sampleHashedLine.split() - # Salt not valid base64. - self.assertRaises( - BinasciiError, HashedEntry.fromString, - ' '.join(["|1|x|" + b2a_base64("stuff").strip(), b, c])) - # Host hash not valid base64. - self.assertRaises( - BinasciiError, HashedEntry.fromString, - ' '.join([HashedEntry.MAGIC + b2a_base64("stuff").strip() + "|x", - b, c])) - # Neither salt nor hash valid base64. - self.assertRaises( - BinasciiError, HashedEntry.fromString, - ' '.join(["|1|x|x", b, c])) - - - def test_hashedBadKey(self): - """ - If the key portion of the entry is valid base64, but is not actually an - SSH key, C{HashedEntry.fromString} should raise L{BadKeyError}. - """ - a, b, c = sampleHashedLine.split() - self.badKeyTest(HashedEntry, a) - - - def test_plainBadKey(self): - """ - If the key portion of the entry is valid base64, but is not actually an - SSH key, C{PlainEntry.fromString} should raise L{BadKeyError}. - """ - self.badKeyTest(PlainEntry, "hostname") - - - -class KnownHostsDatabaseTests(TestCase): - """ - Tests for L{KnownHostsFile}. - """ - - def pathWithContent(self, content): - """ - Return a FilePath with the given initial content. - """ - fp = FilePath(self.mktemp()) - fp.setContent(content) - return fp - - - def loadSampleHostsFile(self, content=( - sampleHashedLine + otherSamplePlaintextLine + - "\n# That was a blank line.\n" - "This is just unparseable.\n" - "|1|This also unparseable.\n")): - """ - Return a sample hosts file, with keys for www.twistedmatrix.com and - divmod.com present. - """ - return KnownHostsFile.fromPath(self.pathWithContent(content)) - - - def test_loadFromPath(self): - """ - Loading a L{KnownHostsFile} from a path with six entries in it will - result in a L{KnownHostsFile} object with six L{IKnownHostEntry} - providers in it. - """ - hostsFile = self.loadSampleHostsFile() - self.assertEqual(len(hostsFile._entries), 6) - - - def test_verifyHashedEntry(self): - """ - Loading a L{KnownHostsFile} from a path containing a single valid - L{HashedEntry} entry will result in a L{KnownHostsFile} object - with one L{IKnownHostEntry} provider. - """ - hostsFile = self.loadSampleHostsFile((sampleHashedLine)) - self.assertIsInstance(hostsFile._entries[0], HashedEntry) - self.assertEqual(True, hostsFile._entries[0].matchesHost( - "www.twistedmatrix.com")) - - - def test_verifyPlainEntry(self): - """ - Loading a L{KnownHostsFile} from a path containing a single valid - L{PlainEntry} entry will result in a L{KnownHostsFile} object - with one L{IKnownHostEntry} provider. - """ - hostsFile = self.loadSampleHostsFile((otherSamplePlaintextLine)) - self.assertIsInstance(hostsFile._entries[0], PlainEntry) - self.assertEqual(True, hostsFile._entries[0].matchesHost( - "divmod.com")) - - - def test_verifyUnparsedEntry(self): - """ - Loading a L{KnownHostsFile} from a path that only contains '\n' will - result in a L{KnownHostsFile} object containing a L{UnparsedEntry} - object. - """ - hostsFile = self.loadSampleHostsFile(("\n")) - self.assertIsInstance(hostsFile._entries[0], UnparsedEntry) - self.assertEqual(hostsFile._entries[0].toString(), "") - - - def test_verifyUnparsedComment(self): - """ - Loading a L{KnownHostsFile} from a path that contains a comment will - result in a L{KnownHostsFile} object containing a L{UnparsedEntry} - object. - """ - hostsFile = self.loadSampleHostsFile(("# That was a blank line.\n")) - self.assertIsInstance(hostsFile._entries[0], UnparsedEntry) - self.assertEqual(hostsFile._entries[0].toString(), - "# That was a blank line.") - - - def test_verifyUnparsableLine(self): - """ - Loading a L{KnownHostsFile} from a path that contains an unparseable - line will be represented as an L{UnparsedEntry} instance. - """ - hostsFile = self.loadSampleHostsFile(("This is just unparseable.\n")) - self.assertIsInstance(hostsFile._entries[0], UnparsedEntry) - self.assertEqual(hostsFile._entries[0].toString(), - "This is just unparseable.") - - - def test_verifyUnparsableEncryptionMarker(self): - """ - Loading a L{KnownHostsFile} from a path containing an unparseable line - that starts with an encryption marker will be represented as an - L{UnparsedEntry} instance. - """ - hostsFile = self.loadSampleHostsFile(("|1|This is unparseable.\n")) - self.assertIsInstance(hostsFile._entries[0], UnparsedEntry) - self.assertEqual(hostsFile._entries[0].toString(), - "|1|This is unparseable.") - - - def test_loadNonExistent(self): - """ - Loading a L{KnownHostsFile} from a path that does not exist should - result in an empty L{KnownHostsFile} that will save back to that path. - """ - pn = self.mktemp() - knownHostsFile = KnownHostsFile.fromPath(FilePath(pn)) - self.assertEqual([], list(knownHostsFile._entries)) - self.assertEqual(False, FilePath(pn).exists()) - knownHostsFile.save() - self.assertEqual(True, FilePath(pn).exists()) - - - def test_loadNonExistentParent(self): - """ - Loading a L{KnownHostsFile} from a path whose parent directory does not - exist should result in an empty L{KnownHostsFile} that will save back - to that path, creating its parent directory(ies) in the process. - """ - thePath = FilePath(self.mktemp()) - knownHostsPath = thePath.child("foo").child("known_hosts") - knownHostsFile = KnownHostsFile.fromPath(knownHostsPath) - knownHostsFile.save() - knownHostsPath.restat(False) - self.assertEqual(True, knownHostsPath.exists()) - - - def test_savingAddsEntry(self): - """ - L{KnownHostsFile.save()} will write out a new file with any entries - that have been added. - """ - path = self.pathWithContent(sampleHashedLine + - otherSamplePlaintextLine) - knownHostsFile = KnownHostsFile.fromPath(path) - newEntry = knownHostsFile.addHostKey("some.example.com", - Key.fromString(thirdSampleKey)) - expectedContent = ( - sampleHashedLine + - otherSamplePlaintextLine + HashedEntry.MAGIC + - b2a_base64(newEntry._hostSalt).strip() + "|" + - b2a_base64(newEntry._hostHash).strip() + " ssh-rsa " + - thirdSampleEncodedKey + "\n") - - # Sanity check, let's make sure the base64 API being used for the test - # isn't inserting spurious newlines. - self.assertEqual(3, expectedContent.count("\n")) - knownHostsFile.save() - self.assertEqual(expectedContent, path.getContent()) - - - def test_hasPresentKey(self): - """ - L{KnownHostsFile.hasHostKey} returns C{True} when a key for the given - hostname is present and matches the expected key. - """ - hostsFile = self.loadSampleHostsFile() - self.assertEqual(True, hostsFile.hasHostKey( - "www.twistedmatrix.com", Key.fromString(sampleKey))) - - - def test_hasNonPresentKey(self): - """ - L{KnownHostsFile.hasHostKey} returns C{False} when a key for the given - hostname is not present. - """ - hostsFile = self.loadSampleHostsFile() - self.assertEqual(False, hostsFile.hasHostKey( - "non-existent.example.com", Key.fromString(sampleKey))) - - - def test_hasKeyMismatch(self): - """ - L{KnownHostsFile.hasHostKey} raises L{HostKeyChanged} if the host key - is present, but different from the expected one. The resulting - exception should have an C{offendingEntry} indicating the given entry. - """ - hostsFile = self.loadSampleHostsFile() - exception = self.assertRaises( - HostKeyChanged, hostsFile.hasHostKey, - "www.twistedmatrix.com", Key.fromString(otherSampleKey)) - self.assertEqual(exception.offendingEntry, hostsFile._entries[0]) - self.assertEqual(exception.lineno, 1) - self.assertEqual(exception.path, hostsFile._savePath) - - - def test_addHostKey(self): - """ - L{KnownHostsFile.addHostKey} adds a new L{HashedEntry} to the host - file, and returns it. - """ - hostsFile = self.loadSampleHostsFile() - aKey = Key.fromString(thirdSampleKey) - self.assertEqual(False, - hostsFile.hasHostKey("somewhere.example.com", aKey)) - newEntry = hostsFile.addHostKey("somewhere.example.com", aKey) - - # The code in OpenSSH requires host salts to be 20 characters long. - # This is the required length of a SHA-1 HMAC hash, so it's just a - # sanity check. - self.assertEqual(20, len(newEntry._hostSalt)) - self.assertEqual(True, - newEntry.matchesHost("somewhere.example.com")) - self.assertEqual(newEntry.keyType, "ssh-rsa") - self.assertEqual(aKey, newEntry.publicKey) - self.assertEqual(True, - hostsFile.hasHostKey("somewhere.example.com", aKey)) - - - def test_randomSalts(self): - """ - L{KnownHostsFile.addHostKey} generates a random salt for each new key, - so subsequent salts will be different. - """ - hostsFile = self.loadSampleHostsFile() - aKey = Key.fromString(thirdSampleKey) - self.assertNotEqual( - hostsFile.addHostKey("somewhere.example.com", aKey)._hostSalt, - hostsFile.addHostKey("somewhere-else.example.com", aKey)._hostSalt) - - - def test_verifyValidKey(self): - """ - Verifying a valid key should return a L{Deferred} which fires with - True. - """ - hostsFile = self.loadSampleHostsFile() - hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey)) - ui = FakeUI() - d = hostsFile.verifyHostKey(ui, "www.twistedmatrix.com", "1.2.3.4", - Key.fromString(sampleKey)) - l = [] - d.addCallback(l.append) - self.assertEqual(l, [True]) - - - def test_verifyInvalidKey(self): - """ - Verfying an invalid key should return a L{Deferred} which fires with a - L{HostKeyChanged} failure. - """ - hostsFile = self.loadSampleHostsFile() - wrongKey = Key.fromString(thirdSampleKey) - ui = FakeUI() - hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey)) - d = hostsFile.verifyHostKey( - ui, "www.twistedmatrix.com", "1.2.3.4", wrongKey) - return self.assertFailure(d, HostKeyChanged) - - - def verifyNonPresentKey(self): - """ - Set up a test to verify a key that isn't present. Return a 3-tuple of - the UI, a list set up to collect the result of the verifyHostKey call, - and the sample L{KnownHostsFile} being used. - - This utility method avoids returning a L{Deferred}, and records results - in the returned list instead, because the events which get generated - here are pre-recorded in the 'ui' object. If the L{Deferred} in - question does not fire, the it will fail quickly with an empty list. - """ - hostsFile = self.loadSampleHostsFile() - absentKey = Key.fromString(thirdSampleKey) - ui = FakeUI() - l = [] - d = hostsFile.verifyHostKey( - ui, "sample-host.example.com", "4.3.2.1", absentKey) - d.addBoth(l.append) - self.assertEqual([], l) - self.assertEqual( - ui.promptText, - "The authenticity of host 'sample-host.example.com (4.3.2.1)' " - "can't be established.\n" - "RSA key fingerprint is " - "89:4e:cc:8c:57:83:96:48:ef:63:ad:ee:99:00:4c:8f.\n" - "Are you sure you want to continue connecting (yes/no)? ") - return ui, l, hostsFile - - - def test_verifyNonPresentKey_Yes(self): - """ - Verifying a key where neither the hostname nor the IP are present - should result in the UI being prompted with a message explaining as - much. If the UI says yes, the Deferred should fire with True. - """ - ui, l, knownHostsFile = self.verifyNonPresentKey() - ui.promptDeferred.callback(True) - self.assertEqual([True], l) - reloaded = KnownHostsFile.fromPath(knownHostsFile._savePath) - self.assertEqual( - True, - reloaded.hasHostKey("4.3.2.1", Key.fromString(thirdSampleKey))) - self.assertEqual( - True, - reloaded.hasHostKey("sample-host.example.com", - Key.fromString(thirdSampleKey))) - - - def test_verifyNonPresentKey_No(self): - """ - Verifying a key where neither the hostname nor the IP are present - should result in the UI being prompted with a message explaining as - much. If the UI says no, the Deferred should fail with - UserRejectedKey. - """ - ui, l, knownHostsFile = self.verifyNonPresentKey() - ui.promptDeferred.callback(False) - l[0].trap(UserRejectedKey) - - - def test_verifyHostIPMismatch(self): - """ - Verifying a key where the host is present (and correct), but the IP is - present and different, should result the deferred firing in a - HostKeyChanged failure. - """ - hostsFile = self.loadSampleHostsFile() - wrongKey = Key.fromString(thirdSampleKey) - ui = FakeUI() - d = hostsFile.verifyHostKey( - ui, "www.twistedmatrix.com", "4.3.2.1", wrongKey) - return self.assertFailure(d, HostKeyChanged) - - - def test_verifyKeyForHostAndIP(self): - """ - Verifying a key where the hostname is present but the IP is not should - result in the key being added for the IP and the user being warned - about the change. - """ - ui = FakeUI() - hostsFile = self.loadSampleHostsFile() - expectedKey = Key.fromString(sampleKey) - hostsFile.verifyHostKey( - ui, "www.twistedmatrix.com", "5.4.3.2", expectedKey) - self.assertEqual( - True, KnownHostsFile.fromPath(hostsFile._savePath).hasHostKey( - "5.4.3.2", expectedKey)) - self.assertEqual( - ["Warning: Permanently added the RSA host key for IP address " - "'5.4.3.2' to the list of known hosts."], - ui.userWarnings) - - -class FakeFile(object): - """ - A fake file-like object that acts enough like a file for - L{ConsoleUI.prompt}. - """ - - def __init__(self): - self.inlines = [] - self.outchunks = [] - self.closed = False - - - def readline(self): - """ - Return a line from the 'inlines' list. - """ - return self.inlines.pop(0) - - - def write(self, chunk): - """ - Append the given item to the 'outchunks' list. - """ - if self.closed: - raise IOError("the file was closed") - self.outchunks.append(chunk) - - - def close(self): - """ - Set the 'closed' flag to True, explicitly marking that it has been - closed. - """ - self.closed = True - - - -class ConsoleUITests(TestCase): - """ - Test cases for L{ConsoleUI}. - """ - - def setUp(self): - """ - Create a L{ConsoleUI} pointed at a L{FakeFile}. - """ - self.fakeFile = FakeFile() - self.ui = ConsoleUI(self.openFile) - - - def openFile(self): - """ - Return the current fake file. - """ - return self.fakeFile - - - def newFile(self, lines): - """ - Create a new fake file (the next file that self.ui will open) with the - given list of lines to be returned from readline(). - """ - self.fakeFile = FakeFile() - self.fakeFile.inlines = lines - - - def test_promptYes(self): - """ - L{ConsoleUI.prompt} writes a message to the console, then reads a line. - If that line is 'yes', then it returns a L{Deferred} that fires with - True. - """ - for okYes in ['yes', 'Yes', 'yes\n']: - self.newFile([okYes]) - l = [] - self.ui.prompt("Hello, world!").addCallback(l.append) - self.assertEqual(["Hello, world!"], self.fakeFile.outchunks) - self.assertEqual([True], l) - self.assertEqual(True, self.fakeFile.closed) - - - def test_promptNo(self): - """ - L{ConsoleUI.prompt} writes a message to the console, then reads a line. - If that line is 'no', then it returns a L{Deferred} that fires with - False. - """ - for okNo in ['no', 'No', 'no\n']: - self.newFile([okNo]) - l = [] - self.ui.prompt("Goodbye, world!").addCallback(l.append) - self.assertEqual(["Goodbye, world!"], self.fakeFile.outchunks) - self.assertEqual([False], l) - self.assertEqual(True, self.fakeFile.closed) - - - def test_promptRepeatedly(self): - """ - L{ConsoleUI.prompt} writes a message to the console, then reads a line. - If that line is neither 'yes' nor 'no', then it says "Please enter - 'yes' or 'no'" until it gets a 'yes' or a 'no', at which point it - returns a Deferred that answers either True or False. - """ - self.newFile(['what', 'uh', 'okay', 'yes']) - l = [] - self.ui.prompt("Please say something useful.").addCallback(l.append) - self.assertEqual([True], l) - self.assertEqual(self.fakeFile.outchunks, - ["Please say something useful."] + - ["Please type 'yes' or 'no': "] * 3) - self.assertEqual(True, self.fakeFile.closed) - self.newFile(['blah', 'stuff', 'feh', 'no']) - l = [] - self.ui.prompt("Please say something negative.").addCallback(l.append) - self.assertEqual([False], l) - self.assertEqual(self.fakeFile.outchunks, - ["Please say something negative."] + - ["Please type 'yes' or 'no': "] * 3) - self.assertEqual(True, self.fakeFile.closed) - - - def test_promptOpenFailed(self): - """ - If the C{opener} passed to L{ConsoleUI} raises an exception, that - exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}. - """ - def raiseIt(): - raise IOError() - ui = ConsoleUI(raiseIt) - d = ui.prompt("This is a test.") - return self.assertFailure(d, IOError) - - - def test_warn(self): - """ - L{ConsoleUI.warn} should output a message to the console object. - """ - self.ui.warn("Test message.") - self.assertEqual(["Test message."], self.fakeFile.outchunks) - self.assertEqual(True, self.fakeFile.closed) - - - def test_warnOpenFailed(self): - """ - L{ConsoleUI.warn} should log a traceback if the output can't be opened. - """ - def raiseIt(): - 1 / 0 - ui = ConsoleUI(raiseIt) - ui.warn("This message never makes it.") - self.assertEqual(len(self.flushLoggedErrors(ZeroDivisionError)), 1) - - - -class FakeUI(object): - """ - A fake UI object, adhering to the interface expected by - L{KnownHostsFile.verifyHostKey} - - @ivar userWarnings: inputs provided to 'warn'. - - @ivar promptDeferred: last result returned from 'prompt'. - - @ivar promptText: the last input provided to 'prompt'. - """ - - def __init__(self): - self.userWarnings = [] - self.promptDeferred = None - self.promptText = None - - - def prompt(self, text): - """ - Issue the user an interactive prompt, which they can accept or deny. - """ - self.promptText = text - self.promptDeferred = Deferred() - return self.promptDeferred - - - def warn(self, text): - """ - Issue a non-interactive warning to the user. - """ - self.userWarnings.append(text) - - - -class FakeObject(object): - """ - A fake object that can have some attributes. Used to fake - L{SSHClientTransport} and L{SSHClientFactory}. - """ - - -class DefaultAPITests(TestCase): - """ - The API in L{twisted.conch.client.default.verifyHostKey} is the integration - point between the code in the rest of conch and L{KnownHostsFile}. - """ - - def patchedOpen(self, fname, mode): - """ - The patched version of 'open'; this returns a L{FakeFile} that the - instantiated L{ConsoleUI} can use. - """ - self.assertEqual(fname, "/dev/tty") - self.assertEqual(mode, "r+b") - return self.fakeFile - - - def setUp(self): - """ - Patch 'open' in verifyHostKey. - """ - self.fakeFile = FakeFile() - self.patch(default, "_open", self.patchedOpen) - self.hostsOption = self.mktemp() - knownHostsFile = KnownHostsFile(FilePath(self.hostsOption)) - knownHostsFile.addHostKey("exists.example.com", - Key.fromString(sampleKey)) - knownHostsFile.addHostKey("4.3.2.1", Key.fromString(sampleKey)) - knownHostsFile.save() - self.fakeTransport = FakeObject() - self.fakeTransport.factory = FakeObject() - self.options = self.fakeTransport.factory.options = { - 'host': "exists.example.com", - 'known-hosts': self.hostsOption - } - - - def test_verifyOKKey(self): - """ - L{default.verifyHostKey} should return a L{Deferred} which fires with - C{1} when passed a host, IP, and key which already match the - known_hosts file it is supposed to check. - """ - l = [] - default.verifyHostKey(self.fakeTransport, "4.3.2.1", sampleKey, - "I don't care.").addCallback(l.append) - self.assertEqual([1], l) - - - def replaceHome(self, tempHome): - """ - Replace the HOME environment variable until the end of the current - test, with the given new home-directory, so that L{os.path.expanduser} - will yield controllable, predictable results. - - @param tempHome: the pathname to replace the HOME variable with. - - @type tempHome: L{str} - """ - oldHome = os.environ.get('HOME') - def cleanupHome(): - if oldHome is None: - del os.environ['HOME'] - else: - os.environ['HOME'] = oldHome - self.addCleanup(cleanupHome) - os.environ['HOME'] = tempHome - - - def test_noKnownHostsOption(self): - """ - L{default.verifyHostKey} should find your known_hosts file in - ~/.ssh/known_hosts if you don't specify one explicitly on the command - line. - """ - l = [] - tmpdir = self.mktemp() - oldHostsOption = self.hostsOption - hostsNonOption = FilePath(tmpdir).child(".ssh").child("known_hosts") - hostsNonOption.parent().makedirs() - FilePath(oldHostsOption).moveTo(hostsNonOption) - self.replaceHome(tmpdir) - self.options['known-hosts'] = None - default.verifyHostKey(self.fakeTransport, "4.3.2.1", sampleKey, - "I don't care.").addCallback(l.append) - self.assertEqual([1], l) - - - def test_verifyHostButNotIP(self): - """ - L{default.verifyHostKey} should return a L{Deferred} which fires with - C{1} when passed a host which matches with an IP is not present in its - known_hosts file, and should also warn the user that it has added the - IP address. - """ - l = [] - default.verifyHostKey(self.fakeTransport, "8.7.6.5", sampleKey, - "Fingerprint not required.").addCallback(l.append) - self.assertEqual( - ["Warning: Permanently added the RSA host key for IP address " - "'8.7.6.5' to the list of known hosts."], - self.fakeFile.outchunks) - self.assertEqual([1], l) - knownHostsFile = KnownHostsFile.fromPath(FilePath(self.hostsOption)) - self.assertEqual(True, knownHostsFile.hasHostKey("8.7.6.5", - Key.fromString(sampleKey))) - - - def test_verifyQuestion(self): - """ - L{default.verifyHostKey} should return a L{Default} which fires with - C{0} when passed a unknown host that the user refuses to acknowledge. - """ - self.fakeTransport.factory.options['host'] = 'fake.example.com' - self.fakeFile.inlines.append("no") - d = default.verifyHostKey( - self.fakeTransport, "9.8.7.6", otherSampleKey, "No fingerprint!") - self.assertEqual( - ["The authenticity of host 'fake.example.com (9.8.7.6)' " - "can't be established.\n" - "RSA key fingerprint is " - "57:a1:c2:a1:07:a0:2b:f4:ce:b5:e5:b7:ae:cc:e1:99.\n" - "Are you sure you want to continue connecting (yes/no)? "], - self.fakeFile.outchunks) - return self.assertFailure(d, UserRejectedKey) - - - def test_verifyBadKey(self): - """ - L{default.verifyHostKey} should return a L{Deferred} which fails with - L{HostKeyChanged} if the host key is incorrect. - """ - d = default.verifyHostKey( - self.fakeTransport, "4.3.2.1", otherSampleKey, - "Again, not required.") - return self.assertFailure(d, HostKeyChanged) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py deleted file mode 100755 index 09dd52c2..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_manhole.py +++ /dev/null @@ -1,372 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_manhole -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.manhole}. -""" - -import traceback - -from twisted.trial import unittest -from twisted.internet import error, defer -from twisted.test.proto_helpers import StringTransport -from twisted.conch.test.test_recvline import _TelnetMixin, _SSHMixin, _StdioMixin, stdio, ssh -from twisted.conch import manhole -from twisted.conch.insults import insults - - -def determineDefaultFunctionName(): - """ - Return the string used by Python as the name for code objects which are - compiled from interactive input or at the top-level of modules. - """ - try: - 1 // 0 - except: - # The last frame is this function. The second to last frame is this - # function's caller, which is module-scope, which is what we want, - # so -2. - return traceback.extract_stack()[-2][2] -defaultFunctionName = determineDefaultFunctionName() - - - -class ManholeInterpreterTests(unittest.TestCase): - """ - Tests for L{manhole.ManholeInterpreter}. - """ - def test_resetBuffer(self): - """ - L{ManholeInterpreter.resetBuffer} should empty the input buffer. - """ - interpreter = manhole.ManholeInterpreter(None) - interpreter.buffer.extend(["1", "2"]) - interpreter.resetBuffer() - self.assertFalse(interpreter.buffer) - - - -class ManholeProtocolTests(unittest.TestCase): - """ - Tests for L{manhole.Manhole}. - """ - def test_interruptResetsInterpreterBuffer(self): - """ - L{manhole.Manhole.handle_INT} should cause the interpreter input buffer - to be reset. - """ - transport = StringTransport() - terminal = insults.ServerProtocol(manhole.Manhole) - terminal.makeConnection(transport) - protocol = terminal.terminalProtocol - interpreter = protocol.interpreter - interpreter.buffer.extend(["1", "2"]) - protocol.handle_INT() - self.assertFalse(interpreter.buffer) - - - -class WriterTestCase(unittest.TestCase): - def testInteger(self): - manhole.lastColorizedLine("1") - - - def testDoubleQuoteString(self): - manhole.lastColorizedLine('"1"') - - - def testSingleQuoteString(self): - manhole.lastColorizedLine("'1'") - - - def testTripleSingleQuotedString(self): - manhole.lastColorizedLine("'''1'''") - - - def testTripleDoubleQuotedString(self): - manhole.lastColorizedLine('"""1"""') - - - def testFunctionDefinition(self): - manhole.lastColorizedLine("def foo():") - - - def testClassDefinition(self): - manhole.lastColorizedLine("class foo:") - - -class ManholeLoopbackMixin: - serverProtocol = manhole.ColoredManhole - - def wfd(self, d): - return defer.waitForDeferred(d) - - def testSimpleExpression(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "1 + 1\n" - "done") - - def finished(ign): - self._assertBuffer( - [">>> 1 + 1", - "2", - ">>> done"]) - - return done.addCallback(finished) - - def testTripleQuoteLineContinuation(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "'''\n'''\n" - "done") - - def finished(ign): - self._assertBuffer( - [">>> '''", - "... '''", - "'\\n'", - ">>> done"]) - - return done.addCallback(finished) - - def testFunctionDefinition(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "def foo(bar):\n" - "\tprint bar\n\n" - "foo(42)\n" - "done") - - def finished(ign): - self._assertBuffer( - [">>> def foo(bar):", - "... print bar", - "... ", - ">>> foo(42)", - "42", - ">>> done"]) - - return done.addCallback(finished) - - def testClassDefinition(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "class Foo:\n" - "\tdef bar(self):\n" - "\t\tprint 'Hello, world!'\n\n" - "Foo().bar()\n" - "done") - - def finished(ign): - self._assertBuffer( - [">>> class Foo:", - "... def bar(self):", - "... print 'Hello, world!'", - "... ", - ">>> Foo().bar()", - "Hello, world!", - ">>> done"]) - - return done.addCallback(finished) - - def testException(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "raise Exception('foo bar baz')\n" - "done") - - def finished(ign): - self._assertBuffer( - [">>> raise Exception('foo bar baz')", - "Traceback (most recent call last):", - ' File "<console>", line 1, in ' + defaultFunctionName, - "Exception: foo bar baz", - ">>> done"]) - - return done.addCallback(finished) - - def testControlC(self): - done = self.recvlineClient.expect("done") - - self._testwrite( - "cancelled line" + manhole.CTRL_C + - "done") - - def finished(ign): - self._assertBuffer( - [">>> cancelled line", - "KeyboardInterrupt", - ">>> done"]) - - return done.addCallback(finished) - - - def test_interruptDuringContinuation(self): - """ - Sending ^C to Manhole while in a state where more input is required to - complete a statement should discard the entire ongoing statement and - reset the input prompt to the non-continuation prompt. - """ - continuing = self.recvlineClient.expect("things") - - self._testwrite("(\nthings") - - def gotContinuation(ignored): - self._assertBuffer( - [">>> (", - "... things"]) - interrupted = self.recvlineClient.expect(">>> ") - self._testwrite(manhole.CTRL_C) - return interrupted - continuing.addCallback(gotContinuation) - - def gotInterruption(ignored): - self._assertBuffer( - [">>> (", - "... things", - "KeyboardInterrupt", - ">>> "]) - continuing.addCallback(gotInterruption) - return continuing - - - def testControlBackslash(self): - self._testwrite("cancelled line") - partialLine = self.recvlineClient.expect("cancelled line") - - def gotPartialLine(ign): - self._assertBuffer( - [">>> cancelled line"]) - self._testwrite(manhole.CTRL_BACKSLASH) - - d = self.recvlineClient.onDisconnection - return self.assertFailure(d, error.ConnectionDone) - - def gotClearedLine(ign): - self._assertBuffer( - [""]) - - return partialLine.addCallback(gotPartialLine).addCallback(gotClearedLine) - - def testControlD(self): - self._testwrite("1 + 1") - helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1")) - yield helloWorld - helloWorld.getResult() - self._assertBuffer([">>> 1 + 1"]) - - self._testwrite(manhole.CTRL_D + " + 1") - cleared = self.wfd(self.recvlineClient.expect(r"\+ 1")) - yield cleared - cleared.getResult() - self._assertBuffer([">>> 1 + 1 + 1"]) - - self._testwrite("\n") - printed = self.wfd(self.recvlineClient.expect("3\n>>> ")) - yield printed - printed.getResult() - - self._testwrite(manhole.CTRL_D) - d = self.recvlineClient.onDisconnection - disconnected = self.wfd(self.assertFailure(d, error.ConnectionDone)) - yield disconnected - disconnected.getResult() - testControlD = defer.deferredGenerator(testControlD) - - - def testControlL(self): - """ - CTRL+L is generally used as a redraw-screen command in terminal - applications. Manhole doesn't currently respect this usage of it, - but it should at least do something reasonable in response to this - event (rather than, say, eating your face). - """ - # Start off with a newline so that when we clear the display we can - # tell by looking for the missing first empty prompt line. - self._testwrite("\n1 + 1") - helloWorld = self.wfd(self.recvlineClient.expect(r"\+ 1")) - yield helloWorld - helloWorld.getResult() - self._assertBuffer([">>> ", ">>> 1 + 1"]) - - self._testwrite(manhole.CTRL_L + " + 1") - redrew = self.wfd(self.recvlineClient.expect(r"1 \+ 1 \+ 1")) - yield redrew - redrew.getResult() - self._assertBuffer([">>> 1 + 1 + 1"]) - testControlL = defer.deferredGenerator(testControlL) - - - def test_controlA(self): - """ - CTRL-A can be used as HOME - returning cursor to beginning of - current line buffer. - """ - self._testwrite('rint "hello"' + '\x01' + 'p') - d = self.recvlineClient.expect('print "hello"') - def cb(ignore): - self._assertBuffer(['>>> print "hello"']) - return d.addCallback(cb) - - - def test_controlE(self): - """ - CTRL-E can be used as END - setting cursor to end of current - line buffer. - """ - self._testwrite('rint "hello' + '\x01' + 'p' + '\x05' + '"') - d = self.recvlineClient.expect('print "hello"') - def cb(ignore): - self._assertBuffer(['>>> print "hello"']) - return d.addCallback(cb) - - - def testDeferred(self): - self._testwrite( - "from twisted.internet import defer, reactor\n" - "d = defer.Deferred()\n" - "d\n") - - deferred = self.wfd(self.recvlineClient.expect("<Deferred #0>")) - yield deferred - deferred.getResult() - - self._testwrite( - "c = reactor.callLater(0.1, d.callback, 'Hi!')\n") - delayed = self.wfd(self.recvlineClient.expect(">>> ")) - yield delayed - delayed.getResult() - - called = self.wfd(self.recvlineClient.expect("Deferred #0 called back: 'Hi!'\n>>> ")) - yield called - called.getResult() - self._assertBuffer( - [">>> from twisted.internet import defer, reactor", - ">>> d = defer.Deferred()", - ">>> d", - "<Deferred #0>", - ">>> c = reactor.callLater(0.1, d.callback, 'Hi!')", - "Deferred #0 called back: 'Hi!'", - ">>> "]) - - testDeferred = defer.deferredGenerator(testDeferred) - -class ManholeLoopbackTelnet(_TelnetMixin, unittest.TestCase, ManholeLoopbackMixin): - pass - -class ManholeLoopbackSSH(_SSHMixin, unittest.TestCase, ManholeLoopbackMixin): - if ssh is None: - skip = "Crypto requirements missing, can't run manhole tests over ssh" - -class ManholeLoopbackStdio(_StdioMixin, unittest.TestCase, ManholeLoopbackMixin): - if stdio is None: - skip = "Terminal requirements missing, can't run manhole tests over stdio" - else: - serverProtocol = stdio.ConsoleManhole diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py deleted file mode 100755 index 74d60eaa..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_mixin.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- twisted.conch.test.test_mixin -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -import time - -from twisted.internet import reactor, protocol - -from twisted.trial import unittest -from twisted.test.proto_helpers import StringTransport - -from twisted.conch import mixin - - -class TestBufferingProto(mixin.BufferingMixin): - scheduled = False - rescheduled = 0 - def schedule(self): - self.scheduled = True - return object() - - def reschedule(self, token): - self.rescheduled += 1 - - - -class BufferingTest(unittest.TestCase): - def testBuffering(self): - p = TestBufferingProto() - t = p.transport = StringTransport() - - self.failIf(p.scheduled) - - L = ['foo', 'bar', 'baz', 'quux'] - - p.write('foo') - self.failUnless(p.scheduled) - self.failIf(p.rescheduled) - - for s in L: - n = p.rescheduled - p.write(s) - self.assertEqual(p.rescheduled, n + 1) - self.assertEqual(t.value(), '') - - p.flush() - self.assertEqual(t.value(), 'foo' + ''.join(L)) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py deleted file mode 100755 index 8b4e1a6f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_openssh_compat.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.openssh_compat}. -""" - -import os - -from twisted.trial.unittest import TestCase -from twisted.python.filepath import FilePath -from twisted.python.compat import set - -try: - import Crypto.Cipher.DES3 - import pyasn1 -except ImportError: - OpenSSHFactory = None -else: - from twisted.conch.openssh_compat.factory import OpenSSHFactory - -from twisted.conch.test import keydata -from twisted.test.test_process import MockOS - - -class OpenSSHFactoryTests(TestCase): - """ - Tests for L{OpenSSHFactory}. - """ - if getattr(os, "geteuid", None) is None: - skip = "geteuid/seteuid not available" - elif OpenSSHFactory is None: - skip = "Cannot run without PyCrypto or PyASN1" - - def setUp(self): - self.factory = OpenSSHFactory() - self.keysDir = FilePath(self.mktemp()) - self.keysDir.makedirs() - self.factory.dataRoot = self.keysDir.path - - self.keysDir.child("ssh_host_foo").setContent("foo") - self.keysDir.child("bar_key").setContent("foo") - self.keysDir.child("ssh_host_one_key").setContent( - keydata.privateRSA_openssh) - self.keysDir.child("ssh_host_two_key").setContent( - keydata.privateDSA_openssh) - self.keysDir.child("ssh_host_three_key").setContent( - "not a key content") - - self.keysDir.child("ssh_host_one_key.pub").setContent( - keydata.publicRSA_openssh) - - self.mockos = MockOS() - self.patch(os, "seteuid", self.mockos.seteuid) - self.patch(os, "setegid", self.mockos.setegid) - - - def test_getPublicKeys(self): - """ - L{OpenSSHFactory.getPublicKeys} should return the available public keys - in the data directory - """ - keys = self.factory.getPublicKeys() - self.assertEqual(len(keys), 1) - keyTypes = keys.keys() - self.assertEqual(keyTypes, ['ssh-rsa']) - - - def test_getPrivateKeys(self): - """ - L{OpenSSHFactory.getPrivateKeys} should return the available private - keys in the data directory. - """ - keys = self.factory.getPrivateKeys() - self.assertEqual(len(keys), 2) - keyTypes = keys.keys() - self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss'])) - self.assertEqual(self.mockos.seteuidCalls, []) - self.assertEqual(self.mockos.setegidCalls, []) - - - def test_getPrivateKeysAsRoot(self): - """ - L{OpenSSHFactory.getPrivateKeys} should switch to root if the keys - aren't readable by the current user. - """ - keyFile = self.keysDir.child("ssh_host_two_key") - # Fake permission error by changing the mode - keyFile.chmod(0000) - self.addCleanup(keyFile.chmod, 0777) - # And restore the right mode when seteuid is called - savedSeteuid = os.seteuid - def seteuid(euid): - keyFile.chmod(0777) - return savedSeteuid(euid) - self.patch(os, "seteuid", seteuid) - keys = self.factory.getPrivateKeys() - self.assertEqual(len(keys), 2) - keyTypes = keys.keys() - self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss'])) - self.assertEqual(self.mockos.seteuidCalls, [0, os.geteuid()]) - self.assertEqual(self.mockos.setegidCalls, [0, os.getegid()]) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py deleted file mode 100755 index 3d535646..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_recvline.py +++ /dev/null @@ -1,706 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_recvline -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.recvline} and fixtures for testing related -functionality. -""" - -import sys, os - -from twisted.conch.insults import insults -from twisted.conch import recvline - -from twisted.python import reflect, components -from twisted.internet import defer, error -from twisted.trial import unittest -from twisted.cred import portal -from twisted.test.proto_helpers import StringTransport - -class Arrows(unittest.TestCase): - def setUp(self): - self.underlyingTransport = StringTransport() - self.pt = insults.ServerProtocol() - self.p = recvline.HistoricRecvLine() - self.pt.protocolFactory = lambda: self.p - self.pt.factory = self - self.pt.makeConnection(self.underlyingTransport) - # self.p.makeConnection(self.pt) - - def test_printableCharacters(self): - """ - When L{HistoricRecvLine} receives a printable character, - it adds it to the current line buffer. - """ - self.p.keystrokeReceived('x', None) - self.p.keystrokeReceived('y', None) - self.p.keystrokeReceived('z', None) - - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - def test_horizontalArrows(self): - """ - When L{HistoricRecvLine} receives an LEFT_ARROW or - RIGHT_ARROW keystroke it moves the cursor left or right - in the current line buffer, respectively. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - for ch in 'xyz': - kR(ch) - - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.RIGHT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.LEFT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('xy', 'z')) - - kR(self.pt.LEFT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('x', 'yz')) - - kR(self.pt.LEFT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('', 'xyz')) - - kR(self.pt.LEFT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('', 'xyz')) - - kR(self.pt.RIGHT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('x', 'yz')) - - kR(self.pt.RIGHT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('xy', 'z')) - - kR(self.pt.RIGHT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.RIGHT_ARROW) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - def test_newline(self): - """ - When {HistoricRecvLine} receives a newline, it adds the current - line buffer to the end of its history buffer. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz\nabc\n123\n': - kR(ch) - - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc', '123'), ())) - - kR('c') - kR('b') - kR('a') - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc', '123'), ())) - - kR('\n') - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc', '123', 'cba'), ())) - - def test_verticalArrows(self): - """ - When L{HistoricRecvLine} receives UP_ARROW or DOWN_ARROW - keystrokes it move the current index in the current history - buffer up or down, and resets the current line buffer to the - previous or next line in history, respectively for each. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz\nabc\n123\n': - kR(ch) - - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc', '123'), ())) - self.assertEqual(self.p.currentLineBuffer(), ('', '')) - - kR(self.pt.UP_ARROW) - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc'), ('123',))) - self.assertEqual(self.p.currentLineBuffer(), ('123', '')) - - kR(self.pt.UP_ARROW) - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz',), ('abc', '123'))) - self.assertEqual(self.p.currentLineBuffer(), ('abc', '')) - - kR(self.pt.UP_ARROW) - self.assertEqual(self.p.currentHistoryBuffer(), - ((), ('xyz', 'abc', '123'))) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.UP_ARROW) - self.assertEqual(self.p.currentHistoryBuffer(), - ((), ('xyz', 'abc', '123'))) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - for i in range(4): - kR(self.pt.DOWN_ARROW) - self.assertEqual(self.p.currentHistoryBuffer(), - (('xyz', 'abc', '123'), ())) - - def test_home(self): - """ - When L{HistoricRecvLine} receives a HOME keystroke it moves the - cursor to the beginning of the current line buffer. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'hello, world': - kR(ch) - self.assertEqual(self.p.currentLineBuffer(), ('hello, world', '')) - - kR(self.pt.HOME) - self.assertEqual(self.p.currentLineBuffer(), ('', 'hello, world')) - - def test_end(self): - """ - When L{HistoricRecvLine} receives a END keystroke it moves the cursor - to the end of the current line buffer. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'hello, world': - kR(ch) - self.assertEqual(self.p.currentLineBuffer(), ('hello, world', '')) - - kR(self.pt.HOME) - kR(self.pt.END) - self.assertEqual(self.p.currentLineBuffer(), ('hello, world', '')) - - def test_backspace(self): - """ - When L{HistoricRecvLine} receives a BACKSPACE keystroke it deletes - the character immediately before the cursor. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz': - kR(ch) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.BACKSPACE) - self.assertEqual(self.p.currentLineBuffer(), ('xy', '')) - - kR(self.pt.LEFT_ARROW) - kR(self.pt.BACKSPACE) - self.assertEqual(self.p.currentLineBuffer(), ('', 'y')) - - kR(self.pt.BACKSPACE) - self.assertEqual(self.p.currentLineBuffer(), ('', 'y')) - - def test_delete(self): - """ - When L{HistoricRecvLine} receives a DELETE keystroke, it - delets the character immediately after the cursor. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz': - kR(ch) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.DELETE) - self.assertEqual(self.p.currentLineBuffer(), ('xyz', '')) - - kR(self.pt.LEFT_ARROW) - kR(self.pt.DELETE) - self.assertEqual(self.p.currentLineBuffer(), ('xy', '')) - - kR(self.pt.LEFT_ARROW) - kR(self.pt.DELETE) - self.assertEqual(self.p.currentLineBuffer(), ('x', '')) - - kR(self.pt.LEFT_ARROW) - kR(self.pt.DELETE) - self.assertEqual(self.p.currentLineBuffer(), ('', '')) - - kR(self.pt.DELETE) - self.assertEqual(self.p.currentLineBuffer(), ('', '')) - - def test_insert(self): - """ - When not in INSERT mode, L{HistoricRecvLine} inserts the typed - character at the cursor before the next character. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz': - kR(ch) - - kR(self.pt.LEFT_ARROW) - kR('A') - self.assertEqual(self.p.currentLineBuffer(), ('xyA', 'z')) - - kR(self.pt.LEFT_ARROW) - kR('B') - self.assertEqual(self.p.currentLineBuffer(), ('xyB', 'Az')) - - def test_typeover(self): - """ - When in INSERT mode and upon receiving a keystroke with a printable - character, L{HistoricRecvLine} replaces the character at - the cursor with the typed character rather than inserting before. - Ah, the ironies of INSERT mode. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - - for ch in 'xyz': - kR(ch) - - kR(self.pt.INSERT) - - kR(self.pt.LEFT_ARROW) - kR('A') - self.assertEqual(self.p.currentLineBuffer(), ('xyA', '')) - - kR(self.pt.LEFT_ARROW) - kR('B') - self.assertEqual(self.p.currentLineBuffer(), ('xyB', '')) - - - def test_unprintableCharacters(self): - """ - When L{HistoricRecvLine} receives a keystroke for an unprintable - function key with no assigned behavior, the line buffer is unmodified. - """ - kR = lambda ch: self.p.keystrokeReceived(ch, None) - pt = self.pt - - for ch in (pt.F1, pt.F2, pt.F3, pt.F4, pt.F5, pt.F6, pt.F7, pt.F8, - pt.F9, pt.F10, pt.F11, pt.F12, pt.PGUP, pt.PGDN): - kR(ch) - self.assertEqual(self.p.currentLineBuffer(), ('', '')) - - -from twisted.conch import telnet -from twisted.conch.insults import helper -from twisted.protocols import loopback - -class EchoServer(recvline.HistoricRecvLine): - def lineReceived(self, line): - self.terminal.write(line + '\n' + self.ps[self.pn]) - -# An insults API for this would be nice. -left = "\x1b[D" -right = "\x1b[C" -up = "\x1b[A" -down = "\x1b[B" -insert = "\x1b[2~" -home = "\x1b[1~" -delete = "\x1b[3~" -end = "\x1b[4~" -backspace = "\x7f" - -from twisted.cred import checkers - -try: - from twisted.conch.ssh import userauth, transport, channel, connection, session - from twisted.conch.manhole_ssh import TerminalUser, TerminalSession, TerminalRealm, TerminalSessionTransport, ConchFactory -except ImportError: - ssh = False -else: - ssh = True - class SessionChannel(channel.SSHChannel): - name = 'session' - - def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, width, height, *a, **kw): - channel.SSHChannel.__init__(self, *a, **kw) - - self.protocolFactory = protocolFactory - self.protocolArgs = protocolArgs - self.protocolKwArgs = protocolKwArgs - - self.width = width - self.height = height - - def channelOpen(self, data): - term = session.packRequest_pty_req("vt102", (self.height, self.width, 0, 0), '') - self.conn.sendRequest(self, 'pty-req', term) - self.conn.sendRequest(self, 'shell', '') - - self._protocolInstance = self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs) - self._protocolInstance.factory = self - self._protocolInstance.makeConnection(self) - - def closed(self): - self._protocolInstance.connectionLost(error.ConnectionDone()) - - def dataReceived(self, data): - self._protocolInstance.dataReceived(data) - - class TestConnection(connection.SSHConnection): - def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, width, height, *a, **kw): - connection.SSHConnection.__init__(self, *a, **kw) - - self.protocolFactory = protocolFactory - self.protocolArgs = protocolArgs - self.protocolKwArgs = protocolKwArgs - - self.width = width - self.height = height - - def serviceStarted(self): - self.__channel = SessionChannel(self.protocolFactory, self.protocolArgs, self.protocolKwArgs, self.width, self.height) - self.openChannel(self.__channel) - - def write(self, bytes): - return self.__channel.write(bytes) - - class TestAuth(userauth.SSHUserAuthClient): - def __init__(self, username, password, *a, **kw): - userauth.SSHUserAuthClient.__init__(self, username, *a, **kw) - self.password = password - - def getPassword(self): - return defer.succeed(self.password) - - class TestTransport(transport.SSHClientTransport): - def __init__(self, protocolFactory, protocolArgs, protocolKwArgs, username, password, width, height, *a, **kw): - # transport.SSHClientTransport.__init__(self, *a, **kw) - self.protocolFactory = protocolFactory - self.protocolArgs = protocolArgs - self.protocolKwArgs = protocolKwArgs - self.username = username - self.password = password - self.width = width - self.height = height - - def verifyHostKey(self, hostKey, fingerprint): - return defer.succeed(True) - - def connectionSecure(self): - self.__connection = TestConnection(self.protocolFactory, self.protocolArgs, self.protocolKwArgs, self.width, self.height) - self.requestService( - TestAuth(self.username, self.password, self.__connection)) - - def write(self, bytes): - return self.__connection.write(bytes) - - class TestSessionTransport(TerminalSessionTransport): - def protocolFactory(self): - return self.avatar.conn.transport.factory.serverProtocol() - - class TestSession(TerminalSession): - transportFactory = TestSessionTransport - - class TestUser(TerminalUser): - pass - - components.registerAdapter(TestSession, TestUser, session.ISession) - - -class LoopbackRelay(loopback.LoopbackRelay): - clearCall = None - - def logPrefix(self): - return "LoopbackRelay(%r)" % (self.target.__class__.__name__,) - - def write(self, bytes): - loopback.LoopbackRelay.write(self, bytes) - if self.clearCall is not None: - self.clearCall.cancel() - - from twisted.internet import reactor - self.clearCall = reactor.callLater(0, self._clearBuffer) - - def _clearBuffer(self): - self.clearCall = None - loopback.LoopbackRelay.clearBuffer(self) - - -class NotifyingExpectableBuffer(helper.ExpectableBuffer): - def __init__(self): - self.onConnection = defer.Deferred() - self.onDisconnection = defer.Deferred() - - def connectionMade(self): - helper.ExpectableBuffer.connectionMade(self) - self.onConnection.callback(self) - - def connectionLost(self, reason): - self.onDisconnection.errback(reason) - - -class _BaseMixin: - WIDTH = 80 - HEIGHT = 24 - - def _assertBuffer(self, lines): - receivedLines = str(self.recvlineClient).splitlines() - expectedLines = lines + ([''] * (self.HEIGHT - len(lines) - 1)) - self.assertEqual(len(receivedLines), len(expectedLines)) - for i in range(len(receivedLines)): - self.assertEqual( - receivedLines[i], expectedLines[i], - str(receivedLines[max(0, i-1):i+1]) + - " != " + - str(expectedLines[max(0, i-1):i+1])) - - def _trivialTest(self, input, output): - done = self.recvlineClient.expect("done") - - self._testwrite(input) - - def finished(ign): - self._assertBuffer(output) - - return done.addCallback(finished) - - -class _SSHMixin(_BaseMixin): - def setUp(self): - if not ssh: - raise unittest.SkipTest("Crypto requirements missing, can't run historic recvline tests over ssh") - - u, p = 'testuser', 'testpass' - rlm = TerminalRealm() - rlm.userFactory = TestUser - rlm.chainedProtocolFactory = lambda: insultsServer - - ptl = portal.Portal( - rlm, - [checkers.InMemoryUsernamePasswordDatabaseDontUse(**{u: p})]) - sshFactory = ConchFactory(ptl) - sshFactory.serverProtocol = self.serverProtocol - sshFactory.startFactory() - - recvlineServer = self.serverProtocol() - insultsServer = insults.ServerProtocol(lambda: recvlineServer) - sshServer = sshFactory.buildProtocol(None) - clientTransport = LoopbackRelay(sshServer) - - recvlineClient = NotifyingExpectableBuffer() - insultsClient = insults.ClientProtocol(lambda: recvlineClient) - sshClient = TestTransport(lambda: insultsClient, (), {}, u, p, self.WIDTH, self.HEIGHT) - serverTransport = LoopbackRelay(sshClient) - - sshClient.makeConnection(clientTransport) - sshServer.makeConnection(serverTransport) - - self.recvlineClient = recvlineClient - self.sshClient = sshClient - self.sshServer = sshServer - self.clientTransport = clientTransport - self.serverTransport = serverTransport - - return recvlineClient.onConnection - - def _testwrite(self, bytes): - self.sshClient.write(bytes) - -from twisted.conch.test import test_telnet - -class TestInsultsClientProtocol(insults.ClientProtocol, - test_telnet.TestProtocol): - pass - - -class TestInsultsServerProtocol(insults.ServerProtocol, - test_telnet.TestProtocol): - pass - -class _TelnetMixin(_BaseMixin): - def setUp(self): - recvlineServer = self.serverProtocol() - insultsServer = TestInsultsServerProtocol(lambda: recvlineServer) - telnetServer = telnet.TelnetTransport(lambda: insultsServer) - clientTransport = LoopbackRelay(telnetServer) - - recvlineClient = NotifyingExpectableBuffer() - insultsClient = TestInsultsClientProtocol(lambda: recvlineClient) - telnetClient = telnet.TelnetTransport(lambda: insultsClient) - serverTransport = LoopbackRelay(telnetClient) - - telnetClient.makeConnection(clientTransport) - telnetServer.makeConnection(serverTransport) - - serverTransport.clearBuffer() - clientTransport.clearBuffer() - - self.recvlineClient = recvlineClient - self.telnetClient = telnetClient - self.clientTransport = clientTransport - self.serverTransport = serverTransport - - return recvlineClient.onConnection - - def _testwrite(self, bytes): - self.telnetClient.write(bytes) - -try: - from twisted.conch import stdio -except ImportError: - stdio = None - -class _StdioMixin(_BaseMixin): - def setUp(self): - # A memory-only terminal emulator, into which the server will - # write things and make other state changes. What ends up - # here is basically what a user would have seen on their - # screen. - testTerminal = NotifyingExpectableBuffer() - - # An insults client protocol which will translate bytes - # received from the child process into keystroke commands for - # an ITerminalProtocol. - insultsClient = insults.ClientProtocol(lambda: testTerminal) - - # A process protocol which will translate stdout and stderr - # received from the child process to dataReceived calls and - # error reporting on an insults client protocol. - processClient = stdio.TerminalProcessProtocol(insultsClient) - - # Run twisted/conch/stdio.py with the name of a class - # implementing ITerminalProtocol. This class will be used to - # handle bytes we send to the child process. - exe = sys.executable - module = stdio.__file__ - if module.endswith('.pyc') or module.endswith('.pyo'): - module = module[:-1] - args = [exe, module, reflect.qual(self.serverProtocol)] - env = os.environ.copy() - env["PYTHONPATH"] = os.pathsep.join(sys.path) - - from twisted.internet import reactor - clientTransport = reactor.spawnProcess(processClient, exe, args, - env=env, usePTY=True) - - self.recvlineClient = self.testTerminal = testTerminal - self.processClient = processClient - self.clientTransport = clientTransport - - # Wait for the process protocol and test terminal to become - # connected before proceeding. The former should always - # happen first, but it doesn't hurt to be safe. - return defer.gatherResults(filter(None, [ - processClient.onConnection, - testTerminal.expect(">>> ")])) - - def tearDown(self): - # Kill the child process. We're done with it. - try: - self.clientTransport.signalProcess("KILL") - except (error.ProcessExitedAlready, OSError): - pass - def trap(failure): - failure.trap(error.ProcessTerminated) - self.assertEqual(failure.value.exitCode, None) - self.assertEqual(failure.value.status, 9) - return self.testTerminal.onDisconnection.addErrback(trap) - - def _testwrite(self, bytes): - self.clientTransport.write(bytes) - -class RecvlineLoopbackMixin: - serverProtocol = EchoServer - - def testSimple(self): - return self._trivialTest( - "first line\ndone", - [">>> first line", - "first line", - ">>> done"]) - - def testLeftArrow(self): - return self._trivialTest( - insert + 'first line' + left * 4 + "xxxx\ndone", - [">>> first xxxx", - "first xxxx", - ">>> done"]) - - def testRightArrow(self): - return self._trivialTest( - insert + 'right line' + left * 4 + right * 2 + "xx\ndone", - [">>> right lixx", - "right lixx", - ">>> done"]) - - def testBackspace(self): - return self._trivialTest( - "second line" + backspace * 4 + "xxxx\ndone", - [">>> second xxxx", - "second xxxx", - ">>> done"]) - - def testDelete(self): - return self._trivialTest( - "delete xxxx" + left * 4 + delete * 4 + "line\ndone", - [">>> delete line", - "delete line", - ">>> done"]) - - def testInsert(self): - return self._trivialTest( - "third ine" + left * 3 + "l\ndone", - [">>> third line", - "third line", - ">>> done"]) - - def testTypeover(self): - return self._trivialTest( - "fourth xine" + left * 4 + insert + "l\ndone", - [">>> fourth line", - "fourth line", - ">>> done"]) - - def testHome(self): - return self._trivialTest( - insert + "blah line" + home + "home\ndone", - [">>> home line", - "home line", - ">>> done"]) - - def testEnd(self): - return self._trivialTest( - "end " + left * 4 + end + "line\ndone", - [">>> end line", - "end line", - ">>> done"]) - -class RecvlineLoopbackTelnet(_TelnetMixin, unittest.TestCase, RecvlineLoopbackMixin): - pass - -class RecvlineLoopbackSSH(_SSHMixin, unittest.TestCase, RecvlineLoopbackMixin): - pass - -class RecvlineLoopbackStdio(_StdioMixin, unittest.TestCase, RecvlineLoopbackMixin): - if stdio is None: - skip = "Terminal requirements missing, can't run recvline tests over stdio" - - -class HistoricRecvlineLoopbackMixin: - serverProtocol = EchoServer - - def testUpArrow(self): - return self._trivialTest( - "first line\n" + up + "\ndone", - [">>> first line", - "first line", - ">>> first line", - "first line", - ">>> done"]) - - def testDownArrow(self): - return self._trivialTest( - "first line\nsecond line\n" + up * 2 + down + "\ndone", - [">>> first line", - "first line", - ">>> second line", - "second line", - ">>> second line", - "second line", - ">>> done"]) - -class HistoricRecvlineLoopbackTelnet(_TelnetMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin): - pass - -class HistoricRecvlineLoopbackSSH(_SSHMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin): - pass - -class HistoricRecvlineLoopbackStdio(_StdioMixin, unittest.TestCase, HistoricRecvlineLoopbackMixin): - if stdio is None: - skip = "Terminal requirements missing, can't run historic recvline tests over stdio" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py deleted file mode 100755 index ae90e828..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_scripts.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for the command-line interfaces to conch. -""" - -try: - import pyasn1 -except ImportError: - pyasn1Skip = "Cannot run without PyASN1" -else: - pyasn1Skip = None - -try: - import Crypto -except ImportError: - cryptoSkip = "can't run w/o PyCrypto" -else: - cryptoSkip = None - -try: - import tty -except ImportError: - ttySkip = "can't run w/o tty" -else: - ttySkip = None - -try: - import Tkinter -except ImportError: - tkskip = "can't run w/o Tkinter" -else: - try: - Tkinter.Tk().destroy() - except Tkinter.TclError, e: - tkskip = "Can't test Tkinter: " + str(e) - else: - tkskip = None - -from twisted.trial.unittest import TestCase -from twisted.scripts.test.test_scripts import ScriptTestsMixin -from twisted.python.test.test_shellcomp import ZshScriptTestMixin - - - -class ScriptTests(TestCase, ScriptTestsMixin): - """ - Tests for the Conch scripts. - """ - skip = pyasn1Skip or cryptoSkip - - - def test_conch(self): - self.scriptTest("conch/conch") - test_conch.skip = ttySkip or skip - - - def test_cftp(self): - self.scriptTest("conch/cftp") - test_cftp.skip = ttySkip or skip - - - def test_ckeygen(self): - self.scriptTest("conch/ckeygen") - - - def test_tkconch(self): - self.scriptTest("conch/tkconch") - test_tkconch.skip = tkskip or skip - - - -class ZshIntegrationTestCase(TestCase, ZshScriptTestMixin): - """ - Test that zsh completion functions are generated without error - """ - generateFor = [('conch', 'twisted.conch.scripts.conch.ClientOptions'), - ('cftp', 'twisted.conch.scripts.cftp.ClientOptions'), - ('ckeygen', 'twisted.conch.scripts.ckeygen.GeneralOptions'), - ('tkconch', 'twisted.conch.scripts.tkconch.GeneralOptions'), - ] diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py deleted file mode 100755 index 4db16298..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_session.py +++ /dev/null @@ -1,1256 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for the 'session' channel implementation in twisted.conch.ssh.session. - -See also RFC 4254. -""" - -import os, signal, sys, struct - -from zope.interface import implements - -from twisted.internet.address import IPv4Address -from twisted.internet.error import ProcessTerminated, ProcessDone -from twisted.python.failure import Failure -from twisted.conch.ssh import common, session, connection -from twisted.internet import defer, protocol, error -from twisted.python import components, failure -from twisted.trial import unittest - - - -class SubsystemOnlyAvatar(object): - """ - A stub class representing an avatar that is only useful for - getting a subsystem. - """ - - - def lookupSubsystem(self, name, data): - """ - If the other side requests the 'subsystem' subsystem, allow it by - returning a MockProtocol to implement it. Otherwise, return - None which is interpreted by SSHSession as a failure. - """ - if name == 'subsystem': - return MockProtocol() - - - -class StubAvatar: - """ - A stub class representing the avatar representing the authenticated user. - It implements the I{ISession} interface. - """ - - - def lookupSubsystem(self, name, data): - """ - If the user requests the TestSubsystem subsystem, connect them to a - MockProtocol. If they request neither, then None is returned which is - interpreted by SSHSession as a failure. - """ - if name == 'TestSubsystem': - self.subsystem = MockProtocol() - self.subsystem.packetData = data - return self.subsystem - - - -class StubSessionForStubAvatar(object): - """ - A stub ISession implementation for our StubAvatar. The instance - variables generally keep track of method invocations so that we can test - that the methods were called. - - @ivar avatar: the L{StubAvatar} we are adapting. - @ivar ptyRequest: if present, the terminal, window size, and modes passed - to the getPty method. - @ivar windowChange: if present, the window size passed to the - windowChangned method. - @ivar shellProtocol: if present, the L{SSHSessionProcessProtocol} passed - to the openShell method. - @ivar shellTransport: if present, the L{EchoTransport} connected to - shellProtocol. - @ivar execProtocol: if present, the L{SSHSessionProcessProtocol} passed - to the execCommand method. - @ivar execTransport: if present, the L{EchoTransport} connected to - execProtocol. - @ivar execCommandLine: if present, the command line passed to the - execCommand method. - @ivar gotEOF: if present, an EOF message was received. - @ivar gotClosed: if present, a closed message was received. - """ - - - implements(session.ISession) - - - def __init__(self, avatar): - """ - Store the avatar we're adapting. - """ - self.avatar = avatar - self.shellProtocol = None - - - def getPty(self, terminal, window, modes): - """ - If the terminal is 'bad', fail. Otherwise, store the information in - the ptyRequest variable. - """ - if terminal != 'bad': - self.ptyRequest = (terminal, window, modes) - else: - raise RuntimeError('not getting a pty') - - - def windowChanged(self, window): - """ - If all the window sizes are 0, fail. Otherwise, store the size in the - windowChange variable. - """ - if window == (0, 0, 0, 0): - raise RuntimeError('not changing the window size') - else: - self.windowChange = window - - - def openShell(self, pp): - """ - If we have gotten a shell request before, fail. Otherwise, store the - process protocol in the shellProtocol variable, connect it to the - EchoTransport and store that as shellTransport. - """ - if self.shellProtocol is not None: - raise RuntimeError('not getting a shell this time') - else: - self.shellProtocol = pp - self.shellTransport = EchoTransport(pp) - - - def execCommand(self, pp, command): - """ - If the command is 'true', store the command, the process protocol, and - the transport we connect to the process protocol. Otherwise, just - store the command and raise an error. - """ - self.execCommandLine = command - if command == 'success': - self.execProtocol = pp - elif command[:6] == 'repeat': - self.execProtocol = pp - self.execTransport = EchoTransport(pp) - pp.outReceived(command[7:]) - else: - raise RuntimeError('not getting a command') - - - def eofReceived(self): - """ - Note that EOF has been received. - """ - self.gotEOF = True - - - def closed(self): - """ - Note that close has been received. - """ - self.gotClosed = True - - - -components.registerAdapter(StubSessionForStubAvatar, StubAvatar, - session.ISession) - - - - -class MockProcessProtocol(protocol.ProcessProtocol): - """ - A mock ProcessProtocol which echoes back data sent to it and - appends a tilde. The tilde is appended so the tests can verify that - we received and processed the data. - - @ivar packetData: C{str} of data to be sent when the connection is made. - @ivar data: a C{str} of data received. - @ivar err: a C{str} of error data received. - @ivar inConnectionOpen: True if the input side is open. - @ivar outConnectionOpen: True if the output side is open. - @ivar errConnectionOpen: True if the error side is open. - @ivar ended: False if the protocol has not ended, a C{Failure} if the - process has ended. - """ - packetData = '' - - - def connectionMade(self): - """ - Set up variables. - """ - self.data = '' - self.err = '' - self.inConnectionOpen = True - self.outConnectionOpen = True - self.errConnectionOpen = True - self.ended = False - if self.packetData: - self.outReceived(self.packetData) - - - def outReceived(self, data): - """ - Data was received. Store it and echo it back with a tilde. - """ - self.data += data - if self.transport is not None: - self.transport.write(data + '~') - - - def errReceived(self, data): - """ - Error data was received. Store it and echo it back backwards. - """ - self.err += data - self.transport.write(data[::-1]) - - - def inConnectionLost(self): - """ - Close the input side. - """ - self.inConnectionOpen = False - - - def outConnectionLost(self): - """ - Close the output side. - """ - self.outConnectionOpen = False - - - def errConnectionLost(self): - """ - Close the error side. - """ - self.errConnectionOpen = False - - - def processEnded(self, reason): - """ - End the process and store the reason. - """ - self.ended = reason - - - -class EchoTransport: - """ - A transport for a ProcessProtocol which echos data that is sent to it with - a Window newline (CR LF) appended to it. If a null byte is in the data, - disconnect. When we are asked to disconnect, disconnect the - C{ProcessProtocol} with a 0 exit code. - - @ivar proto: the C{ProcessProtocol} connected to us. - @ivar data: a C{str} of data written to us. - """ - - - def __init__(self, processProtocol): - """ - Initialize our instance variables. - - @param processProtocol: a C{ProcessProtocol} to connect to ourself. - """ - self.proto = processProtocol - self.closed = False - self.data = '' - processProtocol.makeConnection(self) - - - def write(self, data): - """ - We got some data. Give it back to our C{ProcessProtocol} with - a newline attached. Disconnect if there's a null byte. - """ - self.data += data - self.proto.outReceived(data) - self.proto.outReceived('\r\n') - if '\x00' in data: # mimic 'exit' for the shell test - self.loseConnection() - - - def loseConnection(self): - """ - If we're asked to disconnect (and we haven't already) shut down - the C{ProcessProtocol} with a 0 exit code. - """ - if self.closed: - return - self.closed = 1 - self.proto.inConnectionLost() - self.proto.outConnectionLost() - self.proto.errConnectionLost() - self.proto.processEnded(failure.Failure( - error.ProcessTerminated(0, None, None))) - - - -class MockProtocol(protocol.Protocol): - """ - A sample Protocol which stores the data passed to it. - - @ivar packetData: a C{str} of data to be sent when the connection is made. - @ivar data: a C{str} of the data passed to us. - @ivar open: True if the channel is open. - @ivar reason: if not None, the reason the protocol was closed. - """ - packetData = '' - - - def connectionMade(self): - """ - Set up the instance variables. If we have any packetData, send it - along. - """ - - self.data = '' - self.open = True - self.reason = None - if self.packetData: - self.dataReceived(self.packetData) - - - def dataReceived(self, data): - """ - Store the received data and write it back with a tilde appended. - The tilde is appended so that the tests can verify that we processed - the data. - """ - self.data += data - if self.transport is not None: - self.transport.write(data + '~') - - - def connectionLost(self, reason): - """ - Close the protocol and store the reason. - """ - self.open = False - self.reason = reason - - - -class StubConnection(object): - """ - A stub for twisted.conch.ssh.connection.SSHConnection. Record the data - that channels send, and when they try to close the connection. - - @ivar data: a C{dict} mapping C{SSHChannel}s to a C{list} of C{str} of data - they sent. - @ivar extData: a C{dict} mapping L{SSHChannel}s to a C{list} of C{tuple} of - (C{int}, C{str}) of extended data they sent. - @ivar requests: a C{dict} mapping L{SSHChannel}s to a C{list} of C{tuple} - of (C{str}, C{str}) of channel requests they made. - @ivar eofs: a C{dict} mapping L{SSHChannel}s to C{true} if they have sent - an EOF. - @ivar closes: a C{dict} mapping L{SSHChannel}s to C{true} if they have sent - a close. - """ - - - def __init__(self, transport=None): - """ - Initialize our instance variables. - """ - self.data = {} - self.extData = {} - self.requests = {} - self.eofs = {} - self.closes = {} - self.transport = transport - - - def logPrefix(self): - """ - Return our logging prefix. - """ - return "MockConnection" - - - def sendData(self, channel, data): - """ - Record the sent data. - """ - self.data.setdefault(channel, []).append(data) - - - def sendExtendedData(self, channel, type, data): - """ - Record the sent extended data. - """ - self.extData.setdefault(channel, []).append((type, data)) - - - def sendRequest(self, channel, request, data, wantReply=False): - """ - Record the sent channel request. - """ - self.requests.setdefault(channel, []).append((request, data, - wantReply)) - if wantReply: - return defer.succeed(None) - - - def sendEOF(self, channel): - """ - Record the sent EOF. - """ - self.eofs[channel] = True - - - def sendClose(self, channel): - """ - Record the sent close. - """ - self.closes[channel] = True - - - -class StubTransport: - """ - A stub transport which records the data written. - - @ivar buf: the data sent to the transport. - @type buf: C{str} - - @ivar close: flags indicating if the transport has been closed. - @type close: C{bool} - """ - - buf = '' - close = False - - - def getPeer(self): - """ - Return an arbitrary L{IAddress}. - """ - return IPv4Address('TCP', 'remotehost', 8888) - - - def getHost(self): - """ - Return an arbitrary L{IAddress}. - """ - return IPv4Address('TCP', 'localhost', 9999) - - - def write(self, data): - """ - Record data in the buffer. - """ - self.buf += data - - - def loseConnection(self): - """ - Note that the connection was closed. - """ - self.close = True - - -class StubTransportWithWriteErr(StubTransport): - """ - A version of StubTransport which records the error data sent to it. - - @ivar err: the extended data sent to the transport. - @type err: C{str} - """ - - err = '' - - - def writeErr(self, data): - """ - Record the extended data in the buffer. This was an old interface - that allowed the Transports from ISession.openShell() or - ISession.execCommand() to receive extended data from the client. - """ - self.err += data - - - -class StubClient(object): - """ - A stub class representing the client to a SSHSession. - - @ivar transport: A L{StubTransport} object which keeps track of the data - passed to it. - """ - - - def __init__(self): - self.transport = StubTransportWithWriteErr() - - - -class SessionInterfaceTestCase(unittest.TestCase): - """ - Tests for the SSHSession class interface. This interface is not ideal, but - it is tested in order to maintain backwards compatibility. - """ - - - def setUp(self): - """ - Make an SSHSession object to test. Give the channel some window - so that it's allowed to send packets. 500 and 100 are arbitrary - values. - """ - self.session = session.SSHSession(remoteWindow=500, - remoteMaxPacket=100, conn=StubConnection(), - avatar=StubAvatar()) - - - def assertSessionIsStubSession(self): - """ - Asserts that self.session.session is an instance of - StubSessionForStubOldAvatar. - """ - self.assertIsInstance(self.session.session, - StubSessionForStubAvatar) - - - def test_init(self): - """ - SSHSession initializes its buffer (buf), client, and ISession adapter. - The avatar should not need to be adaptable to an ISession immediately. - """ - s = session.SSHSession(avatar=object) # use object because it doesn't - # have an adapter - self.assertEqual(s.buf, '') - self.assertIdentical(s.client, None) - self.assertIdentical(s.session, None) - - - def test_client_dataReceived(self): - """ - SSHSession.dataReceived() passes data along to a client. If the data - comes before there is a client, the data should be discarded. - """ - self.session.dataReceived('1') - self.session.client = StubClient() - self.session.dataReceived('2') - self.assertEqual(self.session.client.transport.buf, '2') - - def test_client_extReceived(self): - """ - SSHSession.extReceived() passed data of type EXTENDED_DATA_STDERR along - to the client. If the data comes before there is a client, or if the - data is not of type EXTENDED_DATA_STDERR, it is discared. - """ - self.session.extReceived(connection.EXTENDED_DATA_STDERR, '1') - self.session.extReceived(255, '2') # 255 is arbitrary - self.session.client = StubClient() - self.session.extReceived(connection.EXTENDED_DATA_STDERR, '3') - self.assertEqual(self.session.client.transport.err, '3') - - - def test_client_extReceivedWithoutWriteErr(self): - """ - SSHSession.extReceived() should handle the case where the transport - on the client doesn't have a writeErr method. - """ - client = self.session.client = StubClient() - client.transport = StubTransport() # doesn't have writeErr - - # should not raise an error - self.session.extReceived(connection.EXTENDED_DATA_STDERR, 'ignored') - - - - def test_client_closed(self): - """ - SSHSession.closed() should tell the transport connected to the client - that the connection was lost. - """ - self.session.client = StubClient() - self.session.closed() - self.assertTrue(self.session.client.transport.close) - self.session.client.transport.close = False - - - def test_badSubsystemDoesNotCreateClient(self): - """ - When a subsystem request fails, SSHSession.client should not be set. - """ - ret = self.session.requestReceived( - 'subsystem', common.NS('BadSubsystem')) - self.assertFalse(ret) - self.assertIdentical(self.session.client, None) - - - def test_lookupSubsystem(self): - """ - When a client requests a subsystem, the SSHSession object should get - the subsystem by calling avatar.lookupSubsystem, and attach it as - the client. - """ - ret = self.session.requestReceived( - 'subsystem', common.NS('TestSubsystem') + 'data') - self.assertTrue(ret) - self.assertIsInstance(self.session.client, protocol.ProcessProtocol) - self.assertIdentical(self.session.client.transport.proto, - self.session.avatar.subsystem) - - - - def test_lookupSubsystemDoesNotNeedISession(self): - """ - Previously, if one only wanted to implement a subsystem, an ISession - adapter wasn't needed because subsystems were looked up using the - lookupSubsystem method on the avatar. - """ - s = session.SSHSession(avatar=SubsystemOnlyAvatar(), - conn=StubConnection()) - ret = s.request_subsystem( - common.NS('subsystem') + 'data') - self.assertTrue(ret) - self.assertNotIdentical(s.client, None) - self.assertIdentical(s.conn.closes.get(s), None) - s.eofReceived() - self.assertTrue(s.conn.closes.get(s)) - # these should not raise errors - s.loseConnection() - s.closed() - - - def test_lookupSubsystem_data(self): - """ - After having looked up a subsystem, data should be passed along to the - client. Additionally, subsystems were passed the entire request packet - as data, instead of just the additional data. - - We check for the additional tidle to verify that the data passed - through the client. - """ - #self.session.dataReceived('1') - # subsystems didn't get extended data - #self.session.extReceived(connection.EXTENDED_DATA_STDERR, '2') - - self.session.requestReceived('subsystem', - common.NS('TestSubsystem') + 'data') - - self.assertEqual(self.session.conn.data[self.session], - ['\x00\x00\x00\x0dTestSubsystemdata~']) - self.session.dataReceived('more data') - self.assertEqual(self.session.conn.data[self.session][-1], - 'more data~') - - - def test_lookupSubsystem_closeReceived(self): - """ - SSHSession.closeReceived() should sent a close message to the remote - side. - """ - self.session.requestReceived('subsystem', - common.NS('TestSubsystem') + 'data') - - self.session.closeReceived() - self.assertTrue(self.session.conn.closes[self.session]) - - - def assertRequestRaisedRuntimeError(self): - """ - Assert that the request we just made raised a RuntimeError (and only a - RuntimeError). - """ - errors = self.flushLoggedErrors(RuntimeError) - self.assertEqual(len(errors), 1, "Multiple RuntimeErrors raised: %s" % - '\n'.join([repr(error) for error in errors])) - errors[0].trap(RuntimeError) - - - def test_requestShell(self): - """ - When a client requests a shell, the SSHSession object should get - the shell by getting an ISession adapter for the avatar, then - calling openShell() with a ProcessProtocol to attach. - """ - # gets a shell the first time - ret = self.session.requestReceived('shell', '') - self.assertTrue(ret) - self.assertSessionIsStubSession() - self.assertIsInstance(self.session.client, - session.SSHSessionProcessProtocol) - self.assertIdentical(self.session.session.shellProtocol, - self.session.client) - # doesn't get a shell the second time - self.assertFalse(self.session.requestReceived('shell', '')) - self.assertRequestRaisedRuntimeError() - - - def test_requestShellWithData(self): - """ - When a client executes a shell, it should be able to give pass data - back and forth between the local and the remote side. - """ - ret = self.session.requestReceived('shell', '') - self.assertTrue(ret) - self.assertSessionIsStubSession() - self.session.dataReceived('some data\x00') - self.assertEqual(self.session.session.shellTransport.data, - 'some data\x00') - self.assertEqual(self.session.conn.data[self.session], - ['some data\x00', '\r\n']) - self.assertTrue(self.session.session.shellTransport.closed) - self.assertEqual(self.session.conn.requests[self.session], - [('exit-status', '\x00\x00\x00\x00', False)]) - - - def test_requestExec(self): - """ - When a client requests a command, the SSHSession object should get - the command by getting an ISession adapter for the avatar, then - calling execCommand with a ProcessProtocol to attach and the - command line. - """ - ret = self.session.requestReceived('exec', - common.NS('failure')) - self.assertFalse(ret) - self.assertRequestRaisedRuntimeError() - self.assertIdentical(self.session.client, None) - - self.assertTrue(self.session.requestReceived('exec', - common.NS('success'))) - self.assertSessionIsStubSession() - self.assertIsInstance(self.session.client, - session.SSHSessionProcessProtocol) - self.assertIdentical(self.session.session.execProtocol, - self.session.client) - self.assertEqual(self.session.session.execCommandLine, - 'success') - - - def test_requestExecWithData(self): - """ - When a client executes a command, it should be able to give pass data - back and forth. - """ - ret = self.session.requestReceived('exec', - common.NS('repeat hello')) - self.assertTrue(ret) - self.assertSessionIsStubSession() - self.session.dataReceived('some data') - self.assertEqual(self.session.session.execTransport.data, 'some data') - self.assertEqual(self.session.conn.data[self.session], - ['hello', 'some data', '\r\n']) - self.session.eofReceived() - self.session.closeReceived() - self.session.closed() - self.assertTrue(self.session.session.execTransport.closed) - self.assertEqual(self.session.conn.requests[self.session], - [('exit-status', '\x00\x00\x00\x00', False)]) - - - def test_requestPty(self): - """ - When a client requests a PTY, the SSHSession object should make - the request by getting an ISession adapter for the avatar, then - calling getPty with the terminal type, the window size, and any modes - the client gave us. - """ - # 'bad' terminal type fails - ret = self.session.requestReceived( - 'pty_req', session.packRequest_pty_req( - 'bad', (1, 2, 3, 4), '')) - self.assertFalse(ret) - self.assertSessionIsStubSession() - self.assertRequestRaisedRuntimeError() - # 'good' terminal type succeeds - self.assertTrue(self.session.requestReceived('pty_req', - session.packRequest_pty_req('good', (1, 2, 3, 4), ''))) - self.assertEqual(self.session.session.ptyRequest, - ('good', (1, 2, 3, 4), [])) - - - def test_requestWindowChange(self): - """ - When the client requests to change the window size, the SSHSession - object should make the request by getting an ISession adapter for the - avatar, then calling windowChanged with the new window size. - """ - ret = self.session.requestReceived( - 'window_change', - session.packRequest_window_change((0, 0, 0, 0))) - self.assertFalse(ret) - self.assertRequestRaisedRuntimeError() - self.assertSessionIsStubSession() - self.assertTrue(self.session.requestReceived('window_change', - session.packRequest_window_change((1, 2, 3, 4)))) - self.assertEqual(self.session.session.windowChange, - (1, 2, 3, 4)) - - - def test_eofReceived(self): - """ - When an EOF is received and a ISession adapter is present, it should - be notified of the EOF message. - """ - self.session.session = session.ISession(self.session.avatar) - self.session.eofReceived() - self.assertTrue(self.session.session.gotEOF) - - - def test_closeReceived(self): - """ - When a close is received, the session should send a close message. - """ - ret = self.session.closeReceived() - self.assertIdentical(ret, None) - self.assertTrue(self.session.conn.closes[self.session]) - - - def test_closed(self): - """ - When a close is received and a ISession adapter is present, it should - be notified of the close message. - """ - self.session.session = session.ISession(self.session.avatar) - self.session.closed() - self.assertTrue(self.session.session.gotClosed) - - - -class SessionWithNoAvatarTestCase(unittest.TestCase): - """ - Test for the SSHSession interface. Several of the methods (request_shell, - request_exec, request_pty_req, request_window_change) would create a - 'session' instance variable from the avatar if one didn't exist when they - were called. - """ - - - def setUp(self): - self.session = session.SSHSession() - self.session.avatar = StubAvatar() - self.assertIdentical(self.session.session, None) - - - def assertSessionProvidesISession(self): - """ - self.session.session should provide I{ISession}. - """ - self.assertTrue(session.ISession.providedBy(self.session.session), - "ISession not provided by %r" % self.session.session) - - - def test_requestShellGetsSession(self): - """ - If an ISession adapter isn't already present, request_shell should get - one. - """ - self.session.requestReceived('shell', '') - self.assertSessionProvidesISession() - - - def test_requestExecGetsSession(self): - """ - If an ISession adapter isn't already present, request_exec should get - one. - """ - self.session.requestReceived('exec', - common.NS('success')) - self.assertSessionProvidesISession() - - - def test_requestPtyReqGetsSession(self): - """ - If an ISession adapter isn't already present, request_pty_req should - get one. - """ - self.session.requestReceived('pty_req', - session.packRequest_pty_req( - 'term', (0, 0, 0, 0), '')) - self.assertSessionProvidesISession() - - - def test_requestWindowChangeGetsSession(self): - """ - If an ISession adapter isn't already present, request_window_change - should get one. - """ - self.session.requestReceived( - 'window_change', - session.packRequest_window_change( - (1, 1, 1, 1))) - self.assertSessionProvidesISession() - - - -class WrappersTestCase(unittest.TestCase): - """ - A test for the wrapProtocol and wrapProcessProtocol functions. - """ - - def test_wrapProtocol(self): - """ - L{wrapProtocol}, when passed a L{Protocol} should return something that - has write(), writeSequence(), loseConnection() methods which call the - Protocol's dataReceived() and connectionLost() methods, respectively. - """ - protocol = MockProtocol() - protocol.transport = StubTransport() - protocol.connectionMade() - wrapped = session.wrapProtocol(protocol) - wrapped.dataReceived('dataReceived') - self.assertEqual(protocol.transport.buf, 'dataReceived') - wrapped.write('data') - wrapped.writeSequence(['1', '2']) - wrapped.loseConnection() - self.assertEqual(protocol.data, 'data12') - protocol.reason.trap(error.ConnectionDone) - - def test_wrapProcessProtocol_Protocol(self): - """ - L{wrapPRocessProtocol}, when passed a L{Protocol} should return - something that follows the L{IProcessProtocol} interface, with - connectionMade() mapping to connectionMade(), outReceived() mapping to - dataReceived() and processEnded() mapping to connectionLost(). - """ - protocol = MockProtocol() - protocol.transport = StubTransport() - process_protocol = session.wrapProcessProtocol(protocol) - process_protocol.connectionMade() - process_protocol.outReceived('data') - self.assertEqual(protocol.transport.buf, 'data~') - process_protocol.processEnded(failure.Failure( - error.ProcessTerminated(0, None, None))) - protocol.reason.trap(error.ProcessTerminated) - - - -class TestHelpers(unittest.TestCase): - """ - Tests for the 4 helper functions: parseRequest_* and packRequest_*. - """ - - - def test_parseRequest_pty_req(self): - """ - The payload of a pty-req message is:: - string terminal - uint32 columns - uint32 rows - uint32 x pixels - uint32 y pixels - string modes - - Modes are:: - byte mode number - uint32 mode value - """ - self.assertEqual(session.parseRequest_pty_req(common.NS('xterm') + - struct.pack('>4L', - 1, 2, 3, 4) - + common.NS( - struct.pack('>BL', 5, 6))), - ('xterm', (2, 1, 3, 4), [(5, 6)])) - - - def test_packRequest_pty_req_old(self): - """ - See test_parseRequest_pty_req for the payload format. - """ - packed = session.packRequest_pty_req('xterm', (2, 1, 3, 4), - '\x05\x00\x00\x00\x06') - - self.assertEqual(packed, - common.NS('xterm') + struct.pack('>4L', 1, 2, 3, 4) + - common.NS(struct.pack('>BL', 5, 6))) - - - def test_packRequest_pty_req(self): - """ - See test_parseRequest_pty_req for the payload format. - """ - packed = session.packRequest_pty_req('xterm', (2, 1, 3, 4), - '\x05\x00\x00\x00\x06') - self.assertEqual(packed, - common.NS('xterm') + struct.pack('>4L', 1, 2, 3, 4) + - common.NS(struct.pack('>BL', 5, 6))) - - - def test_parseRequest_window_change(self): - """ - The payload of a window_change request is:: - uint32 columns - uint32 rows - uint32 x pixels - uint32 y pixels - - parseRequest_window_change() returns (rows, columns, x pixels, - y pixels). - """ - self.assertEqual(session.parseRequest_window_change( - struct.pack('>4L', 1, 2, 3, 4)), (2, 1, 3, 4)) - - - def test_packRequest_window_change(self): - """ - See test_parseRequest_window_change for the payload format. - """ - self.assertEqual(session.packRequest_window_change((2, 1, 3, 4)), - struct.pack('>4L', 1, 2, 3, 4)) - - - -class SSHSessionProcessProtocolTestCase(unittest.TestCase): - """ - Tests for L{SSHSessionProcessProtocol}. - """ - - def setUp(self): - self.transport = StubTransport() - self.session = session.SSHSession( - conn=StubConnection(self.transport), remoteWindow=500, - remoteMaxPacket=100) - self.pp = session.SSHSessionProcessProtocol(self.session) - self.pp.makeConnection(self.transport) - - - def assertSessionClosed(self): - """ - Assert that C{self.session} is closed. - """ - self.assertTrue(self.session.conn.closes[self.session]) - - - def assertRequestsEqual(self, expectedRequests): - """ - Assert that C{self.session} has sent the C{expectedRequests}. - """ - self.assertEqual( - self.session.conn.requests[self.session], - expectedRequests) - - - def test_init(self): - """ - SSHSessionProcessProtocol should set self.session to the session passed - to the __init__ method. - """ - self.assertEqual(self.pp.session, self.session) - - - def test_getHost(self): - """ - SSHSessionProcessProtocol.getHost() just delegates to its - session.conn.transport.getHost(). - """ - self.assertEqual( - self.session.conn.transport.getHost(), self.pp.getHost()) - - - def test_getPeer(self): - """ - SSHSessionProcessProtocol.getPeer() just delegates to its - session.conn.transport.getPeer(). - """ - self.assertEqual( - self.session.conn.transport.getPeer(), self.pp.getPeer()) - - - def test_connectionMade(self): - """ - SSHSessionProcessProtocol.connectionMade() should check if there's a - 'buf' attribute on its session and write it to the transport if so. - """ - self.session.buf = 'buffer' - self.pp.connectionMade() - self.assertEqual(self.transport.buf, 'buffer') - - - def test_getSignalName(self): - """ - _getSignalName should return the name of a signal when given the - signal number. - """ - for signalName in session.SUPPORTED_SIGNALS: - signalName = 'SIG' + signalName - signalValue = getattr(signal, signalName) - sshName = self.pp._getSignalName(signalValue) - self.assertEqual(sshName, signalName, - "%i: %s != %s" % (signalValue, sshName, - signalName)) - - - def test_getSignalNameWithLocalSignal(self): - """ - If there are signals in the signal module which aren't in the SSH RFC, - we map their name to [signal name]@[platform]. - """ - signal.SIGTwistedTest = signal.NSIG + 1 # value can't exist normally - # Force reinitialization of signals - self.pp._signalValuesToNames = None - self.assertEqual(self.pp._getSignalName(signal.SIGTwistedTest), - 'SIGTwistedTest@' + sys.platform) - - - if getattr(signal, 'SIGALRM', None) is None: - test_getSignalName.skip = test_getSignalNameWithLocalSignal.skip = \ - "Not all signals available" - - - def test_outReceived(self): - """ - When data is passed to the outReceived method, it should be sent to - the session's write method. - """ - self.pp.outReceived('test data') - self.assertEqual(self.session.conn.data[self.session], - ['test data']) - - - def test_write(self): - """ - When data is passed to the write method, it should be sent to the - session channel's write method. - """ - self.pp.write('test data') - self.assertEqual(self.session.conn.data[self.session], - ['test data']) - - def test_writeSequence(self): - """ - When a sequence is passed to the writeSequence method, it should be - joined together and sent to the session channel's write method. - """ - self.pp.writeSequence(['test ', 'data']) - self.assertEqual(self.session.conn.data[self.session], - ['test data']) - - - def test_errReceived(self): - """ - When data is passed to the errReceived method, it should be sent to - the session's writeExtended method. - """ - self.pp.errReceived('test data') - self.assertEqual(self.session.conn.extData[self.session], - [(1, 'test data')]) - - - def test_outConnectionLost(self): - """ - When outConnectionLost and errConnectionLost are both called, we should - send an EOF message. - """ - self.pp.outConnectionLost() - self.assertFalse(self.session in self.session.conn.eofs) - self.pp.errConnectionLost() - self.assertTrue(self.session.conn.eofs[self.session]) - - - def test_errConnectionLost(self): - """ - Make sure reverse ordering of events in test_outConnectionLost also - sends EOF. - """ - self.pp.errConnectionLost() - self.assertFalse(self.session in self.session.conn.eofs) - self.pp.outConnectionLost() - self.assertTrue(self.session.conn.eofs[self.session]) - - - def test_loseConnection(self): - """ - When loseConnection() is called, it should call loseConnection - on the session channel. - """ - self.pp.loseConnection() - self.assertTrue(self.session.conn.closes[self.session]) - - - def test_connectionLost(self): - """ - When connectionLost() is called, it should call loseConnection() - on the session channel. - """ - self.pp.connectionLost(failure.Failure( - ProcessDone(0))) - - - def test_processEndedWithExitCode(self): - """ - When processEnded is called, if there is an exit code in the reason - it should be sent in an exit-status method. The connection should be - closed. - """ - self.pp.processEnded(Failure(ProcessDone(None))) - self.assertRequestsEqual( - [('exit-status', struct.pack('>I', 0) , False)]) - self.assertSessionClosed() - - - def test_processEndedWithExitSignalCoreDump(self): - """ - When processEnded is called, if there is an exit signal in the reason - it should be sent in an exit-signal message. The connection should be - closed. - """ - self.pp.processEnded( - Failure(ProcessTerminated(1, - signal.SIGTERM, 1 << 7))) # 7th bit means core dumped - self.assertRequestsEqual( - [('exit-signal', - common.NS('TERM') # signal name - + '\x01' # core dumped is true - + common.NS('') # error message - + common.NS(''), # language tag - False)]) - self.assertSessionClosed() - - - def test_processEndedWithExitSignalNoCoreDump(self): - """ - When processEnded is called, if there is an exit signal in the - reason it should be sent in an exit-signal message. If no - core was dumped, don't set the core-dump bit. - """ - self.pp.processEnded( - Failure(ProcessTerminated(1, signal.SIGTERM, 0))) - # see comments in test_processEndedWithExitSignalCoreDump for the - # meaning of the parts in the request - self.assertRequestsEqual( - [('exit-signal', common.NS('TERM') + '\x00' + common.NS('') + - common.NS(''), False)]) - self.assertSessionClosed() - - - if getattr(os, 'WCOREDUMP', None) is None: - skipMsg = "can't run this w/o os.WCOREDUMP" - test_processEndedWithExitSignalCoreDump.skip = skipMsg - test_processEndedWithExitSignalNoCoreDump.skip = skipMsg - - - -class SSHSessionClientTestCase(unittest.TestCase): - """ - SSHSessionClient is an obsolete class used to connect standard IO to - an SSHSession. - """ - - - def test_dataReceived(self): - """ - When data is received, it should be sent to the transport. - """ - client = session.SSHSessionClient() - client.transport = StubTransport() - client.dataReceived('test data') - self.assertEqual(client.transport.buf, 'test data') diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py deleted file mode 100755 index 6cf1a1ab..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_ssh.py +++ /dev/null @@ -1,995 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.ssh}. -""" - -import struct - -try: - import Crypto.Cipher.DES3 -except ImportError: - Crypto = None - -try: - import pyasn1 -except ImportError: - pyasn1 = None - -from twisted.conch.ssh import common, session, forwarding -from twisted.conch import avatar, error -from twisted.conch.test.keydata import publicRSA_openssh, privateRSA_openssh -from twisted.conch.test.keydata import publicDSA_openssh, privateDSA_openssh -from twisted.cred import portal -from twisted.cred.error import UnauthorizedLogin -from twisted.internet import defer, protocol, reactor -from twisted.internet.error import ProcessTerminated -from twisted.python import failure, log -from twisted.trial import unittest - -from twisted.conch.test.test_recvline import LoopbackRelay - - - -class ConchTestRealm(object): - """ - A realm which expects a particular avatarId to log in once and creates a - L{ConchTestAvatar} for that request. - - @ivar expectedAvatarID: The only avatarID that this realm will produce an - avatar for. - - @ivar avatar: A reference to the avatar after it is requested. - """ - avatar = None - - def __init__(self, expectedAvatarID): - self.expectedAvatarID = expectedAvatarID - - - def requestAvatar(self, avatarID, mind, *interfaces): - """ - Return a new L{ConchTestAvatar} if the avatarID matches the expected one - and this is the first avatar request. - """ - if avatarID == self.expectedAvatarID: - if self.avatar is not None: - raise UnauthorizedLogin("Only one login allowed") - self.avatar = ConchTestAvatar() - return interfaces[0], self.avatar, self.avatar.logout - raise UnauthorizedLogin( - "Only %r may log in, not %r" % (self.expectedAvatarID, avatarID)) - - - -class ConchTestAvatar(avatar.ConchUser): - """ - An avatar against which various SSH features can be tested. - - @ivar loggedOut: A flag indicating whether the avatar logout method has been - called. - """ - loggedOut = False - - def __init__(self): - avatar.ConchUser.__init__(self) - self.listeners = {} - self.globalRequests = {} - self.channelLookup.update({'session': session.SSHSession, - 'direct-tcpip':forwarding.openConnectForwardingClient}) - self.subsystemLookup.update({'crazy': CrazySubsystem}) - - - def global_foo(self, data): - self.globalRequests['foo'] = data - return 1 - - - def global_foo_2(self, data): - self.globalRequests['foo_2'] = data - return 1, 'data' - - - def global_tcpip_forward(self, data): - host, port = forwarding.unpackGlobal_tcpip_forward(data) - try: - listener = reactor.listenTCP( - port, forwarding.SSHListenForwardingFactory( - self.conn, (host, port), - forwarding.SSHListenServerForwardingChannel), - interface=host) - except: - log.err(None, "something went wrong with remote->local forwarding") - return 0 - else: - self.listeners[(host, port)] = listener - return 1 - - - def global_cancel_tcpip_forward(self, data): - host, port = forwarding.unpackGlobal_tcpip_forward(data) - listener = self.listeners.get((host, port), None) - if not listener: - return 0 - del self.listeners[(host, port)] - listener.stopListening() - return 1 - - - def logout(self): - self.loggedOut = True - for listener in self.listeners.values(): - log.msg('stopListening %s' % listener) - listener.stopListening() - - - -class ConchSessionForTestAvatar(object): - """ - An ISession adapter for ConchTestAvatar. - """ - def __init__(self, avatar): - """ - Initialize the session and create a reference to it on the avatar for - later inspection. - """ - self.avatar = avatar - self.avatar._testSession = self - self.cmd = None - self.proto = None - self.ptyReq = False - self.eof = 0 - self.onClose = defer.Deferred() - - - def getPty(self, term, windowSize, attrs): - log.msg('pty req') - self._terminalType = term - self._windowSize = windowSize - self.ptyReq = True - - - def openShell(self, proto): - log.msg('opening shell') - self.proto = proto - EchoTransport(proto) - self.cmd = 'shell' - - - def execCommand(self, proto, cmd): - self.cmd = cmd - self.proto = proto - f = cmd.split()[0] - if f == 'false': - t = FalseTransport(proto) - # Avoid disconnecting this immediately. If the channel is closed - # before execCommand even returns the caller gets confused. - reactor.callLater(0, t.loseConnection) - elif f == 'echo': - t = EchoTransport(proto) - t.write(cmd[5:]) - t.loseConnection() - elif f == 'secho': - t = SuperEchoTransport(proto) - t.write(cmd[6:]) - t.loseConnection() - elif f == 'eecho': - t = ErrEchoTransport(proto) - t.write(cmd[6:]) - t.loseConnection() - else: - raise error.ConchError('bad exec') - self.avatar.conn.transport.expectedLoseConnection = 1 - - - def eofReceived(self): - self.eof = 1 - - - def closed(self): - log.msg('closed cmd "%s"' % self.cmd) - self.remoteWindowLeftAtClose = self.proto.session.remoteWindowLeft - self.onClose.callback(None) - -from twisted.python import components -components.registerAdapter(ConchSessionForTestAvatar, ConchTestAvatar, session.ISession) - -class CrazySubsystem(protocol.Protocol): - - def __init__(self, *args, **kw): - pass - - def connectionMade(self): - """ - good ... good - """ - - - -class FalseTransport: - """ - False transport should act like a /bin/false execution, i.e. just exit with - nonzero status, writing nothing to the terminal. - - @ivar proto: The protocol associated with this transport. - @ivar closed: A flag tracking whether C{loseConnection} has been called yet. - """ - - def __init__(self, p): - """ - @type p L{twisted.conch.ssh.session.SSHSessionProcessProtocol} instance - """ - self.proto = p - p.makeConnection(self) - self.closed = 0 - - - def loseConnection(self): - """ - Disconnect the protocol associated with this transport. - """ - if self.closed: - return - self.closed = 1 - self.proto.inConnectionLost() - self.proto.outConnectionLost() - self.proto.errConnectionLost() - self.proto.processEnded(failure.Failure(ProcessTerminated(255, None, None))) - - - -class EchoTransport: - - def __init__(self, p): - self.proto = p - p.makeConnection(self) - self.closed = 0 - - def write(self, data): - log.msg(repr(data)) - self.proto.outReceived(data) - self.proto.outReceived('\r\n') - if '\x00' in data: # mimic 'exit' for the shell test - self.loseConnection() - - def loseConnection(self): - if self.closed: return - self.closed = 1 - self.proto.inConnectionLost() - self.proto.outConnectionLost() - self.proto.errConnectionLost() - self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None))) - -class ErrEchoTransport: - - def __init__(self, p): - self.proto = p - p.makeConnection(self) - self.closed = 0 - - def write(self, data): - self.proto.errReceived(data) - self.proto.errReceived('\r\n') - - def loseConnection(self): - if self.closed: return - self.closed = 1 - self.proto.inConnectionLost() - self.proto.outConnectionLost() - self.proto.errConnectionLost() - self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None))) - -class SuperEchoTransport: - - def __init__(self, p): - self.proto = p - p.makeConnection(self) - self.closed = 0 - - def write(self, data): - self.proto.outReceived(data) - self.proto.outReceived('\r\n') - self.proto.errReceived(data) - self.proto.errReceived('\r\n') - - def loseConnection(self): - if self.closed: return - self.closed = 1 - self.proto.inConnectionLost() - self.proto.outConnectionLost() - self.proto.errConnectionLost() - self.proto.processEnded(failure.Failure(ProcessTerminated(0, None, None))) - - -if Crypto is not None and pyasn1 is not None: - from twisted.conch import checkers - from twisted.conch.ssh import channel, connection, factory, keys - from twisted.conch.ssh import transport, userauth - - class UtilityTestCase(unittest.TestCase): - def testCounter(self): - c = transport._Counter('\x00\x00', 2) - for i in xrange(256 * 256): - self.assertEqual(c(), struct.pack('!H', (i + 1) % (2 ** 16))) - # It should wrap around, too. - for i in xrange(256 * 256): - self.assertEqual(c(), struct.pack('!H', (i + 1) % (2 ** 16))) - - - class ConchTestPublicKeyChecker(checkers.SSHPublicKeyDatabase): - def checkKey(self, credentials): - blob = keys.Key.fromString(publicDSA_openssh).blob() - if credentials.username == 'testuser' and credentials.blob == blob: - return True - return False - - - class ConchTestPasswordChecker: - credentialInterfaces = checkers.IUsernamePassword, - - def requestAvatarId(self, credentials): - if credentials.username == 'testuser' and credentials.password == 'testpass': - return defer.succeed(credentials.username) - return defer.fail(Exception("Bad credentials")) - - - class ConchTestSSHChecker(checkers.SSHProtocolChecker): - - def areDone(self, avatarId): - if avatarId != 'testuser' or len(self.successfulCredentials[avatarId]) < 2: - return False - return True - - class ConchTestServerFactory(factory.SSHFactory): - noisy = 0 - - services = { - 'ssh-userauth':userauth.SSHUserAuthServer, - 'ssh-connection':connection.SSHConnection - } - - def buildProtocol(self, addr): - proto = ConchTestServer() - proto.supportedPublicKeys = self.privateKeys.keys() - proto.factory = self - - if hasattr(self, 'expectedLoseConnection'): - proto.expectedLoseConnection = self.expectedLoseConnection - - self.proto = proto - return proto - - def getPublicKeys(self): - return { - 'ssh-rsa': keys.Key.fromString(publicRSA_openssh), - 'ssh-dss': keys.Key.fromString(publicDSA_openssh) - } - - def getPrivateKeys(self): - return { - 'ssh-rsa': keys.Key.fromString(privateRSA_openssh), - 'ssh-dss': keys.Key.fromString(privateDSA_openssh) - } - - def getPrimes(self): - return { - 2048:[(transport.DH_GENERATOR, transport.DH_PRIME)] - } - - def getService(self, trans, name): - return factory.SSHFactory.getService(self, trans, name) - - class ConchTestBase: - - done = 0 - - def connectionLost(self, reason): - if self.done: - return - if not hasattr(self,'expectedLoseConnection'): - unittest.fail('unexpectedly lost connection %s\n%s' % (self, reason)) - self.done = 1 - - def receiveError(self, reasonCode, desc): - self.expectedLoseConnection = 1 - # Some versions of OpenSSH (for example, OpenSSH_5.3p1) will - # send a DISCONNECT_BY_APPLICATION error before closing the - # connection. Other, older versions (for example, - # OpenSSH_5.1p1), won't. So accept this particular error here, - # but no others. - if reasonCode != transport.DISCONNECT_BY_APPLICATION: - log.err( - Exception( - 'got disconnect for %s: reason %s, desc: %s' % ( - self, reasonCode, desc))) - self.loseConnection() - - def receiveUnimplemented(self, seqID): - unittest.fail('got unimplemented: seqid %s' % seqID) - self.expectedLoseConnection = 1 - self.loseConnection() - - class ConchTestServer(ConchTestBase, transport.SSHServerTransport): - - def connectionLost(self, reason): - ConchTestBase.connectionLost(self, reason) - transport.SSHServerTransport.connectionLost(self, reason) - - - class ConchTestClient(ConchTestBase, transport.SSHClientTransport): - """ - @ivar _channelFactory: A callable which accepts an SSH connection and - returns a channel which will be attached to a new channel on that - connection. - """ - def __init__(self, channelFactory): - self._channelFactory = channelFactory - - def connectionLost(self, reason): - ConchTestBase.connectionLost(self, reason) - transport.SSHClientTransport.connectionLost(self, reason) - - def verifyHostKey(self, key, fp): - keyMatch = key == keys.Key.fromString(publicRSA_openssh).blob() - fingerprintMatch = ( - fp == '3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af') - if keyMatch and fingerprintMatch: - return defer.succeed(1) - return defer.fail(Exception("Key or fingerprint mismatch")) - - def connectionSecure(self): - self.requestService(ConchTestClientAuth('testuser', - ConchTestClientConnection(self._channelFactory))) - - - class ConchTestClientAuth(userauth.SSHUserAuthClient): - - hasTriedNone = 0 # have we tried the 'none' auth yet? - canSucceedPublicKey = 0 # can we succed with this yet? - canSucceedPassword = 0 - - def ssh_USERAUTH_SUCCESS(self, packet): - if not self.canSucceedPassword and self.canSucceedPublicKey: - unittest.fail('got USERAUTH_SUCESS before password and publickey') - userauth.SSHUserAuthClient.ssh_USERAUTH_SUCCESS(self, packet) - - def getPassword(self): - self.canSucceedPassword = 1 - return defer.succeed('testpass') - - def getPrivateKey(self): - self.canSucceedPublicKey = 1 - return defer.succeed(keys.Key.fromString(privateDSA_openssh)) - - def getPublicKey(self): - return keys.Key.fromString(publicDSA_openssh) - - - class ConchTestClientConnection(connection.SSHConnection): - """ - @ivar _completed: A L{Deferred} which will be fired when the number of - results collected reaches C{totalResults}. - """ - name = 'ssh-connection' - results = 0 - totalResults = 8 - - def __init__(self, channelFactory): - connection.SSHConnection.__init__(self) - self._channelFactory = channelFactory - - def serviceStarted(self): - self.openChannel(self._channelFactory(conn=self)) - - - class SSHTestChannel(channel.SSHChannel): - - def __init__(self, name, opened, *args, **kwargs): - self.name = name - self._opened = opened - self.received = [] - self.receivedExt = [] - self.onClose = defer.Deferred() - channel.SSHChannel.__init__(self, *args, **kwargs) - - - def openFailed(self, reason): - self._opened.errback(reason) - - - def channelOpen(self, ignore): - self._opened.callback(self) - - - def dataReceived(self, data): - self.received.append(data) - - - def extReceived(self, dataType, data): - if dataType == connection.EXTENDED_DATA_STDERR: - self.receivedExt.append(data) - else: - log.msg("Unrecognized extended data: %r" % (dataType,)) - - - def request_exit_status(self, status): - [self.status] = struct.unpack('>L', status) - - - def eofReceived(self): - self.eofCalled = True - - - def closed(self): - self.onClose.callback(None) - - - -class SSHProtocolTestCase(unittest.TestCase): - """ - Tests for communication between L{SSHServerTransport} and - L{SSHClientTransport}. - """ - - if not Crypto: - skip = "can't run w/o PyCrypto" - - if not pyasn1: - skip = "Cannot run without PyASN1" - - def _ourServerOurClientTest(self, name='session', **kwargs): - """ - Create a connected SSH client and server protocol pair and return a - L{Deferred} which fires with an L{SSHTestChannel} instance connected to - a channel on that SSH connection. - """ - result = defer.Deferred() - self.realm = ConchTestRealm('testuser') - p = portal.Portal(self.realm) - sshpc = ConchTestSSHChecker() - sshpc.registerChecker(ConchTestPasswordChecker()) - sshpc.registerChecker(ConchTestPublicKeyChecker()) - p.registerChecker(sshpc) - fac = ConchTestServerFactory() - fac.portal = p - fac.startFactory() - self.server = fac.buildProtocol(None) - self.clientTransport = LoopbackRelay(self.server) - self.client = ConchTestClient( - lambda conn: SSHTestChannel(name, result, conn=conn, **kwargs)) - - self.serverTransport = LoopbackRelay(self.client) - - self.server.makeConnection(self.serverTransport) - self.client.makeConnection(self.clientTransport) - return result - - - def test_subsystemsAndGlobalRequests(self): - """ - Run the Conch server against the Conch client. Set up several different - channels which exercise different behaviors and wait for them to - complete. Verify that the channels with errors log them. - """ - channel = self._ourServerOurClientTest() - - def cbSubsystem(channel): - self.channel = channel - return self.assertFailure( - channel.conn.sendRequest( - channel, 'subsystem', common.NS('not-crazy'), 1), - Exception) - channel.addCallback(cbSubsystem) - - def cbNotCrazyFailed(ignored): - channel = self.channel - return channel.conn.sendRequest( - channel, 'subsystem', common.NS('crazy'), 1) - channel.addCallback(cbNotCrazyFailed) - - def cbGlobalRequests(ignored): - channel = self.channel - d1 = channel.conn.sendGlobalRequest('foo', 'bar', 1) - - d2 = channel.conn.sendGlobalRequest('foo-2', 'bar2', 1) - d2.addCallback(self.assertEqual, 'data') - - d3 = self.assertFailure( - channel.conn.sendGlobalRequest('bar', 'foo', 1), - Exception) - - return defer.gatherResults([d1, d2, d3]) - channel.addCallback(cbGlobalRequests) - - def disconnect(ignored): - self.assertEqual( - self.realm.avatar.globalRequests, - {"foo": "bar", "foo_2": "bar2"}) - channel = self.channel - channel.conn.transport.expectedLoseConnection = True - channel.conn.serviceStopped() - channel.loseConnection() - channel.addCallback(disconnect) - - return channel - - - def test_shell(self): - """ - L{SSHChannel.sendRequest} can open a shell with a I{pty-req} request, - specifying a terminal type and window size. - """ - channel = self._ourServerOurClientTest() - - data = session.packRequest_pty_req('conch-test-term', (24, 80, 0, 0), '') - def cbChannel(channel): - self.channel = channel - return channel.conn.sendRequest(channel, 'pty-req', data, 1) - channel.addCallback(cbChannel) - - def cbPty(ignored): - # The server-side object corresponding to our client side channel. - session = self.realm.avatar.conn.channels[0].session - self.assertIdentical(session.avatar, self.realm.avatar) - self.assertEqual(session._terminalType, 'conch-test-term') - self.assertEqual(session._windowSize, (24, 80, 0, 0)) - self.assertTrue(session.ptyReq) - channel = self.channel - return channel.conn.sendRequest(channel, 'shell', '', 1) - channel.addCallback(cbPty) - - def cbShell(ignored): - self.channel.write('testing the shell!\x00') - self.channel.conn.sendEOF(self.channel) - return defer.gatherResults([ - self.channel.onClose, - self.realm.avatar._testSession.onClose]) - channel.addCallback(cbShell) - - def cbExited(ignored): - if self.channel.status != 0: - log.msg( - 'shell exit status was not 0: %i' % (self.channel.status,)) - self.assertEqual( - "".join(self.channel.received), - 'testing the shell!\x00\r\n') - self.assertTrue(self.channel.eofCalled) - self.assertTrue( - self.realm.avatar._testSession.eof) - channel.addCallback(cbExited) - return channel - - - def test_failedExec(self): - """ - If L{SSHChannel.sendRequest} issues an exec which the server responds to - with an error, the L{Deferred} it returns fires its errback. - """ - channel = self._ourServerOurClientTest() - - def cbChannel(channel): - self.channel = channel - return self.assertFailure( - channel.conn.sendRequest( - channel, 'exec', common.NS('jumboliah'), 1), - Exception) - channel.addCallback(cbChannel) - - def cbFailed(ignored): - # The server logs this exception when it cannot perform the - # requested exec. - errors = self.flushLoggedErrors(error.ConchError) - self.assertEqual(errors[0].value.args, ('bad exec', None)) - channel.addCallback(cbFailed) - return channel - - - def test_falseChannel(self): - """ - When the process started by a L{SSHChannel.sendRequest} exec request - exits, the exit status is reported to the channel. - """ - channel = self._ourServerOurClientTest() - - def cbChannel(channel): - self.channel = channel - return channel.conn.sendRequest( - channel, 'exec', common.NS('false'), 1) - channel.addCallback(cbChannel) - - def cbExec(ignored): - return self.channel.onClose - channel.addCallback(cbExec) - - def cbClosed(ignored): - # No data is expected - self.assertEqual(self.channel.received, []) - self.assertNotEquals(self.channel.status, 0) - channel.addCallback(cbClosed) - return channel - - - def test_errorChannel(self): - """ - Bytes sent over the extended channel for stderr data are delivered to - the channel's C{extReceived} method. - """ - channel = self._ourServerOurClientTest(localWindow=4, localMaxPacket=5) - - def cbChannel(channel): - self.channel = channel - return channel.conn.sendRequest( - channel, 'exec', common.NS('eecho hello'), 1) - channel.addCallback(cbChannel) - - def cbExec(ignored): - return defer.gatherResults([ - self.channel.onClose, - self.realm.avatar._testSession.onClose]) - channel.addCallback(cbExec) - - def cbClosed(ignored): - self.assertEqual(self.channel.received, []) - self.assertEqual("".join(self.channel.receivedExt), "hello\r\n") - self.assertEqual(self.channel.status, 0) - self.assertTrue(self.channel.eofCalled) - self.assertEqual(self.channel.localWindowLeft, 4) - self.assertEqual( - self.channel.localWindowLeft, - self.realm.avatar._testSession.remoteWindowLeftAtClose) - channel.addCallback(cbClosed) - return channel - - - def test_unknownChannel(self): - """ - When an attempt is made to open an unknown channel type, the L{Deferred} - returned by L{SSHChannel.sendRequest} fires its errback. - """ - d = self.assertFailure( - self._ourServerOurClientTest('crazy-unknown-channel'), Exception) - def cbFailed(ignored): - errors = self.flushLoggedErrors(error.ConchError) - self.assertEqual(errors[0].value.args, (3, 'unknown channel')) - self.assertEqual(len(errors), 1) - d.addCallback(cbFailed) - return d - - - def test_maxPacket(self): - """ - An L{SSHChannel} can be configured with a maximum packet size to - receive. - """ - # localWindow needs to be at least 11 otherwise the assertion about it - # in cbClosed is invalid. - channel = self._ourServerOurClientTest( - localWindow=11, localMaxPacket=1) - - def cbChannel(channel): - self.channel = channel - return channel.conn.sendRequest( - channel, 'exec', common.NS('secho hello'), 1) - channel.addCallback(cbChannel) - - def cbExec(ignored): - return self.channel.onClose - channel.addCallback(cbExec) - - def cbClosed(ignored): - self.assertEqual(self.channel.status, 0) - self.assertEqual("".join(self.channel.received), "hello\r\n") - self.assertEqual("".join(self.channel.receivedExt), "hello\r\n") - self.assertEqual(self.channel.localWindowLeft, 11) - self.assertTrue(self.channel.eofCalled) - channel.addCallback(cbClosed) - return channel - - - def test_echo(self): - """ - Normal standard out bytes are sent to the channel's C{dataReceived} - method. - """ - channel = self._ourServerOurClientTest(localWindow=4, localMaxPacket=5) - - def cbChannel(channel): - self.channel = channel - return channel.conn.sendRequest( - channel, 'exec', common.NS('echo hello'), 1) - channel.addCallback(cbChannel) - - def cbEcho(ignored): - return defer.gatherResults([ - self.channel.onClose, - self.realm.avatar._testSession.onClose]) - channel.addCallback(cbEcho) - - def cbClosed(ignored): - self.assertEqual(self.channel.status, 0) - self.assertEqual("".join(self.channel.received), "hello\r\n") - self.assertEqual(self.channel.localWindowLeft, 4) - self.assertTrue(self.channel.eofCalled) - self.assertEqual( - self.channel.localWindowLeft, - self.realm.avatar._testSession.remoteWindowLeftAtClose) - channel.addCallback(cbClosed) - return channel - - - -class TestSSHFactory(unittest.TestCase): - - if not Crypto: - skip = "can't run w/o PyCrypto" - - if not pyasn1: - skip = "Cannot run without PyASN1" - - def makeSSHFactory(self, primes=None): - sshFactory = factory.SSHFactory() - gpk = lambda: {'ssh-rsa' : keys.Key(None)} - sshFactory.getPrimes = lambda: primes - sshFactory.getPublicKeys = sshFactory.getPrivateKeys = gpk - sshFactory.startFactory() - return sshFactory - - - def test_buildProtocol(self): - """ - By default, buildProtocol() constructs an instance of - SSHServerTransport. - """ - factory = self.makeSSHFactory() - protocol = factory.buildProtocol(None) - self.assertIsInstance(protocol, transport.SSHServerTransport) - - - def test_buildProtocolRespectsProtocol(self): - """ - buildProtocol() calls 'self.protocol()' to construct a protocol - instance. - """ - calls = [] - def makeProtocol(*args): - calls.append(args) - return transport.SSHServerTransport() - factory = self.makeSSHFactory() - factory.protocol = makeProtocol - factory.buildProtocol(None) - self.assertEqual([()], calls) - - - def test_multipleFactories(self): - f1 = self.makeSSHFactory(primes=None) - f2 = self.makeSSHFactory(primes={1:(2,3)}) - p1 = f1.buildProtocol(None) - p2 = f2.buildProtocol(None) - self.failIf('diffie-hellman-group-exchange-sha1' in p1.supportedKeyExchanges, - p1.supportedKeyExchanges) - self.failUnless('diffie-hellman-group-exchange-sha1' in p2.supportedKeyExchanges, - p2.supportedKeyExchanges) - - - -class MPTestCase(unittest.TestCase): - """ - Tests for L{common.getMP}. - - @cvar getMP: a method providing a MP parser. - @type getMP: C{callable} - """ - getMP = staticmethod(common.getMP) - - if not Crypto: - skip = "can't run w/o PyCrypto" - - if not pyasn1: - skip = "Cannot run without PyASN1" - - - def test_getMP(self): - """ - L{common.getMP} should parse the a multiple precision integer from a - string: a 4-byte length followed by length bytes of the integer. - """ - self.assertEqual( - self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01'), - (1, '')) - - - def test_getMPBigInteger(self): - """ - L{common.getMP} should be able to parse a big enough integer - (that doesn't fit on one byte). - """ - self.assertEqual( - self.getMP('\x00\x00\x00\x04\x01\x02\x03\x04'), - (16909060, '')) - - - def test_multipleGetMP(self): - """ - L{common.getMP} has the ability to parse multiple integer in the same - string. - """ - self.assertEqual( - self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01' - '\x00\x00\x00\x04\x00\x00\x00\x02', 2), - (1, 2, '')) - - - def test_getMPRemainingData(self): - """ - When more data than needed is sent to L{common.getMP}, it should return - the remaining data. - """ - self.assertEqual( - self.getMP('\x00\x00\x00\x04\x00\x00\x00\x01foo'), - (1, 'foo')) - - - def test_notEnoughData(self): - """ - When the string passed to L{common.getMP} doesn't even make 5 bytes, - it should raise a L{struct.error}. - """ - self.assertRaises(struct.error, self.getMP, '\x02\x00') - - - -class PyMPTestCase(MPTestCase): - """ - Tests for the python implementation of L{common.getMP}. - """ - getMP = staticmethod(common.getMP_py) - - - -class GMPYMPTestCase(MPTestCase): - """ - Tests for the gmpy implementation of L{common.getMP}. - """ - getMP = staticmethod(common._fastgetMP) - - -class BuiltinPowHackTestCase(unittest.TestCase): - """ - Tests that the builtin pow method is still correct after - L{twisted.conch.ssh.common} monkeypatches it to use gmpy. - """ - - def test_floatBase(self): - """ - pow gives the correct result when passed a base of type float with a - non-integer value. - """ - self.assertEqual(6.25, pow(2.5, 2)) - - def test_intBase(self): - """ - pow gives the correct result when passed a base of type int. - """ - self.assertEqual(81, pow(3, 4)) - - def test_longBase(self): - """ - pow gives the correct result when passed a base of type long. - """ - self.assertEqual(81, pow(3, 4)) - - def test_mpzBase(self): - """ - pow gives the correct result when passed a base of type gmpy.mpz. - """ - if gmpy is None: - raise unittest.SkipTest('gmpy not available') - self.assertEqual(81, pow(gmpy.mpz(3), 4)) - - -try: - import gmpy -except ImportError: - GMPYMPTestCase.skip = "gmpy not available" - gmpy = None diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py deleted file mode 100755 index 44acecd3..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_tap.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.tap}. -""" - -try: - import Crypto.Cipher.DES3 -except: - Crypto = None - -try: - import pyasn1 -except ImportError: - pyasn1 = None - -try: - from twisted.conch import unix -except ImportError: - unix = None - -if Crypto and pyasn1 and unix: - from twisted.conch import tap - from twisted.conch.openssh_compat.factory import OpenSSHFactory - -from twisted.python.compat import set -from twisted.application.internet import StreamServerEndpointService -from twisted.cred import error -from twisted.cred.credentials import IPluggableAuthenticationModules -from twisted.cred.credentials import ISSHPrivateKey -from twisted.cred.credentials import IUsernamePassword, UsernamePassword - -from twisted.trial.unittest import TestCase - - - -class MakeServiceTest(TestCase): - """ - Tests for L{tap.makeService}. - """ - - if not Crypto: - skip = "can't run w/o PyCrypto" - - if not pyasn1: - skip = "Cannot run without PyASN1" - - if not unix: - skip = "can't run on non-posix computers" - - usernamePassword = ('iamuser', 'thisispassword') - - def setUp(self): - """ - Create a file with two users. - """ - self.filename = self.mktemp() - f = open(self.filename, 'wb+') - f.write(':'.join(self.usernamePassword)) - f.close() - self.options = tap.Options() - - - def test_basic(self): - """ - L{tap.makeService} returns a L{StreamServerEndpointService} instance - running on TCP port 22, and the linked protocol factory is an instance - of L{OpenSSHFactory}. - """ - config = tap.Options() - service = tap.makeService(config) - self.assertIsInstance(service, StreamServerEndpointService) - self.assertEqual(service.endpoint._port, 22) - self.assertIsInstance(service.factory, OpenSSHFactory) - - - def test_defaultAuths(self): - """ - Make sure that if the C{--auth} command-line option is not passed, - the default checkers are (for backwards compatibility): SSH, UNIX, and - PAM if available - """ - numCheckers = 2 - try: - from twisted.cred import pamauth - self.assertIn(IPluggableAuthenticationModules, - self.options['credInterfaces'], - "PAM should be one of the modules") - numCheckers += 1 - except ImportError: - pass - - self.assertIn(ISSHPrivateKey, self.options['credInterfaces'], - "SSH should be one of the default checkers") - self.assertIn(IUsernamePassword, self.options['credInterfaces'], - "UNIX should be one of the default checkers") - self.assertEqual(numCheckers, len(self.options['credCheckers']), - "There should be %d checkers by default" % (numCheckers,)) - - - def test_authAdded(self): - """ - The C{--auth} command-line option will add a checker to the list of - checkers, and it should be the only auth checker - """ - self.options.parseOptions(['--auth', 'file:' + self.filename]) - self.assertEqual(len(self.options['credCheckers']), 1) - - - def test_authFailure(self): - """ - The checker created by the C{--auth} command-line option returns a - L{Deferred} that fails with L{UnauthorizedLogin} when - presented with credentials that are unknown to that checker. - """ - self.options.parseOptions(['--auth', 'file:' + self.filename]) - checker = self.options['credCheckers'][-1] - invalid = UsernamePassword(self.usernamePassword[0], 'fake') - # Wrong password should raise error - return self.assertFailure( - checker.requestAvatarId(invalid), error.UnauthorizedLogin) - - - def test_authSuccess(self): - """ - The checker created by the C{--auth} command-line option returns a - L{Deferred} that returns the avatar id when presented with credentials - that are known to that checker. - """ - self.options.parseOptions(['--auth', 'file:' + self.filename]) - checker = self.options['credCheckers'][-1] - correct = UsernamePassword(*self.usernamePassword) - d = checker.requestAvatarId(correct) - - def checkSuccess(username): - self.assertEqual(username, correct.username) - - return d.addCallback(checkSuccess) - - - def test_checkersPamAuth(self): - """ - The L{OpenSSHFactory} built by L{tap.makeService} has a portal with - L{IPluggableAuthenticationModules}, L{ISSHPrivateKey} and - L{IUsernamePassword} interfaces registered as checkers if C{pamauth} is - available. - """ - # Fake the presence of pamauth, even if PyPAM is not installed - self.patch(tap, "pamauth", object()) - config = tap.Options() - service = tap.makeService(config) - portal = service.factory.portal - self.assertEqual( - set(portal.checkers.keys()), - set([IPluggableAuthenticationModules, ISSHPrivateKey, - IUsernamePassword])) - - - def test_checkersWithoutPamAuth(self): - """ - The L{OpenSSHFactory} built by L{tap.makeService} has a portal with - L{ISSHPrivateKey} and L{IUsernamePassword} interfaces registered as - checkers if C{pamauth} is not available. - """ - # Fake the absence of pamauth, even if PyPAM is installed - self.patch(tap, "pamauth", None) - config = tap.Options() - service = tap.makeService(config) - portal = service.factory.portal - self.assertEqual( - set(portal.checkers.keys()), - set([ISSHPrivateKey, IUsernamePassword])) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py deleted file mode 100755 index 9b5bf76a..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_telnet.py +++ /dev/null @@ -1,767 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_telnet -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for L{twisted.conch.telnet}. -""" - -from zope.interface import implements -from zope.interface.verify import verifyObject - -from twisted.internet import defer - -from twisted.conch import telnet - -from twisted.trial import unittest -from twisted.test import proto_helpers - - -class TestProtocol: - implements(telnet.ITelnetProtocol) - - localEnableable = () - remoteEnableable = () - - def __init__(self): - self.bytes = '' - self.subcmd = '' - self.calls = [] - - self.enabledLocal = [] - self.enabledRemote = [] - self.disabledLocal = [] - self.disabledRemote = [] - - def makeConnection(self, transport): - d = transport.negotiationMap = {} - d['\x12'] = self.neg_TEST_COMMAND - - d = transport.commandMap = transport.commandMap.copy() - for cmd in ('NOP', 'DM', 'BRK', 'IP', 'AO', 'AYT', 'EC', 'EL', 'GA'): - d[getattr(telnet, cmd)] = lambda arg, cmd=cmd: self.calls.append(cmd) - - def dataReceived(self, bytes): - self.bytes += bytes - - def connectionLost(self, reason): - pass - - def neg_TEST_COMMAND(self, payload): - self.subcmd = payload - - def enableLocal(self, option): - if option in self.localEnableable: - self.enabledLocal.append(option) - return True - return False - - def disableLocal(self, option): - self.disabledLocal.append(option) - - def enableRemote(self, option): - if option in self.remoteEnableable: - self.enabledRemote.append(option) - return True - return False - - def disableRemote(self, option): - self.disabledRemote.append(option) - - - -class TestInterfaces(unittest.TestCase): - def test_interface(self): - """ - L{telnet.TelnetProtocol} implements L{telnet.ITelnetProtocol} - """ - p = telnet.TelnetProtocol() - verifyObject(telnet.ITelnetProtocol, p) - - - -class TelnetTransportTestCase(unittest.TestCase): - """ - Tests for L{telnet.TelnetTransport}. - """ - def setUp(self): - self.p = telnet.TelnetTransport(TestProtocol) - self.t = proto_helpers.StringTransport() - self.p.makeConnection(self.t) - - def testRegularBytes(self): - # Just send a bunch of bytes. None of these do anything - # with telnet. They should pass right through to the - # application layer. - h = self.p.protocol - - L = ["here are some bytes la la la", - "some more arrive here", - "lots of bytes to play with", - "la la la", - "ta de da", - "dum"] - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.bytes, ''.join(L)) - - def testNewlineHandling(self): - # Send various kinds of newlines and make sure they get translated - # into \n. - h = self.p.protocol - - L = ["here is the first line\r\n", - "here is the second line\r\0", - "here is the third line\r\n", - "here is the last line\r\0"] - - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.bytes, L[0][:-2] + '\n' + - L[1][:-2] + '\r' + - L[2][:-2] + '\n' + - L[3][:-2] + '\r') - - def testIACEscape(self): - # Send a bunch of bytes and a couple quoted \xFFs. Unquoted, - # \xFF is a telnet command. Quoted, one of them from each pair - # should be passed through to the application layer. - h = self.p.protocol - - L = ["here are some bytes\xff\xff with an embedded IAC", - "and here is a test of a border escape\xff", - "\xff did you get that IAC?"] - - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.bytes, ''.join(L).replace('\xff\xff', '\xff')) - - def _simpleCommandTest(self, cmdName): - # Send a single simple telnet command and make sure - # it gets noticed and the appropriate method gets - # called. - h = self.p.protocol - - cmd = telnet.IAC + getattr(telnet, cmdName) - L = ["Here's some bytes, tra la la", - "But ono!" + cmd + " an interrupt"] - - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.calls, [cmdName]) - self.assertEqual(h.bytes, ''.join(L).replace(cmd, '')) - - def testInterrupt(self): - self._simpleCommandTest("IP") - - def testNoOperation(self): - self._simpleCommandTest("NOP") - - def testDataMark(self): - self._simpleCommandTest("DM") - - def testBreak(self): - self._simpleCommandTest("BRK") - - def testAbortOutput(self): - self._simpleCommandTest("AO") - - def testAreYouThere(self): - self._simpleCommandTest("AYT") - - def testEraseCharacter(self): - self._simpleCommandTest("EC") - - def testEraseLine(self): - self._simpleCommandTest("EL") - - def testGoAhead(self): - self._simpleCommandTest("GA") - - def testSubnegotiation(self): - # Send a subnegotiation command and make sure it gets - # parsed and that the correct method is called. - h = self.p.protocol - - cmd = telnet.IAC + telnet.SB + '\x12hello world' + telnet.IAC + telnet.SE - L = ["These are some bytes but soon" + cmd, - "there will be some more"] - - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.bytes, ''.join(L).replace(cmd, '')) - self.assertEqual(h.subcmd, list("hello world")) - - def testSubnegotiationWithEmbeddedSE(self): - # Send a subnegotiation command with an embedded SE. Make sure - # that SE gets passed to the correct method. - h = self.p.protocol - - cmd = (telnet.IAC + telnet.SB + - '\x12' + telnet.SE + - telnet.IAC + telnet.SE) - - L = ["Some bytes are here" + cmd + "and here", - "and here"] - - for b in L: - self.p.dataReceived(b) - - self.assertEqual(h.bytes, ''.join(L).replace(cmd, '')) - self.assertEqual(h.subcmd, [telnet.SE]) - - def testBoundarySubnegotiation(self): - # Send a subnegotiation command. Split it at every possible byte boundary - # and make sure it always gets parsed and that it is passed to the correct - # method. - cmd = (telnet.IAC + telnet.SB + - '\x12' + telnet.SE + 'hello' + - telnet.IAC + telnet.SE) - - for i in range(len(cmd)): - h = self.p.protocol = TestProtocol() - h.makeConnection(self.p) - - a, b = cmd[:i], cmd[i:] - L = ["first part" + a, - b + "last part"] - - for bytes in L: - self.p.dataReceived(bytes) - - self.assertEqual(h.bytes, ''.join(L).replace(cmd, '')) - self.assertEqual(h.subcmd, [telnet.SE] + list('hello')) - - def _enabledHelper(self, o, eL=[], eR=[], dL=[], dR=[]): - self.assertEqual(o.enabledLocal, eL) - self.assertEqual(o.enabledRemote, eR) - self.assertEqual(o.disabledLocal, dL) - self.assertEqual(o.disabledRemote, dR) - - def testRefuseWill(self): - # Try to enable an option. The server should refuse to enable it. - cmd = telnet.IAC + telnet.WILL + '\x12' - - bytes = "surrounding bytes" + cmd + "to spice things up" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x12') - self._enabledHelper(self.p.protocol) - - def testRefuseDo(self): - # Try to enable an option. The server should refuse to enable it. - cmd = telnet.IAC + telnet.DO + '\x12' - - bytes = "surrounding bytes" + cmd + "to spice things up" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), telnet.IAC + telnet.WONT + '\x12') - self._enabledHelper(self.p.protocol) - - def testAcceptDo(self): - # Try to enable an option. The option is in our allowEnable - # list, so we will allow it to be enabled. - cmd = telnet.IAC + telnet.DO + '\x19' - bytes = 'padding' + cmd + 'trailer' - - h = self.p.protocol - h.localEnableable = ('\x19',) - self.p.dataReceived(bytes) - - self.assertEqual(self.t.value(), telnet.IAC + telnet.WILL + '\x19') - self._enabledHelper(h, eL=['\x19']) - - def testAcceptWill(self): - # Same as testAcceptDo, but reversed. - cmd = telnet.IAC + telnet.WILL + '\x91' - bytes = 'header' + cmd + 'padding' - - h = self.p.protocol - h.remoteEnableable = ('\x91',) - self.p.dataReceived(bytes) - - self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x91') - self._enabledHelper(h, eR=['\x91']) - - def testAcceptWont(self): - # Try to disable an option. The server must allow any option to - # be disabled at any time. Make sure it disables it and sends - # back an acknowledgement of this. - cmd = telnet.IAC + telnet.WONT + '\x29' - - # Jimmy it - after these two lines, the server will be in a state - # such that it believes the option to have been previously enabled - # via normal negotiation. - s = self.p.getOptionState('\x29') - s.him.state = 'yes' - - bytes = "fiddle dee" + cmd - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x29') - self.assertEqual(s.him.state, 'no') - self._enabledHelper(self.p.protocol, dR=['\x29']) - - def testAcceptDont(self): - # Try to disable an option. The server must allow any option to - # be disabled at any time. Make sure it disables it and sends - # back an acknowledgement of this. - cmd = telnet.IAC + telnet.DONT + '\x29' - - # Jimmy it - after these two lines, the server will be in a state - # such that it believes the option to have beenp previously enabled - # via normal negotiation. - s = self.p.getOptionState('\x29') - s.us.state = 'yes' - - bytes = "fiddle dum " + cmd - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), telnet.IAC + telnet.WONT + '\x29') - self.assertEqual(s.us.state, 'no') - self._enabledHelper(self.p.protocol, dL=['\x29']) - - def testIgnoreWont(self): - # Try to disable an option. The option is already disabled. The - # server should send nothing in response to this. - cmd = telnet.IAC + telnet.WONT + '\x47' - - bytes = "dum de dum" + cmd + "tra la la" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), '') - self._enabledHelper(self.p.protocol) - - def testIgnoreDont(self): - # Try to disable an option. The option is already disabled. The - # server should send nothing in response to this. Doing so could - # lead to a negotiation loop. - cmd = telnet.IAC + telnet.DONT + '\x47' - - bytes = "dum de dum" + cmd + "tra la la" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), '') - self._enabledHelper(self.p.protocol) - - def testIgnoreWill(self): - # Try to enable an option. The option is already enabled. The - # server should send nothing in response to this. Doing so could - # lead to a negotiation loop. - cmd = telnet.IAC + telnet.WILL + '\x56' - - # Jimmy it - after these two lines, the server will be in a state - # such that it believes the option to have been previously enabled - # via normal negotiation. - s = self.p.getOptionState('\x56') - s.him.state = 'yes' - - bytes = "tra la la" + cmd + "dum de dum" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), '') - self._enabledHelper(self.p.protocol) - - def testIgnoreDo(self): - # Try to enable an option. The option is already enabled. The - # server should send nothing in response to this. Doing so could - # lead to a negotiation loop. - cmd = telnet.IAC + telnet.DO + '\x56' - - # Jimmy it - after these two lines, the server will be in a state - # such that it believes the option to have been previously enabled - # via normal negotiation. - s = self.p.getOptionState('\x56') - s.us.state = 'yes' - - bytes = "tra la la" + cmd + "dum de dum" - self.p.dataReceived(bytes) - - self.assertEqual(self.p.protocol.bytes, bytes.replace(cmd, '')) - self.assertEqual(self.t.value(), '') - self._enabledHelper(self.p.protocol) - - def testAcceptedEnableRequest(self): - # Try to enable an option through the user-level API. This - # returns a Deferred that fires when negotiation about the option - # finishes. Make sure it fires, make sure state gets updated - # properly, make sure the result indicates the option was enabled. - d = self.p.do('\x42') - - h = self.p.protocol - h.remoteEnableable = ('\x42',) - - self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x42') - - self.p.dataReceived(telnet.IAC + telnet.WILL + '\x42') - - d.addCallback(self.assertEqual, True) - d.addCallback(lambda _: self._enabledHelper(h, eR=['\x42'])) - return d - - - def test_refusedEnableRequest(self): - """ - If the peer refuses to enable an option we request it to enable, the - L{Deferred} returned by L{TelnetProtocol.do} fires with an - L{OptionRefused} L{Failure}. - """ - # Try to enable an option through the user-level API. This returns a - # Deferred that fires when negotiation about the option finishes. Make - # sure it fires, make sure state gets updated properly, make sure the - # result indicates the option was enabled. - self.p.protocol.remoteEnableable = ('\x42',) - d = self.p.do('\x42') - - self.assertEqual(self.t.value(), telnet.IAC + telnet.DO + '\x42') - - s = self.p.getOptionState('\x42') - self.assertEqual(s.him.state, 'no') - self.assertEqual(s.us.state, 'no') - self.assertEqual(s.him.negotiating, True) - self.assertEqual(s.us.negotiating, False) - - self.p.dataReceived(telnet.IAC + telnet.WONT + '\x42') - - d = self.assertFailure(d, telnet.OptionRefused) - d.addCallback(lambda ignored: self._enabledHelper(self.p.protocol)) - d.addCallback( - lambda ignored: self.assertEqual(s.him.negotiating, False)) - return d - - - def test_refusedEnableOffer(self): - """ - If the peer refuses to allow us to enable an option, the L{Deferred} - returned by L{TelnetProtocol.will} fires with an L{OptionRefused} - L{Failure}. - """ - # Try to offer an option through the user-level API. This returns a - # Deferred that fires when negotiation about the option finishes. Make - # sure it fires, make sure state gets updated properly, make sure the - # result indicates the option was enabled. - self.p.protocol.localEnableable = ('\x42',) - d = self.p.will('\x42') - - self.assertEqual(self.t.value(), telnet.IAC + telnet.WILL + '\x42') - - s = self.p.getOptionState('\x42') - self.assertEqual(s.him.state, 'no') - self.assertEqual(s.us.state, 'no') - self.assertEqual(s.him.negotiating, False) - self.assertEqual(s.us.negotiating, True) - - self.p.dataReceived(telnet.IAC + telnet.DONT + '\x42') - - d = self.assertFailure(d, telnet.OptionRefused) - d.addCallback(lambda ignored: self._enabledHelper(self.p.protocol)) - d.addCallback( - lambda ignored: self.assertEqual(s.us.negotiating, False)) - return d - - - def testAcceptedDisableRequest(self): - # Try to disable an option through the user-level API. This - # returns a Deferred that fires when negotiation about the option - # finishes. Make sure it fires, make sure state gets updated - # properly, make sure the result indicates the option was enabled. - s = self.p.getOptionState('\x42') - s.him.state = 'yes' - - d = self.p.dont('\x42') - - self.assertEqual(self.t.value(), telnet.IAC + telnet.DONT + '\x42') - - self.p.dataReceived(telnet.IAC + telnet.WONT + '\x42') - - d.addCallback(self.assertEqual, True) - d.addCallback(lambda _: self._enabledHelper(self.p.protocol, - dR=['\x42'])) - return d - - def testNegotiationBlocksFurtherNegotiation(self): - # Try to disable an option, then immediately try to enable it, then - # immediately try to disable it. Ensure that the 2nd and 3rd calls - # fail quickly with the right exception. - s = self.p.getOptionState('\x24') - s.him.state = 'yes' - d2 = self.p.dont('\x24') # fires after the first line of _final - - def _do(x): - d = self.p.do('\x24') - return self.assertFailure(d, telnet.AlreadyNegotiating) - - def _dont(x): - d = self.p.dont('\x24') - return self.assertFailure(d, telnet.AlreadyNegotiating) - - def _final(x): - self.p.dataReceived(telnet.IAC + telnet.WONT + '\x24') - # an assertion that only passes if d2 has fired - self._enabledHelper(self.p.protocol, dR=['\x24']) - # Make sure we allow this - self.p.protocol.remoteEnableable = ('\x24',) - d = self.p.do('\x24') - self.p.dataReceived(telnet.IAC + telnet.WILL + '\x24') - d.addCallback(self.assertEqual, True) - d.addCallback(lambda _: self._enabledHelper(self.p.protocol, - eR=['\x24'], - dR=['\x24'])) - return d - - d = _do(None) - d.addCallback(_dont) - d.addCallback(_final) - return d - - def testSuperfluousDisableRequestRaises(self): - # Try to disable a disabled option. Make sure it fails properly. - d = self.p.dont('\xab') - return self.assertFailure(d, telnet.AlreadyDisabled) - - def testSuperfluousEnableRequestRaises(self): - # Try to disable a disabled option. Make sure it fails properly. - s = self.p.getOptionState('\xab') - s.him.state = 'yes' - d = self.p.do('\xab') - return self.assertFailure(d, telnet.AlreadyEnabled) - - def testLostConnectionFailsDeferreds(self): - d1 = self.p.do('\x12') - d2 = self.p.do('\x23') - d3 = self.p.do('\x34') - - class TestException(Exception): - pass - - self.p.connectionLost(TestException("Total failure!")) - - d1 = self.assertFailure(d1, TestException) - d2 = self.assertFailure(d2, TestException) - d3 = self.assertFailure(d3, TestException) - return defer.gatherResults([d1, d2, d3]) - - -class TestTelnet(telnet.Telnet): - """ - A trivial extension of the telnet protocol class useful to unit tests. - """ - def __init__(self): - telnet.Telnet.__init__(self) - self.events = [] - - - def applicationDataReceived(self, bytes): - """ - Record the given data in C{self.events}. - """ - self.events.append(('bytes', bytes)) - - - def unhandledCommand(self, command, bytes): - """ - Record the given command in C{self.events}. - """ - self.events.append(('command', command, bytes)) - - - def unhandledSubnegotiation(self, command, bytes): - """ - Record the given subnegotiation command in C{self.events}. - """ - self.events.append(('negotiate', command, bytes)) - - - -class TelnetTests(unittest.TestCase): - """ - Tests for L{telnet.Telnet}. - - L{telnet.Telnet} implements the TELNET protocol (RFC 854), including option - and suboption negotiation, and option state tracking. - """ - def setUp(self): - """ - Create an unconnected L{telnet.Telnet} to be used by tests. - """ - self.protocol = TestTelnet() - - - def test_enableLocal(self): - """ - L{telnet.Telnet.enableLocal} should reject all options, since - L{telnet.Telnet} does not know how to implement any options. - """ - self.assertFalse(self.protocol.enableLocal('\0')) - - - def test_enableRemote(self): - """ - L{telnet.Telnet.enableRemote} should reject all options, since - L{telnet.Telnet} does not know how to implement any options. - """ - self.assertFalse(self.protocol.enableRemote('\0')) - - - def test_disableLocal(self): - """ - It is an error for L{telnet.Telnet.disableLocal} to be called, since - L{telnet.Telnet.enableLocal} will never allow any options to be enabled - locally. If a subclass overrides enableLocal, it must also override - disableLocal. - """ - self.assertRaises(NotImplementedError, self.protocol.disableLocal, '\0') - - - def test_disableRemote(self): - """ - It is an error for L{telnet.Telnet.disableRemote} to be called, since - L{telnet.Telnet.enableRemote} will never allow any options to be - enabled remotely. If a subclass overrides enableRemote, it must also - override disableRemote. - """ - self.assertRaises(NotImplementedError, self.protocol.disableRemote, '\0') - - - def test_requestNegotiation(self): - """ - L{telnet.Telnet.requestNegotiation} formats the feature byte and the - payload bytes into the subnegotiation format and sends them. - - See RFC 855. - """ - transport = proto_helpers.StringTransport() - self.protocol.makeConnection(transport) - self.protocol.requestNegotiation('\x01', '\x02\x03') - self.assertEqual( - transport.value(), - # IAC SB feature bytes IAC SE - '\xff\xfa\x01\x02\x03\xff\xf0') - - - def test_requestNegotiationEscapesIAC(self): - """ - If the payload for a subnegotiation includes I{IAC}, it is escaped by - L{telnet.Telnet.requestNegotiation} with another I{IAC}. - - See RFC 855. - """ - transport = proto_helpers.StringTransport() - self.protocol.makeConnection(transport) - self.protocol.requestNegotiation('\x01', '\xff') - self.assertEqual( - transport.value(), - '\xff\xfa\x01\xff\xff\xff\xf0') - - - def _deliver(self, bytes, *expected): - """ - Pass the given bytes to the protocol's C{dataReceived} method and - assert that the given events occur. - """ - received = self.protocol.events = [] - self.protocol.dataReceived(bytes) - self.assertEqual(received, list(expected)) - - - def test_oneApplicationDataByte(self): - """ - One application-data byte in the default state gets delivered right - away. - """ - self._deliver('a', ('bytes', 'a')) - - - def test_twoApplicationDataBytes(self): - """ - Two application-data bytes in the default state get delivered - together. - """ - self._deliver('bc', ('bytes', 'bc')) - - - def test_threeApplicationDataBytes(self): - """ - Three application-data bytes followed by a control byte get - delivered, but the control byte doesn't. - """ - self._deliver('def' + telnet.IAC, ('bytes', 'def')) - - - def test_escapedControl(self): - """ - IAC in the escaped state gets delivered and so does another - application-data byte following it. - """ - self._deliver(telnet.IAC) - self._deliver(telnet.IAC + 'g', ('bytes', telnet.IAC + 'g')) - - - def test_carriageReturn(self): - """ - A carriage return only puts the protocol into the newline state. A - linefeed in the newline state causes just the newline to be - delivered. A nul in the newline state causes a carriage return to - be delivered. An IAC in the newline state causes a carriage return - to be delivered and puts the protocol into the escaped state. - Anything else causes a carriage return and that thing to be - delivered. - """ - self._deliver('\r') - self._deliver('\n', ('bytes', '\n')) - self._deliver('\r\n', ('bytes', '\n')) - - self._deliver('\r') - self._deliver('\0', ('bytes', '\r')) - self._deliver('\r\0', ('bytes', '\r')) - - self._deliver('\r') - self._deliver('a', ('bytes', '\ra')) - self._deliver('\ra', ('bytes', '\ra')) - - self._deliver('\r') - self._deliver( - telnet.IAC + telnet.IAC + 'x', ('bytes', '\r' + telnet.IAC + 'x')) - - - def test_applicationDataBeforeSimpleCommand(self): - """ - Application bytes received before a command are delivered before the - command is processed. - """ - self._deliver( - 'x' + telnet.IAC + telnet.NOP, - ('bytes', 'x'), ('command', telnet.NOP, None)) - - - def test_applicationDataBeforeCommand(self): - """ - Application bytes received before a WILL/WONT/DO/DONT are delivered - before the command is processed. - """ - self.protocol.commandMap = {} - self._deliver( - 'y' + telnet.IAC + telnet.WILL + '\x00', - ('bytes', 'y'), ('command', telnet.WILL, '\x00')) - - - def test_applicationDataBeforeSubnegotiation(self): - """ - Application bytes received before a subnegotiation command are - delivered before the negotiation is processed. - """ - self._deliver( - 'z' + telnet.IAC + telnet.SB + 'Qx' + telnet.IAC + telnet.SE, - ('bytes', 'z'), ('negotiate', 'Q', ['x'])) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py deleted file mode 100755 index 1d688703..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_text.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_text -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -from twisted.trial import unittest - -from twisted.conch.insults import helper, text - -A = text.attributes - -class Serialization(unittest.TestCase): - def setUp(self): - self.attrs = helper.CharacterAttribute() - - def testTrivial(self): - self.assertEqual( - text.flatten(A.normal['Hello, world.'], self.attrs), - 'Hello, world.') - - def testBold(self): - self.assertEqual( - text.flatten(A.bold['Hello, world.'], self.attrs), - '\x1b[1mHello, world.') - - def testUnderline(self): - self.assertEqual( - text.flatten(A.underline['Hello, world.'], self.attrs), - '\x1b[4mHello, world.') - - def testBlink(self): - self.assertEqual( - text.flatten(A.blink['Hello, world.'], self.attrs), - '\x1b[5mHello, world.') - - def testReverseVideo(self): - self.assertEqual( - text.flatten(A.reverseVideo['Hello, world.'], self.attrs), - '\x1b[7mHello, world.') - - def testMinus(self): - self.assertEqual( - text.flatten( - A.bold[A.blink['Hello', -A.bold[' world'], '.']], - self.attrs), - '\x1b[1;5mHello\x1b[0;5m world\x1b[1;5m.') - - def testForeground(self): - self.assertEqual( - text.flatten( - A.normal[A.fg.red['Hello, '], A.fg.green['world!']], - self.attrs), - '\x1b[31mHello, \x1b[32mworld!') - - def testBackground(self): - self.assertEqual( - text.flatten( - A.normal[A.bg.red['Hello, '], A.bg.green['world!']], - self.attrs), - '\x1b[41mHello, \x1b[42mworld!') - - -class EfficiencyTestCase(unittest.TestCase): - todo = ("flatten() isn't quite stateful enough to avoid emitting a few extra bytes in " - "certain circumstances, so these tests fail. The failures take the form of " - "additional elements in the ;-delimited character attribute lists. For example, " - "\\x1b[0;31;46m might be emitted instead of \\x[46m, even if 31 has already been " - "activated and no conflicting attributes are set which need to be cleared.") - - def setUp(self): - self.attrs = helper.CharacterAttribute() - - def testComplexStructure(self): - output = A.normal[ - A.bold[ - A.bg.cyan[ - A.fg.red[ - "Foreground Red, Background Cyan, Bold", - A.blink[ - "Blinking"], - -A.bold[ - "Foreground Red, Background Cyan, normal"]], - A.fg.green[ - "Foreground Green, Background Cyan, Bold"]]]] - - self.assertEqual( - text.flatten(output, self.attrs), - "\x1b[1;31;46mForeground Red, Background Cyan, Bold" - "\x1b[5mBlinking" - "\x1b[0;31;46mForeground Red, Background Cyan, normal" - "\x1b[1;32;46mForeground Green, Background Cyan, Bold") - - def testNesting(self): - self.assertEqual( - text.flatten(A.bold['Hello, ', A.underline['world.']], self.attrs), - '\x1b[1mHello, \x1b[4mworld.') - - self.assertEqual( - text.flatten( - A.bold[A.reverseVideo['Hello, ', A.normal['world'], '.']], - self.attrs), - '\x1b[1;7mHello, \x1b[0mworld\x1b[1;7m.') diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py deleted file mode 100755 index 8b801b0b..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_transport.py +++ /dev/null @@ -1,2225 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for ssh/transport.py and the classes therein. -""" - -try: - import pyasn1 -except ImportError: - pyasn1 = None - -try: - import Crypto.Cipher.DES3 -except ImportError: - Crypto = None - -if pyasn1 is not None and Crypto is not None: - dependencySkip = None - from twisted.conch.ssh import transport, keys, factory - from twisted.conch.test import keydata -else: - if pyasn1 is None: - dependencySkip = "Cannot run without PyASN1" - elif Crypto is None: - dependencySkip = "can't run w/o PyCrypto" - - class transport: # fictional modules to make classes work - class SSHTransportBase: pass - class SSHServerTransport: pass - class SSHClientTransport: pass - class factory: - class SSHFactory: - pass - -from twisted.trial import unittest -from twisted.internet import defer -from twisted.protocols import loopback -from twisted.python import randbytes -from twisted.python.reflect import qual, getClass -from twisted.python.hashlib import md5, sha1 -from twisted.conch.ssh import address, service, common -from twisted.test import proto_helpers - -from twisted.conch.error import ConchError - -class MockTransportBase(transport.SSHTransportBase): - """ - A base class for the client and server protocols. Stores the messages - it receieves instead of ignoring them. - - @ivar errors: a list of tuples: (reasonCode, description) - @ivar unimplementeds: a list of integers: sequence number - @ivar debugs: a list of tuples: (alwaysDisplay, message, lang) - @ivar ignoreds: a list of strings: ignored data - """ - - def connectionMade(self): - """ - Set up instance variables. - """ - transport.SSHTransportBase.connectionMade(self) - self.errors = [] - self.unimplementeds = [] - self.debugs = [] - self.ignoreds = [] - self.gotUnsupportedVersion = None - - - def _unsupportedVersionReceived(self, remoteVersion): - """ - Intercept unsupported version call. - - @type remoteVersion: C{str} - """ - self.gotUnsupportedVersion = remoteVersion - return transport.SSHTransportBase._unsupportedVersionReceived( - self, remoteVersion) - - - def receiveError(self, reasonCode, description): - """ - Store any errors received. - - @type reasonCode: C{int} - @type description: C{str} - """ - self.errors.append((reasonCode, description)) - - - def receiveUnimplemented(self, seqnum): - """ - Store any unimplemented packet messages. - - @type seqnum: C{int} - """ - self.unimplementeds.append(seqnum) - - - def receiveDebug(self, alwaysDisplay, message, lang): - """ - Store any debug messages. - - @type alwaysDisplay: C{bool} - @type message: C{str} - @type lang: C{str} - """ - self.debugs.append((alwaysDisplay, message, lang)) - - - def ssh_IGNORE(self, packet): - """ - Store any ignored data. - - @type packet: C{str} - """ - self.ignoreds.append(packet) - - -class MockCipher(object): - """ - A mocked-up version of twisted.conch.ssh.transport.SSHCiphers. - """ - outCipType = 'test' - encBlockSize = 6 - inCipType = 'test' - decBlockSize = 6 - inMACType = 'test' - outMACType = 'test' - verifyDigestSize = 1 - usedEncrypt = False - usedDecrypt = False - outMAC = (None, '', '', 1) - inMAC = (None, '', '', 1) - keys = () - - - def encrypt(self, x): - """ - Called to encrypt the packet. Simply record that encryption was used - and return the data unchanged. - """ - self.usedEncrypt = True - if (len(x) % self.encBlockSize) != 0: - raise RuntimeError("length %i modulo blocksize %i is not 0: %i" % - (len(x), self.encBlockSize, len(x) % self.encBlockSize)) - return x - - - def decrypt(self, x): - """ - Called to decrypt the packet. Simply record that decryption was used - and return the data unchanged. - """ - self.usedDecrypt = True - if (len(x) % self.encBlockSize) != 0: - raise RuntimeError("length %i modulo blocksize %i is not 0: %i" % - (len(x), self.decBlockSize, len(x) % self.decBlockSize)) - return x - - - def makeMAC(self, outgoingPacketSequence, payload): - """ - Make a Message Authentication Code by sending the character value of - the outgoing packet. - """ - return chr(outgoingPacketSequence) - - - def verify(self, incomingPacketSequence, packet, macData): - """ - Verify the Message Authentication Code by checking that the packet - sequence number is the same. - """ - return chr(incomingPacketSequence) == macData - - - def setKeys(self, ivOut, keyOut, ivIn, keyIn, macIn, macOut): - """ - Record the keys. - """ - self.keys = (ivOut, keyOut, ivIn, keyIn, macIn, macOut) - - - -class MockCompression: - """ - A mocked-up compression, based on the zlib interface. Instead of - compressing, it reverses the data and adds a 0x66 byte to the end. - """ - - - def compress(self, payload): - return payload[::-1] # reversed - - - def decompress(self, payload): - return payload[:-1][::-1] - - - def flush(self, kind): - return '\x66' - - - -class MockService(service.SSHService): - """ - A mocked-up service, based on twisted.conch.ssh.service.SSHService. - - @ivar started: True if this service has been started. - @ivar stopped: True if this service has been stopped. - """ - name = "MockService" - started = False - stopped = False - protocolMessages = {0xff: "MSG_TEST", 71: "MSG_fiction"} - - - def logPrefix(self): - return "MockService" - - - def serviceStarted(self): - """ - Record that the service was started. - """ - self.started = True - - - def serviceStopped(self): - """ - Record that the service was stopped. - """ - self.stopped = True - - - def ssh_TEST(self, packet): - """ - A message that this service responds to. - """ - self.transport.sendPacket(0xff, packet) - - -class MockFactory(factory.SSHFactory): - """ - A mocked-up factory based on twisted.conch.ssh.factory.SSHFactory. - """ - services = { - 'ssh-userauth': MockService} - - - def getPublicKeys(self): - """ - Return the public keys that authenticate this server. - """ - return { - 'ssh-rsa': keys.Key.fromString(keydata.publicRSA_openssh), - 'ssh-dsa': keys.Key.fromString(keydata.publicDSA_openssh)} - - - def getPrivateKeys(self): - """ - Return the private keys that authenticate this server. - """ - return { - 'ssh-rsa': keys.Key.fromString(keydata.privateRSA_openssh), - 'ssh-dsa': keys.Key.fromString(keydata.privateDSA_openssh)} - - - def getPrimes(self): - """ - Return the Diffie-Hellman primes that can be used for the - diffie-hellman-group-exchange-sha1 key exchange. - """ - return { - 1024: ((2, transport.DH_PRIME),), - 2048: ((3, transport.DH_PRIME),), - 4096: ((5, 7),)} - - - -class MockOldFactoryPublicKeys(MockFactory): - """ - The old SSHFactory returned mappings from key names to strings from - getPublicKeys(). We return those here for testing. - """ - - - def getPublicKeys(self): - """ - We used to map key types to public key blobs as strings. - """ - keys = MockFactory.getPublicKeys(self) - for name, key in keys.items()[:]: - keys[name] = key.blob() - return keys - - - -class MockOldFactoryPrivateKeys(MockFactory): - """ - The old SSHFactory returned mappings from key names to PyCrypto key - objects from getPrivateKeys(). We return those here for testing. - """ - - - def getPrivateKeys(self): - """ - We used to map key types to PyCrypto key objects. - """ - keys = MockFactory.getPrivateKeys(self) - for name, key in keys.items()[:]: - keys[name] = key.keyObject - return keys - - -class TransportTestCase(unittest.TestCase): - """ - Base class for transport test cases. - """ - klass = None - - if Crypto is None: - skip = "cannot run w/o PyCrypto" - - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - - def setUp(self): - self.transport = proto_helpers.StringTransport() - self.proto = self.klass() - self.packets = [] - def secureRandom(len): - """ - Return a consistent entropy value - """ - return '\x99' * len - self.oldSecureRandom = randbytes.secureRandom - randbytes.secureRandom = secureRandom - def stubSendPacket(messageType, payload): - self.packets.append((messageType, payload)) - self.proto.makeConnection(self.transport) - # we just let the kex packet go into the transport - self.proto.sendPacket = stubSendPacket - - - def finishKeyExchange(self, proto): - """ - Deliver enough additional messages to C{proto} so that the key exchange - which is started in L{SSHTransportBase.connectionMade} completes and - non-key exchange messages can be sent and received. - """ - proto.dataReceived("SSH-2.0-BogoClient-1.2i\r\n") - proto.dispatchMessage( - transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE) - proto._keySetup("foo", "bar") - # SSHTransportBase can't handle MSG_NEWKEYS, or it would be the right - # thing to deliver next. _newKeys won't work either, because - # sendKexInit (probably) hasn't been called. sendKexInit is - # responsible for setting up certain state _newKeys relies on. So, - # just change the key exchange state to what it would be when key - # exchange is finished. - proto._keyExchangeState = proto._KEY_EXCHANGE_NONE - - - def tearDown(self): - randbytes.secureRandom = self.oldSecureRandom - self.oldSecureRandom = None - - - def simulateKeyExchange(self, sharedSecret, exchangeHash): - """ - Finish a key exchange by calling C{_keySetup} with the given arguments. - Also do extra whitebox stuff to satisfy that method's assumption that - some kind of key exchange has actually taken place. - """ - self.proto._keyExchangeState = self.proto._KEY_EXCHANGE_REQUESTED - self.proto._blockedByKeyExchange = [] - self.proto._keySetup(sharedSecret, exchangeHash) - - - -class BaseSSHTransportTestCase(TransportTestCase): - """ - Test TransportBase. It implements the non-server/client specific - parts of the SSH transport protocol. - """ - - klass = MockTransportBase - - _A_KEXINIT_MESSAGE = ( - "\xAA" * 16 + - common.NS('diffie-hellman-group1-sha1') + - common.NS('ssh-rsa') + - common.NS('aes256-ctr') + - common.NS('aes256-ctr') + - common.NS('hmac-sha1') + - common.NS('hmac-sha1') + - common.NS('none') + - common.NS('none') + - common.NS('') + - common.NS('') + - '\x00' + '\x00\x00\x00\x00') - - def test_sendVersion(self): - """ - Test that the first thing sent over the connection is the version - string. - """ - # the other setup was done in the setup method - self.assertEqual(self.transport.value().split('\r\n', 1)[0], - "SSH-2.0-Twisted") - - - def test_sendPacketPlain(self): - """ - Test that plain (unencrypted, uncompressed) packets are sent - correctly. The format is:: - uint32 length (including type and padding length) - byte padding length - byte type - bytes[length-padding length-2] data - bytes[padding length] padding - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - self.transport.clear() - message = ord('A') - payload = 'BCDEFG' - proto.sendPacket(message, payload) - value = self.transport.value() - self.assertEqual(value, '\x00\x00\x00\x0c\x04ABCDEFG\x99\x99\x99\x99') - - - def test_sendPacketEncrypted(self): - """ - Test that packets sent while encryption is enabled are sent - correctly. The whole packet should be encrypted. - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - proto.currentEncryptions = testCipher = MockCipher() - message = ord('A') - payload = 'BC' - self.transport.clear() - proto.sendPacket(message, payload) - self.assertTrue(testCipher.usedEncrypt) - value = self.transport.value() - self.assertEqual( - value, - # Four byte length prefix - '\x00\x00\x00\x08' - # One byte padding length - '\x04' - # The actual application data - 'ABC' - # "Random" padding - see the secureRandom monkeypatch in setUp - '\x99\x99\x99\x99' - # The MAC - '\x02') - - - def test_sendPacketCompressed(self): - """ - Test that packets sent while compression is enabled are sent - correctly. The packet type and data should be encrypted. - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - proto.outgoingCompression = MockCompression() - self.transport.clear() - proto.sendPacket(ord('A'), 'B') - value = self.transport.value() - self.assertEqual( - value, - '\x00\x00\x00\x0c\x08BA\x66\x99\x99\x99\x99\x99\x99\x99\x99') - - - def test_sendPacketBoth(self): - """ - Test that packets sent while compression and encryption are - enabled are sent correctly. The packet type and data should be - compressed and then the whole packet should be encrypted. - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - proto.currentEncryptions = testCipher = MockCipher() - proto.outgoingCompression = MockCompression() - message = ord('A') - payload = 'BC' - self.transport.clear() - proto.sendPacket(message, payload) - self.assertTrue(testCipher.usedEncrypt) - value = self.transport.value() - self.assertEqual( - value, - # Four byte length prefix - '\x00\x00\x00\x0e' - # One byte padding length - '\x09' - # Compressed application data - 'CBA\x66' - # "Random" padding - see the secureRandom monkeypatch in setUp - '\x99\x99\x99\x99\x99\x99\x99\x99\x99' - # The MAC - '\x02') - - - def test_getPacketPlain(self): - """ - Test that packets are retrieved correctly out of the buffer when - no encryption is enabled. - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - self.transport.clear() - proto.sendPacket(ord('A'), 'BC') - proto.buf = self.transport.value() + 'extra' - self.assertEqual(proto.getPacket(), 'ABC') - self.assertEqual(proto.buf, 'extra') - - - def test_getPacketEncrypted(self): - """ - Test that encrypted packets are retrieved correctly. - See test_sendPacketEncrypted. - """ - proto = MockTransportBase() - proto.sendKexInit = lambda: None # don't send packets - proto.makeConnection(self.transport) - self.transport.clear() - proto.currentEncryptions = testCipher = MockCipher() - proto.sendPacket(ord('A'), 'BCD') - value = self.transport.value() - proto.buf = value[:MockCipher.decBlockSize] - self.assertEqual(proto.getPacket(), None) - self.assertTrue(testCipher.usedDecrypt) - self.assertEqual(proto.first, '\x00\x00\x00\x0e\x09A') - proto.buf += value[MockCipher.decBlockSize:] - self.assertEqual(proto.getPacket(), 'ABCD') - self.assertEqual(proto.buf, '') - - - def test_getPacketCompressed(self): - """ - Test that compressed packets are retrieved correctly. See - test_sendPacketCompressed. - """ - proto = MockTransportBase() - proto.makeConnection(self.transport) - self.finishKeyExchange(proto) - self.transport.clear() - proto.outgoingCompression = MockCompression() - proto.incomingCompression = proto.outgoingCompression - proto.sendPacket(ord('A'), 'BCD') - proto.buf = self.transport.value() - self.assertEqual(proto.getPacket(), 'ABCD') - - - def test_getPacketBoth(self): - """ - Test that compressed and encrypted packets are retrieved correctly. - See test_sendPacketBoth. - """ - proto = MockTransportBase() - proto.sendKexInit = lambda: None - proto.makeConnection(self.transport) - self.transport.clear() - proto.currentEncryptions = MockCipher() - proto.outgoingCompression = MockCompression() - proto.incomingCompression = proto.outgoingCompression - proto.sendPacket(ord('A'), 'BCDEFG') - proto.buf = self.transport.value() - self.assertEqual(proto.getPacket(), 'ABCDEFG') - - - def test_ciphersAreValid(self): - """ - Test that all the supportedCiphers are valid. - """ - ciphers = transport.SSHCiphers('A', 'B', 'C', 'D') - iv = key = '\x00' * 16 - for cipName in self.proto.supportedCiphers: - self.assertTrue(ciphers._getCipher(cipName, iv, key)) - - - def test_sendKexInit(self): - """ - Test that the KEXINIT (key exchange initiation) message is sent - correctly. Payload:: - bytes[16] cookie - string key exchange algorithms - string public key algorithms - string outgoing ciphers - string incoming ciphers - string outgoing MACs - string incoming MACs - string outgoing compressions - string incoming compressions - bool first packet follows - uint32 0 - """ - value = self.transport.value().split('\r\n', 1)[1] - self.proto.buf = value - packet = self.proto.getPacket() - self.assertEqual(packet[0], chr(transport.MSG_KEXINIT)) - self.assertEqual(packet[1:17], '\x99' * 16) - (kex, pubkeys, ciphers1, ciphers2, macs1, macs2, compressions1, - compressions2, languages1, languages2, - buf) = common.getNS(packet[17:], 10) - - self.assertEqual(kex, ','.join(self.proto.supportedKeyExchanges)) - self.assertEqual(pubkeys, ','.join(self.proto.supportedPublicKeys)) - self.assertEqual(ciphers1, ','.join(self.proto.supportedCiphers)) - self.assertEqual(ciphers2, ','.join(self.proto.supportedCiphers)) - self.assertEqual(macs1, ','.join(self.proto.supportedMACs)) - self.assertEqual(macs2, ','.join(self.proto.supportedMACs)) - self.assertEqual(compressions1, - ','.join(self.proto.supportedCompressions)) - self.assertEqual(compressions2, - ','.join(self.proto.supportedCompressions)) - self.assertEqual(languages1, ','.join(self.proto.supportedLanguages)) - self.assertEqual(languages2, ','.join(self.proto.supportedLanguages)) - self.assertEqual(buf, '\x00' * 5) - - - def test_receiveKEXINITReply(self): - """ - Immediately after connecting, the transport expects a KEXINIT message - and does not reply to it. - """ - self.transport.clear() - self.proto.dispatchMessage( - transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE) - self.assertEqual(self.packets, []) - - - def test_sendKEXINITReply(self): - """ - When a KEXINIT message is received which is not a reply to an earlier - KEXINIT message which was sent, a KEXINIT reply is sent. - """ - self.finishKeyExchange(self.proto) - del self.packets[:] - - self.proto.dispatchMessage( - transport.MSG_KEXINIT, self._A_KEXINIT_MESSAGE) - self.assertEqual(len(self.packets), 1) - self.assertEqual(self.packets[0][0], transport.MSG_KEXINIT) - - - def test_sendKexInitTwiceFails(self): - """ - A new key exchange cannot be started while a key exchange is already in - progress. If an attempt is made to send a I{KEXINIT} message using - L{SSHTransportBase.sendKexInit} while a key exchange is in progress - causes that method to raise a L{RuntimeError}. - """ - self.assertRaises(RuntimeError, self.proto.sendKexInit) - - - def test_sendKexInitBlocksOthers(self): - """ - After L{SSHTransportBase.sendKexInit} has been called, messages types - other than the following are queued and not sent until after I{NEWKEYS} - is sent by L{SSHTransportBase._keySetup}. - - RFC 4253, section 7.1. - """ - # sendKexInit is called by connectionMade, which is called in setUp. - # So we're in the state already. - disallowedMessageTypes = [ - transport.MSG_SERVICE_REQUEST, - transport.MSG_KEXINIT, - ] - - # Drop all the bytes sent by setUp, they're not relevant to this test. - self.transport.clear() - - # Get rid of the sendPacket monkey patch, we are testing the behavior - # of sendPacket. - del self.proto.sendPacket - - for messageType in disallowedMessageTypes: - self.proto.sendPacket(messageType, 'foo') - self.assertEqual(self.transport.value(), "") - - self.finishKeyExchange(self.proto) - # Make the bytes written to the transport cleartext so it's easier to - # make an assertion about them. - self.proto.nextEncryptions = MockCipher() - - # Pseudo-deliver the peer's NEWKEYS message, which should flush the - # messages which were queued above. - self.proto._newKeys() - self.assertEqual(self.transport.value().count("foo"), 2) - - - def test_sendDebug(self): - """ - Test that debug messages are sent correctly. Payload:: - bool always display - string debug message - string language - """ - self.proto.sendDebug("test", True, 'en') - self.assertEqual( - self.packets, - [(transport.MSG_DEBUG, - "\x01\x00\x00\x00\x04test\x00\x00\x00\x02en")]) - - - def test_receiveDebug(self): - """ - Test that debug messages are received correctly. See test_sendDebug. - """ - self.proto.dispatchMessage( - transport.MSG_DEBUG, - '\x01\x00\x00\x00\x04test\x00\x00\x00\x02en') - self.assertEqual(self.proto.debugs, [(True, 'test', 'en')]) - - - def test_sendIgnore(self): - """ - Test that ignored messages are sent correctly. Payload:: - string ignored data - """ - self.proto.sendIgnore("test") - self.assertEqual( - self.packets, [(transport.MSG_IGNORE, - '\x00\x00\x00\x04test')]) - - - def test_receiveIgnore(self): - """ - Test that ignored messages are received correctly. See - test_sendIgnore. - """ - self.proto.dispatchMessage(transport.MSG_IGNORE, 'test') - self.assertEqual(self.proto.ignoreds, ['test']) - - - def test_sendUnimplemented(self): - """ - Test that unimplemented messages are sent correctly. Payload:: - uint32 sequence number - """ - self.proto.sendUnimplemented() - self.assertEqual( - self.packets, [(transport.MSG_UNIMPLEMENTED, - '\x00\x00\x00\x00')]) - - - def test_receiveUnimplemented(self): - """ - Test that unimplemented messages are received correctly. See - test_sendUnimplemented. - """ - self.proto.dispatchMessage(transport.MSG_UNIMPLEMENTED, - '\x00\x00\x00\xff') - self.assertEqual(self.proto.unimplementeds, [255]) - - - def test_sendDisconnect(self): - """ - Test that disconnection messages are sent correctly. Payload:: - uint32 reason code - string reason description - string language - """ - disconnected = [False] - def stubLoseConnection(): - disconnected[0] = True - self.transport.loseConnection = stubLoseConnection - self.proto.sendDisconnect(0xff, "test") - self.assertEqual( - self.packets, - [(transport.MSG_DISCONNECT, - "\x00\x00\x00\xff\x00\x00\x00\x04test\x00\x00\x00\x00")]) - self.assertTrue(disconnected[0]) - - - def test_receiveDisconnect(self): - """ - Test that disconnection messages are received correctly. See - test_sendDisconnect. - """ - disconnected = [False] - def stubLoseConnection(): - disconnected[0] = True - self.transport.loseConnection = stubLoseConnection - self.proto.dispatchMessage(transport.MSG_DISCONNECT, - '\x00\x00\x00\xff\x00\x00\x00\x04test') - self.assertEqual(self.proto.errors, [(255, 'test')]) - self.assertTrue(disconnected[0]) - - - def test_dataReceived(self): - """ - Test that dataReceived parses packets and dispatches them to - ssh_* methods. - """ - kexInit = [False] - def stubKEXINIT(packet): - kexInit[0] = True - self.proto.ssh_KEXINIT = stubKEXINIT - self.proto.dataReceived(self.transport.value()) - self.assertTrue(self.proto.gotVersion) - self.assertEqual(self.proto.ourVersionString, - self.proto.otherVersionString) - self.assertTrue(kexInit[0]) - - - def test_service(self): - """ - Test that the transport can set the running service and dispatches - packets to the service's packetReceived method. - """ - service = MockService() - self.proto.setService(service) - self.assertEqual(self.proto.service, service) - self.assertTrue(service.started) - self.proto.dispatchMessage(0xff, "test") - self.assertEqual(self.packets, [(0xff, "test")]) - - service2 = MockService() - self.proto.setService(service2) - self.assertTrue(service2.started) - self.assertTrue(service.stopped) - - self.proto.connectionLost(None) - self.assertTrue(service2.stopped) - - - def test_avatar(self): - """ - Test that the transport notifies the avatar of disconnections. - """ - disconnected = [False] - def logout(): - disconnected[0] = True - self.proto.logoutFunction = logout - self.proto.avatar = True - - self.proto.connectionLost(None) - self.assertTrue(disconnected[0]) - - - def test_isEncrypted(self): - """ - Test that the transport accurately reflects its encrypted status. - """ - self.assertFalse(self.proto.isEncrypted('in')) - self.assertFalse(self.proto.isEncrypted('out')) - self.assertFalse(self.proto.isEncrypted('both')) - self.proto.currentEncryptions = MockCipher() - self.assertTrue(self.proto.isEncrypted('in')) - self.assertTrue(self.proto.isEncrypted('out')) - self.assertTrue(self.proto.isEncrypted('both')) - self.proto.currentEncryptions = transport.SSHCiphers('none', 'none', - 'none', 'none') - self.assertFalse(self.proto.isEncrypted('in')) - self.assertFalse(self.proto.isEncrypted('out')) - self.assertFalse(self.proto.isEncrypted('both')) - - self.assertRaises(TypeError, self.proto.isEncrypted, 'bad') - - - def test_isVerified(self): - """ - Test that the transport accurately reflects its verified status. - """ - self.assertFalse(self.proto.isVerified('in')) - self.assertFalse(self.proto.isVerified('out')) - self.assertFalse(self.proto.isVerified('both')) - self.proto.currentEncryptions = MockCipher() - self.assertTrue(self.proto.isVerified('in')) - self.assertTrue(self.proto.isVerified('out')) - self.assertTrue(self.proto.isVerified('both')) - self.proto.currentEncryptions = transport.SSHCiphers('none', 'none', - 'none', 'none') - self.assertFalse(self.proto.isVerified('in')) - self.assertFalse(self.proto.isVerified('out')) - self.assertFalse(self.proto.isVerified('both')) - - self.assertRaises(TypeError, self.proto.isVerified, 'bad') - - - def test_loseConnection(self): - """ - Test that loseConnection sends a disconnect message and closes the - connection. - """ - disconnected = [False] - def stubLoseConnection(): - disconnected[0] = True - self.transport.loseConnection = stubLoseConnection - self.proto.loseConnection() - self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT) - self.assertEqual(self.packets[0][1][3], - chr(transport.DISCONNECT_CONNECTION_LOST)) - - - def test_badVersion(self): - """ - Test that the transport disconnects when it receives a bad version. - """ - def testBad(version): - self.packets = [] - self.proto.gotVersion = False - disconnected = [False] - def stubLoseConnection(): - disconnected[0] = True - self.transport.loseConnection = stubLoseConnection - for c in version + '\r\n': - self.proto.dataReceived(c) - self.assertTrue(disconnected[0]) - self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT) - self.assertEqual( - self.packets[0][1][3], - chr(transport.DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED)) - testBad('SSH-1.5-OpenSSH') - testBad('SSH-3.0-Twisted') - testBad('GET / HTTP/1.1') - - - def test_dataBeforeVersion(self): - """ - Test that the transport ignores data sent before the version string. - """ - proto = MockTransportBase() - proto.makeConnection(proto_helpers.StringTransport()) - data = ("""here's some stuff beforehand -here's some other stuff -""" + proto.ourVersionString + "\r\n") - [proto.dataReceived(c) for c in data] - self.assertTrue(proto.gotVersion) - self.assertEqual(proto.otherVersionString, proto.ourVersionString) - - - def test_compatabilityVersion(self): - """ - Test that the transport treats the compatbility version (1.99) - as equivalent to version 2.0. - """ - proto = MockTransportBase() - proto.makeConnection(proto_helpers.StringTransport()) - proto.dataReceived("SSH-1.99-OpenSSH\n") - self.assertTrue(proto.gotVersion) - self.assertEqual(proto.otherVersionString, "SSH-1.99-OpenSSH") - - - def test_supportedVersionsAreAllowed(self): - """ - If an unusual SSH version is received and is included in - C{supportedVersions}, an unsupported version error is not emitted. - """ - proto = MockTransportBase() - proto.supportedVersions = ("9.99", ) - proto.makeConnection(proto_helpers.StringTransport()) - proto.dataReceived("SSH-9.99-OpenSSH\n") - self.assertFalse(proto.gotUnsupportedVersion) - - - def test_unsupportedVersionsCallUnsupportedVersionReceived(self): - """ - If an unusual SSH version is received and is not included in - C{supportedVersions}, an unsupported version error is emitted. - """ - proto = MockTransportBase() - proto.supportedVersions = ("2.0", ) - proto.makeConnection(proto_helpers.StringTransport()) - proto.dataReceived("SSH-9.99-OpenSSH\n") - self.assertEqual("9.99", proto.gotUnsupportedVersion) - - - def test_badPackets(self): - """ - Test that the transport disconnects with an error when it receives - bad packets. - """ - def testBad(packet, error=transport.DISCONNECT_PROTOCOL_ERROR): - self.packets = [] - self.proto.buf = packet - self.assertEqual(self.proto.getPacket(), None) - self.assertEqual(len(self.packets), 1) - self.assertEqual(self.packets[0][0], transport.MSG_DISCONNECT) - self.assertEqual(self.packets[0][1][3], chr(error)) - - testBad('\xff' * 8) # big packet - testBad('\x00\x00\x00\x05\x00BCDE') # length not modulo blocksize - oldEncryptions = self.proto.currentEncryptions - self.proto.currentEncryptions = MockCipher() - testBad('\x00\x00\x00\x08\x06AB123456', # bad MAC - transport.DISCONNECT_MAC_ERROR) - self.proto.currentEncryptions.decrypt = lambda x: x[:-1] - testBad('\x00\x00\x00\x08\x06BCDEFGHIJK') # bad decryption - self.proto.currentEncryptions = oldEncryptions - self.proto.incomingCompression = MockCompression() - def stubDecompress(payload): - raise Exception('bad compression') - self.proto.incomingCompression.decompress = stubDecompress - testBad('\x00\x00\x00\x04\x00BCDE', # bad decompression - transport.DISCONNECT_COMPRESSION_ERROR) - self.flushLoggedErrors() - - - def test_unimplementedPackets(self): - """ - Test that unimplemented packet types cause MSG_UNIMPLEMENTED packets - to be sent. - """ - seqnum = self.proto.incomingPacketSequence - def checkUnimplemented(seqnum=seqnum): - self.assertEqual(self.packets[0][0], - transport.MSG_UNIMPLEMENTED) - self.assertEqual(self.packets[0][1][3], chr(seqnum)) - self.proto.packets = [] - seqnum += 1 - - self.proto.dispatchMessage(40, '') - checkUnimplemented() - transport.messages[41] = 'MSG_fiction' - self.proto.dispatchMessage(41, '') - checkUnimplemented() - self.proto.dispatchMessage(60, '') - checkUnimplemented() - self.proto.setService(MockService()) - self.proto.dispatchMessage(70, '') - checkUnimplemented() - self.proto.dispatchMessage(71, '') - checkUnimplemented() - - - def test_getKey(self): - """ - Test that _getKey generates the correct keys. - """ - self.proto.sessionID = 'EF' - - k1 = sha1('AB' + 'CD' + 'K' + self.proto.sessionID).digest() - k2 = sha1('ABCD' + k1).digest() - self.assertEqual(self.proto._getKey('K', 'AB', 'CD'), k1 + k2) - - - def test_multipleClasses(self): - """ - Test that multiple instances have distinct states. - """ - proto = self.proto - proto.dataReceived(self.transport.value()) - proto.currentEncryptions = MockCipher() - proto.outgoingCompression = MockCompression() - proto.incomingCompression = MockCompression() - proto.setService(MockService()) - proto2 = MockTransportBase() - proto2.makeConnection(proto_helpers.StringTransport()) - proto2.sendIgnore('') - self.failIfEquals(proto.gotVersion, proto2.gotVersion) - self.failIfEquals(proto.transport, proto2.transport) - self.failIfEquals(proto.outgoingPacketSequence, - proto2.outgoingPacketSequence) - self.failIfEquals(proto.incomingPacketSequence, - proto2.incomingPacketSequence) - self.failIfEquals(proto.currentEncryptions, - proto2.currentEncryptions) - self.failIfEquals(proto.service, proto2.service) - - - -class ServerAndClientSSHTransportBaseCase: - """ - Tests that need to be run on both the server and the client. - """ - - - def checkDisconnected(self, kind=None): - """ - Helper function to check if the transport disconnected. - """ - if kind is None: - kind = transport.DISCONNECT_PROTOCOL_ERROR - self.assertEqual(self.packets[-1][0], transport.MSG_DISCONNECT) - self.assertEqual(self.packets[-1][1][3], chr(kind)) - - - def connectModifiedProtocol(self, protoModification, - kind=None): - """ - Helper function to connect a modified protocol to the test protocol - and test for disconnection. - """ - if kind is None: - kind = transport.DISCONNECT_KEY_EXCHANGE_FAILED - proto2 = self.klass() - protoModification(proto2) - proto2.makeConnection(proto_helpers.StringTransport()) - self.proto.dataReceived(proto2.transport.value()) - if kind: - self.checkDisconnected(kind) - return proto2 - - - def test_disconnectIfCantMatchKex(self): - """ - Test that the transport disconnects if it can't match the key - exchange - """ - def blankKeyExchanges(proto2): - proto2.supportedKeyExchanges = [] - self.connectModifiedProtocol(blankKeyExchanges) - - - def test_disconnectIfCantMatchKeyAlg(self): - """ - Like test_disconnectIfCantMatchKex, but for the key algorithm. - """ - def blankPublicKeys(proto2): - proto2.supportedPublicKeys = [] - self.connectModifiedProtocol(blankPublicKeys) - - - def test_disconnectIfCantMatchCompression(self): - """ - Like test_disconnectIfCantMatchKex, but for the compression. - """ - def blankCompressions(proto2): - proto2.supportedCompressions = [] - self.connectModifiedProtocol(blankCompressions) - - - def test_disconnectIfCantMatchCipher(self): - """ - Like test_disconnectIfCantMatchKex, but for the encryption. - """ - def blankCiphers(proto2): - proto2.supportedCiphers = [] - self.connectModifiedProtocol(blankCiphers) - - - def test_disconnectIfCantMatchMAC(self): - """ - Like test_disconnectIfCantMatchKex, but for the MAC. - """ - def blankMACs(proto2): - proto2.supportedMACs = [] - self.connectModifiedProtocol(blankMACs) - - def test_getPeer(self): - """ - Test that the transport's L{getPeer} method returns an - L{SSHTransportAddress} with the L{IAddress} of the peer. - """ - self.assertEqual(self.proto.getPeer(), - address.SSHTransportAddress( - self.proto.transport.getPeer())) - - def test_getHost(self): - """ - Test that the transport's L{getHost} method returns an - L{SSHTransportAddress} with the L{IAddress} of the host. - """ - self.assertEqual(self.proto.getHost(), - address.SSHTransportAddress( - self.proto.transport.getHost())) - - - -class ServerSSHTransportTestCase(ServerAndClientSSHTransportBaseCase, - TransportTestCase): - """ - Tests for the SSHServerTransport. - """ - - klass = transport.SSHServerTransport - - - def setUp(self): - TransportTestCase.setUp(self) - self.proto.factory = MockFactory() - self.proto.factory.startFactory() - - - def tearDown(self): - TransportTestCase.tearDown(self) - self.proto.factory.stopFactory() - del self.proto.factory - - - def test_KEXINIT(self): - """ - Test that receiving a KEXINIT packet sets up the correct values on the - server. - """ - self.proto.dataReceived( 'SSH-2.0-Twisted\r\n\x00\x00\x01\xd4\t\x14' - '\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99' - '\x99\x00\x00\x00=diffie-hellman-group1-sha1,diffie-hellman-g' - 'roup-exchange-sha1\x00\x00\x00\x0fssh-dss,ssh-rsa\x00\x00\x00' - '\x85aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,ae' - 's256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3d' - 'es-ctr,3des-cbc\x00\x00\x00\x85aes128-ctr,aes128-cbc,aes192-c' - 'tr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,b' - 'lowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc\x00\x00\x00\x12hma' - 'c-md5,hmac-sha1\x00\x00\x00\x12hmac-md5,hmac-sha1\x00\x00\x00' - '\tnone,zlib\x00\x00\x00\tnone,zlib\x00\x00\x00\x00\x00\x00' - '\x00\x00\x00\x00\x00\x00\x00\x99\x99\x99\x99\x99\x99\x99\x99' - '\x99') - self.assertEqual(self.proto.kexAlg, - 'diffie-hellman-group1-sha1') - self.assertEqual(self.proto.keyAlg, - 'ssh-dss') - self.assertEqual(self.proto.outgoingCompressionType, - 'none') - self.assertEqual(self.proto.incomingCompressionType, - 'none') - ne = self.proto.nextEncryptions - self.assertEqual(ne.outCipType, 'aes128-ctr') - self.assertEqual(ne.inCipType, 'aes128-ctr') - self.assertEqual(ne.outMACType, 'hmac-md5') - self.assertEqual(ne.inMACType, 'hmac-md5') - - - def test_ignoreGuessPacketKex(self): - """ - The client is allowed to send a guessed key exchange packet - after it sends the KEXINIT packet. However, if the key exchanges - do not match, that guess packet must be ignored. This tests that - the packet is ignored in the case of the key exchange method not - matching. - """ - kexInitPacket = '\x00' * 16 + ( - ''.join([common.NS(x) for x in - [','.join(y) for y in - [self.proto.supportedKeyExchanges[::-1], - self.proto.supportedPublicKeys, - self.proto.supportedCiphers, - self.proto.supportedCiphers, - self.proto.supportedMACs, - self.proto.supportedMACs, - self.proto.supportedCompressions, - self.proto.supportedCompressions, - self.proto.supportedLanguages, - self.proto.supportedLanguages]]])) + ( - '\xff\x00\x00\x00\x00') - self.proto.ssh_KEXINIT(kexInitPacket) - self.assertTrue(self.proto.ignoreNextPacket) - self.proto.ssh_DEBUG("\x01\x00\x00\x00\x04test\x00\x00\x00\x00") - self.assertTrue(self.proto.ignoreNextPacket) - - - self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x08\x00') - self.assertFalse(self.proto.ignoreNextPacket) - self.assertEqual(self.packets, []) - self.proto.ignoreNextPacket = True - - self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x08\x00' * 3) - self.assertFalse(self.proto.ignoreNextPacket) - self.assertEqual(self.packets, []) - - - def test_ignoreGuessPacketKey(self): - """ - Like test_ignoreGuessPacketKex, but for an incorrectly guessed - public key format. - """ - kexInitPacket = '\x00' * 16 + ( - ''.join([common.NS(x) for x in - [','.join(y) for y in - [self.proto.supportedKeyExchanges, - self.proto.supportedPublicKeys[::-1], - self.proto.supportedCiphers, - self.proto.supportedCiphers, - self.proto.supportedMACs, - self.proto.supportedMACs, - self.proto.supportedCompressions, - self.proto.supportedCompressions, - self.proto.supportedLanguages, - self.proto.supportedLanguages]]])) + ( - '\xff\x00\x00\x00\x00') - self.proto.ssh_KEXINIT(kexInitPacket) - self.assertTrue(self.proto.ignoreNextPacket) - self.proto.ssh_DEBUG("\x01\x00\x00\x00\x04test\x00\x00\x00\x00") - self.assertTrue(self.proto.ignoreNextPacket) - - self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x08\x00') - self.assertFalse(self.proto.ignoreNextPacket) - self.assertEqual(self.packets, []) - self.proto.ignoreNextPacket = True - - self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x08\x00' * 3) - self.assertFalse(self.proto.ignoreNextPacket) - self.assertEqual(self.packets, []) - - - def test_KEXDH_INIT(self): - """ - Test that the KEXDH_INIT packet causes the server to send a - KEXDH_REPLY with the server's public key and a signature. - """ - self.proto.supportedKeyExchanges = ['diffie-hellman-group1-sha1'] - self.proto.supportedPublicKeys = ['ssh-rsa'] - self.proto.dataReceived(self.transport.value()) - e = pow(transport.DH_GENERATOR, 5000, - transport.DH_PRIME) - - self.proto.ssh_KEX_DH_GEX_REQUEST_OLD(common.MP(e)) - y = common.getMP('\x00\x00\x00\x40' + '\x99' * 64)[0] - f = common._MPpow(transport.DH_GENERATOR, y, transport.DH_PRIME) - sharedSecret = common._MPpow(e, y, transport.DH_PRIME) - - h = sha1() - h.update(common.NS(self.proto.ourVersionString) * 2) - h.update(common.NS(self.proto.ourKexInitPayload) * 2) - h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob())) - h.update(common.MP(e)) - h.update(f) - h.update(sharedSecret) - exchangeHash = h.digest() - - signature = self.proto.factory.privateKeys['ssh-rsa'].sign( - exchangeHash) - - self.assertEqual( - self.packets, - [(transport.MSG_KEXDH_REPLY, - common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()) - + f + common.NS(signature)), - (transport.MSG_NEWKEYS, '')]) - - - def test_KEX_DH_GEX_REQUEST_OLD(self): - """ - Test that the KEX_DH_GEX_REQUEST_OLD message causes the server - to reply with a KEX_DH_GEX_GROUP message with the correct - Diffie-Hellman group. - """ - self.proto.supportedKeyExchanges = [ - 'diffie-hellman-group-exchange-sha1'] - self.proto.supportedPublicKeys = ['ssh-rsa'] - self.proto.dataReceived(self.transport.value()) - self.proto.ssh_KEX_DH_GEX_REQUEST_OLD('\x00\x00\x04\x00') - self.assertEqual( - self.packets, - [(transport.MSG_KEX_DH_GEX_GROUP, - common.MP(transport.DH_PRIME) + '\x00\x00\x00\x01\x02')]) - self.assertEqual(self.proto.g, 2) - self.assertEqual(self.proto.p, transport.DH_PRIME) - - - def test_KEX_DH_GEX_REQUEST_OLD_badKexAlg(self): - """ - Test that if the server recieves a KEX_DH_GEX_REQUEST_OLD message - and the key exchange algorithm is not 'diffie-hellman-group1-sha1' or - 'diffie-hellman-group-exchange-sha1', we raise a ConchError. - """ - self.proto.kexAlg = None - self.assertRaises(ConchError, self.proto.ssh_KEX_DH_GEX_REQUEST_OLD, - None) - - - def test_KEX_DH_GEX_REQUEST(self): - """ - Test that the KEX_DH_GEX_REQUEST message causes the server to reply - with a KEX_DH_GEX_GROUP message with the correct Diffie-Hellman - group. - """ - self.proto.supportedKeyExchanges = [ - 'diffie-hellman-group-exchange-sha1'] - self.proto.supportedPublicKeys = ['ssh-rsa'] - self.proto.dataReceived(self.transport.value()) - self.proto.ssh_KEX_DH_GEX_REQUEST('\x00\x00\x04\x00\x00\x00\x08\x00' + - '\x00\x00\x0c\x00') - self.assertEqual( - self.packets, - [(transport.MSG_KEX_DH_GEX_GROUP, - common.MP(transport.DH_PRIME) + '\x00\x00\x00\x01\x03')]) - self.assertEqual(self.proto.g, 3) - self.assertEqual(self.proto.p, transport.DH_PRIME) - - - def test_KEX_DH_GEX_INIT_after_REQUEST(self): - """ - Test that the KEX_DH_GEX_INIT message after the client sends - KEX_DH_GEX_REQUEST causes the server to send a KEX_DH_GEX_INIT message - with a public key and signature. - """ - self.test_KEX_DH_GEX_REQUEST() - e = pow(self.proto.g, 3, self.proto.p) - y = common.getMP('\x00\x00\x00\x80' + '\x99' * 128)[0] - f = common._MPpow(self.proto.g, y, self.proto.p) - sharedSecret = common._MPpow(e, y, self.proto.p) - h = sha1() - h.update(common.NS(self.proto.ourVersionString) * 2) - h.update(common.NS(self.proto.ourKexInitPayload) * 2) - h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob())) - h.update('\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x0c\x00') - h.update(common.MP(self.proto.p)) - h.update(common.MP(self.proto.g)) - h.update(common.MP(e)) - h.update(f) - h.update(sharedSecret) - exchangeHash = h.digest() - self.proto.ssh_KEX_DH_GEX_INIT(common.MP(e)) - self.assertEqual( - self.packets[1], - (transport.MSG_KEX_DH_GEX_REPLY, - common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()) + - f + common.NS(self.proto.factory.privateKeys['ssh-rsa'].sign( - exchangeHash)))) - - - def test_KEX_DH_GEX_INIT_after_REQUEST_OLD(self): - """ - Test that the KEX_DH_GEX_INIT message after the client sends - KEX_DH_GEX_REQUEST_OLD causes the server to sent a KEX_DH_GEX_INIT - message with a public key and signature. - """ - self.test_KEX_DH_GEX_REQUEST_OLD() - e = pow(self.proto.g, 3, self.proto.p) - y = common.getMP('\x00\x00\x00\x80' + '\x99' * 128)[0] - f = common._MPpow(self.proto.g, y, self.proto.p) - sharedSecret = common._MPpow(e, y, self.proto.p) - h = sha1() - h.update(common.NS(self.proto.ourVersionString) * 2) - h.update(common.NS(self.proto.ourKexInitPayload) * 2) - h.update(common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob())) - h.update('\x00\x00\x04\x00') - h.update(common.MP(self.proto.p)) - h.update(common.MP(self.proto.g)) - h.update(common.MP(e)) - h.update(f) - h.update(sharedSecret) - exchangeHash = h.digest() - self.proto.ssh_KEX_DH_GEX_INIT(common.MP(e)) - self.assertEqual( - self.packets[1:], - [(transport.MSG_KEX_DH_GEX_REPLY, - common.NS(self.proto.factory.publicKeys['ssh-rsa'].blob()) + - f + common.NS(self.proto.factory.privateKeys['ssh-rsa'].sign( - exchangeHash))), - (transport.MSG_NEWKEYS, '')]) - - - def test_keySetup(self): - """ - Test that _keySetup sets up the next encryption keys. - """ - self.proto.nextEncryptions = MockCipher() - self.simulateKeyExchange('AB', 'CD') - self.assertEqual(self.proto.sessionID, 'CD') - self.simulateKeyExchange('AB', 'EF') - self.assertEqual(self.proto.sessionID, 'CD') - self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, '')) - newKeys = [self.proto._getKey(c, 'AB', 'EF') for c in 'ABCDEF'] - self.assertEqual( - self.proto.nextEncryptions.keys, - (newKeys[1], newKeys[3], newKeys[0], newKeys[2], newKeys[5], - newKeys[4])) - - - def test_NEWKEYS(self): - """ - Test that NEWKEYS transitions the keys in nextEncryptions to - currentEncryptions. - """ - self.test_KEXINIT() - - self.proto.nextEncryptions = transport.SSHCiphers('none', 'none', - 'none', 'none') - self.proto.ssh_NEWKEYS('') - self.assertIdentical(self.proto.currentEncryptions, - self.proto.nextEncryptions) - self.assertIdentical(self.proto.outgoingCompression, None) - self.assertIdentical(self.proto.incomingCompression, None) - self.proto.outgoingCompressionType = 'zlib' - self.simulateKeyExchange('AB', 'CD') - self.proto.ssh_NEWKEYS('') - self.failIfIdentical(self.proto.outgoingCompression, None) - self.proto.incomingCompressionType = 'zlib' - self.simulateKeyExchange('AB', 'EF') - self.proto.ssh_NEWKEYS('') - self.failIfIdentical(self.proto.incomingCompression, None) - - - def test_SERVICE_REQUEST(self): - """ - Test that the SERVICE_REQUEST message requests and starts a - service. - """ - self.proto.ssh_SERVICE_REQUEST(common.NS('ssh-userauth')) - self.assertEqual(self.packets, [(transport.MSG_SERVICE_ACCEPT, - common.NS('ssh-userauth'))]) - self.assertEqual(self.proto.service.name, 'MockService') - - - def test_disconnectNEWKEYSData(self): - """ - Test that NEWKEYS disconnects if it receives data. - """ - self.proto.ssh_NEWKEYS("bad packet") - self.checkDisconnected() - - - def test_disconnectSERVICE_REQUESTBadService(self): - """ - Test that SERVICE_REQUESTS disconnects if an unknown service is - requested. - """ - self.proto.ssh_SERVICE_REQUEST(common.NS('no service')) - self.checkDisconnected(transport.DISCONNECT_SERVICE_NOT_AVAILABLE) - - - -class ClientSSHTransportTestCase(ServerAndClientSSHTransportBaseCase, - TransportTestCase): - """ - Tests for SSHClientTransport. - """ - - klass = transport.SSHClientTransport - - - def test_KEXINIT(self): - """ - Test that receiving a KEXINIT packet sets up the correct values on the - client. The way algorithms are picks is that the first item in the - client's list that is also in the server's list is chosen. - """ - self.proto.dataReceived( 'SSH-2.0-Twisted\r\n\x00\x00\x01\xd4\t\x14' - '\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99' - '\x99\x00\x00\x00=diffie-hellman-group1-sha1,diffie-hellman-g' - 'roup-exchange-sha1\x00\x00\x00\x0fssh-dss,ssh-rsa\x00\x00\x00' - '\x85aes128-ctr,aes128-cbc,aes192-ctr,aes192-cbc,aes256-ctr,ae' - 's256-cbc,cast128-ctr,cast128-cbc,blowfish-ctr,blowfish-cbc,3d' - 'es-ctr,3des-cbc\x00\x00\x00\x85aes128-ctr,aes128-cbc,aes192-c' - 'tr,aes192-cbc,aes256-ctr,aes256-cbc,cast128-ctr,cast128-cbc,b' - 'lowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc\x00\x00\x00\x12hma' - 'c-md5,hmac-sha1\x00\x00\x00\x12hmac-md5,hmac-sha1\x00\x00\x00' - '\tzlib,none\x00\x00\x00\tzlib,none\x00\x00\x00\x00\x00\x00' - '\x00\x00\x00\x00\x00\x00\x00\x99\x99\x99\x99\x99\x99\x99\x99' - '\x99') - self.assertEqual(self.proto.kexAlg, - 'diffie-hellman-group-exchange-sha1') - self.assertEqual(self.proto.keyAlg, - 'ssh-rsa') - self.assertEqual(self.proto.outgoingCompressionType, - 'none') - self.assertEqual(self.proto.incomingCompressionType, - 'none') - ne = self.proto.nextEncryptions - self.assertEqual(ne.outCipType, 'aes256-ctr') - self.assertEqual(ne.inCipType, 'aes256-ctr') - self.assertEqual(ne.outMACType, 'hmac-sha1') - self.assertEqual(ne.inMACType, 'hmac-sha1') - - - def verifyHostKey(self, pubKey, fingerprint): - """ - Mock version of SSHClientTransport.verifyHostKey. - """ - self.calledVerifyHostKey = True - self.assertEqual(pubKey, self.blob) - self.assertEqual(fingerprint.replace(':', ''), - md5(pubKey).hexdigest()) - return defer.succeed(True) - - - def setUp(self): - TransportTestCase.setUp(self) - self.blob = keys.Key.fromString(keydata.publicRSA_openssh).blob() - self.privObj = keys.Key.fromString(keydata.privateRSA_openssh) - self.calledVerifyHostKey = False - self.proto.verifyHostKey = self.verifyHostKey - - - def test_notImplementedClientMethods(self): - """ - verifyHostKey() should return a Deferred which fails with a - NotImplementedError exception. connectionSecure() should raise - NotImplementedError(). - """ - self.assertRaises(NotImplementedError, self.klass().connectionSecure) - def _checkRaises(f): - f.trap(NotImplementedError) - d = self.klass().verifyHostKey(None, None) - return d.addCallback(self.fail).addErrback(_checkRaises) - - - def test_KEXINIT_groupexchange(self): - """ - Test that a KEXINIT packet with a group-exchange key exchange results - in a KEX_DH_GEX_REQUEST_OLD message.. - """ - self.proto.supportedKeyExchanges = [ - 'diffie-hellman-group-exchange-sha1'] - self.proto.dataReceived(self.transport.value()) - self.assertEqual(self.packets, [(transport.MSG_KEX_DH_GEX_REQUEST_OLD, - '\x00\x00\x08\x00')]) - - - def test_KEXINIT_group1(self): - """ - Like test_KEXINIT_groupexchange, but for the group-1 key exchange. - """ - self.proto.supportedKeyExchanges = ['diffie-hellman-group1-sha1'] - self.proto.dataReceived(self.transport.value()) - self.assertEqual(common.MP(self.proto.x)[5:], '\x99' * 64) - self.assertEqual(self.packets, - [(transport.MSG_KEXDH_INIT, self.proto.e)]) - - - def test_KEXINIT_badKexAlg(self): - """ - Test that the client raises a ConchError if it receives a - KEXINIT message bug doesn't have a key exchange algorithm that we - understand. - """ - self.proto.supportedKeyExchanges = ['diffie-hellman-group2-sha1'] - data = self.transport.value().replace('group1', 'group2') - self.assertRaises(ConchError, self.proto.dataReceived, data) - - - def test_KEXDH_REPLY(self): - """ - Test that the KEXDH_REPLY message verifies the server. - """ - self.test_KEXINIT_group1() - - sharedSecret = common._MPpow(transport.DH_GENERATOR, - self.proto.x, transport.DH_PRIME) - h = sha1() - h.update(common.NS(self.proto.ourVersionString) * 2) - h.update(common.NS(self.proto.ourKexInitPayload) * 2) - h.update(common.NS(self.blob)) - h.update(self.proto.e) - h.update('\x00\x00\x00\x01\x02') # f - h.update(sharedSecret) - exchangeHash = h.digest() - - def _cbTestKEXDH_REPLY(value): - self.assertIdentical(value, None) - self.assertEqual(self.calledVerifyHostKey, True) - self.assertEqual(self.proto.sessionID, exchangeHash) - - signature = self.privObj.sign(exchangeHash) - - d = self.proto.ssh_KEX_DH_GEX_GROUP( - (common.NS(self.blob) + '\x00\x00\x00\x01\x02' + - common.NS(signature))) - d.addCallback(_cbTestKEXDH_REPLY) - - return d - - - def test_KEX_DH_GEX_GROUP(self): - """ - Test that the KEX_DH_GEX_GROUP message results in a - KEX_DH_GEX_INIT message with the client's Diffie-Hellman public key. - """ - self.test_KEXINIT_groupexchange() - self.proto.ssh_KEX_DH_GEX_GROUP( - '\x00\x00\x00\x01\x0f\x00\x00\x00\x01\x02') - self.assertEqual(self.proto.p, 15) - self.assertEqual(self.proto.g, 2) - self.assertEqual(common.MP(self.proto.x)[5:], '\x99' * 40) - self.assertEqual(self.proto.e, - common.MP(pow(2, self.proto.x, 15))) - self.assertEqual(self.packets[1:], [(transport.MSG_KEX_DH_GEX_INIT, - self.proto.e)]) - - - def test_KEX_DH_GEX_REPLY(self): - """ - Test that the KEX_DH_GEX_REPLY message results in a verified - server. - """ - - self.test_KEX_DH_GEX_GROUP() - sharedSecret = common._MPpow(3, self.proto.x, self.proto.p) - h = sha1() - h.update(common.NS(self.proto.ourVersionString) * 2) - h.update(common.NS(self.proto.ourKexInitPayload) * 2) - h.update(common.NS(self.blob)) - h.update('\x00\x00\x08\x00\x00\x00\x00\x01\x0f\x00\x00\x00\x01\x02') - h.update(self.proto.e) - h.update('\x00\x00\x00\x01\x03') # f - h.update(sharedSecret) - exchangeHash = h.digest() - - def _cbTestKEX_DH_GEX_REPLY(value): - self.assertIdentical(value, None) - self.assertEqual(self.calledVerifyHostKey, True) - self.assertEqual(self.proto.sessionID, exchangeHash) - - signature = self.privObj.sign(exchangeHash) - - d = self.proto.ssh_KEX_DH_GEX_REPLY( - common.NS(self.blob) + - '\x00\x00\x00\x01\x03' + - common.NS(signature)) - d.addCallback(_cbTestKEX_DH_GEX_REPLY) - return d - - - def test_keySetup(self): - """ - Test that _keySetup sets up the next encryption keys. - """ - self.proto.nextEncryptions = MockCipher() - self.simulateKeyExchange('AB', 'CD') - self.assertEqual(self.proto.sessionID, 'CD') - self.simulateKeyExchange('AB', 'EF') - self.assertEqual(self.proto.sessionID, 'CD') - self.assertEqual(self.packets[-1], (transport.MSG_NEWKEYS, '')) - newKeys = [self.proto._getKey(c, 'AB', 'EF') for c in 'ABCDEF'] - self.assertEqual(self.proto.nextEncryptions.keys, - (newKeys[0], newKeys[2], newKeys[1], newKeys[3], - newKeys[4], newKeys[5])) - - - def test_NEWKEYS(self): - """ - Test that NEWKEYS transitions the keys from nextEncryptions to - currentEncryptions. - """ - self.test_KEXINIT() - secure = [False] - def stubConnectionSecure(): - secure[0] = True - self.proto.connectionSecure = stubConnectionSecure - - self.proto.nextEncryptions = transport.SSHCiphers( - 'none', 'none', 'none', 'none') - self.simulateKeyExchange('AB', 'CD') - self.assertNotIdentical( - self.proto.currentEncryptions, self.proto.nextEncryptions) - - self.proto.nextEncryptions = MockCipher() - self.proto.ssh_NEWKEYS('') - self.assertIdentical(self.proto.outgoingCompression, None) - self.assertIdentical(self.proto.incomingCompression, None) - self.assertIdentical(self.proto.currentEncryptions, - self.proto.nextEncryptions) - self.assertTrue(secure[0]) - self.proto.outgoingCompressionType = 'zlib' - self.simulateKeyExchange('AB', 'GH') - self.proto.ssh_NEWKEYS('') - self.failIfIdentical(self.proto.outgoingCompression, None) - self.proto.incomingCompressionType = 'zlib' - self.simulateKeyExchange('AB', 'IJ') - self.proto.ssh_NEWKEYS('') - self.failIfIdentical(self.proto.incomingCompression, None) - - - def test_SERVICE_ACCEPT(self): - """ - Test that the SERVICE_ACCEPT packet starts the requested service. - """ - self.proto.instance = MockService() - self.proto.ssh_SERVICE_ACCEPT('\x00\x00\x00\x0bMockService') - self.assertTrue(self.proto.instance.started) - - - def test_requestService(self): - """ - Test that requesting a service sends a SERVICE_REQUEST packet. - """ - self.proto.requestService(MockService()) - self.assertEqual(self.packets, [(transport.MSG_SERVICE_REQUEST, - '\x00\x00\x00\x0bMockService')]) - - - def test_disconnectKEXDH_REPLYBadSignature(self): - """ - Test that KEXDH_REPLY disconnects if the signature is bad. - """ - self.test_KEXDH_REPLY() - self.proto._continueKEXDH_REPLY(None, self.blob, 3, "bad signature") - self.checkDisconnected(transport.DISCONNECT_KEY_EXCHANGE_FAILED) - - - def test_disconnectGEX_REPLYBadSignature(self): - """ - Like test_disconnectKEXDH_REPLYBadSignature, but for DH_GEX_REPLY. - """ - self.test_KEX_DH_GEX_REPLY() - self.proto._continueGEX_REPLY(None, self.blob, 3, "bad signature") - self.checkDisconnected(transport.DISCONNECT_KEY_EXCHANGE_FAILED) - - - def test_disconnectNEWKEYSData(self): - """ - Test that NEWKEYS disconnects if it receives data. - """ - self.proto.ssh_NEWKEYS("bad packet") - self.checkDisconnected() - - - def test_disconnectSERVICE_ACCEPT(self): - """ - Test that SERVICE_ACCEPT disconnects if the accepted protocol is - differet from the asked-for protocol. - """ - self.proto.instance = MockService() - self.proto.ssh_SERVICE_ACCEPT('\x00\x00\x00\x03bad') - self.checkDisconnected() - - - def test_noPayloadSERVICE_ACCEPT(self): - """ - Some commercial SSH servers don't send a payload with the - SERVICE_ACCEPT message. Conch pretends that it got the correct - name of the service. - """ - self.proto.instance = MockService() - self.proto.ssh_SERVICE_ACCEPT('') # no payload - self.assertTrue(self.proto.instance.started) - self.assertEquals(len(self.packets), 0) # not disconnected - - - -class SSHCiphersTestCase(unittest.TestCase): - """ - Tests for the SSHCiphers helper class. - """ - if Crypto is None: - skip = "cannot run w/o PyCrypto" - - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - - def test_init(self): - """ - Test that the initializer sets up the SSHCiphers object. - """ - ciphers = transport.SSHCiphers('A', 'B', 'C', 'D') - self.assertEqual(ciphers.outCipType, 'A') - self.assertEqual(ciphers.inCipType, 'B') - self.assertEqual(ciphers.outMACType, 'C') - self.assertEqual(ciphers.inMACType, 'D') - - - def test_getCipher(self): - """ - Test that the _getCipher method returns the correct cipher. - """ - ciphers = transport.SSHCiphers('A', 'B', 'C', 'D') - iv = key = '\x00' * 16 - for cipName, (modName, keySize, counter) in ciphers.cipherMap.items(): - cip = ciphers._getCipher(cipName, iv, key) - if cipName == 'none': - self.assertIsInstance(cip, transport._DummyCipher) - else: - self.assertTrue(getClass(cip).__name__.startswith(modName)) - - - def test_getMAC(self): - """ - Test that the _getMAC method returns the correct MAC. - """ - ciphers = transport.SSHCiphers('A', 'B', 'C', 'D') - key = '\x00' * 64 - for macName, mac in ciphers.macMap.items(): - mod = ciphers._getMAC(macName, key) - if macName == 'none': - self.assertIdentical(mac, None) - else: - self.assertEqual(mod[0], mac) - self.assertEqual(mod[1], - Crypto.Cipher.XOR.new('\x36').encrypt(key)) - self.assertEqual(mod[2], - Crypto.Cipher.XOR.new('\x5c').encrypt(key)) - self.assertEqual(mod[3], len(mod[0]().digest())) - - - def test_setKeysCiphers(self): - """ - Test that setKeys sets up the ciphers. - """ - key = '\x00' * 64 - cipherItems = transport.SSHCiphers.cipherMap.items() - for cipName, (modName, keySize, counter) in cipherItems: - encCipher = transport.SSHCiphers(cipName, 'none', 'none', 'none') - decCipher = transport.SSHCiphers('none', cipName, 'none', 'none') - cip = encCipher._getCipher(cipName, key, key) - bs = cip.block_size - encCipher.setKeys(key, key, '', '', '', '') - decCipher.setKeys('', '', key, key, '', '') - self.assertEqual(encCipher.encBlockSize, bs) - self.assertEqual(decCipher.decBlockSize, bs) - enc = cip.encrypt(key[:bs]) - enc2 = cip.encrypt(key[:bs]) - if counter: - self.failIfEquals(enc, enc2) - self.assertEqual(encCipher.encrypt(key[:bs]), enc) - self.assertEqual(encCipher.encrypt(key[:bs]), enc2) - self.assertEqual(decCipher.decrypt(enc), key[:bs]) - self.assertEqual(decCipher.decrypt(enc2), key[:bs]) - - - def test_setKeysMACs(self): - """ - Test that setKeys sets up the MACs. - """ - key = '\x00' * 64 - for macName, mod in transport.SSHCiphers.macMap.items(): - outMac = transport.SSHCiphers('none', 'none', macName, 'none') - inMac = transport.SSHCiphers('none', 'none', 'none', macName) - outMac.setKeys('', '', '', '', key, '') - inMac.setKeys('', '', '', '', '', key) - if mod: - ds = mod().digest_size - else: - ds = 0 - self.assertEqual(inMac.verifyDigestSize, ds) - if mod: - mod, i, o, ds = outMac._getMAC(macName, key) - seqid = 0 - data = key - packet = '\x00' * 4 + key - if mod: - mac = mod(o + mod(i + packet).digest()).digest() - else: - mac = '' - self.assertEqual(outMac.makeMAC(seqid, data), mac) - self.assertTrue(inMac.verify(seqid, data, mac)) - - - -class CounterTestCase(unittest.TestCase): - """ - Tests for the _Counter helper class. - """ - if Crypto is None: - skip = "cannot run w/o PyCrypto" - - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - - def test_init(self): - """ - Test that the counter is initialized correctly. - """ - counter = transport._Counter('\x00' * 8 + '\xff' * 8, 8) - self.assertEqual(counter.blockSize, 8) - self.assertEqual(counter.count.tostring(), '\x00' * 8) - - - def test_count(self): - """ - Test that the counter counts incrementally and wraps at the top. - """ - counter = transport._Counter('\x00', 1) - self.assertEqual(counter(), '\x01') - self.assertEqual(counter(), '\x02') - [counter() for i in range(252)] - self.assertEqual(counter(), '\xff') - self.assertEqual(counter(), '\x00') - - - -class TransportLoopbackTestCase(unittest.TestCase): - """ - Test the server transport and client transport against each other, - """ - if Crypto is None: - skip = "cannot run w/o PyCrypto" - - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - - def _runClientServer(self, mod): - """ - Run an async client and server, modifying each using the mod function - provided. Returns a Deferred called back when both Protocols have - disconnected. - - @type mod: C{func} - @rtype: C{defer.Deferred} - """ - factory = MockFactory() - server = transport.SSHServerTransport() - server.factory = factory - factory.startFactory() - server.errors = [] - server.receiveError = lambda code, desc: server.errors.append(( - code, desc)) - client = transport.SSHClientTransport() - client.verifyHostKey = lambda x, y: defer.succeed(None) - client.errors = [] - client.receiveError = lambda code, desc: client.errors.append(( - code, desc)) - client.connectionSecure = lambda: client.loseConnection() - server = mod(server) - client = mod(client) - def check(ignored, server, client): - name = repr([server.supportedCiphers[0], - server.supportedMACs[0], - server.supportedKeyExchanges[0], - server.supportedCompressions[0]]) - self.assertEqual(client.errors, []) - self.assertEqual(server.errors, [( - transport.DISCONNECT_CONNECTION_LOST, - "user closed connection")]) - if server.supportedCiphers[0] == 'none': - self.assertFalse(server.isEncrypted(), name) - self.assertFalse(client.isEncrypted(), name) - else: - self.assertTrue(server.isEncrypted(), name) - self.assertTrue(client.isEncrypted(), name) - if server.supportedMACs[0] == 'none': - self.assertFalse(server.isVerified(), name) - self.assertFalse(client.isVerified(), name) - else: - self.assertTrue(server.isVerified(), name) - self.assertTrue(client.isVerified(), name) - - d = loopback.loopbackAsync(server, client) - d.addCallback(check, server, client) - return d - - - def test_ciphers(self): - """ - Test that the client and server play nicely together, in all - the various combinations of ciphers. - """ - deferreds = [] - for cipher in transport.SSHTransportBase.supportedCiphers + ['none']: - def setCipher(proto): - proto.supportedCiphers = [cipher] - return proto - deferreds.append(self._runClientServer(setCipher)) - return defer.DeferredList(deferreds, fireOnOneErrback=True) - - - def test_macs(self): - """ - Like test_ciphers, but for the various MACs. - """ - deferreds = [] - for mac in transport.SSHTransportBase.supportedMACs + ['none']: - def setMAC(proto): - proto.supportedMACs = [mac] - return proto - deferreds.append(self._runClientServer(setMAC)) - return defer.DeferredList(deferreds, fireOnOneErrback=True) - - - def test_keyexchanges(self): - """ - Like test_ciphers, but for the various key exchanges. - """ - deferreds = [] - for kex in transport.SSHTransportBase.supportedKeyExchanges: - def setKeyExchange(proto): - proto.supportedKeyExchanges = [kex] - return proto - deferreds.append(self._runClientServer(setKeyExchange)) - return defer.DeferredList(deferreds, fireOnOneErrback=True) - - - def test_compressions(self): - """ - Like test_ciphers, but for the various compressions. - """ - deferreds = [] - for compression in transport.SSHTransportBase.supportedCompressions: - def setCompression(proto): - proto.supportedCompressions = [compression] - return proto - deferreds.append(self._runClientServer(setCompression)) - return defer.DeferredList(deferreds, fireOnOneErrback=True) - - -class RandomNumberTestCase(unittest.TestCase): - """ - Tests for the random number generator L{_getRandomNumber} and private - key generator L{_generateX}. - """ - skip = dependencySkip - - def test_usesSuppliedRandomFunction(self): - """ - L{_getRandomNumber} returns an integer constructed directly from the - bytes returned by the random byte generator passed to it. - """ - def random(bytes): - # The number of bytes requested will be the value of each byte - # we return. - return chr(bytes) * bytes - self.assertEqual( - transport._getRandomNumber(random, 32), - 4 << 24 | 4 << 16 | 4 << 8 | 4) - - - def test_rejectsNonByteMultiples(self): - """ - L{_getRandomNumber} raises L{ValueError} if the number of bits - passed to L{_getRandomNumber} is not a multiple of 8. - """ - self.assertRaises( - ValueError, - transport._getRandomNumber, None, 9) - - - def test_excludesSmall(self): - """ - If the random byte generator passed to L{_generateX} produces bytes - which would result in 0 or 1 being returned, these bytes are - discarded and another attempt is made to produce a larger value. - """ - results = [chr(0), chr(1), chr(127)] - def random(bytes): - return results.pop(0) * bytes - self.assertEqual( - transport._generateX(random, 8), - 127) - - - def test_excludesLarge(self): - """ - If the random byte generator passed to L{_generateX} produces bytes - which would result in C{(2 ** bits) - 1} being returned, these bytes - are discarded and another attempt is made to produce a smaller - value. - """ - results = [chr(255), chr(64)] - def random(bytes): - return results.pop(0) * bytes - self.assertEqual( - transport._generateX(random, 8), - 64) - - - -class OldFactoryTestCase(unittest.TestCase): - """ - The old C{SSHFactory.getPublicKeys}() returned mappings of key names to - strings of key blobs and mappings of key names to PyCrypto key objects from - C{SSHFactory.getPrivateKeys}() (they could also be specified with the - C{publicKeys} and C{privateKeys} attributes). This is no longer supported - by the C{SSHServerTransport}, so we warn the user if they create an old - factory. - """ - - if Crypto is None: - skip = "cannot run w/o PyCrypto" - - if pyasn1 is None: - skip = "Cannot run without PyASN1" - - - def test_getPublicKeysWarning(self): - """ - If the return value of C{getPublicKeys}() isn't a mapping from key - names to C{Key} objects, then warn the user and convert the mapping. - """ - sshFactory = MockOldFactoryPublicKeys() - self.assertWarns(DeprecationWarning, - "Returning a mapping from strings to strings from" - " getPublicKeys()/publicKeys (in %s) is deprecated. Return " - "a mapping from strings to Key objects instead." % - (qual(MockOldFactoryPublicKeys),), - factory.__file__, sshFactory.startFactory) - self.assertEqual(sshFactory.publicKeys, MockFactory().getPublicKeys()) - - - def test_getPrivateKeysWarning(self): - """ - If the return value of C{getPrivateKeys}() isn't a mapping from key - names to C{Key} objects, then warn the user and convert the mapping. - """ - sshFactory = MockOldFactoryPrivateKeys() - self.assertWarns(DeprecationWarning, - "Returning a mapping from strings to PyCrypto key objects from" - " getPrivateKeys()/privateKeys (in %s) is deprecated. Return" - " a mapping from strings to Key objects instead." % - (qual(MockOldFactoryPrivateKeys),), - factory.__file__, sshFactory.startFactory) - self.assertEqual(sshFactory.privateKeys, - MockFactory().getPrivateKeys()) - - - def test_publicKeysWarning(self): - """ - If the value of the C{publicKeys} attribute isn't a mapping from key - names to C{Key} objects, then warn the user and convert the mapping. - """ - sshFactory = MockOldFactoryPublicKeys() - sshFactory.publicKeys = sshFactory.getPublicKeys() - self.assertWarns(DeprecationWarning, - "Returning a mapping from strings to strings from" - " getPublicKeys()/publicKeys (in %s) is deprecated. Return " - "a mapping from strings to Key objects instead." % - (qual(MockOldFactoryPublicKeys),), - factory.__file__, sshFactory.startFactory) - self.assertEqual(sshFactory.publicKeys, MockFactory().getPublicKeys()) - - - def test_privateKeysWarning(self): - """ - If the return value of C{privateKeys} attribute isn't a mapping from - key names to C{Key} objects, then warn the user and convert the - mapping. - """ - sshFactory = MockOldFactoryPrivateKeys() - sshFactory.privateKeys = sshFactory.getPrivateKeys() - self.assertWarns(DeprecationWarning, - "Returning a mapping from strings to PyCrypto key objects from" - " getPrivateKeys()/privateKeys (in %s) is deprecated. Return" - " a mapping from strings to Key objects instead." % - (qual(MockOldFactoryPrivateKeys),), - factory.__file__, sshFactory.startFactory) - self.assertEqual(sshFactory.privateKeys, - MockFactory().getPrivateKeys()) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py deleted file mode 100755 index d027faad..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_userauth.py +++ /dev/null @@ -1,1077 +0,0 @@ -# -*- test-case-name: twisted.conch.test.test_userauth -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -""" -Tests for the implementation of the ssh-userauth service. - -Maintainer: Paul Swartz -""" - -from zope.interface import implements - -from twisted.cred.checkers import ICredentialsChecker -from twisted.cred.credentials import IUsernamePassword, ISSHPrivateKey -from twisted.cred.credentials import IPluggableAuthenticationModules -from twisted.cred.credentials import IAnonymous -from twisted.cred.error import UnauthorizedLogin -from twisted.cred.portal import IRealm, Portal -from twisted.conch.error import ConchError, ValidPublicKey -from twisted.internet import defer, task -from twisted.protocols import loopback -from twisted.trial import unittest - -try: - import Crypto.Cipher.DES3, Crypto.Cipher.XOR - import pyasn1 -except ImportError: - keys = None - - - class transport: - class SSHTransportBase: - """ - A stub class so that later class definitions won't die. - """ - - class userauth: - class SSHUserAuthClient: - """ - A stub class so that later class definitions won't die. - """ -else: - from twisted.conch.ssh.common import NS - from twisted.conch.checkers import SSHProtocolChecker - from twisted.conch.ssh import keys, userauth, transport - from twisted.conch.test import keydata - - - -class ClientUserAuth(userauth.SSHUserAuthClient): - """ - A mock user auth client. - """ - - - def getPublicKey(self): - """ - If this is the first time we've been called, return a blob for - the DSA key. Otherwise, return a blob - for the RSA key. - """ - if self.lastPublicKey: - return keys.Key.fromString(keydata.publicRSA_openssh) - else: - return defer.succeed(keys.Key.fromString(keydata.publicDSA_openssh)) - - - def getPrivateKey(self): - """ - Return the private key object for the RSA key. - """ - return defer.succeed(keys.Key.fromString(keydata.privateRSA_openssh)) - - - def getPassword(self, prompt=None): - """ - Return 'foo' as the password. - """ - return defer.succeed('foo') - - - def getGenericAnswers(self, name, information, answers): - """ - Return 'foo' as the answer to two questions. - """ - return defer.succeed(('foo', 'foo')) - - - -class OldClientAuth(userauth.SSHUserAuthClient): - """ - The old SSHUserAuthClient returned a PyCrypto key object from - getPrivateKey() and a string from getPublicKey - """ - - - def getPrivateKey(self): - return defer.succeed(keys.Key.fromString( - keydata.privateRSA_openssh).keyObject) - - - def getPublicKey(self): - return keys.Key.fromString(keydata.publicRSA_openssh).blob() - -class ClientAuthWithoutPrivateKey(userauth.SSHUserAuthClient): - """ - This client doesn't have a private key, but it does have a public key. - """ - - - def getPrivateKey(self): - return - - - def getPublicKey(self): - return keys.Key.fromString(keydata.publicRSA_openssh) - - - -class FakeTransport(transport.SSHTransportBase): - """ - L{userauth.SSHUserAuthServer} expects an SSH transport which has a factory - attribute which has a portal attribute. Because the portal is important for - testing authentication, we need to be able to provide an interesting portal - object to the L{SSHUserAuthServer}. - - In addition, we want to be able to capture any packets sent over the - transport. - - @ivar packets: a list of 2-tuples: (messageType, data). Each 2-tuple is - a sent packet. - @type packets: C{list} - @param lostConnecion: True if loseConnection has been called on us. - @type lostConnection: C{bool} - """ - - - class Service(object): - """ - A mock service, representing the other service offered by the server. - """ - name = 'nancy' - - - def serviceStarted(self): - pass - - - - class Factory(object): - """ - A mock factory, representing the factory that spawned this user auth - service. - """ - - - def getService(self, transport, service): - """ - Return our fake service. - """ - if service == 'none': - return FakeTransport.Service - - - - def __init__(self, portal): - self.factory = self.Factory() - self.factory.portal = portal - self.lostConnection = False - self.transport = self - self.packets = [] - - - - def sendPacket(self, messageType, message): - """ - Record the packet sent by the service. - """ - self.packets.append((messageType, message)) - - - def isEncrypted(self, direction): - """ - Pretend that this transport encrypts traffic in both directions. The - SSHUserAuthServer disables password authentication if the transport - isn't encrypted. - """ - return True - - - def loseConnection(self): - self.lostConnection = True - - - -class Realm(object): - """ - A mock realm for testing L{userauth.SSHUserAuthServer}. - - This realm is not actually used in the course of testing, so it returns the - simplest thing that could possibly work. - """ - implements(IRealm) - - - def requestAvatar(self, avatarId, mind, *interfaces): - return defer.succeed((interfaces[0], None, lambda: None)) - - - -class PasswordChecker(object): - """ - A very simple username/password checker which authenticates anyone whose - password matches their username and rejects all others. - """ - credentialInterfaces = (IUsernamePassword,) - implements(ICredentialsChecker) - - - def requestAvatarId(self, creds): - if creds.username == creds.password: - return defer.succeed(creds.username) - return defer.fail(UnauthorizedLogin("Invalid username/password pair")) - - - -class PrivateKeyChecker(object): - """ - A very simple public key checker which authenticates anyone whose - public/private keypair is the same keydata.public/privateRSA_openssh. - """ - credentialInterfaces = (ISSHPrivateKey,) - implements(ICredentialsChecker) - - - - def requestAvatarId(self, creds): - if creds.blob == keys.Key.fromString(keydata.publicRSA_openssh).blob(): - if creds.signature is not None: - obj = keys.Key.fromString(creds.blob) - if obj.verify(creds.signature, creds.sigData): - return creds.username - else: - raise ValidPublicKey() - raise UnauthorizedLogin() - - - -class PAMChecker(object): - """ - A simple PAM checker which asks the user for a password, verifying them - if the password is the same as their username. - """ - credentialInterfaces = (IPluggableAuthenticationModules,) - implements(ICredentialsChecker) - - - def requestAvatarId(self, creds): - d = creds.pamConversion([('Name: ', 2), ("Password: ", 1)]) - def check(values): - if values == [(creds.username, 0), (creds.username, 0)]: - return creds.username - raise UnauthorizedLogin() - return d.addCallback(check) - - - -class AnonymousChecker(object): - """ - A simple checker which isn't supported by L{SSHUserAuthServer}. - """ - credentialInterfaces = (IAnonymous,) - implements(ICredentialsChecker) - - - -class SSHUserAuthServerTestCase(unittest.TestCase): - """ - Tests for SSHUserAuthServer. - """ - - - if keys is None: - skip = "cannot run w/o PyCrypto" - - - def setUp(self): - self.realm = Realm() - self.portal = Portal(self.realm) - self.portal.registerChecker(PasswordChecker()) - self.portal.registerChecker(PrivateKeyChecker()) - self.portal.registerChecker(PAMChecker()) - self.authServer = userauth.SSHUserAuthServer() - self.authServer.transport = FakeTransport(self.portal) - self.authServer.serviceStarted() - self.authServer.supportedAuthentications.sort() # give a consistent - # order - - - def tearDown(self): - self.authServer.serviceStopped() - self.authServer = None - - - def _checkFailed(self, ignored): - """ - Check that the authentication has failed. - """ - self.assertEqual(self.authServer.transport.packets[-1], - (userauth.MSG_USERAUTH_FAILURE, - NS('keyboard-interactive,password,publickey') + '\x00')) - - - def test_noneAuthentication(self): - """ - A client may request a list of authentication 'method name' values - that may continue by using the "none" authentication 'method name'. - - See RFC 4252 Section 5.2. - """ - d = self.authServer.ssh_USERAUTH_REQUEST(NS('foo') + NS('service') + - NS('none')) - return d.addCallback(self._checkFailed) - - - def test_successfulPasswordAuthentication(self): - """ - When provided with correct password authentication information, the - server should respond by sending a MSG_USERAUTH_SUCCESS message with - no other data. - - See RFC 4252, Section 5.1. - """ - packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('foo') - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - def check(ignored): - self.assertEqual( - self.authServer.transport.packets, - [(userauth.MSG_USERAUTH_SUCCESS, '')]) - return d.addCallback(check) - - - def test_failedPasswordAuthentication(self): - """ - When provided with invalid authentication details, the server should - respond by sending a MSG_USERAUTH_FAILURE message which states whether - the authentication was partially successful, and provides other, open - options for authentication. - - See RFC 4252, Section 5.1. - """ - # packet = username, next_service, authentication type, FALSE, password - packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('bar') - self.authServer.clock = task.Clock() - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.assertEqual(self.authServer.transport.packets, []) - self.authServer.clock.advance(2) - return d.addCallback(self._checkFailed) - - - def test_successfulPrivateKeyAuthentication(self): - """ - Test that private key authentication completes sucessfully, - """ - blob = keys.Key.fromString(keydata.publicRSA_openssh).blob() - obj = keys.Key.fromString(keydata.privateRSA_openssh) - packet = (NS('foo') + NS('none') + NS('publickey') + '\xff' - + NS(obj.sshType()) + NS(blob)) - self.authServer.transport.sessionID = 'test' - signature = obj.sign(NS('test') + chr(userauth.MSG_USERAUTH_REQUEST) - + packet) - packet += NS(signature) - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - def check(ignored): - self.assertEqual(self.authServer.transport.packets, - [(userauth.MSG_USERAUTH_SUCCESS, '')]) - return d.addCallback(check) - - - def test_requestRaisesConchError(self): - """ - ssh_USERAUTH_REQUEST should raise a ConchError if tryAuth returns - None. Added to catch a bug noticed by pyflakes. - """ - d = defer.Deferred() - - def mockCbFinishedAuth(self, ignored): - self.fail('request should have raised ConochError') - - def mockTryAuth(kind, user, data): - return None - - def mockEbBadAuth(reason): - d.errback(reason.value) - - self.patch(self.authServer, 'tryAuth', mockTryAuth) - self.patch(self.authServer, '_cbFinishedAuth', mockCbFinishedAuth) - self.patch(self.authServer, '_ebBadAuth', mockEbBadAuth) - - packet = NS('user') + NS('none') + NS('public-key') + NS('data') - # If an error other than ConchError is raised, this will trigger an - # exception. - self.authServer.ssh_USERAUTH_REQUEST(packet) - return self.assertFailure(d, ConchError) - - - def test_verifyValidPrivateKey(self): - """ - Test that verifying a valid private key works. - """ - blob = keys.Key.fromString(keydata.publicRSA_openssh).blob() - packet = (NS('foo') + NS('none') + NS('publickey') + '\x00' - + NS('ssh-rsa') + NS(blob)) - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - def check(ignored): - self.assertEqual(self.authServer.transport.packets, - [(userauth.MSG_USERAUTH_PK_OK, NS('ssh-rsa') + NS(blob))]) - return d.addCallback(check) - - - def test_failedPrivateKeyAuthenticationWithoutSignature(self): - """ - Test that private key authentication fails when the public key - is invalid. - """ - blob = keys.Key.fromString(keydata.publicDSA_openssh).blob() - packet = (NS('foo') + NS('none') + NS('publickey') + '\x00' - + NS('ssh-dsa') + NS(blob)) - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - return d.addCallback(self._checkFailed) - - - def test_failedPrivateKeyAuthenticationWithSignature(self): - """ - Test that private key authentication fails when the public key - is invalid. - """ - blob = keys.Key.fromString(keydata.publicRSA_openssh).blob() - obj = keys.Key.fromString(keydata.privateRSA_openssh) - packet = (NS('foo') + NS('none') + NS('publickey') + '\xff' - + NS('ssh-rsa') + NS(blob) + NS(obj.sign(blob))) - self.authServer.transport.sessionID = 'test' - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - return d.addCallback(self._checkFailed) - - - def test_successfulPAMAuthentication(self): - """ - Test that keyboard-interactive authentication succeeds. - """ - packet = (NS('foo') + NS('none') + NS('keyboard-interactive') - + NS('') + NS('')) - response = '\x00\x00\x00\x02' + NS('foo') + NS('foo') - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.ssh_USERAUTH_INFO_RESPONSE(response) - def check(ignored): - self.assertEqual(self.authServer.transport.packets, - [(userauth.MSG_USERAUTH_INFO_REQUEST, (NS('') + NS('') - + NS('') + '\x00\x00\x00\x02' + NS('Name: ') + '\x01' - + NS('Password: ') + '\x00')), - (userauth.MSG_USERAUTH_SUCCESS, '')]) - - return d.addCallback(check) - - - def test_failedPAMAuthentication(self): - """ - Test that keyboard-interactive authentication fails. - """ - packet = (NS('foo') + NS('none') + NS('keyboard-interactive') - + NS('') + NS('')) - response = '\x00\x00\x00\x02' + NS('bar') + NS('bar') - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.ssh_USERAUTH_INFO_RESPONSE(response) - def check(ignored): - self.assertEqual(self.authServer.transport.packets[0], - (userauth.MSG_USERAUTH_INFO_REQUEST, (NS('') + NS('') - + NS('') + '\x00\x00\x00\x02' + NS('Name: ') + '\x01' - + NS('Password: ') + '\x00'))) - return d.addCallback(check).addCallback(self._checkFailed) - - - def test_invalid_USERAUTH_INFO_RESPONSE_not_enough_data(self): - """ - If ssh_USERAUTH_INFO_RESPONSE gets an invalid packet, - the user authentication should fail. - """ - packet = (NS('foo') + NS('none') + NS('keyboard-interactive') - + NS('') + NS('')) - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.ssh_USERAUTH_INFO_RESPONSE(NS('\x00\x00\x00\x00' + - NS('hi'))) - return d.addCallback(self._checkFailed) - - - def test_invalid_USERAUTH_INFO_RESPONSE_too_much_data(self): - """ - If ssh_USERAUTH_INFO_RESPONSE gets too much data, the user - authentication should fail. - """ - packet = (NS('foo') + NS('none') + NS('keyboard-interactive') - + NS('') + NS('')) - response = '\x00\x00\x00\x02' + NS('foo') + NS('foo') + NS('foo') - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.ssh_USERAUTH_INFO_RESPONSE(response) - return d.addCallback(self._checkFailed) - - - def test_onlyOnePAMAuthentication(self): - """ - Because it requires an intermediate message, one can't send a second - keyboard-interactive request while the first is still pending. - """ - packet = (NS('foo') + NS('none') + NS('keyboard-interactive') - + NS('') + NS('')) - self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.ssh_USERAUTH_REQUEST(packet) - self.assertEqual(self.authServer.transport.packets[-1][0], - transport.MSG_DISCONNECT) - self.assertEqual(self.authServer.transport.packets[-1][1][3], - chr(transport.DISCONNECT_PROTOCOL_ERROR)) - - - def test_ignoreUnknownCredInterfaces(self): - """ - L{SSHUserAuthServer} sets up - C{SSHUserAuthServer.supportedAuthentications} by checking the portal's - credentials interfaces and mapping them to SSH authentication method - strings. If the Portal advertises an interface that - L{SSHUserAuthServer} can't map, it should be ignored. This is a white - box test. - """ - server = userauth.SSHUserAuthServer() - server.transport = FakeTransport(self.portal) - self.portal.registerChecker(AnonymousChecker()) - server.serviceStarted() - server.serviceStopped() - server.supportedAuthentications.sort() # give a consistent order - self.assertEqual(server.supportedAuthentications, - ['keyboard-interactive', 'password', 'publickey']) - - - def test_removePasswordIfUnencrypted(self): - """ - Test that the userauth service does not advertise password - authentication if the password would be send in cleartext. - """ - self.assertIn('password', self.authServer.supportedAuthentications) - # no encryption - clearAuthServer = userauth.SSHUserAuthServer() - clearAuthServer.transport = FakeTransport(self.portal) - clearAuthServer.transport.isEncrypted = lambda x: False - clearAuthServer.serviceStarted() - clearAuthServer.serviceStopped() - self.failIfIn('password', clearAuthServer.supportedAuthentications) - # only encrypt incoming (the direction the password is sent) - halfAuthServer = userauth.SSHUserAuthServer() - halfAuthServer.transport = FakeTransport(self.portal) - halfAuthServer.transport.isEncrypted = lambda x: x == 'in' - halfAuthServer.serviceStarted() - halfAuthServer.serviceStopped() - self.assertIn('password', halfAuthServer.supportedAuthentications) - - - def test_removeKeyboardInteractiveIfUnencrypted(self): - """ - Test that the userauth service does not advertise keyboard-interactive - authentication if the password would be send in cleartext. - """ - self.assertIn('keyboard-interactive', - self.authServer.supportedAuthentications) - # no encryption - clearAuthServer = userauth.SSHUserAuthServer() - clearAuthServer.transport = FakeTransport(self.portal) - clearAuthServer.transport.isEncrypted = lambda x: False - clearAuthServer.serviceStarted() - clearAuthServer.serviceStopped() - self.failIfIn('keyboard-interactive', - clearAuthServer.supportedAuthentications) - # only encrypt incoming (the direction the password is sent) - halfAuthServer = userauth.SSHUserAuthServer() - halfAuthServer.transport = FakeTransport(self.portal) - halfAuthServer.transport.isEncrypted = lambda x: x == 'in' - halfAuthServer.serviceStarted() - halfAuthServer.serviceStopped() - self.assertIn('keyboard-interactive', - halfAuthServer.supportedAuthentications) - - - def test_unencryptedConnectionWithoutPasswords(self): - """ - If the L{SSHUserAuthServer} is not advertising passwords, then an - unencrypted connection should not cause any warnings or exceptions. - This is a white box test. - """ - # create a Portal without password authentication - portal = Portal(self.realm) - portal.registerChecker(PrivateKeyChecker()) - - # no encryption - clearAuthServer = userauth.SSHUserAuthServer() - clearAuthServer.transport = FakeTransport(portal) - clearAuthServer.transport.isEncrypted = lambda x: False - clearAuthServer.serviceStarted() - clearAuthServer.serviceStopped() - self.assertEqual(clearAuthServer.supportedAuthentications, - ['publickey']) - - # only encrypt incoming (the direction the password is sent) - halfAuthServer = userauth.SSHUserAuthServer() - halfAuthServer.transport = FakeTransport(portal) - halfAuthServer.transport.isEncrypted = lambda x: x == 'in' - halfAuthServer.serviceStarted() - halfAuthServer.serviceStopped() - self.assertEqual(clearAuthServer.supportedAuthentications, - ['publickey']) - - - def test_loginTimeout(self): - """ - Test that the login times out. - """ - timeoutAuthServer = userauth.SSHUserAuthServer() - timeoutAuthServer.clock = task.Clock() - timeoutAuthServer.transport = FakeTransport(self.portal) - timeoutAuthServer.serviceStarted() - timeoutAuthServer.clock.advance(11 * 60 * 60) - timeoutAuthServer.serviceStopped() - self.assertEqual(timeoutAuthServer.transport.packets, - [(transport.MSG_DISCONNECT, - '\x00' * 3 + - chr(transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) + - NS("you took too long") + NS(''))]) - self.assertTrue(timeoutAuthServer.transport.lostConnection) - - - def test_cancelLoginTimeout(self): - """ - Test that stopping the service also stops the login timeout. - """ - timeoutAuthServer = userauth.SSHUserAuthServer() - timeoutAuthServer.clock = task.Clock() - timeoutAuthServer.transport = FakeTransport(self.portal) - timeoutAuthServer.serviceStarted() - timeoutAuthServer.serviceStopped() - timeoutAuthServer.clock.advance(11 * 60 * 60) - self.assertEqual(timeoutAuthServer.transport.packets, []) - self.assertFalse(timeoutAuthServer.transport.lostConnection) - - - def test_tooManyAttempts(self): - """ - Test that the server disconnects if the client fails authentication - too many times. - """ - packet = NS('foo') + NS('none') + NS('password') + chr(0) + NS('bar') - self.authServer.clock = task.Clock() - for i in range(21): - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - self.authServer.clock.advance(2) - def check(ignored): - self.assertEqual(self.authServer.transport.packets[-1], - (transport.MSG_DISCONNECT, - '\x00' * 3 + - chr(transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) + - NS("too many bad auths") + NS(''))) - return d.addCallback(check) - - - def test_failIfUnknownService(self): - """ - If the user requests a service that we don't support, the - authentication should fail. - """ - packet = NS('foo') + NS('') + NS('password') + chr(0) + NS('foo') - self.authServer.clock = task.Clock() - d = self.authServer.ssh_USERAUTH_REQUEST(packet) - return d.addCallback(self._checkFailed) - - - def test__pamConvErrors(self): - """ - _pamConv should fail if it gets a message that's not 1 or 2. - """ - def secondTest(ignored): - d2 = self.authServer._pamConv([('', 90)]) - return self.assertFailure(d2, ConchError) - - d = self.authServer._pamConv([('', 3)]) - return self.assertFailure(d, ConchError).addCallback(secondTest) - - - def test_tryAuthEdgeCases(self): - """ - tryAuth() has two edge cases that are difficult to reach. - - 1) an authentication method auth_* returns None instead of a Deferred. - 2) an authentication type that is defined does not have a matching - auth_* method. - - Both these cases should return a Deferred which fails with a - ConchError. - """ - def mockAuth(packet): - return None - - self.patch(self.authServer, 'auth_publickey', mockAuth) # first case - self.patch(self.authServer, 'auth_password', None) # second case - - def secondTest(ignored): - d2 = self.authServer.tryAuth('password', None, None) - return self.assertFailure(d2, ConchError) - - d1 = self.authServer.tryAuth('publickey', None, None) - return self.assertFailure(d1, ConchError).addCallback(secondTest) - - - - -class SSHUserAuthClientTestCase(unittest.TestCase): - """ - Tests for SSHUserAuthClient. - """ - - - if keys is None: - skip = "cannot run w/o PyCrypto" - - - def setUp(self): - self.authClient = ClientUserAuth('foo', FakeTransport.Service()) - self.authClient.transport = FakeTransport(None) - self.authClient.transport.sessionID = 'test' - self.authClient.serviceStarted() - - - def tearDown(self): - self.authClient.serviceStopped() - self.authClient = None - - - def test_init(self): - """ - Test that client is initialized properly. - """ - self.assertEqual(self.authClient.user, 'foo') - self.assertEqual(self.authClient.instance.name, 'nancy') - self.assertEqual(self.authClient.transport.packets, - [(userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('none'))]) - - - def test_USERAUTH_SUCCESS(self): - """ - Test that the client succeeds properly. - """ - instance = [None] - def stubSetService(service): - instance[0] = service - self.authClient.transport.setService = stubSetService - self.authClient.ssh_USERAUTH_SUCCESS('') - self.assertEqual(instance[0], self.authClient.instance) - - - def test_publickey(self): - """ - Test that the client can authenticate with a public key. - """ - self.authClient.ssh_USERAUTH_FAILURE(NS('publickey') + '\x00') - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('publickey') + '\x00' + NS('ssh-dss') - + NS(keys.Key.fromString( - keydata.publicDSA_openssh).blob()))) - # that key isn't good - self.authClient.ssh_USERAUTH_FAILURE(NS('publickey') + '\x00') - blob = NS(keys.Key.fromString(keydata.publicRSA_openssh).blob()) - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, (NS('foo') + NS('nancy') - + NS('publickey') + '\x00'+ NS('ssh-rsa') + blob))) - self.authClient.ssh_USERAUTH_PK_OK(NS('ssh-rsa') - + NS(keys.Key.fromString(keydata.publicRSA_openssh).blob())) - sigData = (NS(self.authClient.transport.sessionID) - + chr(userauth.MSG_USERAUTH_REQUEST) + NS('foo') - + NS('nancy') + NS('publickey') + '\x01' + NS('ssh-rsa') - + blob) - obj = keys.Key.fromString(keydata.privateRSA_openssh) - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('publickey') + '\x01' + NS('ssh-rsa') + blob - + NS(obj.sign(sigData)))) - - - def test_publickey_without_privatekey(self): - """ - If the SSHUserAuthClient doesn't return anything from signData, - the client should start the authentication over again by requesting - 'none' authentication. - """ - authClient = ClientAuthWithoutPrivateKey('foo', - FakeTransport.Service()) - - authClient.transport = FakeTransport(None) - authClient.transport.sessionID = 'test' - authClient.serviceStarted() - authClient.tryAuth('publickey') - authClient.transport.packets = [] - self.assertIdentical(authClient.ssh_USERAUTH_PK_OK(''), None) - self.assertEqual(authClient.transport.packets, [ - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') + - NS('none'))]) - - - def test_old_publickey_getPublicKey(self): - """ - Old SSHUserAuthClients returned strings of public key blobs from - getPublicKey(). Test that a Deprecation warning is raised but the key is - verified correctly. - """ - oldAuth = OldClientAuth('foo', FakeTransport.Service()) - oldAuth.transport = FakeTransport(None) - oldAuth.transport.sessionID = 'test' - oldAuth.serviceStarted() - oldAuth.transport.packets = [] - self.assertWarns(DeprecationWarning, "Returning a string from " - "SSHUserAuthClient.getPublicKey() is deprecated since " - "Twisted 9.0. Return a keys.Key() instead.", - userauth.__file__, oldAuth.tryAuth, 'publickey') - self.assertEqual(oldAuth.transport.packets, [ - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') + - NS('publickey') + '\x00' + NS('ssh-rsa') + - NS(keys.Key.fromString(keydata.publicRSA_openssh).blob()))]) - - - def test_old_publickey_getPrivateKey(self): - """ - Old SSHUserAuthClients returned a PyCrypto key object from - getPrivateKey(). Test that _cbSignData signs the data warns the - user about the deprecation, but signs the data correctly. - """ - oldAuth = OldClientAuth('foo', FakeTransport.Service()) - d = self.assertWarns(DeprecationWarning, "Returning a PyCrypto key " - "object from SSHUserAuthClient.getPrivateKey() is " - "deprecated since Twisted 9.0. " - "Return a keys.Key() instead.", userauth.__file__, - oldAuth.signData, None, 'data') - def _checkSignedData(sig): - self.assertEqual(sig, - keys.Key.fromString(keydata.privateRSA_openssh).sign( - 'data')) - d.addCallback(_checkSignedData) - return d - - - def test_no_publickey(self): - """ - If there's no public key, auth_publickey should return a Deferred - called back with a False value. - """ - self.authClient.getPublicKey = lambda x: None - d = self.authClient.tryAuth('publickey') - def check(result): - self.assertFalse(result) - return d.addCallback(check) - - def test_password(self): - """ - Test that the client can authentication with a password. This - includes changing the password. - """ - self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\x00') - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('password') + '\x00' + NS('foo'))) - self.authClient.ssh_USERAUTH_PK_OK(NS('') + NS('')) - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('password') + '\xff' + NS('foo') * 2)) - - - def test_no_password(self): - """ - If getPassword returns None, tryAuth should return False. - """ - self.authClient.getPassword = lambda: None - self.assertFalse(self.authClient.tryAuth('password')) - - - def test_keyboardInteractive(self): - """ - Test that the client can authenticate using keyboard-interactive - authentication. - """ - self.authClient.ssh_USERAUTH_FAILURE(NS('keyboard-interactive') - + '\x00') - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('keyboard-interactive') + NS('')*2)) - self.authClient.ssh_USERAUTH_PK_OK(NS('')*3 + '\x00\x00\x00\x02' - + NS('Name: ') + '\xff' + NS('Password: ') + '\x00') - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_INFO_RESPONSE, '\x00\x00\x00\x02' - + NS('foo')*2)) - - - def test_USERAUTH_PK_OK_unknown_method(self): - """ - If C{SSHUserAuthClient} gets a MSG_USERAUTH_PK_OK packet when it's not - expecting it, it should fail the current authentication and move on to - the next type. - """ - self.authClient.lastAuth = 'unknown' - self.authClient.transport.packets = [] - self.authClient.ssh_USERAUTH_PK_OK('') - self.assertEqual(self.authClient.transport.packets, - [(userauth.MSG_USERAUTH_REQUEST, NS('foo') + - NS('nancy') + NS('none'))]) - - - def test_USERAUTH_FAILURE_sorting(self): - """ - ssh_USERAUTH_FAILURE should sort the methods by their position - in SSHUserAuthClient.preferredOrder. Methods that are not in - preferredOrder should be sorted at the end of that list. - """ - def auth_firstmethod(): - self.authClient.transport.sendPacket(255, 'here is data') - def auth_anothermethod(): - self.authClient.transport.sendPacket(254, 'other data') - return True - self.authClient.auth_firstmethod = auth_firstmethod - self.authClient.auth_anothermethod = auth_anothermethod - - # although they shouldn't get called, method callbacks auth_* MUST - # exist in order for the test to work properly. - self.authClient.ssh_USERAUTH_FAILURE(NS('anothermethod,password') + - '\x00') - # should send password packet - self.assertEqual(self.authClient.transport.packets[-1], - (userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('password') + '\x00' + NS('foo'))) - self.authClient.ssh_USERAUTH_FAILURE( - NS('firstmethod,anothermethod,password') + '\xff') - self.assertEqual(self.authClient.transport.packets[-2:], - [(255, 'here is data'), (254, 'other data')]) - - - def test_disconnectIfNoMoreAuthentication(self): - """ - If there are no more available user authentication messages, - the SSHUserAuthClient should disconnect with code - DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE. - """ - self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\x00') - self.authClient.ssh_USERAUTH_FAILURE(NS('password') + '\xff') - self.assertEqual(self.authClient.transport.packets[-1], - (transport.MSG_DISCONNECT, '\x00\x00\x00\x0e' + - NS('no more authentication methods available') + - '\x00\x00\x00\x00')) - - - def test_ebAuth(self): - """ - _ebAuth (the generic authentication error handler) should send - a request for the 'none' authentication method. - """ - self.authClient.transport.packets = [] - self.authClient._ebAuth(None) - self.assertEqual(self.authClient.transport.packets, - [(userauth.MSG_USERAUTH_REQUEST, NS('foo') + NS('nancy') - + NS('none'))]) - - - def test_defaults(self): - """ - getPublicKey() should return None. getPrivateKey() should return a - failed Deferred. getPassword() should return a failed Deferred. - getGenericAnswers() should return a failed Deferred. - """ - authClient = userauth.SSHUserAuthClient('foo', FakeTransport.Service()) - self.assertIdentical(authClient.getPublicKey(), None) - def check(result): - result.trap(NotImplementedError) - d = authClient.getPassword() - return d.addCallback(self.fail).addErrback(check2) - def check2(result): - result.trap(NotImplementedError) - d = authClient.getGenericAnswers(None, None, None) - return d.addCallback(self.fail).addErrback(check3) - def check3(result): - result.trap(NotImplementedError) - d = authClient.getPrivateKey() - return d.addCallback(self.fail).addErrback(check) - - - -class LoopbackTestCase(unittest.TestCase): - - - if keys is None: - skip = "cannot run w/o PyCrypto or PyASN1" - - - class Factory: - class Service: - name = 'TestService' - - - def serviceStarted(self): - self.transport.loseConnection() - - - def serviceStopped(self): - pass - - - def getService(self, avatar, name): - return self.Service - - - def test_loopback(self): - """ - Test that the userauth server and client play nicely with each other. - """ - server = userauth.SSHUserAuthServer() - client = ClientUserAuth('foo', self.Factory.Service()) - - # set up transports - server.transport = transport.SSHTransportBase() - server.transport.service = server - server.transport.isEncrypted = lambda x: True - client.transport = transport.SSHTransportBase() - client.transport.service = client - server.transport.sessionID = client.transport.sessionID = '' - # don't send key exchange packet - server.transport.sendKexInit = client.transport.sendKexInit = \ - lambda: None - - # set up server authentication - server.transport.factory = self.Factory() - server.passwordDelay = 0 # remove bad password delay - realm = Realm() - portal = Portal(realm) - checker = SSHProtocolChecker() - checker.registerChecker(PasswordChecker()) - checker.registerChecker(PrivateKeyChecker()) - checker.registerChecker(PAMChecker()) - checker.areDone = lambda aId: ( - len(checker.successfulCredentials[aId]) == 3) - portal.registerChecker(checker) - server.transport.factory.portal = portal - - d = loopback.loopbackAsync(server.transport, client.transport) - server.transport.transport.logPrefix = lambda: '_ServerLoopback' - client.transport.transport.logPrefix = lambda: '_ClientLoopback' - - server.serviceStarted() - client.serviceStarted() - - def check(ignored): - self.assertEqual(server.transport.service.name, 'TestService') - return d.addCallback(check) - - - -class ModuleInitializationTestCase(unittest.TestCase): - if keys is None: - skip = "cannot run w/o PyCrypto or PyASN1" - - - def test_messages(self): - # Several message types have value 60, check that MSG_USERAUTH_PK_OK - # is always the one which is mapped. - self.assertEqual(userauth.SSHUserAuthServer.protocolMessages[60], - 'MSG_USERAUTH_PK_OK') - self.assertEqual(userauth.SSHUserAuthClient.protocolMessages[60], - 'MSG_USERAUTH_PK_OK') diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py deleted file mode 100755 index 6d7d9d28..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/test/test_window.py +++ /dev/null @@ -1,67 +0,0 @@ - -""" -Tests for the insults windowing module, L{twisted.conch.insults.window}. -""" - -from twisted.trial.unittest import TestCase - -from twisted.conch.insults.window import TopWindow, ScrolledArea, TextOutput - - -class TopWindowTests(TestCase): - """ - Tests for L{TopWindow}, the root window container class. - """ - - def test_paintScheduling(self): - """ - Verify that L{TopWindow.repaint} schedules an actual paint to occur - using the scheduling object passed to its initializer. - """ - paints = [] - scheduled = [] - root = TopWindow(lambda: paints.append(None), scheduled.append) - - # Nothing should have happened yet. - self.assertEqual(paints, []) - self.assertEqual(scheduled, []) - - # Cause a paint to be scheduled. - root.repaint() - self.assertEqual(paints, []) - self.assertEqual(len(scheduled), 1) - - # Do another one to verify nothing else happens as long as the previous - # one is still pending. - root.repaint() - self.assertEqual(paints, []) - self.assertEqual(len(scheduled), 1) - - # Run the actual paint call. - scheduled.pop()() - self.assertEqual(len(paints), 1) - self.assertEqual(scheduled, []) - - # Do one more to verify that now that the previous one is finished - # future paints will succeed. - root.repaint() - self.assertEqual(len(paints), 1) - self.assertEqual(len(scheduled), 1) - - - -class ScrolledAreaTests(TestCase): - """ - Tests for L{ScrolledArea}, a widget which creates a viewport containing - another widget and can reposition that viewport using scrollbars. - """ - def test_parent(self): - """ - The parent of the widget passed to L{ScrolledArea} is set to a new - L{Viewport} created by the L{ScrolledArea} which itself has the - L{ScrolledArea} instance as its parent. - """ - widget = TextOutput() - scrolled = ScrolledArea(widget) - self.assertIdentical(widget.parent, scrolled._viewport) - self.assertIdentical(scrolled._viewport.parent, scrolled) diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS deleted file mode 100644 index e3a12638..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/NEWS +++ /dev/null @@ -1,414 +0,0 @@ -Ticket numbers in this file can be looked up by visiting -http://twistedmatrix.com/trac/ticket/<number> - -Twisted Conch 12.2.0 (2012-08-26) -================================= - -Features --------- - - twisted.conch.ssh.transport.SSHTransport now returns an - SSHTransportAddress from the getPeer() and getHost() methods. - (#2997) - -Bugfixes --------- - - twisted.conch now supports commercial SSH implementations which - don't comply with the IETF standard (#1902) - - twisted.conch.ssh.userauth now works correctly with hash - randomization enabled. (#5776) - - twisted.conch no longer relies on __builtins__ being a dict, which - is a purely CPython implementation detail (#5779) - -Other ------ - - #5496, #5617, #5700, #5748, #5777 - - -Twisted Conch 12.1.0 (2012-06-02) -================================= - -Features --------- - - twisted.conch.tap now supports cred plugins (#4753) - -Bugfixes --------- - - twisted.conch.client.knownhosts now handles errors encountered - parsing hashed entries in a known hosts file. (#5616) - -Improved Documentation ----------------------- - - Conch examples window.tac and telnet_echo.tac now have better - explanations. (#5590) - -Other ------ - - #5580 - - -Twisted Conch 12.0.0 (2012-02-10) -================================= - -Features --------- - - use Python shadow module for authentication if it's available - (#3242) - -Bugfixes --------- - - twisted.conch.ssh.transport.messages no longer ends with with old - message IDs on platforms with differing dict() orderings (#5352) - -Other ------ - - #5225 - - -Twisted Conch 11.1.0 (2011-11-15) -================================= - -Features --------- - - twisted.conch.ssh.filetransfer.FileTransferClient now handles short - status messages, not strictly allowed by the RFC, but sent by some - SSH implementations. (#3009) - - twisted.conch.manhole now supports CTRL-A and CTRL-E to trigger - HOME and END functions respectively. (#5252) - -Bugfixes --------- - - When run from an unpacked source tarball or a VCS checkout, the - bin/conch/ scripts will now use the version of Twisted they are - part of. (#3526) - - twisted.conch.insults.window.ScrolledArea now passes no extra - arguments to object.__init__ (which works on more versions of - Python). (#4197) - - twisted.conch.telnet.ITelnetProtocol now has the correct signature - for its unhandledSubnegotiation() method. (#4751) - - twisted.conch.ssh.userauth.SSHUserAuthClient now more closely - follows the RFC 4251 definition of boolean values when negotiating - for key-based authentication, allowing better interoperability with - other SSH implementations. (#5241) - - twisted.conch.recvline.RecvLine now ignores certain function keys - in its keystrokeReceived method instead of raising an exception. - (#5246) - -Deprecations and Removals -------------------------- - - The --user option to `twistd manhole' has been removed as it was - dead code with no functionality associated with it. (#5283) - -Other ------ - - #5107, #5256, #5349 - - -Twisted Conch 11.0.0 (2011-04-01) -================================= - -Bugfixes --------- - - The transport for subsystem protocols now declares that it - implements ITransport and implements the getHost and getPeer - methods. (#2453) - - twisted.conch.ssh.transport.SSHTransportBase now responds to key - exchange messages at any time during a connection (instead of only - at connection setup). It also queues non-key exchange messages - sent during key exchange to avoid corrupting the connection state. - (#4395) - - Importing twisted.conch.ssh.common no longer breaks pow(base, exp[, - modulus]) when the gmpy package is installed and base is not an - integer. (#4803) - - twisted.conch.ls.lsLine now returns a time string which does not - consider the locale. (#4937) - -Improved Documentation ----------------------- - - Changed the man page for ckeygen to accurately reflect what it - does, and corrected its synposis so that a second "ckeygen" is not - a required part of the ckeygen command line. (#4738) - -Other ------ - - #2112 - - -Twisted Conch 10.2.0 (2010-11-29) -================================= - -Bugfixes --------- - - twisted.conch.ssh.factory.SSHFactory no longer disables coredumps. - (#2715) - - The Deferred returned by twisted.conch.telnet.TelnetTransport.will - now fires with an OptionRefused failure if the peer responds with a - refusal for the option negotiation. (#4231) - - SSHServerTransport and SSHClientTransport in - twisted.conch.ssh.transport no longer use PyCrypto to generate - random numbers for DH KEX. They also now generate values from the - full valid range, rather than only half of it. (#4469) - - twisted.conch.ssh.connection.SSHConnection now errbacks leftover - request deferreds on connection shutdown. (#4483) - -Other ------ - - #4677 - - -Twisted Conch 10.1.0 (2010-06-27) -================================= - -Features --------- - - twisted.conch.ssh.transport.SSHTransportBase now allows supported - ssh protocol versions to be overriden. (#4428) - -Bugfixes --------- - - SSHSessionProcessProtocol now doesn't close the session when stdin - is closed, but instead when both stdout and stderr are. (#4350) - - The 'cftp' command-line tool will no longer encounter an - intermittent error, crashing at startup with a ZeroDivisionError - while trying to report progress. (#4463) - - twisted.conch.ssh.connection.SSHConnection now replies to requests - to open an unknown channel with a OPEN_UNKNOWN_CHANNEL_TYPE message - instead of closing the connection. (#4490) - -Deprecations and Removals -------------------------- - - twisted.conch.insults.client was deprecated. (#4095) - - twisted.conch.insults.colors has been deprecated. Please use - twisted.conch.insults.helper instead. (#4096) - - Removed twisted.conch.ssh.asn1, which has been deprecated since - Twisted 9.0. (#4097) - - Removed twisted.conch.ssh.common.Entropy, as Entropy.get_bytes has - been deprecated since 2007 and Entropy.get_bytes was the only - attribute of Entropy. (#4098) - - Removed twisted.conch.ssh.keys.getPublicKeyString, which has been - deprecated since 2007. Also updated the conch examples - sshsimpleserver.py and sshsimpleclient.py to reflect this removal. - (#4099) - - Removed twisted.conch.ssh.keys.makePublicKeyString, which has been - deprecated since 2007. (#4100) - - Removed twisted.conch.ssh.keys.getPublicKeyObject, which has been - deprecated since 2007. (#4101) - - Removed twisted.conch.ssh.keys.getPrivateKeyObject, which has been - deprecated since 2007. Also updated the conch examples to reflect - this removal. (#4102) - - Removed twisted.conch.ssh.keys.makePrivateKeyString, which has been - deprecated since 2007. (#4103) - - Removed twisted.conch.ssh.keys.makePublicKeyBlob, which has been - deprecated since 2007. (#4104) - - Removed twisted.conch.ssh.keys.signData, - twisted.conch.ssh.keys.verifySignature, and - twisted.conch.ssh.keys.printKey, which have been deprecated since - 2007. (#4105) - -Other ------ - - #3849, #4408, #4454 - - -Twisted Conch 10.0.0 (2010-03-01) -================================= - -Bugfixes --------- - - twisted.conch.checkers.SSHPublicKeyDatabase now looks in the - correct user directory for authorized_keys files. (#3984) - - - twisted.conch.ssh.SSHUserAuthClient now honors preferredOrder when - authenticating. (#4266) - -Other ------ - - #2391, #4203, #4265 - - -Twisted Conch 9.0.0 (2009-11-24) -================================ - -Fixes ------ - - The SSH key parser has been removed and conch now uses pyASN1 to parse keys. - This should fix a number of cases where parsing a key would fail, but it now - requires users to have pyASN1 installed (#3391) - - The time field on SFTP file listings should now be correct (#3503) - - The day field on SFTP file listings should now be correct on Windows (#3503) - - The "cftp" sftp client now truncates files it is uploading over (#2519) - - The telnet server protocol can now properly respond to subnegotiation - requests (#3655) - - Tests and factoring of the SSHv2 server implementation are now much better - (#2682) - - The SSHv2 server now sends "exit-signal" messages to the client, instead of - raising an exception, when a process dies due to a signal (#2687) - - cftp's client-side "exec" command now uses /bin/sh if the current user has - no shell (#3914) - -Deprecations and Removals -------------------------- - - The buggy SSH connection sharing feature of the SSHv2 client was removed - (#3498) - - Use of strings and PyCrypto objects to represent keys is deprecated in favor - of using Conch Key objects (#2682) - -Other ------ - - #3548, #3537, #3551, #3220, #3568, #3689, #3709, #3809, #2763, #3540, #3750, - #3897, #3813, #3871, #3916, #4047, #3940, #4050 - - -Conch 8.2.0 (2008-12-16) -======================== - -Features --------- - - The type of the protocols instantiated by SSHFactory is now parameterized - (#3443) - -Fixes ------ - - A file descriptor leak has been fixed (#3213, #1789) - - "File Already Exists" errors are now handled more correctly (#3033) - - Handling of CR IAC in TelnetClient is now improved (#3305) - - SSHAgent is no longer completely unusable (#3332) - - The performance of insults.ClientProtocol is now greatly increased by - delivering more than one byte at a time to application code (#3386) - - Manhole and the conch server no longer need to be run as root when not - necessary (#2607) - - The value of FILEXFER_ATTR_ACMODTIME has been corrected (#2902) - - The management of known_hosts and host key verification has been overhauled - (#1376, #1301, #3494, #3496, #1292, #3499) - -Other ------ - - #3193, #1633 - - -8.1.0 (2008-05-18) -================== - -Fixes ------ - - A regression was fixed whereby the publicKeys and privateKeys attributes of - SSHFactory would not be interpreted as strings (#3141) - - The sshsimpleserver.py example had a minor bug fix (#3135) - - The deprecated mktap API is no longer used (#3127) - - An infelicity was fixed whereby a NameError would be raised in certain - circumstances during authentication when a ConchError should have been - (#3154) - - A workaround was added to conch.insults for a bug in gnome-terminal whereby - it would not scroll correctly (#3189) - - -8.0.0 (2008-03-17) -================== - -Features --------- - - Add DEC private mode manipulation methods to ITerminalTransport. (#2403) - -Fixes ------ - - Parameterize the scheduler function used by the insults TopWindow widget. - This change breaks backwards compatibility in the TopWindow initializer. - (#2413) - - Notify subsystems, like SFTP, of connection close. (#2421) - - Change the process file descriptor "connection lost" code to reverse the - setNonBlocking operation done during initialization. (#2371) - - Change ConsoleManhole to wait for connectionLost notification before - stopping the reactor. (#2123, #2371) - - Make SSHUserAuthServer.ssh_USERAUTH_REQUEST return a Deferred. (#2528) - - Manhole's initializer calls its parent class's initializer with its - namespace argument. (#2587) - - Handle ^C during input line continuation in manhole by updating the prompt - and line buffer correctly. (#2663) - - Make twisted.conch.telnet.Telnet by default reject all attempts to enable - options. (#1967) - - Reduce the number of calls into application code to deliver application-level - data in twisted.conch.telnet.Telnet.dataReceived (#2107) - - Fix definition and management of extended attributes in conch file transfer. - (#3010) - - Fix parsing of OpenSSH-generated RSA keys with differing ASN.1 packing style. - (#3008) - - Fix handling of missing $HOME in twisted.conch.client.unix. (#3061) - -Misc ----- - - #2267, #2378, #2604, #2707, #2341, #2685, #2679, #2912, #2977, #2678, #2709 - #2063, #2847 - - -0.8.0 (2007-01-06) -================== - -Features --------- - - Manhole now supports Ctrl-l to emulate the same behavior in the - Python interactive interpreter (#1565) - - Python 2.5 is now supported (#1867) - -Misc ----- - - #1673, #1636, #1892, #1943, #2057, #1180, #1185, #2148, #2159, #2291, - -Deprecations and Removals -------------------------- - - - The old twisted.cred API (Identities, Authorizers, etc) is no - longer supported (#1440) - - -0.7.0 (2006-05-21) -================== - -Features --------- - - Timeout support for ExpectableBuffer.expect() - -Fixes ------ - - ~5x speedup for bulk data transfer (#1325) - - Misc: #1428 - -0.6.0: - - Bugfixes and improvements in SSH support and Insults: - - PAM authenticator support factored out into twisted.cred - - Poorly supported next-line terminal operation replaced with simple \r\n - - New functionality: - - An ITerminalTransport implementation with expect-like features - - Support for the "none" SSH cipher - - Insults support for handling more keystrokes and more methods for - terminal manipulation - - New, simple insults-based widget library added - - Better test coverage: - - Dependence on `localhost' name removed - - Some timing-sensitive tests changed to be more reliable - - Process spawning tests initialize environment more robustly - -0.5.0: - - Many improvements to SSH support. Here's some in particular: - - Add --reconnect option to conch binary - - utmp/wtmp logging - - Unix login improvements, PAM support - - Add "cftp" -- Conch SFTP. - - Deferred retrieval of public keys is supported - - PAM support for client and server - - Bugfixes: - - fix conch failing to exit, and hangs. - - Remote->Local forwarding - - Channel closing - - Invalid known_host writing - - Many others - - New functionality: - - twisted.conch.telnet: new, much improved telnet implementation. - - twisted.conch.insults: Basic curses-like terminal support (server-side). - - twisted.conch.manhole: new interactive python interactive interpreter, - can be used with conch's telnet, ssh, or on the console. - - Main features: Syntax coloring, line editing, and useful interactive - handling of Deferreds. diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README deleted file mode 100644 index aa25bb65..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/topfiles/README +++ /dev/null @@ -1,11 +0,0 @@ -Twisted Conch 12.2.0 - -Twisted Conch depends on Twisted Core and on Python Crypto extensions -(<http://www.pycrypto.org>). - -The pyasn1 module (<http://pyasn1.sourceforge.net/>) is also required. - -gmpy (<http://code.google.com/p/gmpy/>) is strongly recommended to improve -performance. - -Twisted Conch includes a couple simple GUI applications which depend on Tkinter. diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py deleted file mode 100755 index 00b4495f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ttymodes.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -import tty -# this module was autogenerated. - -VINTR = 1 -VQUIT = 2 -VERASE = 3 -VKILL = 4 -VEOF = 5 -VEOL = 6 -VEOL2 = 7 -VSTART = 8 -VSTOP = 9 -VSUSP = 10 -VDSUSP = 11 -VREPRINT = 12 -VWERASE = 13 -VLNEXT = 14 -VFLUSH = 15 -VSWTCH = 16 -VSTATUS = 17 -VDISCARD = 18 -IGNPAR = 30 -PARMRK = 31 -INPCK = 32 -ISTRIP = 33 -INLCR = 34 -IGNCR = 35 -ICRNL = 36 -IUCLC = 37 -IXON = 38 -IXANY = 39 -IXOFF = 40 -IMAXBEL = 41 -ISIG = 50 -ICANON = 51 -XCASE = 52 -ECHO = 53 -ECHOE = 54 -ECHOK = 55 -ECHONL = 56 -NOFLSH = 57 -TOSTOP = 58 -IEXTEN = 59 -ECHOCTL = 60 -ECHOKE = 61 -PENDIN = 62 -OPOST = 70 -OLCUC = 71 -ONLCR = 72 -OCRNL = 73 -ONOCR = 74 -ONLRET = 75 -CS7 = 90 -CS8 = 91 -PARENB = 92 -PARODD = 93 -TTY_OP_ISPEED = 128 -TTY_OP_OSPEED = 129 - -TTYMODES = { - 1 : 'VINTR', - 2 : 'VQUIT', - 3 : 'VERASE', - 4 : 'VKILL', - 5 : 'VEOF', - 6 : 'VEOL', - 7 : 'VEOL2', - 8 : 'VSTART', - 9 : 'VSTOP', - 10 : 'VSUSP', - 11 : 'VDSUSP', - 12 : 'VREPRINT', - 13 : 'VWERASE', - 14 : 'VLNEXT', - 15 : 'VFLUSH', - 16 : 'VSWTCH', - 17 : 'VSTATUS', - 18 : 'VDISCARD', - 30 : (tty.IFLAG, 'IGNPAR'), - 31 : (tty.IFLAG, 'PARMRK'), - 32 : (tty.IFLAG, 'INPCK'), - 33 : (tty.IFLAG, 'ISTRIP'), - 34 : (tty.IFLAG, 'INLCR'), - 35 : (tty.IFLAG, 'IGNCR'), - 36 : (tty.IFLAG, 'ICRNL'), - 37 : (tty.IFLAG, 'IUCLC'), - 38 : (tty.IFLAG, 'IXON'), - 39 : (tty.IFLAG, 'IXANY'), - 40 : (tty.IFLAG, 'IXOFF'), - 41 : (tty.IFLAG, 'IMAXBEL'), - 50 : (tty.LFLAG, 'ISIG'), - 51 : (tty.LFLAG, 'ICANON'), - 52 : (tty.LFLAG, 'XCASE'), - 53 : (tty.LFLAG, 'ECHO'), - 54 : (tty.LFLAG, 'ECHOE'), - 55 : (tty.LFLAG, 'ECHOK'), - 56 : (tty.LFLAG, 'ECHONL'), - 57 : (tty.LFLAG, 'NOFLSH'), - 58 : (tty.LFLAG, 'TOSTOP'), - 59 : (tty.LFLAG, 'IEXTEN'), - 60 : (tty.LFLAG, 'ECHOCTL'), - 61 : (tty.LFLAG, 'ECHOKE'), - 62 : (tty.LFLAG, 'PENDIN'), - 70 : (tty.OFLAG, 'OPOST'), - 71 : (tty.OFLAG, 'OLCUC'), - 72 : (tty.OFLAG, 'ONLCR'), - 73 : (tty.OFLAG, 'OCRNL'), - 74 : (tty.OFLAG, 'ONOCR'), - 75 : (tty.OFLAG, 'ONLRET'), -# 90 : (tty.CFLAG, 'CS7'), -# 91 : (tty.CFLAG, 'CS8'), - 92 : (tty.CFLAG, 'PARENB'), - 93 : (tty.CFLAG, 'PARODD'), - 128 : 'ISPEED', - 129 : 'OSPEED' -} diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py deleted file mode 100755 index ea0eea83..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - - -""" -twisted.conch.ui is home to the UI elements for tkconch. - -Maintainer: Paul Swartz -""" diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py deleted file mode 100755 index 9d5e616a..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/ansi.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# -"""Module to parse ANSI escape sequences - -Maintainer: Jean-Paul Calderone -""" - -import string - -# Twisted imports -from twisted.python import log - -class ColorText: - """ - Represents an element of text along with the texts colors and - additional attributes. - """ - - # The colors to use - COLORS = ('b', 'r', 'g', 'y', 'l', 'm', 'c', 'w') - BOLD_COLORS = tuple([x.upper() for x in COLORS]) - BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(len(COLORS)) - - # Color names - COLOR_NAMES = ( - 'Black', 'Red', 'Green', 'Yellow', 'Blue', 'Magenta', 'Cyan', 'White' - ) - - def __init__(self, text, fg, bg, display, bold, underline, flash, reverse): - self.text, self.fg, self.bg = text, fg, bg - self.display = display - self.bold = bold - self.underline = underline - self.flash = flash - self.reverse = reverse - if self.reverse: - self.fg, self.bg = self.bg, self.fg - - -class AnsiParser: - """ - Parser class for ANSI codes. - """ - - # Terminators for cursor movement ansi controls - unsupported - CURSOR_SET = ('H', 'f', 'A', 'B', 'C', 'D', 'R', 's', 'u', 'd','G') - - # Terminators for erasure ansi controls - unsupported - ERASE_SET = ('J', 'K', 'P') - - # Terminators for mode change ansi controls - unsupported - MODE_SET = ('h', 'l') - - # Terminators for keyboard assignment ansi controls - unsupported - ASSIGN_SET = ('p',) - - # Terminators for color change ansi controls - supported - COLOR_SET = ('m',) - - SETS = (CURSOR_SET, ERASE_SET, MODE_SET, ASSIGN_SET, COLOR_SET) - - def __init__(self, defaultFG, defaultBG): - self.defaultFG, self.defaultBG = defaultFG, defaultBG - self.currentFG, self.currentBG = self.defaultFG, self.defaultBG - self.bold, self.flash, self.underline, self.reverse = 0, 0, 0, 0 - self.display = 1 - self.prepend = '' - - - def stripEscapes(self, string): - """ - Remove all ANSI color escapes from the given string. - """ - result = '' - show = 1 - i = 0 - L = len(string) - while i < L: - if show == 0 and string[i] in _sets: - show = 1 - elif show: - n = string.find('\x1B', i) - if n == -1: - return result + string[i:] - else: - result = result + string[i:n] - i = n - show = 0 - i = i + 1 - return result - - def writeString(self, colorstr): - pass - - def parseString(self, str): - """ - Turn a string input into a list of L{ColorText} elements. - """ - - if self.prepend: - str = self.prepend + str - self.prepend = '' - parts = str.split('\x1B') - - if len(parts) == 1: - self.writeString(self.formatText(parts[0])) - else: - self.writeString(self.formatText(parts[0])) - for s in parts[1:]: - L = len(s) - i = 0 - type = None - while i < L: - if s[i] not in string.digits+'[;?': - break - i+=1 - if not s: - self.prepend = '\x1b' - return - if s[0]!='[': - self.writeString(self.formatText(s[i+1:])) - continue - else: - s=s[1:] - i-=1 - if i==L-1: - self.prepend = '\x1b[' - return - type = _setmap.get(s[i], None) - if type is None: - continue - - if type == AnsiParser.COLOR_SET: - self.parseColor(s[:i + 1]) - s = s[i + 1:] - self.writeString(self.formatText(s)) - elif type == AnsiParser.CURSOR_SET: - cursor, s = s[:i+1], s[i+1:] - self.parseCursor(cursor) - self.writeString(self.formatText(s)) - elif type == AnsiParser.ERASE_SET: - erase, s = s[:i+1], s[i+1:] - self.parseErase(erase) - self.writeString(self.formatText(s)) - elif type == AnsiParser.MODE_SET: - mode, s = s[:i+1], s[i+1:] - #self.parseErase('2J') - self.writeString(self.formatText(s)) - elif i == L: - self.prepend = '\x1B[' + s - else: - log.msg('Unhandled ANSI control type: %c' % (s[i],)) - s = s[i + 1:] - self.writeString(self.formatText(s)) - - def parseColor(self, str): - """ - Handle a single ANSI color sequence - """ - # Drop the trailing 'm' - str = str[:-1] - - if not str: - str = '0' - - try: - parts = map(int, str.split(';')) - except ValueError: - log.msg('Invalid ANSI color sequence (%d): %s' % (len(str), str)) - self.currentFG, self.currentBG = self.defaultFG, self.defaultBG - return - - for x in parts: - if x == 0: - self.currentFG, self.currentBG = self.defaultFG, self.defaultBG - self.bold, self.flash, self.underline, self.reverse = 0, 0, 0, 0 - self.display = 1 - elif x == 1: - self.bold = 1 - elif 30 <= x <= 37: - self.currentFG = x - 30 - elif 40 <= x <= 47: - self.currentBG = x - 40 - elif x == 39: - self.currentFG = self.defaultFG - elif x == 49: - self.currentBG = self.defaultBG - elif x == 4: - self.underline = 1 - elif x == 5: - self.flash = 1 - elif x == 7: - self.reverse = 1 - elif x == 8: - self.display = 0 - elif x == 22: - self.bold = 0 - elif x == 24: - self.underline = 0 - elif x == 25: - self.blink = 0 - elif x == 27: - self.reverse = 0 - elif x == 28: - self.display = 1 - else: - log.msg('Unrecognised ANSI color command: %d' % (x,)) - - def parseCursor(self, cursor): - pass - - def parseErase(self, erase): - pass - - - def pickColor(self, value, mode, BOLD = ColorText.BOLD_COLORS): - if mode: - return ColorText.COLORS[value] - else: - return self.bold and BOLD[value] or ColorText.COLORS[value] - - - def formatText(self, text): - return ColorText( - text, - self.pickColor(self.currentFG, 0), - self.pickColor(self.currentBG, 1), - self.display, self.bold, self.underline, self.flash, self.reverse - ) - - -_sets = ''.join(map(''.join, AnsiParser.SETS)) - -_setmap = {} -for s in AnsiParser.SETS: - for r in s: - _setmap[r] = s -del s diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py deleted file mode 100755 index cd7581da..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/ui/tkvt100.py +++ /dev/null @@ -1,197 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -# - -"""Module to emulate a VT100 terminal in Tkinter. - -Maintainer: Paul Swartz -""" - -import Tkinter, tkFont -import ansi -import string - -ttyFont = None#tkFont.Font(family = 'Courier', size = 10) -fontWidth, fontHeight = None,None#max(map(ttyFont.measure, string.letters+string.digits)), int(ttyFont.metrics()['linespace']) - -colorKeys = ( - 'b', 'r', 'g', 'y', 'l', 'm', 'c', 'w', - 'B', 'R', 'G', 'Y', 'L', 'M', 'C', 'W' -) - -colorMap = { - 'b': '#000000', 'r': '#c40000', 'g': '#00c400', 'y': '#c4c400', - 'l': '#000080', 'm': '#c400c4', 'c': '#00c4c4', 'w': '#c4c4c4', - 'B': '#626262', 'R': '#ff0000', 'G': '#00ff00', 'Y': '#ffff00', - 'L': '#0000ff', 'M': '#ff00ff', 'C': '#00ffff', 'W': '#ffffff', -} - -class VT100Frame(Tkinter.Frame): - def __init__(self, *args, **kw): - global ttyFont, fontHeight, fontWidth - ttyFont = tkFont.Font(family = 'Courier', size = 10) - fontWidth, fontHeight = max(map(ttyFont.measure, string.letters+string.digits)), int(ttyFont.metrics()['linespace']) - self.width = kw.get('width', 80) - self.height = kw.get('height', 25) - self.callback = kw['callback'] - del kw['callback'] - kw['width'] = w = fontWidth * self.width - kw['height'] = h = fontHeight * self.height - Tkinter.Frame.__init__(self, *args, **kw) - self.canvas = Tkinter.Canvas(bg='#000000', width=w, height=h) - self.canvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1) - self.canvas.bind('<Key>', self.keyPressed) - self.canvas.bind('<1>', lambda x: 'break') - self.canvas.bind('<Up>', self.upPressed) - self.canvas.bind('<Down>', self.downPressed) - self.canvas.bind('<Left>', self.leftPressed) - self.canvas.bind('<Right>', self.rightPressed) - self.canvas.focus() - - self.ansiParser = ansi.AnsiParser(ansi.ColorText.WHITE, ansi.ColorText.BLACK) - self.ansiParser.writeString = self.writeString - self.ansiParser.parseCursor = self.parseCursor - self.ansiParser.parseErase = self.parseErase - #for (a, b) in colorMap.items(): - # self.canvas.tag_config(a, foreground=b) - # self.canvas.tag_config('b'+a, background=b) - #self.canvas.tag_config('underline', underline=1) - - self.x = 0 - self.y = 0 - self.cursor = self.canvas.create_rectangle(0,0,fontWidth-1,fontHeight-1,fill='green',outline='green') - - def _delete(self, sx, sy, ex, ey): - csx = sx*fontWidth + 1 - csy = sy*fontHeight + 1 - cex = ex*fontWidth + 3 - cey = ey*fontHeight + 3 - items = self.canvas.find_overlapping(csx,csy, cex,cey) - for item in items: - self.canvas.delete(item) - - def _write(self, ch, fg, bg): - if self.x == self.width: - self.x = 0 - self.y+=1 - if self.y == self.height: - [self.canvas.move(x,0,-fontHeight) for x in self.canvas.find_all()] - self.y-=1 - canvasX = self.x*fontWidth + 1 - canvasY = self.y*fontHeight + 1 - items = self.canvas.find_overlapping(canvasX, canvasY, canvasX+2, canvasY+2) - if items: - [self.canvas.delete(item) for item in items] - if bg: - self.canvas.create_rectangle(canvasX, canvasY, canvasX+fontWidth-1, canvasY+fontHeight-1, fill=bg, outline=bg) - self.canvas.create_text(canvasX, canvasY, anchor=Tkinter.NW, font=ttyFont, text=ch, fill=fg) - self.x+=1 - - def write(self, data): - #print self.x,self.y,repr(data) - #if len(data)>5: raw_input() - self.ansiParser.parseString(data) - self.canvas.delete(self.cursor) - canvasX = self.x*fontWidth + 1 - canvasY = self.y*fontHeight + 1 - self.cursor = self.canvas.create_rectangle(canvasX,canvasY,canvasX+fontWidth-1,canvasY+fontHeight-1, fill='green', outline='green') - self.canvas.lower(self.cursor) - - def writeString(self, i): - if not i.display: - return - fg = colorMap[i.fg] - bg = i.bg != 'b' and colorMap[i.bg] - for ch in i.text: - b = ord(ch) - if b == 7: # bell - self.bell() - elif b == 8: # BS - if self.x: - self.x-=1 - elif b == 9: # TAB - [self._write(' ',fg,bg) for i in range(8)] - elif b == 10: - if self.y == self.height-1: - self._delete(0,0,self.width,0) - [self.canvas.move(x,0,-fontHeight) for x in self.canvas.find_all()] - else: - self.y+=1 - elif b == 13: - self.x = 0 - elif 32 <= b < 127: - self._write(ch, fg, bg) - - def parseErase(self, erase): - if ';' in erase: - end = erase[-1] - parts = erase[:-1].split(';') - [self.parseErase(x+end) for x in parts] - return - start = 0 - x,y = self.x, self.y - if len(erase) > 1: - start = int(erase[:-1]) - if erase[-1] == 'J': - if start == 0: - self._delete(x,y,self.width,self.height) - else: - self._delete(0,0,self.width,self.height) - self.x = 0 - self.y = 0 - elif erase[-1] == 'K': - if start == 0: - self._delete(x,y,self.width,y) - elif start == 1: - self._delete(0,y,x,y) - self.x = 0 - else: - self._delete(0,y,self.width,y) - self.x = 0 - elif erase[-1] == 'P': - self._delete(x,y,x+start,y) - - def parseCursor(self, cursor): - #if ';' in cursor and cursor[-1]!='H': - # end = cursor[-1] - # parts = cursor[:-1].split(';') - # [self.parseCursor(x+end) for x in parts] - # return - start = 1 - if len(cursor) > 1 and cursor[-1]!='H': - start = int(cursor[:-1]) - if cursor[-1] == 'C': - self.x+=start - elif cursor[-1] == 'D': - self.x-=start - elif cursor[-1]=='d': - self.y=start-1 - elif cursor[-1]=='G': - self.x=start-1 - elif cursor[-1]=='H': - if len(cursor)>1: - y,x = map(int, cursor[:-1].split(';')) - y-=1 - x-=1 - else: - x,y=0,0 - self.x = x - self.y = y - - def keyPressed(self, event): - if self.callback and event.char: - self.callback(event.char) - return 'break' - - def upPressed(self, event): - self.callback('\x1bOA') - - def downPressed(self, event): - self.callback('\x1bOB') - - def rightPressed(self, event): - self.callback('\x1bOC') - - def leftPressed(self, event): - self.callback('\x1bOD') diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py deleted file mode 100755 index 3a44be07..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/conch/unix.py +++ /dev/null @@ -1,457 +0,0 @@ -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -from twisted.cred import portal -from twisted.python import components, log -from twisted.internet.error import ProcessExitedAlready -from zope import interface -from ssh import session, forwarding, filetransfer -from ssh.filetransfer import FXF_READ, FXF_WRITE, FXF_APPEND, FXF_CREAT, FXF_TRUNC, FXF_EXCL -from twisted.conch.ls import lsLine - -from avatar import ConchUser -from error import ConchError -from interfaces import ISession, ISFTPServer, ISFTPFile - -import struct, os, time, socket -import fcntl, tty -import pwd, grp -import pty -import ttymodes - -try: - import utmp -except ImportError: - utmp = None - -class UnixSSHRealm: - interface.implements(portal.IRealm) - - def requestAvatar(self, username, mind, *interfaces): - user = UnixConchUser(username) - return interfaces[0], user, user.logout - - -class UnixConchUser(ConchUser): - - def __init__(self, username): - ConchUser.__init__(self) - self.username = username - self.pwdData = pwd.getpwnam(self.username) - l = [self.pwdData[3]] - for groupname, password, gid, userlist in grp.getgrall(): - if username in userlist: - l.append(gid) - self.otherGroups = l - self.listeners = {} # dict mapping (interface, port) -> listener - self.channelLookup.update( - {"session": session.SSHSession, - "direct-tcpip": forwarding.openConnectForwardingClient}) - - self.subsystemLookup.update( - {"sftp": filetransfer.FileTransferServer}) - - def getUserGroupId(self): - return self.pwdData[2:4] - - def getOtherGroups(self): - return self.otherGroups - - def getHomeDir(self): - return self.pwdData[5] - - def getShell(self): - return self.pwdData[6] - - def global_tcpip_forward(self, data): - hostToBind, portToBind = forwarding.unpackGlobal_tcpip_forward(data) - from twisted.internet import reactor - try: listener = self._runAsUser( - reactor.listenTCP, portToBind, - forwarding.SSHListenForwardingFactory(self.conn, - (hostToBind, portToBind), - forwarding.SSHListenServerForwardingChannel), - interface = hostToBind) - except: - return 0 - else: - self.listeners[(hostToBind, portToBind)] = listener - if portToBind == 0: - portToBind = listener.getHost()[2] # the port - return 1, struct.pack('>L', portToBind) - else: - return 1 - - def global_cancel_tcpip_forward(self, data): - hostToBind, portToBind = forwarding.unpackGlobal_tcpip_forward(data) - listener = self.listeners.get((hostToBind, portToBind), None) - if not listener: - return 0 - del self.listeners[(hostToBind, portToBind)] - self._runAsUser(listener.stopListening) - return 1 - - def logout(self): - # remove all listeners - for listener in self.listeners.itervalues(): - self._runAsUser(listener.stopListening) - log.msg('avatar %s logging out (%i)' % (self.username, len(self.listeners))) - - def _runAsUser(self, f, *args, **kw): - euid = os.geteuid() - egid = os.getegid() - groups = os.getgroups() - uid, gid = self.getUserGroupId() - os.setegid(0) - os.seteuid(0) - os.setgroups(self.getOtherGroups()) - os.setegid(gid) - os.seteuid(uid) - try: - f = iter(f) - except TypeError: - f = [(f, args, kw)] - try: - for i in f: - func = i[0] - args = len(i)>1 and i[1] or () - kw = len(i)>2 and i[2] or {} - r = func(*args, **kw) - finally: - os.setegid(0) - os.seteuid(0) - os.setgroups(groups) - os.setegid(egid) - os.seteuid(euid) - return r - -class SSHSessionForUnixConchUser: - - interface.implements(ISession) - - def __init__(self, avatar): - self.avatar = avatar - self. environ = {'PATH':'/bin:/usr/bin:/usr/local/bin'} - self.pty = None - self.ptyTuple = 0 - - def addUTMPEntry(self, loggedIn=1): - if not utmp: - return - ipAddress = self.avatar.conn.transport.transport.getPeer().host - packedIp ,= struct.unpack('L', socket.inet_aton(ipAddress)) - ttyName = self.ptyTuple[2][5:] - t = time.time() - t1 = int(t) - t2 = int((t-t1) * 1e6) - entry = utmp.UtmpEntry() - entry.ut_type = loggedIn and utmp.USER_PROCESS or utmp.DEAD_PROCESS - entry.ut_pid = self.pty.pid - entry.ut_line = ttyName - entry.ut_id = ttyName[-4:] - entry.ut_tv = (t1,t2) - if loggedIn: - entry.ut_user = self.avatar.username - entry.ut_host = socket.gethostbyaddr(ipAddress)[0] - entry.ut_addr_v6 = (packedIp, 0, 0, 0) - a = utmp.UtmpRecord(utmp.UTMP_FILE) - a.pututline(entry) - a.endutent() - b = utmp.UtmpRecord(utmp.WTMP_FILE) - b.pututline(entry) - b.endutent() - - - def getPty(self, term, windowSize, modes): - self.environ['TERM'] = term - self.winSize = windowSize - self.modes = modes - master, slave = pty.openpty() - ttyname = os.ttyname(slave) - self.environ['SSH_TTY'] = ttyname - self.ptyTuple = (master, slave, ttyname) - - def openShell(self, proto): - from twisted.internet import reactor - if not self.ptyTuple: # we didn't get a pty-req - log.msg('tried to get shell without pty, failing') - raise ConchError("no pty") - uid, gid = self.avatar.getUserGroupId() - homeDir = self.avatar.getHomeDir() - shell = self.avatar.getShell() - self.environ['USER'] = self.avatar.username - self.environ['HOME'] = homeDir - self.environ['SHELL'] = shell - shellExec = os.path.basename(shell) - peer = self.avatar.conn.transport.transport.getPeer() - host = self.avatar.conn.transport.transport.getHost() - self.environ['SSH_CLIENT'] = '%s %s %s' % (peer.host, peer.port, host.port) - self.getPtyOwnership() - self.pty = reactor.spawnProcess(proto, \ - shell, ['-%s' % shellExec], self.environ, homeDir, uid, gid, - usePTY = self.ptyTuple) - self.addUTMPEntry() - fcntl.ioctl(self.pty.fileno(), tty.TIOCSWINSZ, - struct.pack('4H', *self.winSize)) - if self.modes: - self.setModes() - self.oldWrite = proto.transport.write - proto.transport.write = self._writeHack - self.avatar.conn.transport.transport.setTcpNoDelay(1) - - def execCommand(self, proto, cmd): - from twisted.internet import reactor - uid, gid = self.avatar.getUserGroupId() - homeDir = self.avatar.getHomeDir() - shell = self.avatar.getShell() or '/bin/sh' - command = (shell, '-c', cmd) - peer = self.avatar.conn.transport.transport.getPeer() - host = self.avatar.conn.transport.transport.getHost() - self.environ['SSH_CLIENT'] = '%s %s %s' % (peer.host, peer.port, host.port) - if self.ptyTuple: - self.getPtyOwnership() - self.pty = reactor.spawnProcess(proto, \ - shell, command, self.environ, homeDir, - uid, gid, usePTY = self.ptyTuple or 0) - if self.ptyTuple: - self.addUTMPEntry() - if self.modes: - self.setModes() -# else: -# tty.setraw(self.pty.pipes[0].fileno(), tty.TCSANOW) - self.avatar.conn.transport.transport.setTcpNoDelay(1) - - def getPtyOwnership(self): - ttyGid = os.stat(self.ptyTuple[2])[5] - uid, gid = self.avatar.getUserGroupId() - euid, egid = os.geteuid(), os.getegid() - os.setegid(0) - os.seteuid(0) - try: - os.chown(self.ptyTuple[2], uid, ttyGid) - finally: - os.setegid(egid) - os.seteuid(euid) - - def setModes(self): - pty = self.pty - attr = tty.tcgetattr(pty.fileno()) - for mode, modeValue in self.modes: - if not ttymodes.TTYMODES.has_key(mode): continue - ttyMode = ttymodes.TTYMODES[mode] - if len(ttyMode) == 2: # flag - flag, ttyAttr = ttyMode - if not hasattr(tty, ttyAttr): continue - ttyval = getattr(tty, ttyAttr) - if modeValue: - attr[flag] = attr[flag]|ttyval - else: - attr[flag] = attr[flag]&~ttyval - elif ttyMode == 'OSPEED': - attr[tty.OSPEED] = getattr(tty, 'B%s'%modeValue) - elif ttyMode == 'ISPEED': - attr[tty.ISPEED] = getattr(tty, 'B%s'%modeValue) - else: - if not hasattr(tty, ttyMode): continue - ttyval = getattr(tty, ttyMode) - attr[tty.CC][ttyval] = chr(modeValue) - tty.tcsetattr(pty.fileno(), tty.TCSANOW, attr) - - def eofReceived(self): - if self.pty: - self.pty.closeStdin() - - def closed(self): - if self.ptyTuple and os.path.exists(self.ptyTuple[2]): - ttyGID = os.stat(self.ptyTuple[2])[5] - os.chown(self.ptyTuple[2], 0, ttyGID) - if self.pty: - try: - self.pty.signalProcess('HUP') - except (OSError,ProcessExitedAlready): - pass - self.pty.loseConnection() - self.addUTMPEntry(0) - log.msg('shell closed') - - def windowChanged(self, winSize): - self.winSize = winSize - fcntl.ioctl(self.pty.fileno(), tty.TIOCSWINSZ, - struct.pack('4H', *self.winSize)) - - def _writeHack(self, data): - """ - Hack to send ignore messages when we aren't echoing. - """ - if self.pty is not None: - attr = tty.tcgetattr(self.pty.fileno())[3] - if not attr & tty.ECHO and attr & tty.ICANON: # no echo - self.avatar.conn.transport.sendIgnore('\x00'*(8+len(data))) - self.oldWrite(data) - - -class SFTPServerForUnixConchUser: - - interface.implements(ISFTPServer) - - def __init__(self, avatar): - self.avatar = avatar - - - def _setAttrs(self, path, attrs): - """ - NOTE: this function assumes it runs as the logged-in user: - i.e. under _runAsUser() - """ - if "uid" in attrs and "gid" in attrs: - os.chown(path, attrs["uid"], attrs["gid"]) - if "permissions" in attrs: - os.chmod(path, attrs["permissions"]) - if "atime" in attrs and "mtime" in attrs: - os.utime(path, (attrs["atime"], attrs["mtime"])) - - def _getAttrs(self, s): - return { - "size" : s.st_size, - "uid" : s.st_uid, - "gid" : s.st_gid, - "permissions" : s.st_mode, - "atime" : int(s.st_atime), - "mtime" : int(s.st_mtime) - } - - def _absPath(self, path): - home = self.avatar.getHomeDir() - return os.path.abspath(os.path.join(home, path)) - - def gotVersion(self, otherVersion, extData): - return {} - - def openFile(self, filename, flags, attrs): - return UnixSFTPFile(self, self._absPath(filename), flags, attrs) - - def removeFile(self, filename): - filename = self._absPath(filename) - return self.avatar._runAsUser(os.remove, filename) - - def renameFile(self, oldpath, newpath): - oldpath = self._absPath(oldpath) - newpath = self._absPath(newpath) - return self.avatar._runAsUser(os.rename, oldpath, newpath) - - def makeDirectory(self, path, attrs): - path = self._absPath(path) - return self.avatar._runAsUser([(os.mkdir, (path,)), - (self._setAttrs, (path, attrs))]) - - def removeDirectory(self, path): - path = self._absPath(path) - self.avatar._runAsUser(os.rmdir, path) - - def openDirectory(self, path): - return UnixSFTPDirectory(self, self._absPath(path)) - - def getAttrs(self, path, followLinks): - path = self._absPath(path) - if followLinks: - s = self.avatar._runAsUser(os.stat, path) - else: - s = self.avatar._runAsUser(os.lstat, path) - return self._getAttrs(s) - - def setAttrs(self, path, attrs): - path = self._absPath(path) - self.avatar._runAsUser(self._setAttrs, path, attrs) - - def readLink(self, path): - path = self._absPath(path) - return self.avatar._runAsUser(os.readlink, path) - - def makeLink(self, linkPath, targetPath): - linkPath = self._absPath(linkPath) - targetPath = self._absPath(targetPath) - return self.avatar._runAsUser(os.symlink, targetPath, linkPath) - - def realPath(self, path): - return os.path.realpath(self._absPath(path)) - - def extendedRequest(self, extName, extData): - raise NotImplementedError - -class UnixSFTPFile: - - interface.implements(ISFTPFile) - - def __init__(self, server, filename, flags, attrs): - self.server = server - openFlags = 0 - if flags & FXF_READ == FXF_READ and flags & FXF_WRITE == 0: - openFlags = os.O_RDONLY - if flags & FXF_WRITE == FXF_WRITE and flags & FXF_READ == 0: - openFlags = os.O_WRONLY - if flags & FXF_WRITE == FXF_WRITE and flags & FXF_READ == FXF_READ: - openFlags = os.O_RDWR - if flags & FXF_APPEND == FXF_APPEND: - openFlags |= os.O_APPEND - if flags & FXF_CREAT == FXF_CREAT: - openFlags |= os.O_CREAT - if flags & FXF_TRUNC == FXF_TRUNC: - openFlags |= os.O_TRUNC - if flags & FXF_EXCL == FXF_EXCL: - openFlags |= os.O_EXCL - if "permissions" in attrs: - mode = attrs["permissions"] - del attrs["permissions"] - else: - mode = 0777 - fd = server.avatar._runAsUser(os.open, filename, openFlags, mode) - if attrs: - server.avatar._runAsUser(server._setAttrs, filename, attrs) - self.fd = fd - - def close(self): - return self.server.avatar._runAsUser(os.close, self.fd) - - def readChunk(self, offset, length): - return self.server.avatar._runAsUser([ (os.lseek, (self.fd, offset, 0)), - (os.read, (self.fd, length)) ]) - - def writeChunk(self, offset, data): - return self.server.avatar._runAsUser([(os.lseek, (self.fd, offset, 0)), - (os.write, (self.fd, data))]) - - def getAttrs(self): - s = self.server.avatar._runAsUser(os.fstat, self.fd) - return self.server._getAttrs(s) - - def setAttrs(self, attrs): - raise NotImplementedError - - -class UnixSFTPDirectory: - - def __init__(self, server, directory): - self.server = server - self.files = server.avatar._runAsUser(os.listdir, directory) - self.dir = directory - - def __iter__(self): - return self - - def next(self): - try: - f = self.files.pop(0) - except IndexError: - raise StopIteration - else: - s = self.server.avatar._runAsUser(os.lstat, os.path.join(self.dir, f)) - longname = lsLine(f, s) - attrs = self.server._getAttrs(s) - return (f, longname, attrs) - - def close(self): - self.files = [] - - -components.registerAdapter(SFTPServerForUnixConchUser, UnixConchUser, filetransfer.ISFTPServer) -components.registerAdapter(SSHSessionForUnixConchUser, UnixConchUser, session.ISession) |