Esempio n. 1
0
    def test_C_generate_ecdsa(self):
        key = ECDSAKey.generate()
        msg = key.sign_ssh_data(b'jerri blank')
        msg.rewind()
        self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
        self.assertEqual(key.get_bits(), 256)
        self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp256')

        key = ECDSAKey.generate(bits=256)
        msg = key.sign_ssh_data(b'jerri blank')
        msg.rewind()
        self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
        self.assertEqual(key.get_bits(), 256)
        self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp256')

        key = ECDSAKey.generate(bits=384)
        msg = key.sign_ssh_data(b'jerri blank')
        msg.rewind()
        self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
        self.assertEqual(key.get_bits(), 384)
        self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp384')

        key = ECDSAKey.generate(bits=521)
        msg = key.sign_ssh_data(b'jerri blank')
        msg.rewind()
        self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
        self.assertEqual(key.get_bits(), 521)
        self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp521')
Esempio n. 2
0
 def test_16_compare_ecdsa_384(self):
     # verify that the private & public keys compare equal
     key = ECDSAKey.from_private_key_file(_support("test_ecdsa_384.key"))
     self.assertEqual(key, key)
     pub = ECDSAKey(data=key.asbytes())
     self.assertTrue(key.can_sign())
     self.assertTrue(not pub.can_sign())
     self.assertEqual(key, pub)
Esempio n. 3
0
 def test_20_compare_ecdsa_521(self):
     # verify that the private & public keys compare equal
     key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
     self.assertEqual(key, key)
     pub = ECDSAKey(data=key.asbytes())
     self.assertTrue(key.can_sign())
     self.assertTrue(not pub.can_sign())
     self.assertEqual(key, pub)
Esempio n. 4
0
 def test_12_compare_ecdsa(self):
     # verify that the private & public keys compare equal
     key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key')
     self.assertEquals(key, key)
     pub = ECDSAKey(data=bytes(key))
     self.assert_(key.can_sign())
     self.assert_(not pub.can_sign())
     self.assertEquals(key, pub)
Esempio n. 5
0
    def test_10_load_ecdsa(self):
        key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key')
        self.assertEquals(b'ecdsa-sha2-nistp256', key.get_name())
        exp_ecdsa = FINGER_ECDSA.split()[1].replace(b':', b'')
        my_ecdsa = hexlify(key.get_fingerprint())
        self.assertEquals(exp_ecdsa, my_ecdsa)
        self.assertEquals(PUB_ECDSA.split()[1], key.get_base64())
        self.assertEquals(256, key.get_bits())

        s = BytesIO()
        key.write_private_key(s)
        self.assertEquals(ECDSA_PRIVATE_OUT, s.getvalue())
        s.seek(0)
        key2 = ECDSAKey.from_private_key(StringIO(s.getvalue().decode()))
        self.assertEquals(key, key2)
Esempio n. 6
0
    def test_21_sign_ecdsa_521(self):
        # verify that the rsa private key can sign and verify
        key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
        msg = key.sign_ssh_data(b'ice weasels')
        self.assertTrue(type(msg) is Message)
        msg.rewind()
        self.assertEqual('ecdsa-sha2-nistp521', msg.get_text())
        # ECDSA signatures, like DSS signatures, tend to be different
        # each time, so we can't compare against a "known correct"
        # signature.
        # Even the length of the signature can change.

        msg.rewind()
        pub = ECDSAKey(data=key.asbytes())
        self.assertTrue(pub.verify_ssh_sig(b'ice weasels', msg))
