Fred Oliver wrote:
It looks like permissions can only be managed or revoked by class.
I made this choice initially because Permission implies(Permssion) is
not like equals(Object), one doesn't necessarily mean the other and
there are many cases where !equal but implies == true. However given
some more thought, I'm sure it would be possible to have a water tight
revocation by Permission instead of class.
However that in itself is not a simple problem, we don't know the
ProtectionDomain's on the caller's stack, we don't know the combination
of Permission's that will cause implies to return true, this would
require a PermissionCollection implies check.
Since we cache the AccessControlContext's, we could create a
DomainCombiner, that amalgamates them, then call implies on the
resultant AccessControlContext, if this returns false, then we know that
one of the ProtectionDomain's has been given access.
If
a domain has been granted more than one SocketPermission (e.g. to
grant permission to use two ports or communicate with two hosts,
etc.), can I revoke one of them?
Yes, but with the current code, both Sockets would be closed, both
delegates would need to catch the Socket Exception and attempt to open a
new Socket, only one would succeed, the one that hadn't been revoked.
If I have a delegate for a complex object (say Socket) to which sets
of permissions may apply, how would the delegate handle the sets? If
one SocketPermission were revoked, does the delegate need deep
knowledge of the object it protects to determine if that revoked
permission applies?
No, I figured the safest way is to know the Socket information, close
it, catch the exception, then create a new Socket from the previous
information. If an AccessControlException is then caught, the delegate
can then close the Socket. This will cause a brief interruption to
service for Sockets where Permission hasn't been revoked, but the Socket
is closed and replaced.
The delegate shouldn't need intimate knowledge of the caller, that's the
job of the ExecutionContextManager (ECM).
Perhaps a delegate could set an atomic integer (via the ECM for each
protected method to monitor execution, if greater than 0, there is a
method that has not yet returned, then action should be taken. If 0 the
permission check will be performed next call and no action to close the
socket needs to be taken.
I guess the AccessControlContext's could be stored in order in an
execution cache, then we would know which are in current execution, we
could re call implies against those. The trouble is, when do method's
exit? So a call (aptly named methodExit()?) would have to be made on
the ECM by the delegate prior to returning any protected method.
Can a delegate always obtain the complete set of
permissions which apply to it to reevaluate more fully?
Yes it is possible to obtain a current set of PermissionGrant's and
query them, provided the delegate has Permission.
Should Controller maintain static maps of its own instances? If that
map were contained by instances of RevokeableDynamicPolicy, then there
could be multiple policy objects in use at one time.
Hmm, true, the implementation forces a single revokeable policy for the
JVM, what advantage is there to having multiple Dynamic policies?
PrincipalGrant extends PermissionGrant and contains two Collections
which are both used in the hash value and equals method. I would be
inclined to enforce their immutability with
Collections.unmodifiableCollection().
OK.
In the equals method, you might
return false if the stored hash values are different before comparing
the collections.
Thanks, speed tip.
PermissionGrant.getPermissions() is documented as returning an
immutable Collection, but the method returns a mutable array instead?
Previously it did, however I realised that since anyone can implement
PermissionGrant, (with appropriate Permission) I could not guarantee the
immutability of the underlying collection, with regard to the way the
RevokeableDynamicPolicy see's it, so I decided that at the time the
Policy checks GrantPermission, that it clone the array and cache it, in
a Weakly referenced Map with PermissionGrant as it's key.
If the underlying collection cannot be guaranteed immutable, the policy
would not check GrantPermission again, an implementer could gain
elevated Permission's via mutability otherwise, so I figured.
Thanks, you've given me some more ideas.
Cheers,
Peter.
Fred
On Wed, Aug 11, 2010 at 2:56 AM, Peter Firmstone <[email protected]> wrote:
Fred,
Any thoughts? The ExecutionContextManager interface and implementation
(Controller) are shown below, the RevokeableDynamicPolicy and
PermissionGrant interfaces have implementations available on svn.
The ExecutionContextManager is based around our discussion.
Note that no Security Delegate is provided here, just a tool, which a
delegate or any other object may use,
ExecutionContextManager.checkPermission() and another method
addAction(Runnable r), to accept a Runnable to perform any clean up tasks
for complete revocation such as closing Socket's etc. The delegate need not
implement any interface other than the object it encapsulates.
Cheers,
Peter.