def test_saveKeysha256(self):
     """
     L{_saveKey} will generate key fingerprint in
     L{FingerprintFormats.SHA256-BASE64} format if explicitly specified.
     """
     base = FilePath(self.mktemp())
     base.makedirs()
     filename = base.child('id_rsa').path
     key = Key.fromString(privateRSA_openssh)
     _saveKey(key, {'filename': filename, 'pass': '******',
         'format': 'sha256-base64'})
     self.assertEqual(
         self.stdout.getvalue(),
         "Your identification has been saved in %s\n"
         "Your public key has been saved in %s.pub\n"
         "The key fingerprint in <FingerprintFormats=SHA256_BASE64> is:\n"
         "ryaugIFT0B8ItuszldMEU7q14rG/wj9HkRosMeBWkts=\n" % (
             filename,
             filename))
     self.assertEqual(
         key.fromString(
             base.child('id_rsa').getContent(), None, 'passphrase'),
         key)
     self.assertEqual(
         Key.fromString(base.child('id_rsa.pub').getContent()),
         key.public())
Example #2
0
def manhole(username, password, globals):
    """Starts a ssh listener with password authentication using
    the given username and password. Clients connecting to the ssh
    listener will find themselves in a colored python shell with
    the supplied globals.

    Args:
        username(str): The username ssh clients should auth with.
        password(str): The password ssh clients should auth with.
        globals(dict): The variables to expose in the shell.

    Returns:
        twisted.internet.protocol.Factory: A factory to pass to ``listenTCP``
    """
    if not isinstance(password, bytes):
        password = password.encode('ascii')

    checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(
        **{username: password}
    )

    rlm = manhole_ssh.TerminalRealm()
    rlm.chainedProtocolFactory = lambda: insults.ServerProtocol(
        SynapseManhole,
        dict(globals, __name__="__console__")
    )

    factory = manhole_ssh.ConchFactory(portal.Portal(rlm, [checker]))
    factory.publicKeys[b'ssh-rsa'] = Key.fromString(PUBLIC_KEY)
    factory.privateKeys[b'ssh-rsa'] = Key.fromString(PRIVATE_KEY)

    return factory
Example #3
0
def verify_SSL_key_and_cert(keyfile, certfile):
    """
    This function looks for RSA key and certificate in the current
    directory. If files ssl.key and ssl.cert does not exist, they
    are created.
    """

    if not (os.path.exists(keyfile) and os.path.exists(certfile)):
        # key/cert does not exist. Create.
        import subprocess
        from Crypto.PublicKey import RSA
        from twisted.conch.ssh.keys import Key

        print("  Creating SSL key and certificate ... ", end=' ')

        try:
            # create the RSA key and store it.
            KEY_LENGTH = 1024
            rsaKey = Key(RSA.generate(KEY_LENGTH))
            keyString = rsaKey.toString(type="OPENSSH")
            file(keyfile, 'w+b').write(keyString)
        except Exception as err:
            print(NO_AUTOGEN.format(err=err, keyfile=keyfile))
            sys.exit(5)

        # try to create the certificate
        CERT_EXPIRE = 365 * 20  # twenty years validity
        # default:
        # openssl req -new -x509 -key ssl.key -out ssl.cert -days 7300
        exestring = "openssl req -new -x509 -key %s -out %s -days %s" % (keyfile, certfile, CERT_EXPIRE)
        try:
            subprocess.call(exestring)
        except OSError as err:
            raise OSError(NO_AUTOCERT.format(err=err, certfile=certfile, keyfile=keyfile, exestring=exestring))
        print("done.")
Example #4
0
 def test_saveKey(self):
     """
     L{_saveKey} writes the private and public parts of a key to two
     different files and writes a report of this to standard out.
     """
     base = FilePath(self.mktemp())
     base.makedirs()
     filename = base.child('id_rsa').path
     key = Key.fromString(privateRSA_openssh)
     _saveKey(
         key.keyObject,
         {'filename': filename, 'pass': '******'})
     self.assertEqual(
         self.stdout.getvalue(),
         "Your identification has been saved in %s\n"
         "Your public key has been saved in %s.pub\n"
         "The key fingerprint is:\n"
         "3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af\n" % (
             filename,
             filename))
     self.assertEqual(
         key.fromString(
             base.child('id_rsa').getContent(), None, 'passphrase'),
         key)
     self.assertEqual(
         Key.fromString(base.child('id_rsa.pub').getContent()),
         key.public())
Example #5
0
def main(keys_path, username_get=None, gid=None, port=2022):
    settings.username_get = username_get
    settings.gid = gid
    key_path = keys_path + '/id_rsa'

    if not os.path.exists(key_path):
        subprocess.check_call(['ssh-keygen', '-f', key_path,
                               '-t', 'rsa', '-N', ''])

    with open(key_path) as privateBlobFile:
        privateBlob = privateBlobFile.read()
        privateKey = Key.fromString(data=privateBlob)

    with open(key_path + '.pub') as publicBlobFile:
        publicBlob = publicBlobFile.read()
        publicKey = Key.fromString(data=publicBlob)

    factory = SSHFactory()
    factory.privateKeys = {'ssh-rsa': privateKey}
    factory.publicKeys = {'ssh-rsa': publicKey}
    factory.portal = Portal(KeyRealm())
    factory.portal.registerChecker(KeyChecker())

    reactor.listenTCP(port, factory)
    reactor.run()
