Michal Kleczek wrote:
Some more thoughts.
There is one scenario that is not covered here:
I get an service, verify the module that loads its class using a
ModuleAuthority that I trust. This service in turn downloads some other
objects that it verified. There is no way I can delegate trust verification to
the service - I must trust Modules (actually ModuleAuthorities) of those
subsequent objects.
1. I have to have a way to allow or disallow module trust delegation (looks
like a case for dynamic permission grants)
Currently PreferredClassLoader uses DownloadPermission to prevent or
allow a CodeSource class loading, because the CodeSource hasn't yet been
loaded, we cannot dynamically grant DownloadPermission to a CodeSource,
using DynamicPolicy.
However I have RevokeableDyanamicPolicy (browse svn under
jtsk/skunk/pepe/src/org/apache/river/security) and an implementation
that allows dynamic grant's for CodeSource's.
This will allow us to delay granting DownloadPermission until after
authentication, forcing the service to initially use a local Module.
Once we've authenticated we know the Subject, so we could recreate the
proxy in a new ClassLoader that uses the Subject in it's identity. We
already recreate the proxy for client constraints.
This ClassLoader would represent the Service Proxy's private namespace,
under which an embedded OSGi or Maven or other management framework or
libraries could be loaded privately by the proxy, solely for its use.
Since remote method call threads are run with the remote Subject, we can
find the correct ClassLoader, without using a CodeSource hack.
Cheers,
Peter.
2. This delegation has to be automatic (IOW the service does not have to do
anything - it is solely my decision to delegate)
Any ideas?
Michal
On Thursday 07 of October 2010 21:57:48 Michal Kleczek wrote:
So...
I've spent a day on some thinking and prototyping and hopefully I got an
idea. Here is an outline:
1. We annotate classes with an object implementing Module interface:
interface Module {
//methods copied from ClassLoading but there is no annotation argument
Class loadClass(...);
Class loadProxyClass();
}
This makes class loading pluggable - a service can designate it's own class
loading mechanism.
Note that the methods take boolean verifyCodebaseIntegrity argument. I
think it could be replaced by placing constraints on a Module.
2. Before using a Module we prepare it using a ProxyPreparer - that way we
make sure we trust the Module before letting it load classes
3. We have a default implementation of Module that delegates class loading
to ClassLoading:
RmiModule implements Module {
private String annotation;
}
4. There is a single instance of RmiModule called BOOTSTRAP that we use to
load RmiModule class. This is implemented in:
RmiModule {
...
static Module getModuleOf(final Class cl) {
/*
* RmiModule is equivalent of String annotation
* so it should be available locally
*/
if (cl == RmiModule.class) {
return getBootstrap();
}
final ClassLoader loader = getClassLoader(cl);
if (loader instanceof ModuleClassLoader) {
return ((ModuleClassLoader) loader).getModule();
}
final String annotation = RMIClassLoader.getClassAnnotation(cl);
return annotation != null ? RmiModule.getInstance(
annotation,getModuleTrust(loader)) : getBootstrap();
}
...
}
5. We use the above method in annotateClass and annotateProxyClass of our
MarshalOutputStream
6. RmiModule can be verified by ProxyTrustVerifier. It's ProxyTrust
implementation delegates TrustVerifier retrieval to:
public interface ModuleAuthority extends Remote {
TrustVerifier getModuleVerifier() throws RemoteException;
}
7. We implement some helper functions that make it simpler to export a
service and provide its clients with either third party ModuleAuthority or
designate itself as a ModuleAuthority.
8. Before all this is implemented in PreferredClassProvider we have to
cache association between a ClassLoader and a Module. It's implemented in
RmiModule.
9. If we implement it in PreferredClassProvider our ClassLoaders can keep a
reference to associated Module
10. If we implement it in PreferredClassProvider we can have different
ClassLoaders for the same annotation but different ModuleAuthority - that
would actually allow us to grant permissions to Modules - before that two
different Modules with the same annotation are going to share permissions.
I've attached a prototype implementation (note - it is a proto-proto-
prototype) so that you guys can verify if you have some spare time.
Don't know if mailing list server allows attachments.
Michal
On Tuesday 05 of October 2010 16:48:22 Michal Kleczek wrote:
On Tuesday 05 of October 2010 16:36:47 Gregg Wonderly wrote:
On 10/1/2010 12:38 PM, Michal Kleczek wrote:
When I think about it some more - the below idea is not enough and we
need a more general solution.
How about class annotation not being a String but rather an object...
I have to give it some more thought.
There are been some thought and discussion about doing this. It is
possible, but the problem becomes that if you send an object with the
annotation, then how does the receiver unmarshall that object? Is that
object something that everyone knows about ahead of time?
My line of thought was - yes. It would have to be something similar to
ProxyTrust - a factory to receive an Unmarshaller.
I haven't really given it enough thought.
But I am more and more convinced that doing that at the higher (proxy
preparation) level - as I described it earlier - could actually be
enough.
Michal