[Python-Dev] Capabilities (original) (raw)
Ka-Ping Yee ping@zesty.ca
Sat, 29 Mar 2003 18:31:18 -0600 (CST)
- Previous message: [Python-Dev] Capabilities
- Next message: [Python-Dev] Capabilities
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Mon, 10 Mar 2003, Jim Fulton wrote:
> Maybe every Python object should have a flag which > can be set to prevent introspection -- like the current > restricted execution mechanism, but on a per-object > basis. Then any object could be used as a capability.
Yes, but not a very useful one. For example, given a file, you often want to create a "file read" capability which is an object that allows reading the file but not writing the file. Just preventing introspection isn't enough.
All right. Let me provide an example; maybe this can help ground the discussion a bit. We seem to be doing a lot of dancing around the issue of what a capability is.
In my view, it's a red herring to discuss whether or not a particular object "is a capability" or not. It's like asking whether something is an "object". Capabilities are a discipline under which objects are used -- it's better to think of them as a technique or a style of programming.
What is at issue here (IMHO) is "how might Python change to facilitate this style of programming?"
(The analogy with object-oriented programming holds here also. Even if Python didn't have a "class" keyword, you could still program in an object-oriented style. In fact, the C implementation of Python is clearly object-oriented, even though C has no features specifically designed for OOP. But adding "class" made it a lot easier to do a particular style of object-oriented programming in Python. Unfortunately, the particular style encouraged by Python's "class" keyword doesn't work so well for capability-style programming, because all instance state is public. But Python's "class" is not the only way to do object-oriented programming -- see below.)
Okay, at last to the example, then.
Here is one way to program in a capability style using today's Python, relying on no changes to the interpreter. This example defines a "class" called DirectoryReader that provides read-only access to only a particular subtree of the filesystem.
import os
class Namespace:
def __init__(self, *args, **kw):
for value in args:
self.__dict__[value.__name__] = value
for name, value in kw.items():
self.__dict__[name] = value
class ReadOnly(Namespace):
def __setattr__(self, name, value):
raise TypeError('read-only namespace')
def FileReader(path, name):
self = Namespace(file=open(path, 'r'))
def __repr__():
return '<FileReader %r>' % name
def reset():
self.file.seek(0)
return ReadOnly(__repr__, reset, self.file.read, self.file.close)
def DirectoryReader(path, name):
def __repr__():
return '<DirectoryReader %r>' % name
def list():
return os.listdir(path)
def readfile(name):
fullpath = os.path.join(path, name)
if os.path.isfile(fullpath):
return FileReader(fullpath, name)
def getdir(name):
fullpath = os.path.join(path, name)
if os.path.isdir(fullpath):
return DirectoryReader(fullpath, name)
return ReadOnly(__repr__, list, readfile, getdir)
Now, if we pass an instance of DirectoryReader to code running in restricted mode, i think this is actually secure.
Specifically, the only introspective attributes we have to disallow, in order for these objects to enforce their intended restrictions, are im_self and func_globals. Of course, we still have to hide import and sys.modules if we want to prevent code from obtaining access to the filesystem in other ways.
Hiding dict, while it has no impact on restricting filesystem access, allows us to pass the same DirectoryReader object to two clients without inadvertently creating a communication channel between them.
-- ?!ng
- Previous message: [Python-Dev] Capabilities
- Next message: [Python-Dev] Capabilities
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]