Puzzle: Adding domain-based security to Squeak.

Ron Teitelbaum Ron at USMedRec.com
Sat Aug 5 17:04:09 UTC 2006


Hi Michael,

If changing the base object is not possible (like adding an ivar to Object)
then solve the problem with a back pointer.

Object subclass: DomainConnector
Ivars: 'domain subject'

Object subclass: Domain
Ivars: 'name'

Obviously you need a way to figure out what domain a user is on

Object subclass: User
Ivars: '.... domain'

Now for every object created that needs to be attached to a domain you do

DomainConnector addObject: anObject toDomain: aDomain
	"Create a domain connector object which links anObject to aDomain

	^self new
		subject: anObject;
		domain: aDomain;
		yourself.

Depending on whether or not you are using a database you could manage
objects.
	As you said not every object needs a domain so you could implement a
#needsDomain method on the objects that need it.  Consider root objects and
places where creating a dependent object doesn't make sense to your class
model (I would never have classB without an instance of ClassA) and then
implement needs domain on that root class.
	The update of domain objects could be done at the time of commit for
a database, 
	commitObjectsForUser: aUser
		domainObjects := self objectsToCommit select: [:a | a
needsDomain].
		domainObjects do: [:a | DomainConnector addObject: a
toDomain: aUser domain].

	Or you could change new to do newForUser on root objects.

There are lots of possibilities, the main point is that once the connecter
is created you can find out if an object is in a domain by querying the back
pointer.
	If you are in a database the query is simple 
	Object >> isInDomain: aDomain
		self needsDomain ifFalse: [NotInDomainError signal: 'Not a
Domain Object'].
		aConnector := DomainConnector where: [:a | a subject =
self].
		^aConnector domain = aDomain
	If you are not in a database then updating a dictionary that lives
on a class variable that separates by class, object oids or something will
speed lookup of domain objects.
	aConnector := (DomainConnecter someOrginazationDictionaryFind: self
).
	^aConnector domain = aDomain.

Hope that helps!

Happy coding!

Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
Ron at USMedRec.com 

> -----Original Message-----
> From: squeak-dev-bounces at lists.squeakfoundation.org [mailto:squeak-dev-
> bounces at lists.squeakfoundation.org] On Behalf Of Michael van der Gulik
> Sent: Saturday, August 05, 2006 5:20 AM
> To: squeak-dev at lists.squeakfoundation.org
> Subject: Puzzle: Adding domain-based security to Squeak.
> 
> Hi all.
> 
> Here's a generic problem for people that like puzzles that I can't seem
> to work out: I want to add "Domains" to Squeak, so that system resources
> can be managed.
> 
> Here's how it would work, in theory:
> 
> * A domain would typically be a group of objects related to a particular
> application.
> * Every object belongs to a domain.
> 
> And then:
> 
> - A domain's memory usage can be capped. Object>>new would be
> implemented so that it would wait for free memory or throw an Exception
> if the memory cap has been breached.
> 
> - A domain can only start up a limited number of Processes. This would
> control fork bombs etc. Process>>new or some other entry point would
> check for this and wait or throw an Exception if the process limit has
> been breached.
> 
> - Ditto for other system resources, such as disk usage, network
> bandwidth, access to devices etc.
> 
> - I'm implementing a distributed system, so remote objects that come in
> will already belong to a particular domain. A local DomainManager or
> some other mechanism would determine if objects from that domain are
> allowed to use local system resources, and at which priorities.
> 
> For example, I could have two domains: "AlicesEmail" an "BobsEmail".
> AlicesEmail is capped at 10Mb of memory and 6 processes. BobsEmail is
> capped at 20Mb of memory and 15 processes. Assuming that the Squeak
> image is a remote mail server; now neither Alice nor Bob can make the
> image explode by doing funny things with their email. Both domains use
> the same classes.
> 
> Now, here's the problem:
> 
> How would I implement Object>>new and Process>>new (or other equally
> good locations) so that the domain for that object is found and a
> DomainManager queried about that domain's privileges?
> 
> The possibilities that I've thought of so far are:
> 
> 1. Adding an instance variable called 'domain' to Object is a bad idea -
> consider SmallIntegers and parts of the VM that assume certain instance
> variables are in certain places.
> 
> 2. Creating dictionaries of which objects are in which domains would
> work, but is going to be extremely inefficient. _Every_ object in the
> image would have an entry in these dictionaries.
> 
> 3. Creating a subclass of Object with an instance variable "domain"
> could work, and then all other objects that are used by domain-using
> code are subclasses. I'm still thinking through the implications.
> 
> 4. Assigning domains to processes rather than objects is a possibility,
> but this would allow resource theft when invocations are done on objects
> out of the current domain. If this was done, the current domain would
> just be <<thisContext domain>>.
> 
> 5. Another option is to make radical changes to the VM, so that a domain
> of objects are all kept in the same range of memory. This would be a
> rather major change and would introduce bugs.
> 
> 6. I could do fancy tricks with the garbage collector like ImageSegment
> does and trace references back to an object which identifies the current
> domain. This is slow and yuck.
> 
> So far alternatives 3 or 4 seem possible.
> 
> Thinking aloud; option 4 could be implemented by implementing
> Domain>>doPrivileged: taking a block as an argument. Object>>new and
> Process>>new can then search down the stack until Domain>>doPrivileged:
> is found and ask the global DomainManager what that domain is allowed to
> do. Calls out of the current domain can be stripped of privileges by
> doing something like noPrivilegesDomain>>doPrivileged: [otherObject
> doSomething]. otherObject would then need to call doPrivileged: again
> with its own domain to regain the ability to fork and make new objects.
> 
> Umm... this would need some way of preventing user processes from
> peeking down the stack and stealing another domain (i.e. using
> capability-based security).
> 
> Option 3 has the advantage of making less work for the poor application
> developer, but incurs an extra pointer for every single object.
> 
> Java does something similar, but it does it based on classes or jar
> files (afaik). This is not particularly good - you can't have two
> domains with different privileges which share the same implementation.
> For example, you can't have an "AlicesEmail" and "BobsEmail" domains
> with different privileges if they both use the same classes.
> 
> Thoughts? Does anything like this already exist?
> 
> Mikevdg.
> 





More information about the Squeak-dev mailing list