Esempio n. 7
0
    def test_14_load_ecdsa_384(self):
        key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_384.key'))
        self.assertEqual('ecdsa-sha2-nistp384', key.get_name())
        exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(':', ''))
        my_ecdsa = hexlify(key.get_fingerprint())
        self.assertEqual(exp_ecdsa, my_ecdsa)
        self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
        self.assertEqual(384, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(ECDSA_PRIVATE_OUT_384, s.getvalue())
        s.seek(0)
        key2 = ECDSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Esempio n. 8
0
    def test_13_sign_ecdsa(self):
        # verify that the rsa private key can sign and verify
        key = ECDSAKey.from_private_key_file('tests/test_ecdsa.key')
        msg = key.sign_ssh_data(rng, b'ice weasels')
        self.assert_(type(msg) is Message)
        msg.rewind()
        self.assertEquals(b'ecdsa-sha2-nistp256', msg.get_string())
        # ECDSA signatures, like DSS signatures, tend to be different
        # each time, so we can't compare against a "known correct"
        # signature.
        # Even the length of the signature can change.

        msg.rewind()
        pub = ECDSAKey(data=bytes(key))
        self.assert_(pub.verify_ssh_sig(b'ice weasels', msg))
Esempio n. 9
0
    def test_10_load_ecdsa_256(self):
        key = ECDSAKey.from_private_key_file(_support("test_ecdsa_256.key"))
        self.assertEqual("ecdsa-sha2-nistp256", key.get_name())
        exp_ecdsa = b(FINGER_ECDSA_256.split()[1].replace(":", ""))
        my_ecdsa = hexlify(key.get_fingerprint())
        self.assertEqual(exp_ecdsa, my_ecdsa)
        self.assertEqual(PUB_ECDSA_256.split()[1], key.get_base64())
        self.assertEqual(256, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        self.assertEqual(ECDSA_PRIVATE_OUT_256, s.getvalue())
        s.seek(0)
        key2 = ECDSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Esempio n. 10
0
 def test_11_load_ecdsa_password(self):
     key = ECDSAKey.from_private_key_file('tests/test_ecdsa_password.key', 'television')
     self.assertEquals(b'ecdsa-sha2-nistp256', key.get_name())
     exp_ecdsa = FINGER_ECDSA.split()[1].replace(b':', b'')
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEquals(exp_ecdsa, my_ecdsa)
     self.assertEquals(PUB_ECDSA.split()[1], key.get_base64())
     self.assertEquals(256, key.get_bits())
Esempio n. 11
0
 def test_15_load_ecdsa_password_384(self):
     key = ECDSAKey.from_private_key_file(_support('test_ecdsa_password_384.key'), b'television')
     self.assertEqual('ecdsa-sha2-nistp384', key.get_name())
     exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(':', ''))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
     self.assertEqual(384, key.get_bits())
Esempio n. 12
0
 def test_19_load_ecdsa_password_521(self):
     key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_password_521.key'), b'television')
     self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
     exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
     self.assertEqual(521, key.get_bits())
Esempio n. 13
0
 def test_11_load_ecdsa_password(self):
     key = ECDSAKey.from_private_key_file(test_path("test_ecdsa_password.key"), b"television")
     self.assertEqual("ecdsa-sha2-nistp256", key.get_name())
     exp_ecdsa = b(FINGER_ECDSA.split()[1].replace(":", ""))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA.split()[1], key.get_base64())
     self.assertEqual(256, key.get_bits())
Esempio n. 14
0
 def test_load_EC_key_new_format(self):
     key = ECDSAKey.from_private_key_file(_support('test_ecdsa_384_o.key'),
                                          b'television')
     self.assertEqual('ecdsa-sha2-nistp384', key.get_name())
     self.assertEqual(PUB_EC_384_OPENSSH.split()[1], key.get_base64())
     self.assertEqual(384, key.get_bits())
     exp_fp = b(FINGER_EC_384_OPENSSH.split()[1].replace(':', ''))
     my_fp = hexlify(key.get_fingerprint())
     self.assertEqual(exp_fp, my_fp)
Esempio n. 15
0
 def test_load_ecdsa_password_521(self):
     key = ECDSAKey.from_private_key_file(
         _support('test_ecdsa_password_521.key'), b'television')
     self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
     exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
     self.assertEqual(521, key.get_bits())