Example #6
0
def getKeyPair(pubkeyfile, privkeyfile):
    """
    This function looks for RSA keypair files in the current directory. If they
    do not exist, the keypair is created.
    """

    if not (os.path.exists(pubkeyfile) and os.path.exists(privkeyfile)):
        # No keypair exists. Generate a new RSA keypair
        from Crypto.PublicKey import RSA

        rsa_key = Key(RSA.generate(_KEY_LENGTH))
        public_key_string = rsa_key.public().toString(type="OPENSSH")
        private_key_string = rsa_key.toString(type="OPENSSH")

        # save keys for the future.
        with open(privkeyfile, 'wt') as pfile:
            pfile.write(private_key_string)
            print("Created SSH private key in '{}'".format(_PRIVATE_KEY_FILE))
        with open(pubkeyfile, 'wt') as pfile:
            pfile.write(public_key_string)
            print("Created SSH public key in '{}'".format(_PUBLIC_KEY_FILE))
    else:
        with open(pubkeyfile) as pfile:
            public_key_string = pfile.read()
        with open(privkeyfile) as pfile:
            private_key_string = pfile.read()

    return Key.fromString(public_key_string), Key.fromString(private_key_string)
Example #7
0
    def _check_public_key (self, key, ) :
        try :
            Key.fromString(data=key, )
        except BadKeyError :
            raise _exceptions.BAD_ARGUMENT("invalid public key.")

        return key.strip()
    def test_savingsPreservesExisting(self):
        """
        L{KnownHostsFile.save} will not overwrite existing entries in its save
        path, even if they were only added after the L{KnownHostsFile} instance
        was initialized.
        """
        # Start off with one host/key pair in the file
        path = self.pathWithContent(sampleHashedLine)
        knownHosts = KnownHostsFile.fromPath(path)

        # After initializing the KnownHostsFile instance, add a second host/key
        # pair to the file directly - without the instance's help or knowledge.
        with path.open("a") as hostsFileObj:
            hostsFileObj.write(otherSamplePlaintextLine)

        # Add a third host/key pair using the KnownHostsFile instance
        key = Key.fromString(thirdSampleKey)
        knownHosts.addHostKey("brandnew.example.com", key)
        knownHosts.save()

        # Check that all three host/key pairs are present.
        knownHosts = KnownHostsFile.fromPath(path)
        self.assertEqual([True, True, True], [
                knownHosts.hasHostKey(
                    "www.twistedmatrix.com", Key.fromString(sampleKey)),
                knownHosts.hasHostKey(
                    "divmod.com", Key.fromString(otherSampleKey)),
                knownHosts.hasHostKey("brandnew.example.com", key)])
    def __init__(self, options):

        self.options = options
        
        # load private key
        with open(options['host-key']) as privateBlobFile:
            privateBlob = privateBlobFile.read()
            privateKey = Key.fromString(data=privateBlob)

        # load public key
        with open(options['host-key']+'.pub') as publicBlobFile:
            publicBlob = publicBlobFile.read()
            publicKey = Key.fromString(data=publicBlob)

        tickets = {}
        factory = AMPSSHFactory(tickets, self.options)
        factory.services['ssh-connection'] = SSHConnection

        # Load in keys the way SSHFactory expects them.
        factory.privateKeys = {'ssh-rsa': privateKey}
        factory.publicKeys = {'ssh-rsa': publicKey}

        # Give it a portal to authenticate clients with
        factory.portal = Portal(SimpleRealm(tickets, options, factory))

        # validate against keys in authorized_keys files
        checker = AuthorizedKeys(options['authorized-keys'])
        factory.portal.registerChecker(checker)

        # init TCPServer with port and factory.
        internet.TCPServer.__init__(self, options['ssh-port'], factory)

        # remember for future reference
        self.factory = factory
Example #10
0
def getKeyPair(pubkeyfile, privkeyfile):
    """
    This function looks for RSA keypair files in the current directory. If they
    do not exist, the keypair is created.
    """

    if not (os.path.exists(pubkeyfile) and os.path.exists(privkeyfile)):
        # No keypair exists. Generate a new RSA keypair
        print("  Generating SSH RSA keypair ...", end=' ')
        from Crypto.PublicKey import RSA

        KEY_LENGTH = 1024
        rsaKey = Key(RSA.generate(KEY_LENGTH))
        publicKeyString = rsaKey.public().toString(type="OPENSSH")
        privateKeyString = rsaKey.toString(type="OPENSSH")

        # save keys for the future.
        file(pubkeyfile, 'w+b').write(publicKeyString)
        file(privkeyfile, 'w+b').write(privateKeyString)
        print(" done.")
    else:
        publicKeyString = file(pubkeyfile).read()
        privateKeyString = file(privkeyfile).read()

    return Key.fromString(publicKeyString), Key.fromString(privateKeyString)
 def test_saveKeyECDSA(self):
     """
     L{_saveKey} writes the private and public parts of a key to two
     different files and writes a report of this to standard out.
     Test with ECDSA key.
     """
     base = FilePath(self.mktemp())
     base.makedirs()
     filename = base.child('id_ecdsa').path
     key = Key.fromString(privateECDSA_openssh)
     _saveKey(key, {'filename': filename, 'pass': '******',
         'format': 'md5-hex'})
     self.assertEqual(
         self.stdout.getvalue(),
         "Your identification has been saved in %s\n"
         "Your public key has been saved in %s.pub\n"
         "The key fingerprint in <FingerprintFormats=MD5_HEX> is:\n"
         "e2:3b:e8:1c:f8:c9:c7:de:8b:c0:00:68:2e:c9:2c:8a\n" % (
             filename,
             filename))
     self.assertEqual(
         key.fromString(
             base.child('id_ecdsa').getContent(), None, 'passphrase'),
         key)
     self.assertEqual(
         Key.fromString(base.child('id_ecdsa.pub').getContent()),
         key.public())
