You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2012/07/06 23:28:48 UTC
[5/9] [Defect / Enhancement / New Feature] CS-15281 : Removal of
third party dependencies in Citrix code base
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/pkey.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/pkey.py b/tools/migration/paramiko/pkey.py
deleted file mode 100644
index 58e6686..0000000
--- a/tools/migration/paramiko/pkey.py
+++ /dev/null
@@ -1,377 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Common API for all public keys.
-"""
-
-import base64
-from binascii import hexlify, unhexlify
-import os
-
-from Crypto.Hash import MD5
-from Crypto.Cipher import DES3
-
-from paramiko.common import *
-from paramiko import util
-from paramiko.message import Message
-from paramiko.ssh_exception import SSHException, PasswordRequiredException
-
-
-class PKey (object):
- """
- Base class for public keys.
- """
-
- # known encryption types for private key files:
- _CIPHER_TABLE = {
- 'DES-EDE3-CBC': { 'cipher': DES3, 'keysize': 24, 'blocksize': 8, 'mode': DES3.MODE_CBC }
- }
-
-
- def __init__(self, msg=None, data=None):
- """
- Create a new instance of this public key type. If C{msg} is given,
- the key's public part(s) will be filled in from the message. If
- C{data} is given, the key's public part(s) will be filled in from
- the string.
-
- @param msg: an optional SSH L{Message} containing a public key of this
- type.
- @type msg: L{Message}
- @param data: an optional string containing a public key of this type
- @type data: str
-
- @raise SSHException: if a key cannot be created from the C{data} or
- C{msg} given, or no key was passed in.
- """
- pass
-
- def __str__(self):
- """
- Return a string of an SSH L{Message} made up of the public part(s) of
- this key. This string is suitable for passing to L{__init__} to
- re-create the key object later.
-
- @return: string representation of an SSH key message.
- @rtype: str
- """
- return ''
-
- def __cmp__(self, other):
- """
- Compare this key to another. Returns 0 if this key is equivalent to
- the given key, or non-0 if they are different. Only the public parts
- of the key are compared, so a public key will compare equal to its
- corresponding private key.
-
- @param other: key to compare to.
- @type other: L{PKey}
- @return: 0 if the two keys are equivalent, non-0 otherwise.
- @rtype: int
- """
- hs = hash(self)
- ho = hash(other)
- if hs != ho:
- return cmp(hs, ho)
- return cmp(str(self), str(other))
-
- def get_name(self):
- """
- Return the name of this private key implementation.
-
- @return: name of this private key type, in SSH terminology (for
- example, C{"ssh-rsa"}).
- @rtype: str
- """
- return ''
-
- def get_bits(self):
- """
- Return the number of significant bits in this key. This is useful
- for judging the relative security of a key.
-
- @return: bits in the key.
- @rtype: int
- """
- return 0
-
- def can_sign(self):
- """
- Return C{True} if this key has the private part necessary for signing
- data.
-
- @return: C{True} if this is a private key.
- @rtype: bool
- """
- return False
-
- def get_fingerprint(self):
- """
- Return an MD5 fingerprint of the public part of this key. Nothing
- secret is revealed.
-
- @return: a 16-byte string (binary) of the MD5 fingerprint, in SSH
- format.
- @rtype: str
- """
- return MD5.new(str(self)).digest()
-
- def get_base64(self):
- """
- Return a base64 string containing the public part of this key. Nothing
- secret is revealed. This format is compatible with that used to store
- public key files or recognized host keys.
-
- @return: a base64 string containing the public part of the key.
- @rtype: str
- """
- return base64.encodestring(str(self)).replace('\n', '')
-
- def sign_ssh_data(self, randpool, data):
- """
- Sign a blob of data with this private key, and return a L{Message}
- representing an SSH signature message.
-
- @param randpool: a secure random number generator.
- @type randpool: L{Crypto.Util.randpool.RandomPool}
- @param data: the data to sign.
- @type data: str
- @return: an SSH signature message.
- @rtype: L{Message}
- """
- return ''
-
- def verify_ssh_sig(self, data, msg):
- """
- Given a blob of data, and an SSH message representing a signature of
- that data, verify that it was signed with this key.
-
- @param data: the data that was signed.
- @type data: str
- @param msg: an SSH signature message
- @type msg: L{Message}
- @return: C{True} if the signature verifies correctly; C{False}
- otherwise.
- @rtype: boolean
- """
- return False
-
- def from_private_key_file(cls, filename, password=None):
- """
- Create a key object by reading a private key file. If the private
- key is encrypted and C{password} is not C{None}, the given password
- will be used to decrypt the key (otherwise L{PasswordRequiredException}
- is thrown). Through the magic of python, this factory method will
- exist in all subclasses of PKey (such as L{RSAKey} or L{DSSKey}), but
- is useless on the abstract PKey class.
-
- @param filename: name of the file to read
- @type filename: str
- @param password: an optional password to use to decrypt the key file,
- if it's encrypted
- @type password: str
- @return: a new key object based on the given private key
- @rtype: L{PKey}
-
- @raise IOError: if there was an error reading the file
- @raise PasswordRequiredException: if the private key file is
- encrypted, and C{password} is C{None}
- @raise SSHException: if the key file is invalid
- """
- key = cls(filename=filename, password=password)
- return key
- from_private_key_file = classmethod(from_private_key_file)
-
- def from_private_key(cls, file_obj, password=None):
- """
- Create a key object by reading a private key from a file (or file-like)
- object. If the private key is encrypted and C{password} is not C{None},
- the given password will be used to decrypt the key (otherwise
- L{PasswordRequiredException} is thrown).
-
- @param file_obj: the file to read from
- @type file_obj: file
- @param password: an optional password to use to decrypt the key, if it's
- encrypted
- @type password: str
- @return: a new key object based on the given private key
- @rtype: L{PKey}
-
- @raise IOError: if there was an error reading the key
- @raise PasswordRequiredException: if the private key file is encrypted,
- and C{password} is C{None}
- @raise SSHException: if the key file is invalid
- """
- key = cls(file_obj=file_obj, password=password)
- return key
- from_private_key = classmethod(from_private_key)
-
- def write_private_key_file(self, filename, password=None):
- """
- Write private key contents into a file. If the password is not
- C{None}, the key is encrypted before writing.
-
- @param filename: name of the file to write
- @type filename: str
- @param password: an optional password to use to encrypt the key file
- @type password: str
-
- @raise IOError: if there was an error writing the file
- @raise SSHException: if the key is invalid
- """
- raise Exception('Not implemented in PKey')
-
- def write_private_key(self, file_obj, password=None):
- """
- Write private key contents into a file (or file-like) object. If the
- password is not C{None}, the key is encrypted before writing.
-
- @param file_obj: the file object to write into
- @type file_obj: file
- @param password: an optional password to use to encrypt the key
- @type password: str
-
- @raise IOError: if there was an error writing to the file
- @raise SSHException: if the key is invalid
- """
- raise Exception('Not implemented in PKey')
-
- def _read_private_key_file(self, tag, filename, password=None):
- """
- Read an SSH2-format private key file, looking for a string of the type
- C{"BEGIN xxx PRIVATE KEY"} for some C{xxx}, base64-decode the text we
- find, and return it as a string. If the private key is encrypted and
- C{password} is not C{None}, the given password will be used to decrypt
- the key (otherwise L{PasswordRequiredException} is thrown).
-
- @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block.
- @type tag: str
- @param filename: name of the file to read.
- @type filename: str
- @param password: an optional password to use to decrypt the key file,
- if it's encrypted.
- @type password: str
- @return: data blob that makes up the private key.
- @rtype: str
-
- @raise IOError: if there was an error reading the file.
- @raise PasswordRequiredException: if the private key file is
- encrypted, and C{password} is C{None}.
- @raise SSHException: if the key file is invalid.
- """
- f = open(filename, 'r')
- data = self._read_private_key(tag, f, password)
- f.close()
- return data
-
- def _read_private_key(self, tag, f, password=None):
- lines = f.readlines()
- start = 0
- while (start < len(lines)) and (lines[start].strip() != '-----BEGIN ' + tag + ' PRIVATE KEY-----'):
- start += 1
- if start >= len(lines):
- raise SSHException('not a valid ' + tag + ' private key file')
- # parse any headers first
- headers = {}
- start += 1
- while start < len(lines):
- l = lines[start].split(': ')
- if len(l) == 1:
- break
- headers[l[0].lower()] = l[1].strip()
- start += 1
- # find end
- end = start
- while (lines[end].strip() != '-----END ' + tag + ' PRIVATE KEY-----') and (end < len(lines)):
- end += 1
- # if we trudged to the end of the file, just try to cope.
- try:
- data = base64.decodestring(''.join(lines[start:end]))
- except base64.binascii.Error, e:
- raise SSHException('base64 decoding error: ' + str(e))
- if 'proc-type' not in headers:
- # unencryped: done
- return data
- # encrypted keyfile: will need a password
- if headers['proc-type'] != '4,ENCRYPTED':
- raise SSHException('Unknown private key structure "%s"' % headers['proc-type'])
- try:
- encryption_type, saltstr = headers['dek-info'].split(',')
- except:
- raise SSHException('Can\'t parse DEK-info in private key file')
- if encryption_type not in self._CIPHER_TABLE:
- raise SSHException('Unknown private key cipher "%s"' % encryption_type)
- # if no password was passed in, raise an exception pointing out that we need one
- if password is None:
- raise PasswordRequiredException('Private key file is encrypted')
- cipher = self._CIPHER_TABLE[encryption_type]['cipher']
- keysize = self._CIPHER_TABLE[encryption_type]['keysize']
- mode = self._CIPHER_TABLE[encryption_type]['mode']
- salt = unhexlify(saltstr)
- key = util.generate_key_bytes(MD5, salt, password, keysize)
- return cipher.new(key, mode, salt).decrypt(data)
-
- def _write_private_key_file(self, tag, filename, data, password=None):
- """
- Write an SSH2-format private key file in a form that can be read by
- paramiko or openssh. If no password is given, the key is written in
- a trivially-encoded format (base64) which is completely insecure. If
- a password is given, DES-EDE3-CBC is used.
-
- @param tag: C{"RSA"} or C{"DSA"}, the tag used to mark the data block.
- @type tag: str
- @param filename: name of the file to write.
- @type filename: str
- @param data: data blob that makes up the private key.
- @type data: str
- @param password: an optional password to use to encrypt the file.
- @type password: str
-
- @raise IOError: if there was an error writing the file.
- """
- f = open(filename, 'w', 0600)
- # grrr... the mode doesn't always take hold
- os.chmod(filename, 0600)
- self._write_private_key(tag, f, data, password)
- f.close()
-
- def _write_private_key(self, tag, f, data, password=None):
- f.write('-----BEGIN %s PRIVATE KEY-----\n' % tag)
- if password is not None:
- # since we only support one cipher here, use it
- cipher_name = self._CIPHER_TABLE.keys()[0]
- cipher = self._CIPHER_TABLE[cipher_name]['cipher']
- keysize = self._CIPHER_TABLE[cipher_name]['keysize']
- blocksize = self._CIPHER_TABLE[cipher_name]['blocksize']
- mode = self._CIPHER_TABLE[cipher_name]['mode']
- salt = randpool.get_bytes(8)
- key = util.generate_key_bytes(MD5, salt, password, keysize)
- if len(data) % blocksize != 0:
- n = blocksize - len(data) % blocksize
- #data += randpool.get_bytes(n)
- # that would make more sense ^, but it confuses openssh.
- data += '\0' * n
- data = cipher.new(key, mode, salt).encrypt(data)
- f.write('Proc-Type: 4,ENCRYPTED\n')
- f.write('DEK-Info: %s,%s\n' % (cipher_name, hexlify(salt).upper()))
- f.write('\n')
- s = base64.encodestring(data)
- # re-wrap to 64-char lines
- s = ''.join(s.split('\n'))
- s = '\n'.join([s[i : i+64] for i in range(0, len(s), 64)])
- f.write(s)
- f.write('\n')
- f.write('-----END %s PRIVATE KEY-----\n' % tag)
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/primes.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/primes.py b/tools/migration/paramiko/primes.py
deleted file mode 100644
index 0c12732..0000000
--- a/tools/migration/paramiko/primes.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Utility functions for dealing with primes.
-"""
-
-from Crypto.Util import number
-
-from paramiko import util
-from paramiko.ssh_exception import SSHException
-
-
-def _generate_prime(bits, randpool):
- "primtive attempt at prime generation"
- hbyte_mask = pow(2, bits % 8) - 1
- while True:
- # loop catches the case where we increment n into a higher bit-range
- x = randpool.get_bytes((bits+7) // 8)
- if hbyte_mask > 0:
- x = chr(ord(x[0]) & hbyte_mask) + x[1:]
- n = util.inflate_long(x, 1)
- n |= 1
- n |= (1 << (bits - 1))
- while not number.isPrime(n):
- n += 2
- if util.bit_length(n) == bits:
- break
- return n
-
-def _roll_random(rpool, n):
- "returns a random # from 0 to N-1"
- bits = util.bit_length(n-1)
- bytes = (bits + 7) // 8
- hbyte_mask = pow(2, bits % 8) - 1
-
- # so here's the plan:
- # we fetch as many random bits as we'd need to fit N-1, and if the
- # generated number is >= N, we try again. in the worst case (N-1 is a
- # power of 2), we have slightly better than 50% odds of getting one that
- # fits, so i can't guarantee that this loop will ever finish, but the odds
- # of it looping forever should be infinitesimal.
- while True:
- x = rpool.get_bytes(bytes)
- if hbyte_mask > 0:
- x = chr(ord(x[0]) & hbyte_mask) + x[1:]
- num = util.inflate_long(x, 1)
- if num < n:
- break
- return num
-
-
-class ModulusPack (object):
- """
- convenience object for holding the contents of the /etc/ssh/moduli file,
- on systems that have such a file.
- """
-
- def __init__(self, rpool):
- # pack is a hash of: bits -> [ (generator, modulus) ... ]
- self.pack = {}
- self.discarded = []
- self.randpool = rpool
-
- def _parse_modulus(self, line):
- timestamp, mod_type, tests, tries, size, generator, modulus = line.split()
- mod_type = int(mod_type)
- tests = int(tests)
- tries = int(tries)
- size = int(size)
- generator = int(generator)
- modulus = long(modulus, 16)
-
- # weed out primes that aren't at least:
- # type 2 (meets basic structural requirements)
- # test 4 (more than just a small-prime sieve)
- # tries < 100 if test & 4 (at least 100 tries of miller-rabin)
- if (mod_type < 2) or (tests < 4) or ((tests & 4) and (tests < 8) and (tries < 100)):
- self.discarded.append((modulus, 'does not meet basic requirements'))
- return
- if generator == 0:
- generator = 2
-
- # there's a bug in the ssh "moduli" file (yeah, i know: shock! dismay!
- # call cnn!) where it understates the bit lengths of these primes by 1.
- # this is okay.
- bl = util.bit_length(modulus)
- if (bl != size) and (bl != size + 1):
- self.discarded.append((modulus, 'incorrectly reported bit length %d' % size))
- return
- if bl not in self.pack:
- self.pack[bl] = []
- self.pack[bl].append((generator, modulus))
-
- def read_file(self, filename):
- """
- @raise IOError: passed from any file operations that fail.
- """
- self.pack = {}
- f = open(filename, 'r')
- for line in f:
- line = line.strip()
- if (len(line) == 0) or (line[0] == '#'):
- continue
- try:
- self._parse_modulus(line)
- except:
- continue
- f.close()
-
- def get_modulus(self, min, prefer, max):
- bitsizes = self.pack.keys()
- bitsizes.sort()
- if len(bitsizes) == 0:
- raise SSHException('no moduli available')
- good = -1
- # find nearest bitsize >= preferred
- for b in bitsizes:
- if (b >= prefer) and (b < max) and ((b < good) or (good == -1)):
- good = b
- # if that failed, find greatest bitsize >= min
- if good == -1:
- for b in bitsizes:
- if (b >= min) and (b < max) and (b > good):
- good = b
- if good == -1:
- # their entire (min, max) range has no intersection with our range.
- # if their range is below ours, pick the smallest. otherwise pick
- # the largest. it'll be out of their range requirement either way,
- # but we'll be sending them the closest one we have.
- good = bitsizes[0]
- if min > good:
- good = bitsizes[-1]
- # now pick a random modulus of this bitsize
- n = _roll_random(self.randpool, len(self.pack[good]))
- return self.pack[good][n]
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/resource.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/resource.py b/tools/migration/paramiko/resource.py
deleted file mode 100644
index e8d35fd..0000000
--- a/tools/migration/paramiko/resource.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Resource manager.
-"""
-
-import weakref
-
-
-class ResourceManager (object):
- """
- A registry of objects and resources that should be closed when those
- objects are deleted.
-
- This is meant to be a safer alternative to python's C{__del__} method,
- which can cause reference cycles to never be collected. Objects registered
- with the ResourceManager can be collected but still free resources when
- they die.
-
- Resources are registered using L{register}, and when an object is garbage
- collected, each registered resource is closed by having its C{close()}
- method called. Multiple resources may be registered per object, but a
- resource will only be closed once, even if multiple objects register it.
- (The last object to register it wins.)
- """
-
- def __init__(self):
- self._table = {}
-
- def register(self, obj, resource):
- """
- Register a resource to be closed with an object is collected.
-
- When the given C{obj} is garbage-collected by the python interpreter,
- the C{resource} will be closed by having its C{close()} method called.
- Any exceptions are ignored.
-
- @param obj: the object to track
- @type obj: object
- @param resource: the resource to close when the object is collected
- @type resource: object
- """
- def callback(ref):
- try:
- resource.close()
- except:
- pass
- del self._table[id(resource)]
-
- # keep the weakref in a table so it sticks around long enough to get
- # its callback called. :)
- self._table[id(resource)] = weakref.ref(obj, callback)
-
-
-# singleton
-ResourceManager = ResourceManager()
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/rng.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/rng.py b/tools/migration/paramiko/rng.py
deleted file mode 100644
index fdfaa5e..0000000
--- a/tools/migration/paramiko/rng.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/python
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# -*- coding: ascii -*-
-# Copyright (C) 2008 Dwayne C. Litzenberger <dl...@dlitz.net>
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import sys
-import threading
-from Crypto.Util.randpool import RandomPool as _RandomPool
-
-try:
- import platform
-except ImportError:
- platform = None # Not available using Python 2.2
-
-def _strxor(a, b):
- assert len(a) == len(b)
- return "".join(map(lambda x, y: chr(ord(x) ^ ord(y)), a, b))
-
-## Find a strong random entropy source, depending on the detected platform.
-## WARNING TO DEVELOPERS: This will fail on some systems, but do NOT use
-## Crypto.Util.randpool.RandomPool as a fall-back. RandomPool will happily run
-## with very little entropy, thus _silently_ defeating any security that
-## Paramiko attempts to provide. (This is current as of PyCrypto 2.0.1).
-
-if ((platform is not None and platform.system().lower() == 'windows') or
- sys.platform == 'win32'):
- # MS Windows
- from paramiko import rng_win32
- rng_device = rng_win32.open_rng_device()
-else:
- # Assume POSIX (any system where /dev/urandom exists)
- from paramiko import rng_posix
- rng_device = rng_posix.open_rng_device()
-
-
-class StrongLockingRandomPool(object):
- """Wrapper around RandomPool guaranteeing strong random numbers.
-
- Crypto.Util.randpool.RandomPool will silently operate even if it is seeded
- with little or no entropy, and it provides no prediction resistance if its
- state is ever compromised throughout its runtime. It is also not thread-safe.
-
- This wrapper augments RandomPool by XORing its output with random bits from
- the operating system, and by controlling access to the underlying
- RandomPool using an exclusive lock.
- """
-
- def __init__(self, instance=None):
- if instance is None:
- instance = _RandomPool()
- self.randpool = instance
- self.randpool_lock = threading.Lock()
- self.entropy = rng_device
-
- # Stir 256 bits of entropy from the RNG device into the RandomPool.
- self.randpool.stir(self.entropy.read(32))
- self.entropy.randomize()
-
- def stir(self, s=''):
- self.randpool_lock.acquire()
- try:
- self.randpool.stir(s)
- finally:
- self.randpool_lock.release()
- self.entropy.randomize()
-
- def randomize(self, N=0):
- self.randpool_lock.acquire()
- try:
- self.randpool.randomize(N)
- finally:
- self.randpool_lock.release()
- self.entropy.randomize()
-
- def add_event(self, s=''):
- self.randpool_lock.acquire()
- try:
- self.randpool.add_event(s)
- finally:
- self.randpool_lock.release()
-
- def get_bytes(self, N):
- self.randpool_lock.acquire()
- try:
- randpool_data = self.randpool.get_bytes(N)
- finally:
- self.randpool_lock.release()
- entropy_data = self.entropy.read(N)
- result = _strxor(randpool_data, entropy_data)
- assert len(randpool_data) == N and len(entropy_data) == N and len(result) == N
- return result
-
-# vim:set ts=4 sw=4 sts=4 expandtab:
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/rng_posix.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/rng_posix.py b/tools/migration/paramiko/rng_posix.py
deleted file mode 100644
index f138950..0000000
--- a/tools/migration/paramiko/rng_posix.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/python
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# -*- coding: ascii -*-
-# Copyright (C) 2008 Dwayne C. Litzenberger <dl...@dlitz.net>
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import os
-import stat
-
-class error(Exception):
- pass
-
-class _RNG(object):
- def __init__(self, file):
- self.file = file
-
- def read(self, bytes):
- return self.file.read(bytes)
-
- def close(self):
- return self.file.close()
-
- def randomize(self):
- return
-
-def open_rng_device(device_path=None):
- """Open /dev/urandom and perform some sanity checks."""
-
- f = None
- g = None
-
- if device_path is None:
- device_path = "/dev/urandom"
-
- try:
- # Try to open /dev/urandom now so that paramiko will be able to access
- # it even if os.chroot() is invoked later.
- try:
- f = open(device_path, "rb", 0)
- except EnvironmentError:
- raise error("Unable to open /dev/urandom")
-
- # Open a second file descriptor for sanity checking later.
- try:
- g = open(device_path, "rb", 0)
- except EnvironmentError:
- raise error("Unable to open /dev/urandom")
-
- # Check that /dev/urandom is a character special device, not a regular file.
- st = os.fstat(f.fileno()) # f
- if stat.S_ISREG(st.st_mode) or not stat.S_ISCHR(st.st_mode):
- raise error("/dev/urandom is not a character special device")
-
- st = os.fstat(g.fileno()) # g
- if stat.S_ISREG(st.st_mode) or not stat.S_ISCHR(st.st_mode):
- raise error("/dev/urandom is not a character special device")
-
- # Check that /dev/urandom always returns the number of bytes requested
- x = f.read(20)
- y = g.read(20)
- if len(x) != 20 or len(y) != 20:
- raise error("Error reading from /dev/urandom: input truncated")
-
- # Check that different reads return different data
- if x == y:
- raise error("/dev/urandom is broken; returning identical data: %r == %r" % (x, y))
-
- # Close the duplicate file object
- g.close()
-
- # Return the first file object
- return _RNG(f)
-
- except error:
- if f is not None:
- f.close()
- if g is not None:
- g.close()
- raise
-
-# vim:set ts=4 sw=4 sts=4 expandtab:
-
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/rng_win32.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/rng_win32.py b/tools/migration/paramiko/rng_win32.py
deleted file mode 100644
index 8065e94..0000000
--- a/tools/migration/paramiko/rng_win32.py
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/python
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# -*- coding: ascii -*-
-# Copyright (C) 2008 Dwayne C. Litzenberger <dl...@dlitz.net>
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-class error(Exception):
- pass
-
-# Try to import the "winrandom" module
-try:
- from Crypto.Util import winrandom as _winrandom
-except ImportError:
- _winrandom = None
-
-# Try to import the "urandom" module
-try:
- from os import urandom as _urandom
-except ImportError:
- _urandom = None
-
-
-class _RNG(object):
- def __init__(self, readfunc):
- self.read = readfunc
-
- def randomize(self):
- # According to "Cryptanalysis of the Random Number Generator of the
- # Windows Operating System", by Leo Dorrendorf and Zvi Gutterman
- # and Benny Pinkas <http://eprint.iacr.org/2007/419>,
- # CryptGenRandom only updates its internal state using kernel-provided
- # random data every 128KiB of output.
- self.read(128*1024) # discard 128 KiB of output
-
-def _open_winrandom():
- if _winrandom is None:
- raise error("Crypto.Util.winrandom module not found")
-
- # Check that we can open the winrandom module
- try:
- r0 = _winrandom.new()
- r1 = _winrandom.new()
- except Exception, exc:
- raise error("winrandom.new() failed: %s" % str(exc), exc)
-
- # Check that we can read from the winrandom module
- try:
- x = r0.get_bytes(20)
- y = r1.get_bytes(20)
- except Exception, exc:
- raise error("winrandom get_bytes failed: %s" % str(exc), exc)
-
- # Check that the requested number of bytes are returned
- if len(x) != 20 or len(y) != 20:
- raise error("Error reading from winrandom: input truncated")
-
- # Check that different reads return different data
- if x == y:
- raise error("winrandom broken: returning identical data")
-
- return _RNG(r0.get_bytes)
-
-def _open_urandom():
- if _urandom is None:
- raise error("os.urandom function not found")
-
- # Check that we can read from os.urandom()
- try:
- x = _urandom(20)
- y = _urandom(20)
- except Exception, exc:
- raise error("os.urandom failed: %s" % str(exc), exc)
-
- # Check that the requested number of bytes are returned
- if len(x) != 20 or len(y) != 20:
- raise error("os.urandom failed: input truncated")
-
- # Check that different reads return different data
- if x == y:
- raise error("os.urandom failed: returning identical data")
-
- return _RNG(_urandom)
-
-def open_rng_device():
- # Try using the Crypto.Util.winrandom module
- try:
- return _open_winrandom()
- except error:
- pass
-
- # Several versions of PyCrypto do not contain the winrandom module, but
- # Python >= 2.4 has os.urandom, so try to use that.
- try:
- return _open_urandom()
- except error:
- pass
-
- # SECURITY NOTE: DO NOT USE Crypto.Util.randpool.RandomPool HERE!
- # If we got to this point, RandomPool will silently run with very little
- # entropy. (This is current as of PyCrypto 2.0.1).
- # See http://www.lag.net/pipermail/paramiko/2008-January/000599.html
- # and http://www.lag.net/pipermail/paramiko/2008-April/000678.html
-
- raise error("Unable to find a strong random entropy source. You cannot run this software securely under the current configuration.")
-
-# vim:set ts=4 sw=4 sts=4 expandtab:
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/rsakey.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/rsakey.py b/tools/migration/paramiko/rsakey.py
deleted file mode 100644
index 160ad69..0000000
--- a/tools/migration/paramiko/rsakey.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-L{RSAKey}
-"""
-
-from Crypto.PublicKey import RSA
-from Crypto.Hash import SHA, MD5
-from Crypto.Cipher import DES3
-
-from paramiko.common import *
-from paramiko import util
-from paramiko.message import Message
-from paramiko.ber import BER, BERException
-from paramiko.pkey import PKey
-from paramiko.ssh_exception import SSHException
-
-
-class RSAKey (PKey):
- """
- Representation of an RSA key which can be used to sign and verify SSH2
- data.
- """
-
- def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None):
- self.n = None
- self.e = None
- self.d = None
- self.p = None
- self.q = None
- if file_obj is not None:
- self._from_private_key(file_obj, password)
- return
- if filename is not None:
- self._from_private_key_file(filename, password)
- return
- if (msg is None) and (data is not None):
- msg = Message(data)
- if vals is not None:
- self.e, self.n = vals
- else:
- if msg is None:
- raise SSHException('Key object may not be empty')
- if msg.get_string() != 'ssh-rsa':
- raise SSHException('Invalid key')
- self.e = msg.get_mpint()
- self.n = msg.get_mpint()
- self.size = util.bit_length(self.n)
-
- def __str__(self):
- m = Message()
- m.add_string('ssh-rsa')
- m.add_mpint(self.e)
- m.add_mpint(self.n)
- return str(m)
-
- def __hash__(self):
- h = hash(self.get_name())
- h = h * 37 + hash(self.e)
- h = h * 37 + hash(self.n)
- return hash(h)
-
- def get_name(self):
- return 'ssh-rsa'
-
- def get_bits(self):
- return self.size
-
- def can_sign(self):
- return self.d is not None
-
- def sign_ssh_data(self, rpool, data):
- digest = SHA.new(data).digest()
- rsa = RSA.construct((long(self.n), long(self.e), long(self.d)))
- sig = util.deflate_long(rsa.sign(self._pkcs1imify(digest), '')[0], 0)
- m = Message()
- m.add_string('ssh-rsa')
- m.add_string(sig)
- return m
-
- def verify_ssh_sig(self, data, msg):
- if msg.get_string() != 'ssh-rsa':
- return False
- sig = util.inflate_long(msg.get_string(), True)
- # verify the signature by SHA'ing the data and encrypting it using the
- # public key. some wackiness ensues where we "pkcs1imify" the 20-byte
- # hash into a string as long as the RSA key.
- hash_obj = util.inflate_long(self._pkcs1imify(SHA.new(data).digest()), True)
- rsa = RSA.construct((long(self.n), long(self.e)))
- return rsa.verify(hash_obj, (sig,))
-
- def _encode_key(self):
- if (self.p is None) or (self.q is None):
- raise SSHException('Not enough key info to write private key file')
- keylist = [ 0, self.n, self.e, self.d, self.p, self.q,
- self.d % (self.p - 1), self.d % (self.q - 1),
- util.mod_inverse(self.q, self.p) ]
- try:
- b = BER()
- b.encode(keylist)
- except BERException:
- raise SSHException('Unable to create ber encoding of key')
- return str(b)
-
- def write_private_key_file(self, filename, password=None):
- self._write_private_key_file('RSA', filename, self._encode_key(), password)
-
- def write_private_key(self, file_obj, password=None):
- self._write_private_key('RSA', file_obj, self._encode_key(), password)
-
- def generate(bits, progress_func=None):
- """
- Generate a new private RSA key. This factory function can be used to
- generate a new host key or authentication key.
-
- @param bits: number of bits the generated key should be.
- @type bits: int
- @param progress_func: an optional function to call at key points in
- key generation (used by C{pyCrypto.PublicKey}).
- @type progress_func: function
- @return: new private key
- @rtype: L{RSAKey}
- """
- randpool.stir()
- rsa = RSA.generate(bits, randpool.get_bytes, progress_func)
- key = RSAKey(vals=(rsa.e, rsa.n))
- key.d = rsa.d
- key.p = rsa.p
- key.q = rsa.q
- return key
- generate = staticmethod(generate)
-
-
- ### internals...
-
-
- def _pkcs1imify(self, data):
- """
- turn a 20-byte SHA1 hash into a blob of data as large as the key's N,
- using PKCS1's \"emsa-pkcs1-v1_5\" encoding. totally bizarre.
- """
- SHA1_DIGESTINFO = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'
- size = len(util.deflate_long(self.n, 0))
- filler = '\xff' * (size - len(SHA1_DIGESTINFO) - len(data) - 3)
- return '\x00\x01' + filler + '\x00' + SHA1_DIGESTINFO + data
-
- def _from_private_key_file(self, filename, password):
- data = self._read_private_key_file('RSA', filename, password)
- self._decode_key(data)
-
- def _from_private_key(self, file_obj, password):
- data = self._read_private_key('RSA', file_obj, password)
- self._decode_key(data)
-
- def _decode_key(self, data):
- # private key file contains:
- # RSAPrivateKey = { version = 0, n, e, d, p, q, d mod p-1, d mod q-1, q**-1 mod p }
- try:
- keylist = BER(data).decode()
- except BERException:
- raise SSHException('Unable to parse key file')
- if (type(keylist) is not list) or (len(keylist) < 4) or (keylist[0] != 0):
- raise SSHException('Not a valid RSA private key file (bad ber encoding)')
- self.n = keylist[1]
- self.e = keylist[2]
- self.d = keylist[3]
- # not really needed
- self.p = keylist[4]
- self.q = keylist[5]
- self.size = util.bit_length(self.n)
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/server.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/server.py b/tools/migration/paramiko/server.py
deleted file mode 100644
index 67147f6..0000000
--- a/tools/migration/paramiko/server.py
+++ /dev/null
@@ -1,629 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-L{ServerInterface} is an interface to override for server support.
-"""
-
-import threading
-from paramiko.common import *
-from paramiko import util
-
-
-class InteractiveQuery (object):
- """
- A query (set of prompts) for a user during interactive authentication.
- """
-
- def __init__(self, name='', instructions='', *prompts):
- """
- Create a new interactive query to send to the client. The name and
- instructions are optional, but are generally displayed to the end
- user. A list of prompts may be included, or they may be added via
- the L{add_prompt} method.
-
- @param name: name of this query
- @type name: str
- @param instructions: user instructions (usually short) about this query
- @type instructions: str
- @param prompts: one or more authentication prompts
- @type prompts: str
- """
- self.name = name
- self.instructions = instructions
- self.prompts = []
- for x in prompts:
- if (type(x) is str) or (type(x) is unicode):
- self.add_prompt(x)
- else:
- self.add_prompt(x[0], x[1])
-
- def add_prompt(self, prompt, echo=True):
- """
- Add a prompt to this query. The prompt should be a (reasonably short)
- string. Multiple prompts can be added to the same query.
-
- @param prompt: the user prompt
- @type prompt: str
- @param echo: C{True} (default) if the user's response should be echoed;
- C{False} if not (for a password or similar)
- @type echo: bool
- """
- self.prompts.append((prompt, echo))
-
-
-class ServerInterface (object):
- """
- This class defines an interface for controlling the behavior of paramiko
- in server mode.
-
- Methods on this class are called from paramiko's primary thread, so you
- shouldn't do too much work in them. (Certainly nothing that blocks or
- sleeps.)
- """
-
- def check_channel_request(self, kind, chanid):
- """
- Determine if a channel request of a given type will be granted, and
- return C{OPEN_SUCCEEDED} or an error code. This method is
- called in server mode when the client requests a channel, after
- authentication is complete.
-
- If you allow channel requests (and an ssh server that didn't would be
- useless), you should also override some of the channel request methods
- below, which are used to determine which services will be allowed on
- a given channel:
- - L{check_channel_pty_request}
- - L{check_channel_shell_request}
- - L{check_channel_subsystem_request}
- - L{check_channel_window_change_request}
- - L{check_channel_x11_request}
-
- The C{chanid} parameter is a small number that uniquely identifies the
- channel within a L{Transport}. A L{Channel} object is not created
- unless this method returns C{OPEN_SUCCEEDED} -- once a
- L{Channel} object is created, you can call L{Channel.get_id} to
- retrieve the channel ID.
-
- The return value should either be C{OPEN_SUCCEEDED} (or
- C{0}) to allow the channel request, or one of the following error
- codes to reject it:
- - C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}
- - C{OPEN_FAILED_CONNECT_FAILED}
- - C{OPEN_FAILED_UNKNOWN_CHANNEL_TYPE}
- - C{OPEN_FAILED_RESOURCE_SHORTAGE}
-
- The default implementation always returns
- C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}.
-
- @param kind: the kind of channel the client would like to open
- (usually C{"session"}).
- @type kind: str
- @param chanid: ID of the channel
- @type chanid: int
- @return: a success or failure code (listed above)
- @rtype: int
- """
- return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
-
- def get_allowed_auths(self, username):
- """
- Return a list of authentication methods supported by the server.
- This list is sent to clients attempting to authenticate, to inform them
- of authentication methods that might be successful.
-
- The "list" is actually a string of comma-separated names of types of
- authentication. Possible values are C{"password"}, C{"publickey"},
- and C{"none"}.
-
- The default implementation always returns C{"password"}.
-
- @param username: the username requesting authentication.
- @type username: str
- @return: a comma-separated list of authentication types
- @rtype: str
- """
- return 'password'
-
- def check_auth_none(self, username):
- """
- Determine if a client may open channels with no (further)
- authentication.
-
- Return L{AUTH_FAILED} if the client must authenticate, or
- L{AUTH_SUCCESSFUL} if it's okay for the client to not
- authenticate.
-
- The default implementation always returns L{AUTH_FAILED}.
-
- @param username: the username of the client.
- @type username: str
- @return: L{AUTH_FAILED} if the authentication fails;
- L{AUTH_SUCCESSFUL} if it succeeds.
- @rtype: int
- """
- return AUTH_FAILED
-
- def check_auth_password(self, username, password):
- """
- Determine if a given username and password supplied by the client is
- acceptable for use in authentication.
-
- Return L{AUTH_FAILED} if the password is not accepted,
- L{AUTH_SUCCESSFUL} if the password is accepted and completes
- the authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
- authentication is stateful, and this key is accepted for
- authentication, but more authentication is required. (In this latter
- case, L{get_allowed_auths} will be called to report to the client what
- options it has for continuing the authentication.)
-
- The default implementation always returns L{AUTH_FAILED}.
-
- @param username: the username of the authenticating client.
- @type username: str
- @param password: the password given by the client.
- @type password: str
- @return: L{AUTH_FAILED} if the authentication fails;
- L{AUTH_SUCCESSFUL} if it succeeds;
- L{AUTH_PARTIALLY_SUCCESSFUL} if the password auth is
- successful, but authentication must continue.
- @rtype: int
- """
- return AUTH_FAILED
-
- def check_auth_publickey(self, username, key):
- """
- Determine if a given key supplied by the client is acceptable for use
- in authentication. You should override this method in server mode to
- check the username and key and decide if you would accept a signature
- made using this key.
-
- Return L{AUTH_FAILED} if the key is not accepted,
- L{AUTH_SUCCESSFUL} if the key is accepted and completes the
- authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
- authentication is stateful, and this password is accepted for
- authentication, but more authentication is required. (In this latter
- case, L{get_allowed_auths} will be called to report to the client what
- options it has for continuing the authentication.)
-
- Note that you don't have to actually verify any key signtature here.
- If you're willing to accept the key, paramiko will do the work of
- verifying the client's signature.
-
- The default implementation always returns L{AUTH_FAILED}.
-
- @param username: the username of the authenticating client
- @type username: str
- @param key: the key object provided by the client
- @type key: L{PKey <pkey.PKey>}
- @return: L{AUTH_FAILED} if the client can't authenticate
- with this key; L{AUTH_SUCCESSFUL} if it can;
- L{AUTH_PARTIALLY_SUCCESSFUL} if it can authenticate with
- this key but must continue with authentication
- @rtype: int
- """
- return AUTH_FAILED
-
- def check_auth_interactive(self, username, submethods):
- """
- Begin an interactive authentication challenge, if supported. You
- should override this method in server mode if you want to support the
- C{"keyboard-interactive"} auth type, which requires you to send a
- series of questions for the client to answer.
-
- Return L{AUTH_FAILED} if this auth method isn't supported. Otherwise,
- you should return an L{InteractiveQuery} object containing the prompts
- and instructions for the user. The response will be sent via a call
- to L{check_auth_interactive_response}.
-
- The default implementation always returns L{AUTH_FAILED}.
-
- @param username: the username of the authenticating client
- @type username: str
- @param submethods: a comma-separated list of methods preferred by the
- client (usually empty)
- @type submethods: str
- @return: L{AUTH_FAILED} if this auth method isn't supported; otherwise
- an object containing queries for the user
- @rtype: int or L{InteractiveQuery}
- """
- return AUTH_FAILED
-
- def check_auth_interactive_response(self, responses):
- """
- Continue or finish an interactive authentication challenge, if
- supported. You should override this method in server mode if you want
- to support the C{"keyboard-interactive"} auth type.
-
- Return L{AUTH_FAILED} if the responses are not accepted,
- L{AUTH_SUCCESSFUL} if the responses are accepted and complete
- the authentication, or L{AUTH_PARTIALLY_SUCCESSFUL} if your
- authentication is stateful, and this set of responses is accepted for
- authentication, but more authentication is required. (In this latter
- case, L{get_allowed_auths} will be called to report to the client what
- options it has for continuing the authentication.)
-
- If you wish to continue interactive authentication with more questions,
- you may return an L{InteractiveQuery} object, which should cause the
- client to respond with more answers, calling this method again. This
- cycle can continue indefinitely.
-
- The default implementation always returns L{AUTH_FAILED}.
-
- @param responses: list of responses from the client
- @type responses: list(str)
- @return: L{AUTH_FAILED} if the authentication fails;
- L{AUTH_SUCCESSFUL} if it succeeds;
- L{AUTH_PARTIALLY_SUCCESSFUL} if the interactive auth is
- successful, but authentication must continue; otherwise an object
- containing queries for the user
- @rtype: int or L{InteractiveQuery}
- """
- return AUTH_FAILED
-
- def check_port_forward_request(self, address, port):
- """
- Handle a request for port forwarding. The client is asking that
- connections to the given address and port be forwarded back across
- this ssh connection. An address of C{"0.0.0.0"} indicates a global
- address (any address associated with this server) and a port of C{0}
- indicates that no specific port is requested (usually the OS will pick
- a port).
-
- The default implementation always returns C{False}, rejecting the
- port forwarding request. If the request is accepted, you should return
- the port opened for listening.
-
- @param address: the requested address
- @type address: str
- @param port: the requested port
- @type port: int
- @return: the port number that was opened for listening, or C{False} to
- reject
- @rtype: int
- """
- return False
-
- def cancel_port_forward_request(self, address, port):
- """
- The client would like to cancel a previous port-forwarding request.
- If the given address and port is being forwarded across this ssh
- connection, the port should be closed.
-
- @param address: the forwarded address
- @type address: str
- @param port: the forwarded port
- @type port: int
- """
- pass
-
- def check_global_request(self, kind, msg):
- """
- Handle a global request of the given C{kind}. This method is called
- in server mode and client mode, whenever the remote host makes a global
- request. If there are any arguments to the request, they will be in
- C{msg}.
-
- There aren't any useful global requests defined, aside from port
- forwarding, so usually this type of request is an extension to the
- protocol.
-
- If the request was successful and you would like to return contextual
- data to the remote host, return a tuple. Items in the tuple will be
- sent back with the successful result. (Note that the items in the
- tuple can only be strings, ints, longs, or bools.)
-
- The default implementation always returns C{False}, indicating that it
- does not support any global requests.
-
- @note: Port forwarding requests are handled separately, in
- L{check_port_forward_request}.
-
- @param kind: the kind of global request being made.
- @type kind: str
- @param msg: any extra arguments to the request.
- @type msg: L{Message}
- @return: C{True} or a tuple of data if the request was granted;
- C{False} otherwise.
- @rtype: bool
- """
- return False
-
-
- ### Channel requests
-
-
- def check_channel_pty_request(self, channel, term, width, height, pixelwidth, pixelheight,
- modes):
- """
- Determine if a pseudo-terminal of the given dimensions (usually
- requested for shell access) can be provided on the given channel.
-
- The default implementation always returns C{False}.
-
- @param channel: the L{Channel} the pty request arrived on.
- @type channel: L{Channel}
- @param term: type of terminal requested (for example, C{"vt100"}).
- @type term: str
- @param width: width of screen in characters.
- @type width: int
- @param height: height of screen in characters.
- @type height: int
- @param pixelwidth: width of screen in pixels, if known (may be C{0} if
- unknown).
- @type pixelwidth: int
- @param pixelheight: height of screen in pixels, if known (may be C{0}
- if unknown).
- @type pixelheight: int
- @return: C{True} if the psuedo-terminal has been allocated; C{False}
- otherwise.
- @rtype: bool
- """
- return False
-
- def check_channel_shell_request(self, channel):
- """
- Determine if a shell will be provided to the client on the given
- channel. If this method returns C{True}, the channel should be
- connected to the stdin/stdout of a shell (or something that acts like
- a shell).
-
- The default implementation always returns C{False}.
-
- @param channel: the L{Channel} the request arrived on.
- @type channel: L{Channel}
- @return: C{True} if this channel is now hooked up to a shell; C{False}
- if a shell can't or won't be provided.
- @rtype: bool
- """
- return False
-
- def check_channel_exec_request(self, channel, command):
- """
- Determine if a shell command will be executed for the client. If this
- method returns C{True}, the channel should be connected to the stdin,
- stdout, and stderr of the shell command.
-
- The default implementation always returns C{False}.
-
- @param channel: the L{Channel} the request arrived on.
- @type channel: L{Channel}
- @param command: the command to execute.
- @type command: str
- @return: C{True} if this channel is now hooked up to the stdin,
- stdout, and stderr of the executing command; C{False} if the
- command will not be executed.
- @rtype: bool
-
- @since: 1.1
- """
- return False
-
- def check_channel_subsystem_request(self, channel, name):
- """
- Determine if a requested subsystem will be provided to the client on
- the given channel. If this method returns C{True}, all future I/O
- through this channel will be assumed to be connected to the requested
- subsystem. An example of a subsystem is C{sftp}.
-
- The default implementation checks for a subsystem handler assigned via
- L{Transport.set_subsystem_handler}.
- If one has been set, the handler is invoked and this method returns
- C{True}. Otherwise it returns C{False}.
-
- @note: Because the default implementation uses the L{Transport} to
- identify valid subsystems, you probably won't need to override this
- method.
-
- @param channel: the L{Channel} the pty request arrived on.
- @type channel: L{Channel}
- @param name: name of the requested subsystem.
- @type name: str
- @return: C{True} if this channel is now hooked up to the requested
- subsystem; C{False} if that subsystem can't or won't be provided.
- @rtype: bool
- """
- handler_class, larg, kwarg = channel.get_transport()._get_subsystem_handler(name)
- if handler_class is None:
- return False
- handler = handler_class(channel, name, self, *larg, **kwarg)
- handler.start()
- return True
-
- def check_channel_window_change_request(self, channel, width, height, pixelwidth, pixelheight):
- """
- Determine if the pseudo-terminal on the given channel can be resized.
- This only makes sense if a pty was previously allocated on it.
-
- The default implementation always returns C{False}.
-
- @param channel: the L{Channel} the pty request arrived on.
- @type channel: L{Channel}
- @param width: width of screen in characters.
- @type width: int
- @param height: height of screen in characters.
- @type height: int
- @param pixelwidth: width of screen in pixels, if known (may be C{0} if
- unknown).
- @type pixelwidth: int
- @param pixelheight: height of screen in pixels, if known (may be C{0}
- if unknown).
- @type pixelheight: int
- @return: C{True} if the terminal was resized; C{False} if not.
- @rtype: bool
- """
- return False
-
- def check_channel_x11_request(self, channel, single_connection, auth_protocol, auth_cookie, screen_number):
- """
- Determine if the client will be provided with an X11 session. If this
- method returns C{True}, X11 applications should be routed through new
- SSH channels, using L{Transport.open_x11_channel}.
-
- The default implementation always returns C{False}.
-
- @param channel: the L{Channel} the X11 request arrived on
- @type channel: L{Channel}
- @param single_connection: C{True} if only a single X11 channel should
- be opened
- @type single_connection: bool
- @param auth_protocol: the protocol used for X11 authentication
- @type auth_protocol: str
- @param auth_cookie: the cookie used to authenticate to X11
- @type auth_cookie: str
- @param screen_number: the number of the X11 screen to connect to
- @type screen_number: int
- @return: C{True} if the X11 session was opened; C{False} if not
- @rtype: bool
- """
- return False
-
- def check_channel_direct_tcpip_request(self, chanid, origin, destination):
- """
- Determine if a local port forwarding channel will be granted, and
- return C{OPEN_SUCCEEDED} or an error code. This method is
- called in server mode when the client requests a channel, after
- authentication is complete.
-
- The C{chanid} parameter is a small number that uniquely identifies the
- channel within a L{Transport}. A L{Channel} object is not created
- unless this method returns C{OPEN_SUCCEEDED} -- once a
- L{Channel} object is created, you can call L{Channel.get_id} to
- retrieve the channel ID.
-
- The origin and destination parameters are (ip_address, port) tuples
- that correspond to both ends of the TCP connection in the forwarding
- tunnel.
-
- The return value should either be C{OPEN_SUCCEEDED} (or
- C{0}) to allow the channel request, or one of the following error
- codes to reject it:
- - C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}
- - C{OPEN_FAILED_CONNECT_FAILED}
- - C{OPEN_FAILED_UNKNOWN_CHANNEL_TYPE}
- - C{OPEN_FAILED_RESOURCE_SHORTAGE}
-
- The default implementation always returns
- C{OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED}.
-
- @param chanid: ID of the channel
- @type chanid: int
- @param origin: 2-tuple containing the IP address and port of the
- originator (client side)
- @type origin: tuple
- @param destination: 2-tuple containing the IP address and port of the
- destination (server side)
- @type destination: tuple
- @return: a success or failure code (listed above)
- @rtype: int
- """
- return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
-
-
-class SubsystemHandler (threading.Thread):
- """
- Handler for a subsytem in server mode. If you create a subclass of this
- class and pass it to
- L{Transport.set_subsystem_handler},
- an object of this
- class will be created for each request for this subsystem. Each new object
- will be executed within its own new thread by calling L{start_subsystem}.
- When that method completes, the channel is closed.
-
- For example, if you made a subclass C{MP3Handler} and registered it as the
- handler for subsystem C{"mp3"}, then whenever a client has successfully
- authenticated and requests subsytem C{"mp3"}, an object of class
- C{MP3Handler} will be created, and L{start_subsystem} will be called on
- it from a new thread.
- """
- def __init__(self, channel, name, server):
- """
- Create a new handler for a channel. This is used by L{ServerInterface}
- to start up a new handler when a channel requests this subsystem. You
- don't need to override this method, but if you do, be sure to pass the
- C{channel} and C{name} parameters through to the original C{__init__}
- method here.
-
- @param channel: the channel associated with this subsystem request.
- @type channel: L{Channel}
- @param name: name of the requested subsystem.
- @type name: str
- @param server: the server object for the session that started this
- subsystem
- @type server: L{ServerInterface}
- """
- threading.Thread.__init__(self, target=self._run)
- self.__channel = channel
- self.__transport = channel.get_transport()
- self.__name = name
- self.__server = server
-
- def get_server(self):
- """
- Return the L{ServerInterface} object associated with this channel and
- subsystem.
-
- @rtype: L{ServerInterface}
- """
- return self.__server
-
- def _run(self):
- try:
- self.__transport._log(DEBUG, 'Starting handler for subsystem %s' % self.__name)
- self.start_subsystem(self.__name, self.__transport, self.__channel)
- except Exception, e:
- self.__transport._log(ERROR, 'Exception in subsystem handler for "%s": %s' %
- (self.__name, str(e)))
- self.__transport._log(ERROR, util.tb_strings())
- try:
- self.finish_subsystem()
- except:
- pass
-
- def start_subsystem(self, name, transport, channel):
- """
- Process an ssh subsystem in server mode. This method is called on a
- new object (and in a new thread) for each subsystem request. It is
- assumed that all subsystem logic will take place here, and when the
- subsystem is finished, this method will return. After this method
- returns, the channel is closed.
-
- The combination of C{transport} and C{channel} are unique; this handler
- corresponds to exactly one L{Channel} on one L{Transport}.
-
- @note: It is the responsibility of this method to exit if the
- underlying L{Transport} is closed. This can be done by checking
- L{Transport.is_active} or noticing an EOF
- on the L{Channel}. If this method loops forever without checking
- for this case, your python interpreter may refuse to exit because
- this thread will still be running.
-
- @param name: name of the requested subsystem.
- @type name: str
- @param transport: the server-mode L{Transport}.
- @type transport: L{Transport}
- @param channel: the channel associated with this subsystem request.
- @type channel: L{Channel}
- """
- pass
-
- def finish_subsystem(self):
- """
- Perform any cleanup at the end of a subsystem. The default
- implementation just closes the channel.
-
- @since: 1.1
- """
- self.__channel.close()
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/sftp.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/sftp.py b/tools/migration/paramiko/sftp.py
deleted file mode 100644
index 0ed6796..0000000
--- a/tools/migration/paramiko/sftp.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-import select
-import socket
-import struct
-
-from paramiko.common import *
-from paramiko import util
-from paramiko.channel import Channel
-from paramiko.message import Message
-
-
-CMD_INIT, CMD_VERSION, CMD_OPEN, CMD_CLOSE, CMD_READ, CMD_WRITE, CMD_LSTAT, CMD_FSTAT, \
- CMD_SETSTAT, CMD_FSETSTAT, CMD_OPENDIR, CMD_READDIR, CMD_REMOVE, CMD_MKDIR, \
- CMD_RMDIR, CMD_REALPATH, CMD_STAT, CMD_RENAME, CMD_READLINK, CMD_SYMLINK \
- = range(1, 21)
-CMD_STATUS, CMD_HANDLE, CMD_DATA, CMD_NAME, CMD_ATTRS = range(101, 106)
-CMD_EXTENDED, CMD_EXTENDED_REPLY = range(200, 202)
-
-SFTP_OK = 0
-SFTP_EOF, SFTP_NO_SUCH_FILE, SFTP_PERMISSION_DENIED, SFTP_FAILURE, SFTP_BAD_MESSAGE, \
- SFTP_NO_CONNECTION, SFTP_CONNECTION_LOST, SFTP_OP_UNSUPPORTED = range(1, 9)
-
-SFTP_DESC = [ 'Success',
- 'End of file',
- 'No such file',
- 'Permission denied',
- 'Failure',
- 'Bad message',
- 'No connection',
- 'Connection lost',
- 'Operation unsupported' ]
-
-SFTP_FLAG_READ = 0x1
-SFTP_FLAG_WRITE = 0x2
-SFTP_FLAG_APPEND = 0x4
-SFTP_FLAG_CREATE = 0x8
-SFTP_FLAG_TRUNC = 0x10
-SFTP_FLAG_EXCL = 0x20
-
-_VERSION = 3
-
-
-# for debugging
-CMD_NAMES = {
- CMD_INIT: 'init',
- CMD_VERSION: 'version',
- CMD_OPEN: 'open',
- CMD_CLOSE: 'close',
- CMD_READ: 'read',
- CMD_WRITE: 'write',
- CMD_LSTAT: 'lstat',
- CMD_FSTAT: 'fstat',
- CMD_SETSTAT: 'setstat',
- CMD_FSETSTAT: 'fsetstat',
- CMD_OPENDIR: 'opendir',
- CMD_READDIR: 'readdir',
- CMD_REMOVE: 'remove',
- CMD_MKDIR: 'mkdir',
- CMD_RMDIR: 'rmdir',
- CMD_REALPATH: 'realpath',
- CMD_STAT: 'stat',
- CMD_RENAME: 'rename',
- CMD_READLINK: 'readlink',
- CMD_SYMLINK: 'symlink',
- CMD_STATUS: 'status',
- CMD_HANDLE: 'handle',
- CMD_DATA: 'data',
- CMD_NAME: 'name',
- CMD_ATTRS: 'attrs',
- CMD_EXTENDED: 'extended',
- CMD_EXTENDED_REPLY: 'extended_reply'
- }
-
-
-class SFTPError (Exception):
- pass
-
-
-class BaseSFTP (object):
- def __init__(self):
- self.logger = util.get_logger('paramiko.sftp')
- self.sock = None
- self.ultra_debug = False
-
-
- ### internals...
-
-
- def _send_version(self):
- self._send_packet(CMD_INIT, struct.pack('>I', _VERSION))
- t, data = self._read_packet()
- if t != CMD_VERSION:
- raise SFTPError('Incompatible sftp protocol')
- version = struct.unpack('>I', data[:4])[0]
- # if version != _VERSION:
- # raise SFTPError('Incompatible sftp protocol')
- return version
-
- def _send_server_version(self):
- # winscp will freak out if the server sends version info before the
- # client finishes sending INIT.
- t, data = self._read_packet()
- if t != CMD_INIT:
- raise SFTPError('Incompatible sftp protocol')
- version = struct.unpack('>I', data[:4])[0]
- # advertise that we support "check-file"
- extension_pairs = [ 'check-file', 'md5,sha1' ]
- msg = Message()
- msg.add_int(_VERSION)
- msg.add(*extension_pairs)
- self._send_packet(CMD_VERSION, str(msg))
- return version
-
- def _log(self, level, msg, *args):
- self.logger.log(level, msg, *args)
-
- def _write_all(self, out):
- while len(out) > 0:
- n = self.sock.send(out)
- if n <= 0:
- raise EOFError()
- if n == len(out):
- return
- out = out[n:]
- return
-
- def _read_all(self, n):
- out = ''
- while n > 0:
- if isinstance(self.sock, socket.socket):
- # sometimes sftp is used directly over a socket instead of
- # through a paramiko channel. in this case, check periodically
- # if the socket is closed. (for some reason, recv() won't ever
- # return or raise an exception, but calling select on a closed
- # socket will.)
- while True:
- read, write, err = select.select([ self.sock ], [], [], 0.1)
- if len(read) > 0:
- x = self.sock.recv(n)
- break
- else:
- x = self.sock.recv(n)
-
- if len(x) == 0:
- raise EOFError()
- out += x
- n -= len(x)
- return out
-
- def _send_packet(self, t, packet):
- #self._log(DEBUG2, 'write: %s (len=%d)' % (CMD_NAMES.get(t, '0x%02x' % t), len(packet)))
- out = struct.pack('>I', len(packet) + 1) + chr(t) + packet
- if self.ultra_debug:
- self._log(DEBUG, util.format_binary(out, 'OUT: '))
- self._write_all(out)
-
- def _read_packet(self):
- x = self._read_all(4)
- # most sftp servers won't accept packets larger than about 32k, so
- # anything with the high byte set (> 16MB) is just garbage.
- if x[0] != '\x00':
- raise SFTPError('Garbage packet received')
- size = struct.unpack('>I', x)[0]
- data = self._read_all(size)
- if self.ultra_debug:
- self._log(DEBUG, util.format_binary(data, 'IN: '));
- if size > 0:
- t = ord(data[0])
- #self._log(DEBUG2, 'read: %s (len=%d)' % (CMD_NAMES.get(t), '0x%02x' % t, len(data)-1))
- return t, data[1:]
- return 0, ''
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/sftp_attr.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/sftp_attr.py b/tools/migration/paramiko/sftp_attr.py
deleted file mode 100644
index 731386f..0000000
--- a/tools/migration/paramiko/sftp_attr.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright (C) 2003-2006 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-import stat
-import time
-from paramiko.common import *
-from paramiko.sftp import *
-
-
-class SFTPAttributes (object):
- """
- Representation of the attributes of a file (or proxied file) for SFTP in
- client or server mode. It attemps to mirror the object returned by
- C{os.stat} as closely as possible, so it may have the following fields,
- with the same meanings as those returned by an C{os.stat} object:
- - st_size
- - st_uid
- - st_gid
- - st_mode
- - st_atime
- - st_mtime
-
- Because SFTP allows flags to have other arbitrary named attributes, these
- are stored in a dict named C{attr}. Occasionally, the filename is also
- stored, in C{filename}.
- """
-
- FLAG_SIZE = 1
- FLAG_UIDGID = 2
- FLAG_PERMISSIONS = 4
- FLAG_AMTIME = 8
- FLAG_EXTENDED = 0x80000000L
-
- def __init__(self):
- """
- Create a new (empty) SFTPAttributes object. All fields will be empty.
- """
- self._flags = 0
- self.st_size = None
- self.st_uid = None
- self.st_gid = None
- self.st_mode = None
- self.st_atime = None
- self.st_mtime = None
- self.attr = {}
-
- def from_stat(cls, obj, filename=None):
- """
- Create an SFTPAttributes object from an existing C{stat} object (an
- object returned by C{os.stat}).
-
- @param obj: an object returned by C{os.stat} (or equivalent).
- @type obj: object
- @param filename: the filename associated with this file.
- @type filename: str
- @return: new L{SFTPAttributes} object with the same attribute fields.
- @rtype: L{SFTPAttributes}
- """
- attr = cls()
- attr.st_size = obj.st_size
- attr.st_uid = obj.st_uid
- attr.st_gid = obj.st_gid
- attr.st_mode = obj.st_mode
- attr.st_atime = obj.st_atime
- attr.st_mtime = obj.st_mtime
- if filename is not None:
- attr.filename = filename
- return attr
- from_stat = classmethod(from_stat)
-
- def __repr__(self):
- return '<SFTPAttributes: %s>' % self._debug_str()
-
-
- ### internals...
-
-
- def _from_msg(cls, msg, filename=None, longname=None):
- attr = cls()
- attr._unpack(msg)
- if filename is not None:
- attr.filename = filename
- if longname is not None:
- attr.longname = longname
- return attr
- _from_msg = classmethod(_from_msg)
-
- def _unpack(self, msg):
- self._flags = msg.get_int()
- if self._flags & self.FLAG_SIZE:
- self.st_size = msg.get_int64()
- if self._flags & self.FLAG_UIDGID:
- self.st_uid = msg.get_int()
- self.st_gid = msg.get_int()
- if self._flags & self.FLAG_PERMISSIONS:
- self.st_mode = msg.get_int()
- if self._flags & self.FLAG_AMTIME:
- self.st_atime = msg.get_int()
- self.st_mtime = msg.get_int()
- if self._flags & self.FLAG_EXTENDED:
- count = msg.get_int()
- for i in range(count):
- self.attr[msg.get_string()] = msg.get_string()
-
- def _pack(self, msg):
- self._flags = 0
- if self.st_size is not None:
- self._flags |= self.FLAG_SIZE
- if (self.st_uid is not None) and (self.st_gid is not None):
- self._flags |= self.FLAG_UIDGID
- if self.st_mode is not None:
- self._flags |= self.FLAG_PERMISSIONS
- if (self.st_atime is not None) and (self.st_mtime is not None):
- self._flags |= self.FLAG_AMTIME
- if len(self.attr) > 0:
- self._flags |= self.FLAG_EXTENDED
- msg.add_int(self._flags)
- if self._flags & self.FLAG_SIZE:
- msg.add_int64(self.st_size)
- if self._flags & self.FLAG_UIDGID:
- msg.add_int(self.st_uid)
- msg.add_int(self.st_gid)
- if self._flags & self.FLAG_PERMISSIONS:
- msg.add_int(self.st_mode)
- if self._flags & self.FLAG_AMTIME:
- # throw away any fractional seconds
- msg.add_int(long(self.st_atime))
- msg.add_int(long(self.st_mtime))
- if self._flags & self.FLAG_EXTENDED:
- msg.add_int(len(self.attr))
- for key, val in self.attr.iteritems():
- msg.add_string(key)
- msg.add_string(val)
- return
-
- def _debug_str(self):
- out = '[ '
- if self.st_size is not None:
- out += 'size=%d ' % self.st_size
- if (self.st_uid is not None) and (self.st_gid is not None):
- out += 'uid=%d gid=%d ' % (self.st_uid, self.st_gid)
- if self.st_mode is not None:
- out += 'mode=' + oct(self.st_mode) + ' '
- if (self.st_atime is not None) and (self.st_mtime is not None):
- out += 'atime=%d mtime=%d ' % (self.st_atime, self.st_mtime)
- for k, v in self.attr.iteritems():
- out += '"%s"=%r ' % (str(k), v)
- out += ']'
- return out
-
- def _rwx(n, suid, sticky=False):
- if suid:
- suid = 2
- out = '-r'[n >> 2] + '-w'[(n >> 1) & 1]
- if sticky:
- out += '-xTt'[suid + (n & 1)]
- else:
- out += '-xSs'[suid + (n & 1)]
- return out
- _rwx = staticmethod(_rwx)
-
- def __str__(self):
- "create a unix-style long description of the file (like ls -l)"
- if self.st_mode is not None:
- kind = stat.S_IFMT(self.st_mode)
- if kind == stat.S_IFIFO:
- ks = 'p'
- elif kind == stat.S_IFCHR:
- ks = 'c'
- elif kind == stat.S_IFDIR:
- ks = 'd'
- elif kind == stat.S_IFBLK:
- ks = 'b'
- elif kind == stat.S_IFREG:
- ks = '-'
- elif kind == stat.S_IFLNK:
- ks = 'l'
- elif kind == stat.S_IFSOCK:
- ks = 's'
- else:
- ks = '?'
- ks += self._rwx((self.st_mode & 0700) >> 6, self.st_mode & stat.S_ISUID)
- ks += self._rwx((self.st_mode & 070) >> 3, self.st_mode & stat.S_ISGID)
- ks += self._rwx(self.st_mode & 7, self.st_mode & stat.S_ISVTX, True)
- else:
- ks = '?---------'
- # compute display date
- if (self.st_mtime is None) or (self.st_mtime == 0xffffffff):
- # shouldn't really happen
- datestr = '(unknown date)'
- else:
- if abs(time.time() - self.st_mtime) > 15552000:
- # (15552000 = 6 months)
- datestr = time.strftime('%d %b %Y', time.localtime(self.st_mtime))
- else:
- datestr = time.strftime('%d %b %H:%M', time.localtime(self.st_mtime))
- filename = getattr(self, 'filename', '?')
-
- # not all servers support uid/gid
- uid = self.st_uid
- gid = self.st_gid
- if uid is None:
- uid = 0
- if gid is None:
- gid = 0
-
- return '%s 1 %-8d %-8d %8d %-12s %s' % (ks, uid, gid, self.st_size, datestr, filename)
-