Esempio n. 16
0
    def test_load_ecdsa_521(self):
        key = ECDSAKey.from_private_key_file(_support('test_ecdsa_521.key'))
        self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
        exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
        my_ecdsa = hexlify(key.get_fingerprint())
        self.assertEqual(exp_ecdsa, my_ecdsa)
        self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
        self.assertEqual(521, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        # Different versions of OpenSSL (SSLeay versions 0x1000100f and
        # 0x1000207f for instance) use different apparently valid (as far as
        # ssh-keygen is concerned) padding. So we can't check the actual value
        # of the pem encoded key.
        s.seek(0)
        key2 = ECDSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Esempio n. 17
0
 def test_11_load_ecdsa_password(self):
     key = ECDSAKey.from_private_key_file(
         test_path('test_ecdsa_password.key'), b'television')
     self.assertEqual('ecdsa-sha2-nistp256', key.get_name())
     exp_ecdsa = b(FINGER_ECDSA.split()[1].replace(':', ''))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA.split()[1], key.get_base64())
     self.assertEqual(256, key.get_bits())
Esempio n. 18
0
    def test_18_load_ecdsa_521(self):
        key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
        self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
        exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
        my_ecdsa = hexlify(key.get_fingerprint())
        self.assertEqual(exp_ecdsa, my_ecdsa)
        self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
        self.assertEqual(521, key.get_bits())

        s = StringIO()
        key.write_private_key(s)
        # Different versions of OpenSSL (SSLeay versions 0x1000100f and
        # 0x1000207f for instance) use different apparently valid (as far as
        # ssh-keygen is concerned) padding. So we can't check the actual value
        # of the pem encoded key.
        s.seek(0)
        key2 = ECDSAKey.from_private_key(s)
        self.assertEqual(key, key2)
Esempio n. 19
0
 def test_15_load_ecdsa_password_384(self):
     key = ECDSAKey.from_private_key_file(
         _support("test_ecdsa_password_384.key"), b"television"
     )
     self.assertEqual("ecdsa-sha2-nistp384", key.get_name())
     exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(":", ""))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
     self.assertEqual(384, key.get_bits())
Esempio n. 20
0
 def test_19_load_ecdsa_password_521(self):
     key = ECDSAKey.from_private_key_file(
         _support("test_ecdsa_password_521.key"), b"television"
     )
     self.assertEqual("ecdsa-sha2-nistp521", key.get_name())
     exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(":", ""))
     my_ecdsa = hexlify(key.get_fingerprint())
     self.assertEqual(exp_ecdsa, my_ecdsa)
     self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
     self.assertEqual(521, key.get_bits())
Esempio n. 21
0
    def dehydrate(self, bundle):
        if bundle.obj.key_type == "ssh-rsa":
            key = RSAKey(data=base64.b64decode(bundle.obj.public_key))
        elif bundle.obj.key_type == "ssh-dss":
            key = DSSKey(data=base64.b64decode(bundle.obj.public_key))
        elif bundle.obj.key_type.startswith("ecdsa"):
            key = ECDSAKey(data=base64.b64decode(bundle.obj.public_key))
        else:
            raise HydrationError("Unknown key type: %s" %
                                 bundle.object.key_type)

        bundle.data['fingerprint'] = u(hexlify(key.get_fingerprint()))

        return bundle
Esempio n. 22
0
    def load(self):
        """Try to load the public key

        We support RSA, ECDSA and Ed25519 keys and return instances of:
        * paramiko.rsakey.RSAKey
        * paramiko.ecdsakey.ECDSAKey
        * paramiko.ed25519key.Ed25519Key (requires paramiko >= 2.2)
        """
        # I don't think there is a key type independent way of doing this
        public_key_blob = b64decode(self.key_base64)
        if self.key_algorithm.startswith('ssh-ed25519'):
            try:
                return Ed25519Key(data=public_key_blob)
            except NameError:
                raise ValidationError('Paramiko too old to load ed25519 keys')
        elif self.key_algorithm.startswith('ecdsa-'):
            return ECDSAKey(data=public_key_blob)
        elif self.key_algorithm.startswith('ssh-rsa'):
            return RSAKey(data=public_key_blob)

        raise SSHException('Key is not RSA, ECDSA or Ed25519')