Example #12
0
    def addKeyFile(self, kfile, password=None):
        if not os.path.exists(kfile):
            raise Exception("Key file not found %s", kfile)

        try:
            self.keys.append(Key.fromFile(kfile))
        except EncryptedKeyError:
            self.keys.append(Key.fromFile(kfile, passphrase=password))
Example #13
0
 def makeFactory(self):
     """Create and start the factory that our SSH server uses."""
     factory = Factory(
         get_portal(None, None),
         private_key=Key.fromFile(
             get_key_path(PRIVATE_KEY_FILE)),
         public_key=Key.fromFile(
             get_key_path(PUBLIC_KEY_FILE)))
     factory.startFactory()
     return factory
Example #14
0
 def __init__(self, settings):
     self.settings = settings
     self.portal = Portal(Realm(settings))
     self.portal.registerChecker(Checker(settings))
     self.privateKeys = {
         'ssh-rsa': Key.fromFile(settings['hadoukngit']['private_key']),
     }
     self.publicKeys = {
         'ssh-rsa': Key.fromFile(settings['hadoukngit']['public_key']),
     }
Example #15
0
 def __init__(self, settings):
     self.settings = settings
     self.portal = Portal(OpenRukoRealm(settings))
     self.portal.registerChecker(OpenRukoCredentialChecker(settings))
     self.privateKeys = {
         'ssh-rsa': Key.fromFile(settings['gitmouth_private_key']),
     }
     self.publicKeys = {
         'ssh-rsa': Key.fromFile(settings['gitmouth_public_key']),
     }
Example #16
0
def getRSAKeys():
    print "running getRSAKeys"
    with open('/home/pi/.ssh/id_rsa') as privateBlobFile:
        privateBlob = privateBlobFile.read()
        privateKey = Key.fromString(data=privateBlob)

    with open('/home/pi/.ssh/id_rsa.pub') as publicBlobFile:
        publicBlob = publicBlobFile.read()
        publicKey = Key.fromString(data=publicBlob)

    return publicKey, privateKey
 def test_notPresentKey(self):
     """
     L{KnownHostsFile.hasHostKey} returns C{False} when a key for the given
     hostname is not present.
     """
     hostsFile = self.loadSampleHostsFile()
     self.assertFalse(hostsFile.hasHostKey(
             b"non-existent.example.com", Key.fromString(sampleKey)))
     self.assertTrue(hostsFile.hasHostKey(
             b"www.twistedmatrix.com", Key.fromString(sampleKey)))
     self.assertFalse(hostsFile.hasHostKey(
             b"www.twistedmatrix.com", Key.fromString(ecdsaSampleKey)))
Example #18
0
 def test_verifyInvalidKey(self):
     """
     Verifying an invalid key should return a L{Deferred} which fires with a
     L{HostKeyChanged} failure.
     """
     hostsFile = self.loadSampleHostsFile()
     wrongKey = Key.fromString(thirdSampleKey)
     ui = FakeUI()
     hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey))
     d = hostsFile.verifyHostKey(
         ui, "www.twistedmatrix.com", "1.2.3.4", wrongKey)
     return self.assertFailure(d, HostKeyChanged)
Example #19
0
 def test_verifyValidKey(self):
     """
     Verifying a valid key should return a L{Deferred} which fires with
     True.
     """
     hostsFile = self.loadSampleHostsFile()
     hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey))
     ui = FakeUI()
     d = hostsFile.verifyHostKey(ui, "www.twistedmatrix.com", "1.2.3.4",
                                 Key.fromString(sampleKey))
     l = []
     d.addCallback(l.append)
     self.assertEqual(l, [True])
Example #20
0
 def test_matchesKey(self):
     """
     L{IKnownHostEntry.matchesKey} checks to see if an entry matches a given
     SSH key.
     """
     twistedmatrixDotCom = Key.fromString(sampleKey)
     divmodDotCom = Key.fromString(otherSampleKey)
     self.assertEqual(
         True,
         self.entry.matchesKey(twistedmatrixDotCom))
     self.assertEqual(
         False,
         self.entry.matchesKey(divmodDotCom))
    def test_equality(self):
        """
        Two L{HashedEntry} instances compare equal if and only if they represent
        the same host and key in exactly the same way: the host salt, host hash,
        public key type, public key, and comment fields must all be equal.
        """
        hostSalt = b"gJbSEPBG9ZSBoZpHNtZBD1bHKBA"
        hostHash = b"bQv+0Xa0dByrwkA1EB0E7Xop/Fo"
        publicKey = Key.fromString(sampleKey)
        keyType = networkString(publicKey.type())
        comment = b"hello, world"

        entry = HashedEntry(
            hostSalt, hostHash, keyType, publicKey, comment)
        duplicate = HashedEntry(
            hostSalt, hostHash, keyType, publicKey, comment)

        # Vary the host salt
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(
                hostSalt[::-1], hostHash, keyType, publicKey,
                comment))

        # Vary the host hash
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(
                hostSalt, hostHash[::-1], keyType, publicKey,
                comment))

        # Vary the key type
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(
                hostSalt, hostHash, keyType[::-1], publicKey,
                comment))

        # Vary the key
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(
                hostSalt, hostHash, keyType,
                Key.fromString(otherSampleKey), comment))

        # Vary the comment
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(
                hostSalt, hostHash, keyType, publicKey,
                comment[::-1]))
