Re: zkpython problem with settings acls.

2010-04-28 Thread Patrick Hunt

Here's a version that seems to work (doesn't fail).

The issue was that the sha1 digest should be run on the credentials, not 
just the password (so sha1(user:pass)).


Please open a JIRA for this (better docs on how to do digest auth, I'm 
sure there's a wealth of other issues that could also be created around 
this code, feel free to open other issues as you see fit).


Patrick

On 04/28/2010 02:50 PM, Kapil Thangavelu wrote:

Hi Folks,

I'm trying to use zookeeper via zkpython to set an acl on a node, and
then test that acl. I've configured a super user, and create a node with
an acl with the all permission and a digest scheme. However i find that
i end up not being able to touch the node with the credentials as per
the configured acl user, perhaps even more oddly i can't access the node
with the super user (passed in via system property on the cli via
Dzookeeper.DigestAuthenticationProvider.superDigest). Any attempt to
acces the node raises an exception
zookeeper.NoAuthException: not authenticated

i've attached a demonstration script that exhibits the problem. Is there
something i'm doing wrong here or is it an issue with zkpython?

thanks,

Kapil
import zookeeper
import threading
import hashlib
import base64

ZOO_OPEN_ACL_UNSAFE = {'scheme': 'world',
   'id': 'anyone',
   'perms': zookeeper.PERM_ALL}


class Connection(object):

def __init__(self, servers):
self.servers = servers
self.connected = False
self.timeout = 1
self.cv = threading.Condition()
self.handle = None

self.cv.acquire()
self.handle = zookeeper.init(
servers, self.connection_watcher, self.timeout)

self.cv.wait(self.timeout/1000)
if not self.connected:
raise RuntimeError("unable to connect %s" % servers)

def connection_watcher(self, handle, type, state, path):
print type, state, path
self.handle = handle
self.cv.acquire()
self.connected = True
self.cv.notifyAll()
self.cv.release()

def close(self):
return zookeeper.close(self.handle)

def authenticate(self, scheme, credentials):

def callback(handle, result):
self.cv.acquire()
assert self.handle == handle
self.cv.notify()
self.cv.release()

self.cv.acquire()
zookeeper.add_auth(
self.handle, scheme, credentials, callback)
self.cv.wait()

def create(self, path, data="", acl=[ZOO_OPEN_ACL_UNSAFE]):
return zookeeper.create(self.handle, path, data, acl,
zookeeper.EPHEMERAL)

def get_children(self, path):
return zookeeper.get_children(self.handle, path)


def identity(credentials):
user, password = credentials.split(":")
return "%s:%s" % (user,
   base64.b64encode(hashlib.sha1(credentials).digest()))


USER_ROOT = "super:test"
USER_TRUCKS = "trucks:foobar"


def main():
conn = Connection("127.0.0.1:2181")
conn.authenticate("digest", USER_ROOT)
conn.create("/cars")

children = conn.get_children("/cars")
assert not children

truck_acl = [
{'scheme': 'digest',
 'perms': zookeeper.PERM_ALL,
 'id': identity(USER_TRUCKS)}]

# create an ephemeral truck node with the given acl
conn.create("/trucks", acl=truck_acl)

# this also fails, but demonstrating with another conn for completeness.
#conn.get_children("/trucks")

conn2 = Connection("127.0.0.1:2181")
conn2.authenticate("digest", USER_TRUCKS)

try:
conn2.get_children("/trucks")
finally:
conn.close()
conn2.close()

if __name__ == '__main__':
main()


zkpython problem with settings acls.

2010-04-28 Thread Kapil Thangavelu
Hi Folks,

I'm trying to use zookeeper via zkpython to set an acl on a node, and then
test that acl. I've configured a super user, and create a node with an acl
with the all permission and a digest scheme. However i find that i end up
not being able to touch the node with the credentials as per the configured
acl user, perhaps even more oddly i can't access the node with the super
user (passed in via system property on the cli via
Dzookeeper.DigestAuthenticationProvider.superDigest). Any attempt to acces
the node raises an exception
zookeeper.NoAuthException: not authenticated

i've attached a demonstration script that exhibits the problem. Is there
something i'm doing wrong here or is it an issue with zkpython?

thanks,

Kapil
import zookeeper
import threading
import hashlib
import base64

ZOO_OPEN_ACL_UNSAFE = {'scheme': 'world',
   'id': 'anyone',
   'perms': zookeeper.PERM_ALL}


class Connection(object):

def __init__(self, servers):
self.servers = servers
self.connected = False
self.timeout = 1
self.cv = threading.Condition()
self.handle = None

self.cv.acquire()
self.handle = zookeeper.init(
servers, self.connection_watcher, self.timeout)

self.cv.wait(self.timeout/1000)
if not self.connected:
raise RuntimeError("unable to connect %s" % servers)

def connection_watcher(self, handle, type, state, path):
print type, state, path
self.handle = handle
self.cv.acquire()
self.connected = True
self.cv.notifyAll()
self.cv.release()

def close(self):
return zookeeper.close(self.handle)

def authenticate(self, scheme, credentials):

def callback(handle, result):
self.cv.acquire()
assert self.handle == handle
self.cv.notify()
self.cv.release()

self.cv.acquire()
zookeeper.add_auth(
self.handle, scheme, credentials, callback)
self.cv.wait()

def create(self, path, data="", acl=[ZOO_OPEN_ACL_UNSAFE]):
return zookeeper.create(self.handle, path, data, acl,
zookeeper.EPHEMERAL)

def get_children(self, path):
return zookeeper.get_children(self.handle, path)


def identity(credentials):
user, password = credentials.split(":")
return "%s:%s" % (user,
   base64.b64encode(hashlib.new("sha1", password).digest()))


USER_ROOT = "super:pass"
USER_TRUCKS = "trucks:foobar"


def main():
conn = Connection("127.0.0.1:2181")
conn.authenticate("digest", USER_ROOT)
conn.create("/cars")

children = conn.get_children("/cars")
assert not children

truck_acl = [
{'scheme': 'digest',
 'perms': zookeeper.PERM_ALL,
 'id': identity(USER_TRUCKS)},
{'scheme': 'digest',
 'perms': zookeeper.PERM_ALL,
 'id': identity(USER_ROOT)}]

# create an ephemeral truck node with the given acl
conn.create("/trucks", acl=truck_acl)

# this also fails, but demonstrating with another conn for completeness.
#conn.get_children("/trucks")

conn2 = Connection("127.0.0.1:2181")
conn2.authenticate("digest", USER_TRUCKS)

try:
conn2.get_children("/trucks")
finally:
conn.close()
conn2.close()

if __name__ == '__main__':
main()