Esempio n. 23
0
    def clean(self):
        data = super().clean()
        key_type = data.get('key_type')
        public_key = data.get('public_key')

        try:
            if key_type == "ssh-rsa":
                k = RSAKey(data=base64.b64decode(public_key))
            elif key_type == "ssh-dss":
                k = DSSKey(data=base64.b64decode(public_key))
            elif key_type.startswith('ecdsa'):
                k = ECDSAKey(data=base64.b64decode(public_key))
            else:
                raise forms.ValidationError(
                    _("Unsupport key type: %(keytype)s"),
                    code='invalid keytype',
                    params={'key_type': key_type}
                )

            data['key_type'] = k.get_name()
            data['public_key'] = k.get_base64()

        except (TypeError, SSHException, UnicodeDecodeError) as err:
            if len(public_key) > 30:
                body = public_key[0:30]
            else:
                body = public_key

            raise forms.ValidationError(
                _("Body of SSH public key is invalid:\n%(body)s\n"
                  "Error: %(err)s"),
                code='invalid key body',
                params={'body': body + "...", 'err': err}
            )

        return data
Esempio n. 24
0
    def test_load_openssh_format_EC_key(self):
        key = ECDSAKey.from_private_key_file(
            _support("test_ecdsa_384_openssh.key"), b"television")
        self.assertEqual("ecdsa-sha2-nistp384", key.get_name())

        self.assert_key_fingerprints(key, FINGER_EC_384_OPENSSH)
Esempio n. 25
0
class SSH(AbstractCommunicator):
    CONFIGURATION_KEYS = ("host_key", "host_key_type", "username",
                          "private_key", "private_key_type")
    SUPPORTED_HOST_TYPES = ("Darwin", "Linux_AMD64", "Windows")
    IDENTIFIER = "SSH"

    PRIVATE_KEY_FORMAT_MAPPINGS = {
        'DSS': paramiko.DSSKey.from_private_key,
        'RSA': paramiko.RSAKey.from_private_key,
        'ECDSA': paramiko.ECDSAKey.from_private_key,
        'Ed25519': paramiko.Ed25519Key.from_private_key
    }

    HOST_KEY_FORMAT_MAPPINGS = {
        'ssh-dss': paramiko.DSSKey,
        'ssh-rsa': paramiko.RSAKey,
        'ssh-ed25519': paramiko.Ed25519Key
    }
    for key in ECDSAKey.supported_key_format_identifiers():
        HOST_KEY_FORMAT_MAPPINGS[key] = paramiko.ECDSAKey

    def __init__(self, host):
        super().__init__(host)
        self.username = self.config["username"]

    def get_host_key(self) -> PKey:
        # Decide what kind of key we're looking at and create an object
        # to hold it accordingly.
        key_type = self.host.config['host_key_type']
        if key_type not in self.HOST_KEY_FORMAT_MAPPINGS:
            raise SSHError(f"Unable to handle key of type {key_type}")

        try:
            key = self.host.config['host_key'].encode('utf-8')
            host_key = self.HOST_KEY_FORMAT_MAPPINGS[key_type](
                data=decodebytes(key))
        except binascii.Error as e:
            raise InvalidHostKey(repr(self.host), e)
        return host_key

    def get_private_key(self):
        # Decide what kind of key we're looking at and create an object
        # to hold it accordingly.
        key_type = self.config['private_key_type']
        if key_type not in self.PRIVATE_KEY_FORMAT_MAPPINGS:
            raise SSHError(f"Unable to handle key of type {key_type}")

        try:
            key = self.config['private_key']
            private_key = self.PRIVATE_KEY_FORMAT_MAPPINGS[key_type](
                StringIO(key))
        except binascii.Error as e:
            raise SSHError(f"Private key error {repr(self.host)}", e)
        return private_key

    def get_client(self):
        client = paramiko.SSHClient()
        host_keys = HostKeys()
        host_keys.add(hostname=self.host.address,
                      keytype=self.config['host_key_type'],
                      key=self.get_host_key())
        client._host_keys = host_keys  # If you not a better way than accessing a private member I am all ears
        return client

    def execute_command(self, command: str) -> CommandResponse:
        client = self.get_client()
        try:
            client.connect(self.host.address,
                           username=self.config["username"],
                           pkey=self.get_private_key(),
                           timeout=settings.SSH_CONNECT_TIMEOUT)
            stdin, stdout, stderr = client.exec_command(
                command=command, timeout=settings.SSH_EXEC_TIMEOUT)
            return_code = stdout.channel.recv_exit_status()
            stdout_str = stdout.read().decode('UTF-8')
            stderr_str = stderr.read().decode('UTF-8')
            if return_code != 0:
                logger.info(
                    f"host={self.username}@{self.host.address} rc={return_code} command={command} stdout={stdout_str} stderr={stderr_str}"
                )
        except paramiko.SSHException as e:
            logger.exception(
                f"Error: host={self.username}@{self.host.address}, command={command}"
            )
            raise SSHError(
                f"Ran into problems connecting to {self.username}@{self.host.address}: {e}"
            )
        finally:
            client.close()

        return CommandResponse(return_code, stdout_str, stderr_str)

    def is_host_reachable(self) -> bool:
        try:
            if self.host.type == "Windows":
                response = self.execute_command('date /t')
            else:
                response = self.execute_command('true')
        except Exception:
            return False
        return True