Example #22
0
 def test_verifyInvalidKey(self):
     """
     Verfying an invalid key should return a L{Deferred} which fires with a
     L{HostKeyChanged} failure.
     """
     hostsFile = self.loadSampleHostsFile()
     wrongKey = Key.fromString(thirdSampleKey)
     ui = FakeUI()
     hostsFile.addHostKey("1.2.3.4", Key.fromString(sampleKey))
     d = hostsFile.verifyHostKey(
         ui, "www.twistedmatrix.com", "1.2.3.4", wrongKey)
     l = []
     d.addErrback(l.append)
     hkc = l[0].trap(HostKeyChanged)
 def _testrun(self, keyType, keySize=None):
     filename = self.mktemp()
     if keySize is None:
         subprocess.call(['ckeygen', '-t', keyType, '-f', filename, '--no-passphrase'])
     else:
         subprocess.call(['ckeygen', '-t', keyType, '-f', filename, '--no-passphrase',
             '-b', keySize])
     privKey = Key.fromFile(filename)
     pubKey = Key.fromFile(filename + '.pub')
     if keyType == 'ecdsa':
         self.assertEqual(privKey.type(), 'EC')
     else:
         self.assertEqual(privKey.type(), keyType.upper())
     self.assertTrue(pubKey.isPublic())
Example #24
0
 def __init__(self,
              private_key_path,
              public_key_path,
              moduli_path=None,
              banner=None):
     portal = self._makePortal()
     ssh_factory = ParsnipSSHFactory(
         portal,
         private_key=Key.fromFile(private_key_path),
         public_key=Key.fromFile(public_key_path),
         banner=banner,
         moduli_path=moduli_path
     )
     self.service = strports.service('tcp:22', ssh_factory)
Example #25
0
    def test_saveResetsClobberState(self):
        """
        After L{KnownHostsFile.save} is used once with an instance initialized
        by the default initializer, contents of the save path are respected and
        preserved.
        """
        hostsFile = KnownHostsFile(self.pathWithContent(sampleHashedLine))
        preSave = hostsFile.addHostKey(
            "www.example.com", Key.fromString(otherSampleKey))
        hostsFile.save()
        postSave = hostsFile.addHostKey(
            "another.example.com", Key.fromString(thirdSampleKey))
        hostsFile.save()

        self.assertEqual([preSave, postSave], list(hostsFile.iterentries()))
Example #26
0
 def test_verifyHostIPMismatch(self):
     """
     Verifying a key where the host is present (and correct), but the IP is
     present and different, should result the deferred firing in a
     HostKeyChanged failure.
     """
     hostsFile = self.loadSampleHostsFile()
     rightKey = Key.fromString(sampleKey)
     wrongKey = Key.fromString(thirdSampleKey)
     ui = FakeUI()
     l = []
     d = hostsFile.verifyHostKey(
         ui, "www.twistedmatrix.com", "4.3.2.1", wrongKey)
     d.addErrback(l.append)
     l[0].trap(HostKeyChanged)
Example #27
0
def _load_key(filename):
    try:
        return Key.fromFile(filename)
    except EncryptedKeyError:
        for i in xrange(3):
            passphrase = getpass.getpass("passphrase for %s: " % (filename,))
            if not passphrase:
                continue

            try:
                return Key.fromFile(filename, passphrase=passphrase)
            except BadKeyError:
                pass

        raise BadKeyPassphraseError()
Example #28
0
    def test_publicKeyAuthenticationFailure(self):
        """
        If the SSH server rejects the key pair presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        """
        badKey = Key.fromString(privateRSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user,
            self.hostname, self.port, keys=[badKey],
            knownHosts=self.knownHosts, ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(AuthenticationFailed)
        # XXX Should assert something specific about the arguments of the
        # exception

        # Nothing useful can be done with the connection at this point, so the
        # endpoint should close it.
        self.assertTrue(client.transport.disconnecting)
Example #29
0
 def setUp(self):
     self.rsaPublic = Key.fromString(keydata.publicRSA_openssh)
     self.tmpdir = FilePath(self.mktemp())
     self.tmpdir.makedirs()
     self.rsaFile = self.tmpdir.child('id_rsa')
     self.rsaFile.setContent(keydata.privateRSA_openssh)
     self.tmpdir.child('id_rsa.pub').setContent(keydata.publicRSA_openssh)
Example #30
0
    def test_mismatchedHostKey(self):
        """
        If the SSH public key presented by the SSH server does not match the
        previously remembered key, as reported by the L{KnownHostsFile}
        instance use to construct the endpoint, for that server, the
        L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with
        a L{Failure} wrapping L{HostKeyChanged}.
        """
        differentKey = Key.fromString(privateDSA_openssh).public()
        knownHosts = KnownHostsFile(self.mktemp())
        knownHosts.addHostKey(self.serverAddress.host, differentKey)
        knownHosts.addHostKey(self.hostname, differentKey)

        # The UI may answer true to any questions asked of it; they should
        # make no difference, since a *mismatched* key is not even optionally
        # allowed to complete a connection.
        ui = FixedResponseUI(True)

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, password=b"dummy password",
            knownHosts=knownHosts, ui=ui)

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(HostKeyChanged)
Example #31
0
 def _testrun(self, keyType, keySize=None, privateKeySubtype=None):
     filename = self.mktemp()
     args = ["ckeygen", "-t", keyType, "-f", filename, "--no-passphrase"]
     if keySize is not None:
         args.extend(["-b", keySize])
     if privateKeySubtype is not None:
         args.extend(["--private-key-subtype", privateKeySubtype])
     subprocess.call(args)
     privKey = Key.fromFile(filename)
     pubKey = Key.fromFile(filename + ".pub")
     if keyType == "ecdsa":
         self.assertEqual(privKey.type(), "EC")
     elif keyType == "ed25519":
         self.assertEqual(privKey.type(), "Ed25519")
     else:
         self.assertEqual(privKey.type(), keyType.upper())
     self.assertTrue(pubKey.isPublic())
