The actual implementation of revocation by the Policy provider is actually very simple, it's just an array of PermissionGrant's, which can be added or removed, grant's can also require Principals, if you want, but it isn't essential.
But I'm generally looking at the simpler case of untrusted code, rather than user trust.
So the policy with the ability to revoke PermissionGrant's is just simpler, in both cases we need Security Delegate's with associated ProxyPermission's, to protect security sensitive object's from escaping into untrusted code.
My current testing indicates we can get away without the ExecutionContextManager if I create a non blocking ProxyPermissionCollection, this combined with the new, non blocking Concurrent Policy provider will help speed Permission checks. This will make the implementation even simpler. We just make the AccessController.checkPermission calls as cheap as possible, so we can afford to call them on every method invocation, nothing new to learn for the Application developer.
The greatest cost is the AccessController.getContext call, used to obtain the current AccessControlContext from the Thread's stack. The AccessControlContext is maintained by the JVM to represent the code in execution, even if that code has been inlined etc, the Virtual Stack as it's sometimes called represents the relationships of the original bytecode.
So in summary I think this can be done simply were the River platform to provide standard ProxyPermission's and Security Delegates (invisible to application developers), that control the Proxy's access to the Network and any hardware resources.
The Service can provide an Entry which details the ProxyPermission's it requires.
When your finished with a proxy, River can provide a security method that disposes of the proxy (performs the revocation etc). Any remnant objects that you obtained from the proxy, won't be able to gain any unwanted privileges, the delegates will throw AccessControlExceptions if unprivileged code is on the stack when one of it's methods are called.
Cheers, Peter. Peter Firmstone wrote:
Fred Oliver wrote:On Fri, Aug 20, 2010 at 6:38 PM, Peter Firmstone <[email protected]> wrote:I haven't had time to look over the code...What does recycling the classloader mean?Currently we typically use the SDM and the JoinManager to maintain a pool of Services. I'd like to make it possible to browse Services from untrusted networks like the internet, one concept I have is that there could be multiple services that share common codebase's, because of open source development. It seems possible to process Services with common codebase's sequentially. I mean to use the same ClassLoader for common codebases, but first I want to remove trust before I re-grant it to some new Service's proxy.But in order to share codebases, I'd like to provide a URL scheme, that doesn't include the http:// address of the codebase, but rather provision it using Maven, where the codebase is identified by a name, a version and checksum.If we assign a Principal after proxy verification, that will work, but I'm worried that someone might be able to forge some new classes that extend existing proxy classes. Which is why I've created the ProtectionDomain based grant, instead of just a ClassLoader Permission Grant.The codebase itself isn't trusted either, or any more than the service, just common among different untrusted Services.There is already a classloader cache for codebases, so that a multiple references to the same codebase will give the same classloader. Beyond that, could you say more about reliance on grants to codebases (as opposed to subjects) being the important part?Is there a time when we would trust a Subject, but not the codebase? Then we'd want to establish that we trust the code before elevating trust.You'd want to disallow certain actions. Assuming that Service S is in a remote JVM, with a simple reflective proxy for S running on client A. The Smart proxy served by A runs in it's own ClassLoader in Service S's remote JVM. We also need to ensure that The smart proxy from A can only see classes from the Service API, such that Service S and Smart Proxy A are both in child ClassLoaders, below a common parent ClassLoader that has the Service API, they are using to communicate in Service S's remote JVM.Let's say you have a service S in a VM which is the place where you are concerned about permission revocation. Now add a client A which calls a method in S, passing in a smart proxy located with a URL served by A. At this point, you wish to allow or disallow certain actions by the smart proxy running in S?If a ClassLoader in Service S, is already in use by Smart Proxy A, which has had it's proxy verified and gained some trust, then we cannot utilise the same ClassLoader for Smart Proxy B, since this would be a security risk, unless we decide to revoke Permission's to A first, then try to verify both Smart proxy A and B, before granting trust again. But what happens if we can't verify B? If we are finished with Smart Proxy A, we can revoke it's permission's (I'm thinking about a utility, you can pass the proxy to for disposal, which automatically removes any grants), and then commence proxy verification with B.What if client B attempts the same operation with a smart proxy served by B? Are you concerned about granting different permissions to the proxies from A and B?It might be easier to give Smart Proxy B it's own ClassLoader in this case. Although we could use Subject's to provide different levels of trust and share the same ClassLoader, there is a real danger that B could share some information from A, using Static variables, where references to security sensitive objects are allowed to escape.The problem is, in an internet environment, it's the codebases as well as the principals we don't trust.Then if A is trusted, this should be ok, since Service S, will be dealing with A directly via it's proxy, even though it has been given to it by client B.What if client B attempts the same operation with a smart proxy served by A? (B makes the call specifying A's codebase.)What if a hostile smart proxy from B loads the smart proxy from A and manipulates it in S?In the remote JVM hosting Service S, we would want the proxy's in separate ClassLoaders, so they can only communicate using a parent ClassLoader, via common Service API, each proxy would have it's own permission grants. There is no other safe way.So to recycle ClassLoader's we first have to dispose of the existing proxy. We'd need River platform functionality to look after ClassLoader allocation and proxy disposal on our behalf. The disposal mechanism might also determine if a ClassLoader has received trust that cannot be revoked and instead create a new ClassLoader, rather than re use an existing one.I understand this is complicated and apologise to anyone on the list who doesn't follow, please remember we're exploring and experimenting.Cheers, Peter.FredFred Oliver wrote:Yes that has happened, as my understanding of the platform improves during implementation. I also realised during implementation, that revocation was not the Delegate's concern, in spite of the fact that for proper Revocation,Peter, I'll try to take look over the weekend. In general, I am concerned that the implementation is driving the security model when it should be the other way around.delegates must be utilised. However what I really want is a simple way to add and remove somePermission's from the policy and to ensure that when they have been removed,no protected references have escaped.Part of my concern is that I don't understand the application. Could you explain more about why permissions would be revoked in your application?Two uses:The first is to allow ClassLoader recycling, for multiple smart proxy basedservices (one at a time), with identical CodeSource's.The second, is enabling limited trust for Java Smart Proxy's from unknownuntrusted Services. Providing some basic Permission's to enable the Smart proxy to access: 1. Network 2. Sound 3. Microphone 4. WebCam 5. GPS. vi a ServiceUI, or other services. If the client has any remaining objects from the untrusted Service, toprevent remnant objects's from continuing to utilise the Permission's forongoing communication after the Service has been discarded.- What resources does your application need to give and then revoke permissions for?See above.- To whom (principal, codebase, etc.) are permissions given and taken away?Definitely CodeSources.- Are resources shared between multiple principals, codebases, etc.?The network will be. The codebases may be common, for services, butgenerally not shared at the same time, although it is possible if permissiongrant's are delayed until all services sharing a codebase have verifiedtheir proxy's. If a ClassLoader is recycled, the client and new Servicewill need to verify the new proxy, before any permission's are granted.Like using a guest account for services? Using a DomainCombiner to injectI think it would be much easier to restrict the problem scope if you only needed to associate principals with resources, if that were the case.principals. Cheers, Peter.Fred