Esempio n. 26
0
args = parser.parse_args()
args.local_dir = os.path.abspath(args.local_dir)

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s - %(message)s",
                    datefmt="%H:%M:%S")
logging.getLogger("paramiko.transport").setLevel(logging.ERROR)
logger = logging.getLogger()

if args.configure:
    logger.info("here is where we run ansible playbooks")
    exit(0)

try:
    key_file = os.path.expanduser(args.identity)
    private_key = ECDSAKey.from_private_key_file(key_file)
except FileNotFoundError as e:
    logger.error(f"{args.identity} not found")
    exit(1)
except SSHException as e:
    logger.error(f"{key_file}; {e}")
    exit(1)

ssh = SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.load_system_host_keys()

try:
    logger.info(f"connecting to {args.hostname}")
    ssh.connect(args.hostname, username=args.user, pkey=private_key)
except AuthenticationException as e:
Esempio n. 27
0
from ...command_util import GenericUserError
from .. import URLConfig
from ..archive import ensure_archive

from . import Uploader
KEYTYPES = {
    'RSA': RSAKey,
    'ECDSA': ECDSAKey,
    'DSA': DSSKey,
    'DSS': DSSKey,
    'ED25519': Ed25519Key
}

KNOWN_HOSTS_KEY_TYPE_MAP = {
    'RSA': ('ssh-rsa', ),
    'ECDSA': tuple(ECDSAKey.supported_key_format_identifiers()),
    'DSA': ('ssh-dss', ),
    'DSS': ('ssh-dss', ),
    'ED25519': ('ssh-ed25519', )
}


class DumbSFTPUploader(Uploader):
    '''
    A dumb SFTP uploader that just sends a bundle to a remote directory.

    The server has to decide what to do with the bundle (e.g., putting it where it can be
    downloaded)
    '''
    def __init__(self, upload_url):
        '''
Esempio n. 28
0
 def test_load_ecdsa_password_521(self):
     key = ECDSAKey.from_private_key_file(
         _support('test_ecdsa_password_521.key'), b'television')
     self.assert_key_values(key, 'ecdsa-sha2-nistp521', 521, PUB_ECDSA_521,
                            FINGER_ECDSA_521.split()[1],
                            FINGER_SHA256_ECDSA_521)