def test_partial_auth(started_cluster, get_zk): auth_connection = get_zk() auth_connection.add_auth('digest', 'user1:password1') auth_connection.create("/test_partial_acl", b"data", acl=[make_acl("auth", "", read=False, write=True, create=True, delete=True, admin=True)]) auth_connection.set("/test_partial_acl", b"X") auth_connection.create("/test_partial_acl/subnode", b"X", acl=[make_acl("auth", "", read=False, write=True, create=True, delete=True, admin=True)]) with pytest.raises(NoAuthError): auth_connection.get("/test_partial_acl") with pytest.raises(NoAuthError): auth_connection.get_children("/test_partial_acl") # exists works without read perm assert auth_connection.exists("/test_partial_acl") is not None auth_connection.create("/test_partial_acl_create", b"data", acl=[make_acl("auth", "", read=True, write=True, create=False, delete=True, admin=True)]) with pytest.raises(NoAuthError): auth_connection.create("/test_partial_acl_create/subnode") auth_connection.create("/test_partial_acl_set", b"data", acl=[make_acl("auth", "", read=True, write=False, create=True, delete=True, admin=True)]) with pytest.raises(NoAuthError): auth_connection.set("/test_partial_acl_set", b"X") # not allowed to delete child node auth_connection.create("/test_partial_acl_delete", b"data", acl=[make_acl("auth", "", read=True, write=True, create=True, delete=False, admin=True)]) auth_connection.create("/test_partial_acl_delete/subnode") with pytest.raises(NoAuthError): auth_connection.delete("/test_partial_acl_delete/subnode")
def test_get_set_acl(started_cluster, get_zk): auth_connection = get_zk() auth_connection.add_auth('digest', 'username1:secret1') auth_connection.add_auth('digest', 'username2:secret2') auth_connection.create("/test_set_get_acl", b"data", acl=[make_acl("auth", "", all=True)]) acls, stat = auth_connection.get_acls("/test_set_get_acl") assert stat.aversion == 0 assert len(acls) == 2 for acl in acls: assert acl.acl_list == ['ALL'] assert acl.id.scheme == 'digest' assert acl.perms == 31 assert acl.id.id in ('username1:eGncMdBgOfGS/TCojt51xWsWv/Y=', 'username2:qgSSumukVlhftkVycylbHNvxhFU=') other_auth_connection = get_zk() other_auth_connection.add_auth('digest', 'username1:secret1') other_auth_connection.add_auth('digest', 'username3:secret3') other_auth_connection.set_acls("/test_set_get_acl", acls=[make_acl("auth", "", read=True, write=False, create=True, delete=True, admin=True)]) acls, stat = other_auth_connection.get_acls("/test_set_get_acl") assert stat.aversion == 1 assert len(acls) == 2 for acl in acls: assert acl.acl_list == ['READ', 'CREATE', 'DELETE', 'ADMIN'] assert acl.id.scheme == 'digest' assert acl.perms == 29 assert acl.id.id in ('username1:eGncMdBgOfGS/TCojt51xWsWv/Y=', 'username3:CvWITOxxTwk+u6S5PoGlQ4hNoWI=') with pytest.raises(KazooException): other_auth_connection.set_acls("/test_set_get_acl", acls=[make_acl("auth", "", all=True)], version=0)
def test_auth_snapshot(started_cluster): connection = get_fake_zk() connection.add_auth("digest", "user1:password1") connection.create( "/test_snapshot_acl", b"data", acl=[make_acl("auth", "", all=True)] ) connection1 = get_fake_zk() connection1.add_auth("digest", "user2:password2") connection1.create( "/test_snapshot_acl1", b"data", acl=[make_acl("auth", "", all=True)] ) connection2 = get_fake_zk() connection2.create("/test_snapshot_acl2", b"data") for i in range(100): connection.create( f"/test_snapshot_acl/path{i}", b"data", acl=[make_acl("auth", "", all=True)] ) node.restart_clickhouse() connection = get_fake_zk() with pytest.raises(NoAuthError): connection.get("/test_snapshot_acl") connection.add_auth("digest", "user1:password1") assert connection.get("/test_snapshot_acl")[0] == b"data" with pytest.raises(NoAuthError): connection.get("/test_snapshot_acl1") assert connection.get("/test_snapshot_acl2")[0] == b"data" for i in range(100): assert connection.get(f"/test_snapshot_acl/path{i}")[0] == b"data" connection1 = get_fake_zk() connection1.add_auth("digest", "user2:password2") assert connection1.get("/test_snapshot_acl1")[0] == b"data" with pytest.raises(NoAuthError): connection1.get("/test_snapshot_acl") connection2 = get_fake_zk() assert connection2.get("/test_snapshot_acl2")[0] == b"data" with pytest.raises(NoAuthError): connection2.get("/test_snapshot_acl") with pytest.raises(NoAuthError): connection2.get("/test_snapshot_acl1")
def test_digest_auth_basic(started_cluster, get_zk): auth_connection = get_zk() auth_connection.add_auth('digest', 'user1:password1') auth_connection.create("/test_no_acl", b"") auth_connection.create("/test_all_acl", b"data", acl=[make_acl("auth", "", all=True)]) # Consistent with zookeeper, accept generated digest auth_connection.create("/test_all_digest_acl", b"dataX", acl=[make_acl("digest", "user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=", all=True)]) assert auth_connection.get("/test_all_acl")[0] == b"data" assert auth_connection.get("/test_all_digest_acl")[0] == b"dataX" no_auth_connection = get_zk() no_auth_connection.set("/test_no_acl", b"hello") # no ACL, so cannot access these nodes assert no_auth_connection.get("/test_no_acl")[0] == b"hello" with pytest.raises(NoAuthError): no_auth_connection.set("/test_all_acl", b"hello") with pytest.raises(NoAuthError): no_auth_connection.get("/test_all_acl") with pytest.raises(NoAuthError): no_auth_connection.get("/test_all_digest_acl") # still doesn't help with pytest.raises(AuthFailedError): no_auth_connection.add_auth("world", "anyone") # session became broken, reconnect no_auth_connection = get_zk() # wrong auth no_auth_connection.add_auth('digest', 'user2:password2') with pytest.raises(NoAuthError): no_auth_connection.set("/test_all_acl", b"hello") with pytest.raises(NoAuthError): no_auth_connection.set("/test_all_acl", b"hello") with pytest.raises(NoAuthError): no_auth_connection.get("/test_all_acl") with pytest.raises(NoAuthError): no_auth_connection.get("/test_all_digest_acl") # but can access some non restricted nodes no_auth_connection.create("/some_allowed_node", b"data") # auth added, go on no_auth_connection.add_auth('digest', 'user1:password1') for path in ["/test_no_acl", "/test_all_acl"]: no_auth_connection.set(path, b"auth_added") assert no_auth_connection.get(path)[0] == b"auth_added"
def test_acls(started_cluster, create_snapshots): restart_and_clear_zookeeper() genuine_connection = get_genuine_zk() genuine_connection.add_auth('digest', 'user1:password1') genuine_connection.add_auth('digest', 'user2:password2') genuine_connection.add_auth('digest', 'user3:password3') genuine_connection.create("/test_multi_all_acl", b"data", acl=[make_acl("auth", "", all=True)]) other_connection = get_genuine_zk() other_connection.add_auth('digest', 'user1:password1') other_connection.set("/test_multi_all_acl", b"X") assert other_connection.get("/test_multi_all_acl")[0] == b"X" yet_other_auth_connection = get_genuine_zk() yet_other_auth_connection.add_auth('digest', 'user2:password2') yet_other_auth_connection.set("/test_multi_all_acl", b"Y") genuine_connection.add_auth('digest', 'user3:password3') # just to check that we are able to deserialize it genuine_connection.set_acls("/test_multi_all_acl", acls=[make_acl("auth", "", read=True, write=False, create=True, delete=True, admin=True)]) no_auth_connection = get_genuine_zk() with pytest.raises(Exception): no_auth_connection.set("/test_multi_all_acl", b"Z") copy_zookeeper_data(create_snapshots) genuine_connection = get_genuine_zk() genuine_connection.add_auth('digest', 'user1:password1') genuine_connection.add_auth('digest', 'user2:password2') genuine_connection.add_auth('digest', 'user3:password3') fake_connection = get_fake_zk() fake_connection.add_auth('digest', 'user1:password1') fake_connection.add_auth('digest', 'user2:password2') fake_connection.add_auth('digest', 'user3:password3') compare_states(genuine_connection, fake_connection) for connection in [genuine_connection, fake_connection]: acls, stat = connection.get_acls("/test_multi_all_acl") assert stat.aversion == 1 assert len(acls) == 3 for acl in acls: assert acl.acl_list == ['READ', 'CREATE', 'DELETE', 'ADMIN'] assert acl.id.scheme == 'digest' assert acl.perms == 29 assert acl.id.id in ('user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=', 'user2:lo/iTtNMP+gEZlpUNaCqLYO3i5U=', 'user3:wr5Y0kEs9nFX3bKrTMKxrlcFeWo=')
def get_zk(): global _zk if _zk is None: _zk = KazooClient( app.config['ZK_CONNECTION_STRING'], default_acl=( # grants read permissions to anyone. make_acl('world', 'anyone', read=True), # grants all permissions to the creator of the node. make_acl('auth', '', all=True) ) ) _zk.start() _zk.add_auth('digest', jones_credential) _zk.DataWatch('/services', func=ensure_root) return _zk
def test_connect_sasl_auth(self): from kazoo.security import make_acl username = "******" password = "******" acl = make_acl("sasl", credential=username, all=True) client = self._get_client( sasl_options={ "mechanism": "DIGEST-MD5", "username": username, "password": password, }) client.start() try: client.create("/1", acl=(acl, )) # give ZK a chance to copy data to other node time.sleep(0.1) with pytest.raises(NoAuthError): self.client.get("/1") finally: client.delete("/1") client.stop() client.close()
def test_connect_gssapi_auth(self): from kazoo.security import make_acl # Ensure we have a client ticket subprocess.check_call([ "kinit", "-kt", os.path.expandvars("${KRB5_TEST_ENV}/client.keytab"), "client", ]) acl = make_acl("sasl", credential="*****@*****.**", all=True) client = self._get_client(sasl_options={"mechanism": "GSSAPI"}) client.start() try: client.create("/1", acl=(acl, )) # give ZK a chance to copy data to other node time.sleep(0.1) with pytest.raises(NoAuthError): self.client.get("/1") finally: client.delete("/1") client.stop() client.close()
def test_connect_sasl_auth(self): from kazoo.security import make_acl if TRAVIS_ZK_VERSION: version = TRAVIS_ZK_VERSION else: version = self.client.server_version() if not version or version < (3, 4): raise SkipTest("Must use Zookeeper 3.4 or above") try: import puresasl # NOQA except ImportError: raise SkipTest('PureSASL not available.') username = "******" password = "******" acl = make_acl('sasl', credential=username, all=True) client = self._get_client( sasl_options={'mechanism': 'DIGEST-MD5', 'username': username, 'password': password} ) client.start() try: client.create('/1', acl=(acl,)) # give ZK a chance to copy data to other node time.sleep(0.1) self.assertRaises(NoAuthError, self.client.get, "/1") finally: client.delete('/1') client.stop() client.close()
def test_connect_sasl_auth(self): from kazoo.security import make_acl if TRAVIS_ZK_VERSION: version = TRAVIS_ZK_VERSION else: version = self.client.server_version() if not version or version < (3, 4): raise SkipTest("Must use Zookeeper 3.4 or above") username = "******" password = "******" sasl_auth = "%s:%s" % (username, password) acl = make_acl('sasl', credential=username, all=True) client = self._get_client(auth_data=[('sasl', sasl_auth)]) client.start() try: client.create('/1', acl=(acl,)) # give ZK a chance to copy data to other node time.sleep(0.1) self.assertRaises(NoAuthError, self.client.get, "/1") finally: client.delete('/1') client.stop() client.close()
def test_connect_sasl_auth(self): from kazoo.security import make_acl if TRAVIS_ZK_VERSION: version = TRAVIS_ZK_VERSION else: version = self.client.server_version() if not version or version < (3, 4): raise SkipTest("Must use Zookeeper 3.4 or above") username = "******" password = "******" sasl_auth = "%s:%s" % (username, password) acl = make_acl('sasl', credential=username, all=True) client = self._get_client(auth_data=[('sasl', sasl_auth)]) client.start() try: client.create('/1', acl=(acl, )) # give ZK a chance to copy data to other node time.sleep(0.1) self.assertRaises(NoAuthError, self.client.get, "/1") finally: client.delete('/1') client.stop() client.close()
def extract_acl(cls, acl): """ parse an individual ACL (i.e.: world:anyone:cdrwa) """ try: scheme, rest = acl.split(":", 1) credential = ":".join(rest.split(":")[0:-1]) cdrwa = rest.split(":")[-1] except ValueError: raise cls.BadACL("Bad ACL: %s. Format is scheme:id:perms" % (acl)) if scheme not in cls.valid_schemes: raise cls.BadACL("Invalid scheme: %s" % (acl)) create = True if "c" in cdrwa else False read = True if "r" in cdrwa else False write = True if "w" in cdrwa else False delete = True if "d" in cdrwa else False admin = True if "a" in cdrwa else False if scheme == "username_password": try: username, password = credential.split(":", 1) except ValueError: raise cls.BadACL("Bad ACL: %s. Format is scheme:id:perms" % (acl)) return make_digest_acl(username, password, read, write, create, delete, admin) else: return make_acl(scheme, credential, read, write, create, delete, admin)
def process(self, opt, arg, cli): path = arg[1] # FIXME duplicate code acl_info = arg[2].split(':') if len(acl_info) == 4: scheme, username, password, perm = acl_info id = f'{username}:{password}' elif len(acl_info) == 3: scheme, id, perm = acl_info scheme = scheme.lower() perm = perm.lower() if opt.unencrypted and scheme == 'digest': username, password = id.split(":") id = make_digest_acl_credential(username, password) try: perm_kw = { 'all': perm == 'all', 'read': 'r' in perm, 'write': 'w' in perm, 'create': 'c' in perm, 'delete': 'd' in perm, 'admin': 'a' in perm, } cli.client.set_acls(path, [make_acl(scheme, id, **perm_kw)], opt.version) except NoAuthError as e: raise ValueError(f"Authentication is not valid, '{path}'") except NoNodeError as e: raise ValueError(f"Path '{path}' not exists") except Exception as e: import traceback raise ValueError(f"Illegal arguments! {traceback.format_exc()}") return PlainViewModel(content='setAcl successfully', color='info')
def str2acl(s, hidden=False): create = False delete = False read = False write = False admin = False if re.match(".+:.+:.+", s): permissions = re.sub(r"(.*):([^:]*)", r"\2", s) s = re.sub(r"(.*):([^:]*)", r"\1", s) scheme, credential = re.split(":", s, 1) if re.search("c", permissions): create = True if re.search("d", permissions): delete = True if re.search("r", permissions) and not hidden: read = True if re.search("w", permissions): write = True if re.search("a", permissions) and not hidden: admin = True if create or delete or read or write or admin: return make_acl(scheme, credential, create=create, delete=delete, read=read, write=write, admin=admin) else: return None else: print >> sys.stderr, "Warning: invalid ACL: %s" % s return None
def make_acl(cls, scheme, credential, read=False, write=False, create=False, delete=False, admin=False, all=False): """Given a scheme and credential, return an :class:`kazoo.security.ACL` object appropriate for use with ZKClient. :param scheme: The scheme to use, i.e. ``digest``. :param credential: A colon separated username, password. The password should be hashed with the ``scheme`` specified. The :meth:`make_digest_acl_credential` method will create and return a credential appropriate for use with the ``digest`` scheme. :param write: Write permission. :type write: bool :param create: Create permission. :type create: bool :param delete: Delete permission. :type delete: bool :param admin: Admin permission. :type admin: bool :param all: All permissions. :type all: bool :rtype: :class:`kazoo.security.ACL` """ from kazoo.security import make_acl return make_acl(scheme, credential, read=read, write=write, create=create, delete=delete, admin=admin, all=all)
def get_acl(scheme, credential, acl_access): acl_access = get_acl_access_table(acl_access) return make_acl(scheme, credential, read=acl_access['read'], write=acl_access['write'], create=acl_access['create'], delete=acl_access['delete'], admin=acl_access['admin'])
def make_acl(self): if self.check_acl(): return make_acl(self.scheme, self.credential, read=self.read, write=self.write, create=self.create, delete=self.delete, all=self.all) else: return None
def test_remove_acl(started_cluster, get_zk): auth_connection = get_zk() auth_connection.add_auth('digest', 'user1:password1') # Consistent with zookeeper, accept generated digest auth_connection.create("/test_remove_acl1", b"dataX", acl=[make_acl("digest", "user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=", read=True, write=False, create=False, delete=False, admin=False)]) auth_connection.create("/test_remove_acl2", b"dataX", acl=[make_acl("digest", "user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=", read=True, write=True, create=False, delete=False, admin=False)]) auth_connection.create("/test_remove_acl3", b"dataX", acl=[make_acl("digest", "user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=", all=True)]) auth_connection.delete("/test_remove_acl2") auth_connection.create("/test_remove_acl4", b"dataX", acl=[make_acl("digest", "user1:XDkd2dsEuhc9ImU3q8pa8UOdtpI=", read=True, write=True, create=True, delete=False, admin=False)]) acls, stat = auth_connection.get_acls("/test_remove_acl3") assert stat.aversion == 0 assert len(acls) == 1 for acl in acls: assert acl.acl_list == ['ALL'] assert acl.perms == 31
def __init__(self, config): super(ZooKeeper, self).__init__(config) hosts = config.get('hosts', []) if isinstance(hosts, list): hosts = ','.join(hosts) mapping = { 'use_ssl': 'use_ssl', 'verify': 'verify_certs', 'cacert': 'ca', 'cert': 'certfile', 'key': 'keyfile', 'key_password': '******' } kwargs = {v: config[k] for k, v in mapping.items() if k in config} if 'set_acls' in config: kwargs['default_acl'] = [] for principal, permissions in config['set_acls'].items(): normalizedPermissions = [p.upper() for p in permissions] kwargs['default_acl'].append( make_acl(scheme='x509', credential=principal, read='READ' in normalizedPermissions, write='WRITE' in normalizedPermissions, create='CREATE' in normalizedPermissions, delete='DELETE' in normalizedPermissions, admin='ADMIN' in normalizedPermissions, all='ALL' in normalizedPermissions)) self._client = PatroniKazooClient( hosts, handler=PatroniSequentialThreadingHandler(config['retry_timeout']), timeout=config['ttl'], connection_retry=KazooRetry(max_delay=1, max_tries=-1, sleep_func=time.sleep), command_retry=KazooRetry(max_delay=1, max_tries=-1, deadline=config['retry_timeout'], sleep_func=time.sleep), **kwargs) self._client.add_listener(self.session_listener) self._fetch_cluster = True self._fetch_status = True self.__last_member_data = None self._orig_kazoo_connect = self._client._connection._connect self._client._connection._connect = self._kazoo_connect self._client.start()
def parse_acl(s): parts = s.split(':') if len(parts) < 3: raise RuntimeError("invalid ACL spec: %s" % s) scheme, cred, perms = parts[0], parts[1:-1], parts[-1] return make_acl(scheme, ':'.join(cred), read='r' in perms, write='w' in perms, create='c' in perms, delete='d' in perms, admin='a' in perms, all='*' in perms)
def test_super_auth(started_cluster): auth_connection = get_fake_zk() auth_connection.add_auth('digest', 'user1:password1') auth_connection.create("/test_super_no_acl", b"") auth_connection.create("/test_super_all_acl", b"data", acl=[make_acl("auth", "", all=True)]) super_connection = get_fake_zk() super_connection.add_auth('digest', 'super:admin') for path in ["/test_super_no_acl", "/test_super_all_acl"]: super_connection.set(path, b"value") assert super_connection.get(path)[0] == b"value"
def to_acl(access): cred = access.credential().get() if access.scheme().get() == 'digest': cred_parts = access.credential().get().split(':') if len(cred_parts) != 2: app.error('Digest credential should be of the form <user>:<password>') cred = make_digest_acl_credential(cred_parts[0], cred_parts[1]) return make_acl(access.scheme().get(), cred, read=access.permissions().read().get(), write=access.permissions().write().get(), create=access.permissions().create().get(), delete=access.permissions().delete().get(), admin=access.permissions().admin().get())
def __init__(self, processor, handler, config): self._logger = logging.getLogger(__name__) self._section_name = utils.get_module(__name__) self._server = None self._service_name = config.get(self._section_name, "service", required=True) self._port = config.getint(self._section_name, "port", required=True) self._zk_connect_str = config.get(self._section_name, "zk_connect_str", required=True) self._auth_user = config.get(self._section_name, "auth_user", required=True) self._auth_password = config.get(self._section_name, "auth_password", required=True) self._monitor = config.getboolean(self._section_name, "monitor", default=settings.SERVICE_MONITOR) self._c_module_serialize = config.getboolean(self._section_name, "c_module_serialize", default=settings.USE_C_MODULE_SERIALIZE) self._server_name = config.get(self._section_name, "name") self._owner = config.get(self._section_name, "owner") hosts = "%s/%s" % (self._zk_connect_str, settings.DEFAULT_ZK_NAMESPACE_ROOT) self._server_path = "%s/%s" % (self._service_name, settings.DEFAULT_ZK_NAMESPACE_SERVERS) self._statistic_path = "%s/%s/%s" % (self._service_name, settings.DEFAULT_ZK_NAMESPACE_STATISTICS, settings.DEFAULT_ZK_NAMESPACE_SERVERS) # create zk acl self._acls = [] self._acls.append(make_digest_acl(self._auth_user, self._auth_password, all=True)) self._acls.append(make_acl("world", "anyone", read=True)) # create zk_client self._zkclient = HARpcZKClientManager.make(hosts, config, "server") self._zkclient.add_auth("digest", "%s:%s" % (self._auth_user, self._auth_password)) # create zkpath if not self._zkclient.exists(self._service_name): self._zkclient.create(self._service_name, makepath=True) if not self._zkclient.exists(self._server_path): self._zkclient.create(self._server_path, acl=self._acls) if not self._zkclient.exists(self._statistic_path): self._zkclient.create(self._statistic_path, makepath=True) self.transport = TSocket.TServerSocket(port=self._port) self.tfactory = TTransport.TBufferedTransportFactory() if self._monitor: self._collector = StatisticsCollector(self._zkclient, config, is_server=True) self._processor = self._statistics_wrapper(processor)(handler) else: self._processor = processor(handler) if self._c_module_serialize: self.pfactory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory() else: self.pfactory = TBinaryProtocol.TBinaryProtocolFactory()
def to_acl(access): cred = access.credential().get() if access.scheme().get() == 'digest': cred_parts = access.credential().get().split(':') if len(cred_parts) != 2: app.error( 'Digest credential should be of the form <user>:<password>') cred = make_digest_acl_credential(cred_parts[0], cred_parts[1]) return make_acl(access.scheme().get(), cred, read=access.permissions().read().get(), write=access.permissions().write().get(), create=access.permissions().create().get(), delete=access.permissions().delete().get(), admin=access.permissions().admin().get())
def test_parse_kazoo_acl(self): inp = ( security.make_acl('world', 'anyone', all=True), security.make_digest_acl('foo', 'bar', create=True, read=True), security.make_digest_acl('xp', '123', all=True), ) expected = (('world', 'anyone', 'cdrwa'), ('digest', 'foo', 'rc'), ('digest', 'xp', 'cdrwa')) dd(inp) rst = zkutil.parse_kazoo_acl(inp) dd(rst) self.assertEqual(expected, tuple(rst))
def test_parse_kazoo_acl(self): inp = (security.make_acl('world', 'anyone', all=True), security.make_digest_acl('foo', 'bar', create=True, read=True), security.make_digest_acl('xp', '123', all=True), ) expected = (('world', 'anyone', 'cdrwa'), ('digest', 'foo', 'rc'), ('digest', 'xp', 'cdrwa')) dd(inp) rst = zkutil.parse_kazoo_acl(inp) dd(rst) self.assertEqual(expected, tuple(rst))
def __init__(self): self.zk_hosts = settings.ZK_HOSTS self.zk_root = settings.ZK_ROOT self.zk_timeout = settings.ZK_TIMEOUT self.zk_servers = settings.ZK_SERVERS self.zk_clients = settings.ZK_CLIENTS self.zk_configs = settings.ZK_CONFIGS self.zk_statistics = settings.ZK_STATISTICS self.zk_username = settings.ZK_USERNAME self.zk_password = settings.ZK_PASSWORD self.zk_flush = time.time() self.lock = threading.Lock() self.resource = {} self.zk_harpc_acl = make_digest_acl(username=self.zk_username, password=self.zk_password, all=True) self.zk_anyone_acl = make_acl(scheme='world', credential='anyone', read=True)
def add_acl(self, path, permissions, scheme, id): perms = get_permissions(permissions) if scheme == "digest": username, password = id.split(":") acl = make_digest_acl(username, password, **perms) else: acl = make_acl(scheme, id, **perms) current_acls = self.get_acl(path) current_acls.append(acl) try: self._zookeeper.set_acls(path, current_acls) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except InvalidACLError as exc: raise ZooKeeperException("Invalid ACL format: {}".format(str(exc))) except NoAuthError: raise ZooKeeperException("No access to add acl on node: {}".format(path))
def test_digest_auth_multiple(started_cluster, get_zk): auth_connection = get_zk() auth_connection.add_auth('digest', 'user1:password1') auth_connection.add_auth('digest', 'user2:password2') auth_connection.add_auth('digest', 'user3:password3') auth_connection.create("/test_multi_all_acl", b"data", acl=[make_acl("auth", "", all=True)]) one_auth_connection = get_zk() one_auth_connection.add_auth('digest', 'user1:password1') one_auth_connection.set("/test_multi_all_acl", b"X") assert one_auth_connection.get("/test_multi_all_acl")[0] == b"X" other_auth_connection = get_zk() other_auth_connection.add_auth('digest', 'user2:password2') other_auth_connection.set("/test_multi_all_acl", b"Y") assert other_auth_connection.get("/test_multi_all_acl")[0] == b"Y"
def test_connect_sasl_auth(self): from kazoo.security import make_acl username = "******" password = "******" acl = make_acl("sasl", credential=username, all=True) sasl_auth = "%s:%s" % (username, password) client = self._get_client(auth_data=[("sasl", sasl_auth)]) client.start() try: client.create("/1", acl=(acl, )) # give ZK a chance to copy data to other node time.sleep(0.1) self.assertRaises(NoAuthError, self.client.get, "/1") finally: client.delete("/1") client.stop() client.close()
from flask import Flask from flask import request from flask import Response from flask_cors import CORS from kazoo.client import KazooClient from kazoo.security import make_digest_acl, make_acl, make_digest_acl_credential app = Flask(__name__) cors = CORS(app, origin='*') ZOO_HOSTS = '127.0.0.1:2181' client = KazooClient(hosts=ZOO_HOSTS) client.start() ROOT = '/config' anonymous_acl = make_acl('world', 'anyone', read=True) def make_response(success=True, data=None, code=0, msg=''): resp_json = { 'success': success, 'code': code, 'data': data, 'msg': msg } return Response(json.dumps(resp_json)) def get_credential(): username = request.json['auth']['username'] password = request.json['auth']['password']
def _makeOne(self, *args, **kwargs): from kazoo.security import make_acl return make_acl(*args, **kwargs)
def __init__(self, processor, handler, config): self._logger = logging.getLogger(__name__) self._section_name = utils.get_module(__name__) self._server = None self._service_name = config.get(self._section_name, "service", required=True) self._port = config.getint(self._section_name, "port", required=True) self._zk_connect_str = config.get(self._section_name, "zk_connect_str", required=True) self._auth_user = config.get(self._section_name, "auth_user", required=True) self._auth_password = config.get(self._section_name, "auth_password", required=True) self._monitor = config.getboolean(self._section_name, "monitor", default=settings.SERVICE_MONITOR) self._c_module_serialize = config.getboolean( self._section_name, "c_module_serialize", default=settings.USE_C_MODULE_SERIALIZE) self._server_name = config.get(self._section_name, "name") self._owner = config.get(self._section_name, "owner") hosts = "%s/%s" % (self._zk_connect_str, settings.DEFAULT_ZK_NAMESPACE_ROOT) self._server_path = "%s/%s" % (self._service_name, settings.DEFAULT_ZK_NAMESPACE_SERVERS) self._statistic_path = "%s/%s/%s" % ( self._service_name, settings.DEFAULT_ZK_NAMESPACE_STATISTICS, settings.DEFAULT_ZK_NAMESPACE_SERVERS) # create zk acl self._acls = [] self._acls.append( make_digest_acl(self._auth_user, self._auth_password, all=True)) self._acls.append(make_acl("world", "anyone", read=True)) # create zk_client self._zkclient = HARpcZKClientManager.make(hosts, config, "server") self._zkclient.add_auth( "digest", "%s:%s" % (self._auth_user, self._auth_password)) # create zkpath if not self._zkclient.exists(self._service_name): self._zkclient.create(self._service_name, makepath=True) if not self._zkclient.exists(self._server_path): self._zkclient.create(self._server_path, acl=self._acls) if not self._zkclient.exists(self._statistic_path): self._zkclient.create(self._statistic_path, makepath=True) self.transport = TSocket.TServerSocket(port=self._port) self.tfactory = TTransport.TBufferedTransportFactory() if self._monitor: self._collector = StatisticsCollector(self._zkclient, config, is_server=True) self._processor = self._statistics_wrapper(processor)(handler) else: self._processor = processor(handler) if self._c_module_serialize: self.pfactory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory() else: self.pfactory = TBinaryProtocol.TBinaryProtocolFactory()
def test_bad_auth(started_cluster): auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): auth_connection.add_auth("world", "anyone") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 1") auth_connection.add_auth("adssagf", "user1:password1") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 2") auth_connection.add_auth("digest", "") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 3") auth_connection.add_auth("", "user1:password1") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 4") auth_connection.add_auth("digest", "user1") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 5") auth_connection.add_auth("digest", "user1:password:otherpassword") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 6") auth_connection.add_auth("auth", "user1:password") auth_connection = get_fake_zk() with pytest.raises(AuthFailedError): print("Sending 7") auth_connection.add_auth("world", "somebody") auth_connection = get_fake_zk() with pytest.raises(InvalidACLError): print("Sending 8") auth_connection.create( "/test_bad_acl", b"data", acl=[ make_acl( "dasd", "", read=True, write=False, create=True, delete=True, admin=True, ) ], ) auth_connection = get_fake_zk() with pytest.raises(InvalidACLError): print("Sending 9") auth_connection.create( "/test_bad_acl", b"data", acl=[ make_acl( "digest", "", read=True, write=False, create=True, delete=True, admin=True, ) ], ) auth_connection = get_fake_zk() with pytest.raises(InvalidACLError): print("Sending 10") auth_connection.create( "/test_bad_acl", b"data", acl=[ make_acl( "", "", read=True, write=False, create=True, delete=True, admin=True ) ], ) auth_connection = get_fake_zk() with pytest.raises(InvalidACLError): print("Sending 11") auth_connection.create( "/test_bad_acl", b"data", acl=[ make_acl( "digest", "dsdasda", read=True, write=False, create=True, delete=True, admin=True, ) ], ) auth_connection = get_fake_zk() with pytest.raises(InvalidACLError): print("Sending 12") auth_connection.create( "/test_bad_acl", b"data", acl=[ make_acl( "digest", "dsad:DSAa:d", read=True, write=False, create=True, delete=True, admin=True, ) ], )
app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) app.config.from_object(jonesconfig) app.config.from_envvar('JONES_SETTINGS', silent=True) if 'SENTRY_DSN' in app.config: sentry = Sentry(app) jones_credential = make_digest_acl_credential('Jones', app.config['ZK_DIGEST_PASSWORD']) zk = KazooClient( app.config['ZK_CONNECTION_STRING'], default_acl=( # grants read permissions to anyone. make_acl('world', 'anyone', read=True), # grants all permissions to the creator of the node. make_acl('auth', '', all=True))) zk.start() zk.add_auth('digest', jones_credential) @zk.DataWatch('/services') def ensure_root(data, stat): if not data: zk.ensure_path('/services') def request_wants(t): types = ['text/plain', 'text/html', 'application/json'] assert t in types
from kazoo.client import KazooClient from kazoo.security import ACL, make_acl client = KazooClient(hosts='127.0.0.1:2181') try: client.start() # world auth digest ip scheme = '' # anyone # addauth digest user:pwd # username:base64 # ID = '' # r = client.add_auth('digest', 'xjj:123456') # print(r, type(r)) r = client.set_acls('/a', [make_acl('auth', 'xyj:123123', all=True)]) # r = client.get_acls('/a') print(r, type(r), len(r)) finally: client.stop()
import random import signal import sys import time from docopt import docopt from kazoo import security import core params = docopt(__doc__) if not params["--host"]: params["--host"] = "127.0.0.1:2181" zk = core.connect(hosts=params["--host"]) # # Change / to be readable by everyone, and writeable only by localhost. # acls = [ security.make_acl( "world", "anyone", read=True, ), security.make_acl("ip", "127.0.0.1", all=True), ] zk.set_acls("/", acls) logging.info("/ has been changed to read-only for everyone but localhost")
app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) app.config.from_object(jonesconfig) app.config.from_envvar('JONES_SETTINGS', silent=True) if 'SENTRY_DSN' in app.config: sentry = Sentry(app) jones_credential = make_digest_acl_credential( 'Jones', app.config['ZK_DIGEST_PASSWORD'] ) zk = KazooClient( app.config['ZK_CONNECTION_STRING'], default_acl=( # grants read permissions to anyone. make_acl('world', 'anyone', read=True), # grants all permissions to the creator of the node. make_acl('auth', '', all=True) ) ) zk.connect() zk.add_auth('digest', jones_credential) zk.ensure_path('/services') def request_wants(t): types = ['text/plain', 'text/html', 'application/json'] assert t in types best = request.accept_mimetypes \ .best_match(types) return best == t
# # All our nodes that we create # all_nodes = [] # # Connect to Zookeeper and create some nodes of varying permissions # zk = core.connect(hosts=params["--host"]) # # Create a node that we can read # acls = [security.make_acl( "ip", "127.0.0.1", read=True, )] (key_full, key_local) = core.createKey(zk, acls) all_nodes.append(key_full) core.watch_node(zk, key_full, watch_node_worker) #print zk.get_acls(key_full) zk.get(key_full) # # Now create a node that is world:anyone with no permissions and see what happens # acls = [security.make_acl("world", "anyone", all=False)] (key_full, key_local) = core.createKey(zk, acls) all_nodes.append(key_full) try: