Exemple #1
0
    def createMergedServer(self, *responses):
        """
        Create an MergedLDAP server for testing. Initialize with
        len(responses) clients.
        :param responses: The responses to initialize the `LDAPClientTestDrives`.
        :type responses: args of lists of lists
        :return a deferred, fires when server finished connecting
        """
        def createClient(factory):
            factory.doStart()
            proto = factory.buildProtocol(addr=None)
            proto.connectionMade()

        clients = []
        for r in responses:
            clients.append(testutil.LDAPClientTestDriver(*r))

        conf = config.LDAPConfig(serviceLocationOverrides={"": createClient})
        server = MergedLDAPServer([conf for _ in clients],
                                  [False for _ in clients])
        self.clients = clients * 1
        server.protocol = lambda: clients.pop()
        server.transport = proto_helpers.StringTransport()
        server.connectionMade()

        d = server._whenConnected(lambda: server)
        return d
Exemple #2
0
def createServer(proto, *responses, **kw):
    """
    Create an LDAP server for testing.
    :param proto: The server protocol factory (e.g. `ProxyBase`).
    :param responses: The responses to initialize the `LDAPClientTestDrive`.
    :param proto_args: Optional mapping passed as keyword args to protocol factory.
    """
    if "proto_args" in kw:
        proto_args = kw["proto_args"]
        del kw["proto_args"]
    else:
        proto_args = {}

    def createClient(factory):
        factory.doStart()
        proto = factory.buildProtocol(addr=None)
        proto.connectionMade()

    overrides = kw.setdefault("serviceLocationOverrides", {})
    overrides.setdefault("", createClient)
    conf = config.LDAPConfig(**kw)
    server = proto(conf, **proto_args)
    clientTestDriver = LDAPClientTestDriver(*responses)
    server.protocol = lambda: clientTestDriver
    server.clientTestDriver = clientTestDriver
    server.transport = proto_helpers.StringTransport()
    server.connectionMade()
    return server
Exemple #3
0
    def testGetIdentitySearchNoSection(self):
        """
        When the configuration file does not contains the `authentication`
        section it will use a default expression.
        """
        sut = config.LDAPConfig()

        result = sut.getIdentitySearch("foo")

        self.assertEqual("(|(cn=foo)(uid=foo))", result)
Exemple #4
0
    def testgetIdentitySearchFromInitArguments(self):
        """
        When data is provided at LDAPConfig initialization it is used
        as the backend data.
        """
        sut = config.LDAPConfig(identitySearch="(&(bar=thud)(quux=%(name)s))")

        result = sut.getIdentitySearch("foo")

        self.assertEqual("(&(bar=thud)(quux=foo))", result)
Exemple #5
0
def console_script():
    try:
        opts = MyOptions()
        opts.parseOptions()
    except usage.UsageError as ue:
        sys.stderr.write("{}: {}\n".format(sys.argv[0], ue))
        sys.exit(1)

    cfg = config.LDAPConfig(baseDN=opts["base"],
                            serviceLocationOverrides=opts["service-location"])
    main(cfg, opts["filter"])
Exemple #6
0
    def testGetIdentityBaseSectionSection(self):
        """
        When the configuration does not contains the
        `[authentication]` section it will return the configured Base DN.
        """
        reloadFromContent(self, b"[ldap]\n" b"basE=dc=test,dc=net\n")
        sut = config.LDAPConfig()

        result = sut.getIdentityBaseDN()

        self.assertEqual("dc=test,dc=net", result)
Exemple #7
0
    def testGetBaseDNOK(self):
        """
        It will return the base DN found in the configuration in the [ldap]
        section as `base` option.
        """
        reloadFromContent(self, b"[ldap]\nbase=dc=test,dc=net\n")
        sut = config.LDAPConfig()

        result = sut.getBaseDN()

        self.assertEqual("dc=test,dc=net", result)
Exemple #8
0
    def setUp(self):
        self.dir = self.mktemp()
        os.mkdir(self.dir)
        self.f1 = os.path.join(self.dir, 'one.cfg')
        writeFile(
            self.f1, """\
[authentication]
identity-search = (something=%(name)s)
""")
        self.cfg = config.loadConfig(configFiles=[self.f1], reload=True)
        self.config = config.LDAPConfig()
Exemple #9
0
    def testGetBaseDNNoSection(self):
        """
        It raise an exception when the the configuration has no [ldap]
        section.
        """
        reloadFromContent(self, b"[other]\nbase=dc=test,dc=net\n")
        sut = config.LDAPConfig()

        self.assertRaises(
            config.MissingBaseDNError,
            sut.getBaseDN,
        )
Exemple #10
0
    def testGetIdentitySearchNoOption(self):
        """
        When the configuration file contains the `authentication`
        section but without the identity search option,
        it will use a default expression.
        """
        reloadFromContent(self, b"[authentication]\nother_key=value")
        sut = config.LDAPConfig()

        result = sut.getIdentitySearch("foo")

        self.assertEqual("(|(cn=foo)(uid=foo))", result)
Exemple #11
0
    def testGetBaseDNNoOption(self):
        """
        It raise an exception when the the configuration has [ldap]
        section but no `base` option.
        """
        reloadFromContent(self, b'[ldap]\nbaseless=dc=test,dc=net\n')
        sut = config.LDAPConfig()

        self.assertRaises(
            config.MissingBaseDNError,
            sut.getBaseDN,
        )
Exemple #12
0
    def testCopy(self):
        """
        It returns a copy of the configuration.
        """
        sut = config.LDAPConfig()

        copied = sut.copy(identitySearch="(&(bar=baz)(quux=%(name)s))")

        self.assertIsInstance(copied, config.LDAPConfig)

        result = copied.getIdentitySearch("foo")

        self.assertEqual("(&(bar=baz)(quux=foo))", result)
Exemple #13
0
    def testGetIdentityBaseDNOK(self):
        """
        It will return the value found in the configuration in the
        [authentication] section as `identity-base` option.
        """
        reloadFromContent(
            self, b"[authentication]\n"
            b"identity-base=ou=users,dc=test,dc=net\n")
        sut = config.LDAPConfig()

        result = sut.getIdentityBaseDN()

        self.assertEqual("ou=users,dc=test,dc=net", result)
Exemple #14
0
    def testGetIdentitySearchOK(self):
        """
        It will use the value from to configuration for its return value.
        """
        reloadFromContent(
            self, """[authentication]
identity-search = (something=%(name)s)
""")
        sut = config.LDAPConfig()

        result = sut.getIdentitySearch('foo')

        self.assertEqual('(something=foo)', result)
Exemple #15
0
def console_script():
    from twisted.python import log

    log.startLogging(sys.stderr, setStdout=0)

    try:
        opts = MyOptions()
        opts.parseOptions()
    except usage.UsageError as ue:
        sys.stderr.write("{}: {}\n".format(sys.argv[0], ue))
        sys.exit(1)

    cfg = config.LDAPConfig(baseDN=opts["base"],
                            serviceLocationOverrides=opts["service-location"])
    main(cfg)
Exemple #16
0
def createServer(proto, *responses, **kw):
    def createClient(factory):
        factory.doStart()
        #TODO factory.startedConnecting(c)
        proto = factory.buildProtocol(addr=None)
        proto.connectionMade()

    cfg = config.loadConfig(configFiles=[], reload=True)
    overrides = kw.setdefault('serviceLocationOverrides', {})
    overrides.setdefault('', createClient)
    conf = config.LDAPConfig(**kw)
    server = proto(conf)
    server.protocol = lambda: LDAPClientTestDriver(*responses)
    server.transport = proto_helpers.StringTransport()
    server.connectionMade()
    return server
Exemple #17
0
 def test_cannot_connect_to_proxied_server_no_pending_requests(self):
     """
     When making a request and the proxy cannot connect to the proxied server, the
     connection is terminated.
     """
     conf = config.LDAPConfig(
         serviceLocationOverrides={'': ('localhost', 8080)})
     server = proxybase.ProxyBase(conf, reactor_=Clock())
     server.transport = proto_helpers.StringTransport()
     server.clientCreator = makeClientCreatorFactory(0)
     server.connectionMade()
     server.clientCreator = WontConnectClientCreator
     server.dataReceived(
         str(pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=4)))
     server.reactor.advance(1)
     self.assertEquals(server.transport.value(), "")
Exemple #18
0
    def testGetIdentityBaseNoOption(self):
        """
        When the configuration does not contains the `identity-base` option
        inside the `[authentication]` section it will return the configured
        Base DN.
        """
        reloadFromContent(
            self, b'[ldap]\n'
            b'BASE=dc=test,dc=net\n'
            b'[authentication]\n'
            b'no-identity-base=dont care\n')
        sut = config.LDAPConfig()

        result = sut.getIdentityBaseDN()

        self.assertEqual('dc=test,dc=net', result)
