Esempio n. 1
0
    def setup_secure_access(self):
        try:
            from twisted.cred import portal
            portal = portal.Portal(NetconfRealm(self, self.grpc_client))

            # setup userid-password access
            password_file = '{}/{}/{}'.format(dir_path,
                                              C.CLIENT_CRED_DIRECTORY,
                                              self.client_passwords_file)
            portal.registerChecker(FilePasswordDB(password_file))

            # setup access when client uses keys
            keys_file = '{}/{}/{}'.format(dir_path, C.CLIENT_CRED_DIRECTORY,
                                          self.client_public_keys_file)
            with open(keys_file) as f:
                users = [line.rstrip('\n') for line in f]
            users_dict = {}
            for user in users:
                users_dict[user.split(':')[0]] = [
                    keys.Key.fromFile('{}/{}/{}'.format(
                        dir_path, C.CLIENT_CRED_DIRECTORY,
                        user.split(':')[1]))
                ]
            sshDB = SSHPublicKeyChecker(InMemorySSHKeyDB(users_dict))
            portal.registerChecker(sshDB)
            return portal
        except Exception as e:
            log.error('setup-secure-access-fail', exception=repr(e))
 def generateChecker(self, argstring=''):
     """
     This checker factory ignores the argument string. Everything
     needed to authenticate users is pulled out of the public keys
     listed in user .ssh/ directories.
     """
     return SSHPublicKeyChecker(UNIXAuthorizedKeysFiles())
Esempio n. 3
0
 def startService(self):
     components.registerAdapter(SSHSession, SSHAvatar, session.ISession)
     portal = ptl.Portal(SSHRealm())
     passwdDB = InMemoryUsernamePasswordDatabaseDontUse()
     passwdDB.addUser(b'user', b'password')
     sshDB = SSHPublicKeyChecker(
         InMemorySSHKeyDB({b'user':
                           [keys.Key.fromFile(CLIENT_RSA_PUBLIC)]}))
     portal.registerChecker(passwdDB)
     portal.registerChecker(sshDB)
     SSHServerFactory.portal = portal
     self.endpoint = TCP4ServerEndpoint(reactor, 2222)
     self.endpoint.listen(SSHServerFactory())
Esempio n. 4
0
def conch_helper(endpoint,
                 proto=None,
                 namespace=dict(),
                 keyDir=None,
                 keySize=4096):
    """
    Return a L{SSHKeyDirectory} based SSH service with the given parameters.

    Authorized keys are read as per L{SSHKeyDirectory} with ``baseDir`` being
    ``keyDir/users``.

    @param endpoint: endpoint for the SSH service
    @param namespace: the manhole namespace
    @param keyDir: directory that holds server/server.key file and
        users directory, which is used as ``baseDir`` in L{SSHKeyDirectory}
    @see: L{SSHKeyDirectory}
    """
    if keyDir is None:
        from twisted.python._appdirs import getDataDirectory

        keyDir = getDataDirectory()

    keyDir = filepath.FilePath(keyDir)
    keyDir.child("server").makedirs(True)
    keyDir.child("users").makedirs(True)

    checker = SSHPublicKeyChecker(SSHKeyDirectory(keyDir.child("users")))

    if proto is None:
        sshRealm = manhole_ssh.TerminalRealm()
        sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)
    else:
        sshRealm = SSHSimpleRealm(proto)
    sshPortal = portal.Portal(sshRealm, [checker])

    sshKeyPath = keyDir.child("server").child("server.key")
    sshKey = keys._getPersistentRSAKey(sshKeyPath, keySize)

    sshFactory = manhole_ssh.ConchFactory(sshPortal)
    sshFactory.publicKeys[b"ssh-rsa"] = sshKey
    sshFactory.privateKeys[b"ssh-rsa"] = sshKey

    sshService = strports.service(endpoint, sshFactory)
    return sshService
Esempio n. 5
0
 def __init__(self, client, accountfile):
     self.client = client
     self.passwords = BytesKeyDict()
     pubkeys = BytesKeyDict()
     self.rootcaps = BytesKeyDict()
     with open(abspath_expanduser_unicode(accountfile), "rb") as f:
         for line in f:
             line = line.strip()
             if line.startswith(b"#") or not line:
                 continue
             name, passwd, rest = line.split(None, 2)
             if passwd.startswith(b"ssh-"):
                 bits = rest.split()
                 keystring = b" ".join([passwd] + bits[:-1])
                 key = keys.Key.fromString(keystring)
                 rootcap = bits[-1]
                 pubkeys[name] = [key]
             else:
                 self.passwords[name] = passwd
                 rootcap = rest
             self.rootcaps[name] = rootcap
     self._pubkeychecker = SSHPublicKeyChecker(InMemorySSHKeyDB(pubkeys))