Example #32
0
 def getPublicKey(self):
     path = self.options['ssh-key']
     # this works with rsa too
     # just change the name here and in getPrivateKey
     if not os.path.exists(path) or self.lastPublicKey:
         # the file doesn't exist, or we've tried a public key
         return
     return Key.fromFile(filename=path + '.pub')
Example #33
0
 def _testrun(self, keyType, keySize=None):
     filename = self.mktemp()
     if keySize is None:
         subprocess.call(
             ['ckeygen', '-t', keyType, '-f', filename, '--no-passphrase'])
     else:
         subprocess.call([
             'ckeygen', '-t', keyType, '-f', filename, '--no-passphrase',
             '-b', keySize
         ])
     privKey = Key.fromFile(filename)
     pubKey = Key.fromFile(filename + '.pub')
     if keyType == 'ecdsa':
         self.assertEqual(privKey.type(), 'EC')
     else:
         self.assertEqual(privKey.type(), keyType.upper())
     self.assertTrue(pubKey.isPublic())
Example #34
0
def _generate():
    """
    Generate a new SSH key pair.
    """
    privateKey = rsa.generate_private_key(public_exponent=65537,
                                          key_size=4096,
                                          backend=default_backend())
    return Key(privateKey).toString('openssh')
Example #35
0
 def _testrun(self, keyType, keySize=None, privateKeySubtype=None):
     filename = self.mktemp()
     args = ['ckeygen', '-t', keyType, '-f', filename, '--no-passphrase']
     if keySize is not None:
         args.extend(['-b', keySize])
     if privateKeySubtype is not None:
         args.extend(['--private-key-subtype', privateKeySubtype])
     subprocess.call(args)
     privKey = Key.fromFile(filename)
     pubKey = Key.fromFile(filename + '.pub')
     if keyType == 'ecdsa':
         self.assertEqual(privKey.type(), 'EC')
     elif keyType == 'ed25519':
         self.assertEqual(privKey.type(), 'Ed25519')
     else:
         self.assertEqual(privKey.type(), keyType.upper())
     self.assertTrue(pubKey.isPublic())
Example #36
0
 def test_iterentriesUnsaved(self):
     """
     If the save path for a L{KnownHostsFile} does not exist,
     L{KnownHostsFile.iterentries} still returns added but unsaved entries.
     """
     hostsFile = KnownHostsFile(FilePath(self.mktemp()))
     hostsFile.addHostKey("www.example.com", Key.fromString(sampleKey))
     self.assertEqual(1, len(list(hostsFile.iterentries())))
Example #37
0
 def test_unsavedEntryHasKeyMismatch(self):
     """
     L{KnownHostsFile.hasHostKey} raises L{HostKeyChanged} if the host key is
     present in memory (but not yet saved), but different from the expected
     one.  The resulting exception has a C{offendingEntry} indicating the
     given entry, but no filename or line number information (reflecting the
     fact that the entry exists only in memory).
     """
     hostsFile = KnownHostsFile(FilePath(self.mktemp()))
     entry = hostsFile.addHostKey("www.example.com",
                                  Key.fromString(otherSampleKey))
     exception = self.assertRaises(HostKeyChanged, hostsFile.hasHostKey,
                                   "www.example.com",
                                   Key.fromString(thirdSampleKey))
     self.assertEqual(exception.offendingEntry, entry)
     self.assertEqual(exception.lineno, None)
     self.assertEqual(exception.path, None)
Example #38
0
 def test_verifyNonPresentKey_Yes(self):
     """
     Verifying a key where neither the hostname nor the IP are present
     should result in the UI being prompted with a message explaining as
     much.  If the UI says yes, the Deferred should fire with True.
     """
     ui, l, knownHostsFile = self.verifyNonPresentKey()
     ui.promptDeferred.callback(True)
     self.assertEqual([True], l)
     reloaded = KnownHostsFile.fromPath(knownHostsFile.savePath)
     self.assertEqual(
         True, reloaded.hasHostKey("4.3.2.1",
                                   Key.fromString(thirdSampleKey)))
     self.assertEqual(
         True,
         reloaded.hasHostKey("sample-host.example.com",
                             Key.fromString(thirdSampleKey)))
Example #39
0
 def test_hasNonPresentKey(self):
     """
     L{KnownHostsFile.hasHostKey} returns C{False} when a key for the given
     hostname is not present.
     """
     hostsFile = self.loadSampleHostsFile()
     self.assertEqual(False, hostsFile.hasHostKey(
             "non-existent.example.com", Key.fromString(sampleKey)))