Exemple #19
0
 def test_cannot_connect_to_proxied_server_pending_requests(self):
     """
     When making a request and the proxy cannot connect to the proxied server,
     pending BIND and startTLS requests are replied to and the connection
     is closed.
     """
     conf = config.LDAPConfig(
         serviceLocationOverrides={'': ('localhost', 8080)})
     server = proxybase.ProxyBase(conf, reactor_=Clock())
     server.transport = proto_helpers.StringTransport()
     server.clientCreator = makeClientCreatorFactory(2)
     server.connectionMade()
     server.dataReceived(
         str(pureldap.LDAPMessage(pureldap.LDAPBindRequest(), id=4)))
     server.reactor.advance(2)
     self.assertEquals(
         server.transport.value(),
         str(
             pureldap.LDAPMessage(pureldap.LDAPBindResponse(resultCode=52),
                                  id=4)))
Exemple #20
0
 def http_cred_checker(self):
     # Check whether we've been configured with the attribute forming the
     # relative DN for identity entries within the directory and use the
     # appropriate LDAP credential checker object.
     rdn = self.vars.get("identityrdn")
     if rdn:
         return LDAPAuthedBindingChecker(
             LDAPAuthedConfig(','.join(self.vars.get("basedn")), {
                 ','.join(self.vars.get("basedn")):
                 (self.vars.get("ldaphost"),
                  int(self.vars.get("ldapport", 389)))
             },
                              identityRelativeDN=rdn))
     else:
         return checkers.LDAPBindingChecker(
             config.LDAPConfig(
                 ','.join(self.vars.get("basedn")), {
                     ','.join(self.vars.get("basedn")):
                     (self.vars.get("ldaphost"),
                      int(self.vars.get("ldapport", 389)))
                 }))
Exemple #21
0
def console_script():
    try:
        opts = MyOptions()
        opts.parseOptions()
    except usage.UsageError as ue:
        sys.stderr.write("{}: {}\n".format(sys.argv[0], ue))
        sys.exit(1)

    from twisted.python import log

    log.startLogging(sys.stderr, setStdout=0)

    cfg = config.LDAPConfig(serviceLocationOverrides=opts["service-location"])

    bindPassword = None
    if opts["bind-auth-fd"]:
        f = os.fdopen(opts["bind-auth-fd"])
        bindPassword = f.readline()
        assert bindPassword[-1] == "\n"
        bindPassword = bindPassword[:-1]
        f.close()

    main(cfg, opts["from"], opts["to"], opts["binddn"], bindPassword)
Exemple #22
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
Exemple #23
0
                                    reply)
            return d


if __name__ == "__main__":
    """
    Demonstration LDAP proxy; passes all requests to localhost:389.
    """
    from twisted.internet import reactor, protocol
    from twisted.python import log
    import sys

    log.startLogging(sys.stderr)
    from ldaptor import config

    factory = protocol.ServerFactory()
    cfg = config.LDAPConfig(serviceLocationOverrides={
        "": ("localhost", 389),
    })
    factory.protocol = lambda: ServiceBindingProxy(
        config=cfg,
        services=[
            "svc1",
            "svc2",
            "svc3",
        ],
        fallback=True,
    )
    reactor.listenTCP(10389, factory)
    reactor.run()
Exemple #24
0
 def testInitArg(self):
     conf = config.LDAPConfig(identitySearch='(&(bar=thud)(quux=%(name)s))')
     self.assertEquals(conf.getIdentitySearch('foo'),
                       '(&(bar=thud)(quux=foo))')
            d = self._whenConnected(self._startSearch,
                                    request, controls, reply)
            return d


if __name__ == '__main__':
    """
    Demonstration LDAP proxy; passes all requests to localhost:389.
    """
    from twisted.internet import reactor, protocol
    from twisted.python import log
    import sys

    log.startLogging(sys.stderr)
    from ldaptor import config

    factory = protocol.ServerFactory()
    cfg = config.LDAPConfig(serviceLocationOverrides={
        '': ('localhost', 389),
        })
    factory.protocol = lambda : ServiceBindingProxy(config=cfg,
                                                    services=[
        'svc1',
        'svc2',
        'svc3',
        ],
                                                    fallback=True,
                                                    )
    reactor.listenTCP(10389, factory)
    reactor.run()