Esempio n. 6
0
    # Server's host keys.
    # To simplify the example this server is defined only with a host key of
    # type RSA.
    publicKeys = {'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PUBLIC)}
    privateKeys = {'ssh-rsa': keys.Key.fromFile(SERVER_RSA_PRIVATE)}
    # Service handlers.
    services = {
        'ssh-userauth': userauth.SSHUserAuthServer,
        'ssh-connection': connection.SSHConnection
    }

    def getPrimes(self):
        """
        See: L{factory.SSHFactory}
        """
        return PRIMES


portal = portal.Portal(ExampleRealm())
passwdDB = InMemoryUsernamePasswordDatabaseDontUse()
passwdDB.addUser('user', 'password')
sshDB = SSHPublicKeyChecker(
    InMemorySSHKeyDB({'user': [keys.Key.fromFile(CLIENT_RSA_PUBLIC)]}))
portal.registerChecker(passwdDB)
portal.registerChecker(sshDB)
ExampleFactory.portal = portal

if __name__ == '__main__':
    reactor.listenTCP(5022, ExampleFactory())
    reactor.run()
Esempio n. 7
0
    def startService(self):
        """
        This is the main entry point into the service when it
        starts.  Multiple components need to be created and
        assembled to create the final service.  It helps to
        look at the process in reverse.

        An endpoint (`ep`) is created that listens on a port.  When a
        connection is received, it uses a protocol `factory` to create
        a new SSH protocol instance.

        The factory is configure with a portal that will be used to
        authenticate users and create avatars for them at the service.

        The factory portal registered a :py:class:`SSHPublicKeychecker`
        instance so that users can authenticate using SSH public/private
        key pairs.  The allowed public keys and the matching users are
        configured in a JSON file that the service reads on start up.

        The protocol factory (:py:class:`twisted.conch.ssh.factory.SSHFactory`)
        is indirectly responsible for calling the `login` method on its portal.
        When the "ssh-userauth" service of the SSH protocol is requested, the
        factory creates an instance of 
        :py:class:`twisted.conch.ssh.userauth.SSHUserAuthServer` to create a
        public key credential and pass it to the portal's `login` method.  It
        is at this point the public key checker can authenticate the credential.

        The portal was also configured with `self.realmFactory` which happens
        to produce an instance of :py:class:`auth.SSHRealm`.  This realm creates 
        an avatar instance which will represent the user on the service side of
        the connection.

        The avatar created will be an instance of :py:class:`auth.SSHAvatar`.
        This avatar is responsible for connecting the user to the service
        application logic.
        """
        assert self.realmFactory is not None, "`realmFactory` must not be None!"
        with open(self.servicePrivateKey, "r") as privateBlobFile:
            privateBlob = privateBlobFile.read()
            privateKey = Key.fromString(data=privateBlob)
        with open(self.servicePublicKey, "r") as publicBlobFile:
            publicBlob = publicBlobFile.read()
            publicKey = Key.fromString(data=publicBlob)
        factory = SSHFactory()
        factory.privateKeys = {b'ssh-rsa': privateKey}
        factory.publicKeys = {b'ssh-rsa': publicKey}
        sshRealm = self.realmFactory()
        sshRealm.reactor = self.reactor
        sshPortal = Portal(sshRealm)
        factory.portal = sshPortal
        with open(self.key_db_path, "r") as f:
            raw_key_map = json.load(f)
        l = []
        for avatar_id, keys in raw_key_map.items():
            key_objects = [Key.fromString(k.encode('utf-8')) for k in keys]
            l.append((avatar_id.encode('utf-8'), key_objects))
        key_map = dict(l)
        keydb = InMemorySSHKeyDB(key_map)
        factory.portal.registerChecker(SSHPublicKeyChecker(keydb))
        ep = endpoints.serverFromString(self.reactor, self.endpoint_str)
        d = ep.listen(factory)
        self.port_info_ = []
        d.addCallback(self.onListen)
Esempio n. 8
0
        pass

    def closed(self):
        pass


from twisted.python import components
components.registerAdapter(ExampleSession, ExampleAvatar, session.ISession)


class ExampleFactory(factory.SSHFactory):
    publicKeys = {'ssh-rsa': keys.Key.fromString(data=publicKey)}
    privateKeys = {'ssh-rsa': keys.Key.fromString(data=privateKey)}
    services = {
        'ssh-userauth': userauth.SSHUserAuthServer,
        'ssh-connection': connection.SSHConnection
    }


portal = portal.Portal(SSHDemoRealm())
passwdDB = InMemoryUsernamePasswordDatabaseDontUse()
passwdDB.addUser('user', 'password')
sshDB = SSHPublicKeyChecker(
    InMemorySSHKeyDB({'user': [keys.Key.fromString(data=publicKey)]}))
portal.registerChecker(passwdDB)
portal.registerChecker(sshDB)
ExampleFactory.portal = portal

if __name__ == '__main__':
    reactor.listenTCP(interface="0.0.0.0", port=2222, factory=ExampleFactory())
    reactor.run()
Esempio n. 9
0
        self.env = {}

    def request_pty_req(self, data):
        print "request pty"
        return True

    def request_shell(self, data):
        protocol = EchoProtocol()
        transport = SSHSessionProcessProtocol(self)
        protocol.makeConnection(transport)
        transport.makeConnection(wrapProtocol(protocol))
        self.client = transport
        return True

    def request_env(self, data):
        (key, value, _) = getNS(data, count=2)
        self.env[key] = value
        return True


if __name__ == '__main__':
    portal = portal.Portal(MetisRealm())
    sshDB = SSHPublicKeyChecker(
        InMemorySSHKeyDB({
            'edd': [keys.Key.fromFile('/Users/edd/.ssh/id_rsa.personal.pub')]
        }))
    portal.registerChecker(sshDB)
    factory = MetisSSHFactory(portal)
    reactor.listenTCP(5022, factory)
    reactor.run()
Esempio n. 10
0
 def __init__(self):
     passwdDB = InMemoryUsernamePasswordDatabaseDontUse(user="******")
     sshDB = SSHPublicKeyChecker(
         InMemorySSHKeyDB({b"user":
                           [keys.Key.fromFile(CLIENT_RSA_PUBLIC)]}))
     self.portal = portal.Portal(ExampleRealm(), [passwdDB, sshDB])
Esempio n. 11
0
def getObjshPortal(protocol_class, acl_options):

    realm = ObjshRealm(protocol_class)
    portal = cred_portal.Portal(realm)

    # ssh client's public key
    sshclient_pubkey_folders = acl_options.get('client_publickeys')
    if sshclient_pubkey_folders:
        del acl_options['client_publickeys']
        client_keydb = {}
        loaded_folders = []
        for sshclient_pubkey_folder in sshclient_pubkey_folders:
            if sshclient_pubkey_folder in loaded_folders: continue
            if not os.path.exists(sshclient_pubkey_folder): continue
            loaded_folders.append(sshclient_pubkey_folder)
            for file in os.listdir(sshclient_pubkey_folder):
                username, ext = os.path.splitext(file)
                if username.startswith('.') or ext != '.pub': continue
                try:
                    client_keydb[username].append(
                        ssh_keys.Key.fromFile(
                            os.path.join(sshclient_pubkey_folder, file)))
                    log.msg('load key-based ssh user ' + username)
                except KeyError:
                    try:
                        client_keydb[username] = [
                            ssh_keys.Key.fromFile(
                                os.path.join(sshclient_pubkey_folder, file))
                        ]
                        log.msg('load key-based ssh user ' + username)
                    except ssh_keys.BadKeyError:
                        log.msg('Warning! failed to load sshkey of ' +
                                username)
        sshDB = SSHPublicKeyChecker(InMemorySSHKeyDB(client_keydb))

        # this should register to portal to make it work
        portal.registerChecker(sshDB)

    # username, password based authentication
    cascading_checker = CascadingChecker()
    for acl_name, acl_settings in acl_options.items():
        if acl_settings['kind'] == 'LDAP':
            if LDAPBindingChecker is None:
                log.msg(
                    'Warning: package ldaptor is not installed, LDAP authentication ignored'
                )
                continue
            #basedn = 'dc=example,dc=com'
            basedn = acl_settings['basedn']
            query = '(%s=%%(name)s)' % acl_settings['uid_attrname']
            cfg = ldaptor_config.LDAPConfig(basedn, {
                basedn: (acl_settings['host'], acl_settings.get('port', 389))
            }, None, query)
            checker = LDAPBindingChecker(acl_settings['uid_attrname'], cfg)
            cascading_checker.registerChecker(checker)
        elif acl_settings['kind'] == 'PAM':
            # system accounts
            cascading_checker.registerChecker(
                PamPasswordDatabase(acl_settings['usernames'],
                                    acl_settings['username_prefix']))
        elif acl_settings['kind'] == 'IN_MEMORY_ACCOUNTS':
            # in memory accounts
            passwdDB = InMemoryUsernamePasswordDatabaseDontUse()
            for username, password in acl_settings.get('accounts', {}).items():
                username = username.strip()  # do not allow empty username
                password = password.strip()  # do not allow empty password
                if password and username:
                    passwdDB.addUser(username, password)
                    log.msg('Warning! in memory account: %s' % (username))
            cascading_checker.registerChecker(passwdDB)
        else:
            raise ValueError('Acl kind of %s is unknown' % acl_name)

    portal.registerChecker(cascading_checker)
    return portal
Esempio n. 12
0
 def __init__(self, client, accountfile):
     self.client = client
     path = abspath_expanduser_unicode(accountfile)
     with open_account_file(path) as f:
         self.rootcaps, pubkeys = load_account_file(f)
     self._pubkeychecker = SSHPublicKeyChecker(InMemorySSHKeyDB(pubkeys))