Example #40
0
 def test_hasPresentKey(self):
     """
     L{KnownHostsFile.hasHostKey} returns C{True} when a key for the given
     hostname is present and matches the expected key.
     """
     hostsFile = self.loadSampleHostsFile()
     self.assertEqual(True, hostsFile.hasHostKey(
             "www.twistedmatrix.com", Key.fromString(sampleKey)))
Example #41
0
 def test_getHostKeyAlgorithms(self):
     """
     For a given host, get the host key algorithms for that
     host in the known_hosts file.
     """
     hostsFile = self.loadSampleHostsFile()
     hostsFile.addHostKey(b"www.twistedmatrix.com",
                          Key.fromString(otherSampleKey))
     hostsFile.addHostKey(b"www.twistedmatrix.com",
                          Key.fromString(ecdsaSampleKey))
     hostsFile.save()
     options = {}
     options["known-hosts"] = hostsFile.savePath.path
     algorithms = default.getHostKeyAlgorithms(b"www.twistedmatrix.com",
                                               options)
     expectedAlgorithms = [b"ssh-rsa", b"ecdsa-sha2-nistp256"]
     self.assertEqual(algorithms, expectedAlgorithms)
Example #42
0
    def test_equality(self):
        """
        Two L{HashedEntry} instances compare equal if and only if they represent
        the same host and key in exactly the same way: the host salt, host hash,
        public key type, public key, and comment fields must all be equal.
        """
        hostSalt = "gJbSEPBG9ZSBoZpHNtZBD1bHKBA"
        hostHash = "bQv+0Xa0dByrwkA1EB0E7Xop/Fo"
        publicKey = Key.fromString(sampleKey)
        comment = "hello, world"

        entry = HashedEntry(hostSalt, hostHash, publicKey.type(), publicKey,
                            comment)
        duplicate = HashedEntry(hostSalt, hostHash, publicKey.type(),
                                publicKey, comment)

        # Vary the host salt
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(hostSalt[::-1], hostHash, publicKey.type(), publicKey,
                        comment))

        # Vary the host hash
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(hostSalt, hostHash[::-1], publicKey.type(), publicKey,
                        comment))

        # Vary the key type
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(hostSalt, hostHash,
                        publicKey.type()[::-1], publicKey, comment))

        # Vary the key
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(hostSalt, hostHash, publicKey.type(),
                        Key.fromString(otherSampleKey), comment))

        # Vary the comment
        self.assertNormalEqualityImplementation(
            entry, duplicate,
            HashedEntry(hostSalt, hostHash, publicKey.type(), publicKey,
                        comment[::-1]))
Example #43
0
 def check_keys(results):
     for key_data, comment in results:
         agent_key = Key.fromString(key_data, type='blob')
         Message.new(message_type="flocker.provision.ssh:agent_key",
                     key_fingerprint=agent_key.fingerprint(),
                     commnet=comment).write()
         if agent_key == key:
             return True
     raise KeyNotFound(expected_key=key)
Example #44
0
 def assertHostKey(self, shell, factory):
     """
     Assert that the public and private keys provided by C{factory}
     match those specified by C{shell} and that they are L{Key}
     instances.
     """
     privateKey = Key.fromString(shell.hostKey)
     self.assertEqual(factory.publicKeys, {'ssh-rsa': privateKey.public()})
     self.assertEqual(factory.privateKeys, {'ssh-rsa': privateKey})
Example #45
0
def validate_ssh_public_key(value):
    """Validate that the given value contains a valid SSH public key."""
    try:
        key = Key.fromString(value)
        if not key.isPublic():
            raise ValidationError(
                "Invalid SSH public key (this key is a private key).")
    except (BadKeyError, binascii.Error):
        raise ValidationError("Invalid SSH public key.")
Example #46
0
 def __repr__(self):
     """
     Return a summarized representation of this item.
     """
     fmt = "SecureShellConfiguration(storeID=%d, hostKeyFingerprint='%s')"
     privateKey = Key.fromString(data=self.hostKey)
     publicKeyBlob = privateKey.blob()
     fingerprint = md5(publicKeyBlob).hexdigest()
     return fmt % (self.storeID, fingerprint)
Example #47
0
    def verifyHostKey(self, pubKey, fingerprint):
        self._state = b'SECURING'

        hostname = self.factory.hostname
        ip = self.transport.getPeer().host
        d = self.knownHosts.verifyHostKey(self.factory.ui, hostname, ip,
                                          Key.fromString(pubKey))
        d.addErrback(self._saveHostKeyFailure)
        return d
Example #48
0
    def test_key_not_regenerated(self):
        """
        ``create_keypair`` does not generate a new key pair if one can
        already be found in ``id_rsa_flocker`` and ``id_rsa_flocker.pub``.
        """
        ssh_config = FilePath(self.mktemp())
        configurator = OpenSSHConfiguration(ssh_config_path=ssh_config,
                                            flocker_path=None)

        id_rsa = ssh_config.child(b"id_rsa_flocker")

        configurator.create_keypair()

        expected_key = Key.fromFile(id_rsa.path)

        configurator.create_keypair()

        self.assertEqual(expected_key, Key.fromFile(id_rsa.path))
Example #49
0
def main(keys_path, port):
    with open(keys_path + '/id_rsa') as privateBlobFile:
        privateBlob = privateBlobFile.read()
        privateKey = Key.fromString(data=privateBlob)

    with open(keys_path + '/id_rsa.pub') as publicBlobFile:
        publicBlob = publicBlobFile.read()
        publicKey = Key.fromString(data=publicBlob)

    factory = SSHFactory()
    factory.privateKeys = {'ssh-rsa': privateKey}
    factory.publicKeys = {'ssh-rsa': publicKey}
    factory.portal = Portal(KeyRealm())
    factory.portal.registerChecker(KeyChecker())
    factory.portal.registerChecker(PasswordChecker())

    reactor.listenTCP(port, factory)
    reactor.run()
Example #50
0
 def setUp(self):
     """
     Patch 'open' in verifyHostKey.
     """
     self.fakeFile = FakeFile()
     self.patch(default, "_open", self.patchedOpen)
     self.hostsOption = self.mktemp()
     knownHostsFile = KnownHostsFile(FilePath(self.hostsOption))
     knownHostsFile.addHostKey("exists.example.com",
                               Key.fromString(sampleKey))
     knownHostsFile.addHostKey("4.3.2.1", Key.fromString(sampleKey))
     knownHostsFile.save()
     self.fakeTransport = FakeObject()
     self.fakeTransport.factory = FakeObject()
     self.options = self.fakeTransport.factory.options = {
         'host': "exists.example.com",
         'known-hosts': self.hostsOption
     }
Example #51
0
    def __init__(self,
                 portal,
                 private_key_path,
                 public_key_path,
                 oops_configuration,
                 main_log,
                 access_log,
                 access_log_path,
                 strport='tcp:22',
                 factory_decorator=None,
                 banner=None):
        """Construct an SSH service.

        :param portal: The `twisted.cred.portal.Portal` that turns
            authentication requests into views on the system.
        :param private_key_path: The path to the SSH server's private key.
        :param public_key_path: The path to the SSH server's public key.
        :param oops_configuration: The section of the configuration file with
            the OOPS config details for this server.
        :param main_log: The name of the logger to log most of the server
            stuff to.
        :param access_log: The name of the logger object to log the server
            access details to.
        :param access_log_path: The path to the access log file.
        :param strport: The port to run the server on, expressed in Twisted's
            "strports" mini-language. Defaults to 'tcp:22'.
        :param factory_decorator: An optional callable that can decorate the
            server factory (e.g. with a
            `twisted.protocols.policies.TimeoutFactory`).  It takes one
            argument, a factory, and must return a factory.
        :param banner: An announcement printed to users when they connect.
            By default, announce nothing.
        """
        ssh_factory = Factory(portal,
                              private_key=Key.fromFile(private_key_path),
                              public_key=Key.fromFile(public_key_path),
                              banner=banner)
        if factory_decorator is not None:
            ssh_factory = factory_decorator(ssh_factory)
        self.service = strports.service(strport, ssh_factory)
        self._oops_configuration = oops_configuration
        self._main_log = main_log
        self._access_log = access_log
        self._access_log_path = access_log_path
Example #52
0
 def test_inKnownHostsKeyChanged(self):
     """
     L{default.isInKnownHosts} should return C{2} when a host with a key
     other than the given one is in the known hosts file.
     """
     host = self.hashedEntries[b"4.3.2.1"].toString().split()[0]
     r = default.isInKnownHosts(
         host, Key.fromString(otherSampleKey).blob(),
         {"known-hosts": FilePath(self.hostsOption).path})
     self.assertEqual(2, r)
Example #53
0
 def test_randomSalts(self):
     """
     L{KnownHostsFile.addHostKey} generates a random salt for each new key,
     so subsequent salts will be different.
     """
     hostsFile = self.loadSampleHostsFile()
     aKey = Key.fromString(thirdSampleKey)
     self.assertNotEqual(
         hostsFile.addHostKey("somewhere.example.com", aKey)._hostSalt,
         hostsFile.addHostKey("somewhere-else.example.com", aKey)._hostSalt)
Example #54
0
def verify_SSL_key_and_cert(keyfile, certfile):
    """
    This function looks for RSA key and certificate in the current
    directory. If files ssl.key and ssl.cert does not exist, they
    are created.
    """

    if not (os.path.exists(keyfile) and os.path.exists(certfile)):
        # key/cert does not exist. Create.
        import subprocess
        from Crypto.PublicKey import RSA
        from twisted.conch.ssh.keys import Key

        print("  Creating SSL key and certificate ... ", end=" ")

        try:
            # create the RSA key and store it.
            KEY_LENGTH = 1024
            rsaKey = Key(RSA.generate(KEY_LENGTH))
            keyString = rsaKey.toString(type="OPENSSH")
            file(keyfile, "w+b").write(keyString)
        except Exception as err:
            print(NO_AUTOGEN.format(err=err, keyfile=keyfile))
            sys.exit(5)

        # try to create the certificate
        CERT_EXPIRE = 365 * 20  # twenty years validity
        # default:
        # openssl req -new -x509 -key ssl.key -out ssl.cert -days 7300
        exestring = "openssl req -new -x509 -key %s -out %s -days %s" % (
            keyfile,
            certfile,
            CERT_EXPIRE,
        )
        try:
            subprocess.call(exestring)
        except OSError as err:
            raise OSError(
                NO_AUTOCERT.format(err=err,
                                   certfile=certfile,
                                   keyfile=keyfile,
                                   exestring=exestring))
        print("done.")
Example #55
0
 def test_savedEntryAfterAddHasKeyMismatch(self):
     """
     Even after a new entry has been added in memory but not yet saved, the
     L{HostKeyChanged} exception raised by L{KnownHostsFile.hasHostKey} has a
     C{lineno} attribute which indicates the 1-based line number of the
     offending entry in the underlying file when the given host key does not
     match the expected host key.
     """
     hostsFile = self.loadSampleHostsFile()
     hostsFile.addHostKey(b"www.example.com",
                          Key.fromString(otherSampleKey))
     exception = self.assertRaises(
         HostKeyChanged,
         hostsFile.hasHostKey,
         b"www.twistedmatrix.com",
         Key.fromString(otherSampleKey),
     )
     self.assertEqual(exception.lineno, 1)
     self.assertEqual(exception.path, hostsFile.savePath)
Example #56
0
def get_manhole_factory(namespace):
    """ Build a twisted manhole factory """

    from twisted.conch import manhole, manhole_ssh
    from twisted.cred import portal, checkers

    # I really hate Twisted's default colors
    colors = {
        'identifier': '\x1b[1;36m',
        'keyword': '\x1b[33m',
        'parameter': '\x1b[33m',
        'variable': '\x1b[36m',
        'string': '\x1b[35m',
        'number': '\x1b[1;32m',
        'op': '\x1b[33m'
    }

    manhole.VT102Writer.typeToColor.update(colors)

    realm = manhole_ssh.TerminalRealm()

    def get_manhole(_):
        return manhole.ColoredManhole(namespace)

    realm.chainedProtocolFactory.protocolFactory = get_manhole
    p = portal.Portal(realm)
    checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
    checker.addUser(config.backdoor_user, config.backdoor_password)
    p.registerChecker(checker)

    factory = manhole_ssh.ConchFactory(p)
    # As of Twisted~v16.0.0 we now have to give host SSH keys to any subclass of SSHFactory
    key_path = os.path.expanduser(config.ssh_key_path)
    factory.publicKeys = {
        'ssh-rsa': Key.fromFile(key_path)
    }

    factory.privateKeys = {
        'ssh-rsa': Key.fromFile(key_path)
    }

    return factory
Example #57
0
 def test_displayPublicKeyEncrypted(self):
     """
     L{displayPublicKey} prints out the public key associated with a given
     private key using the given passphrase when it's encrypted.
     """
     filename = self.mktemp()
     pubKey = Key.fromString(publicRSA_openssh)
     FilePath(filename).setContent(privateRSA_openssh_encrypted)
     displayPublicKey({'filename': filename, 'pass': '******'})
     self.assertEqual(self.stdout.getvalue().strip('\n'),
                      pubKey.toString('openssh'))
Example #58
0
 def test_displayPublicKey(self):
     """
     L{displayPublicKey} prints out the public key associated with a given
     private key.
     """
     filename = self.mktemp()
     pubKey = Key.fromString(publicRSA_openssh)
     FilePath(filename).setContent(privateRSA_openssh)
     displayPublicKey({'filename': filename})
     self.assertEqual(self.stdout.getvalue().strip('\n'),
                      pubKey.toString('openssh'))
Example #59
0
def manhole(settings: ManholeConfig, globals: Dict[str, Any]) -> Factory:
    """Starts a ssh listener with password authentication using
    the given username and password. Clients connecting to the ssh
    listener will find themselves in a colored python shell with
    the supplied globals.

    Args:
        username: The username ssh clients should auth with.
        password: The password ssh clients should auth with.
        globals: The variables to expose in the shell.

    Returns:
        A factory to pass to ``listenTCP``
    """
    username = settings.username
    password = settings.password.encode("ascii")
    priv_key = settings.priv_key
    if priv_key is None:
        priv_key = Key.fromString(PRIVATE_KEY)
    pub_key = settings.pub_key
    if pub_key is None:
        pub_key = Key.fromString(PUBLIC_KEY)

    checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(**{username: password})

    rlm = manhole_ssh.TerminalRealm()
    # mypy ignored here because:
    # - can't deduce types of lambdas
    # - variable is Type[ServerProtocol], expr is Callable[[], ServerProtocol]
    rlm.chainedProtocolFactory = lambda: insults.ServerProtocol(  # type: ignore[misc,assignment]
        SynapseManhole, dict(globals, __name__="__console__")
    )

    factory = manhole_ssh.ConchFactory(portal.Portal(rlm, [checker]))

    # conch has the wrong type on these dicts (says bytes to bytes,
    # should be bytes to Keys judging by how it's used).
    factory.privateKeys[b"ssh-rsa"] = priv_key  # type: ignore[assignment]
    factory.publicKeys[b"ssh-rsa"] = pub_key  # type: ignore[assignment]

    return factory
Example #60
0
 def test_fromString(self):
     """
     Constructing a plain text entry from an unhashed known_hosts entry will
     result in an L{IKnownHostEntry} provider with 'keyString', 'hostname',
     and 'keyType' attributes.  While outside the interface in question,
     these attributes are held in common by L{PlainEntry} and L{HashedEntry}
     implementations; other implementations should override this method in
     subclasses.
     """
     entry = self.entry
     self.assertEqual(entry.publicKey, Key.fromString(sampleKey))
     self.assertEqual(entry.keyType, "ssh-rsa")