Michal Kleczek wrote:
On Tuesday 12 of October 2010 00:27:12 Peter Firmstone wrote:
Michal Kleczek wrote:
On Monday 11 of October 2010 15:41:46 Peter Firmstone wrote:
What about the case where a Module depends on another Module?
I'm guessing that was the intent.
Actually - no :)
There are two different things to consider:
1. Module dependencies (which I actually did not think about too much).
Actually I'm thinking there shouldn't be any dependencies, other than
the Jini Platform and ServiceAPI, which has been used to obtain the
Module.
This is true as long as we have one special ClassLoader that loads
ServiceAPIs. That is the case with current Jini and has its ramifications.
Once you think about peer class loading model where different versions of the
same class (even ServiceAPI class) can coexist you need Module dependencies.
But let's not go there at this moment.
I don't think there are many differences between our ideas - let me summarize
them (at least how I understand them).
1. You want to issue a remote call to _retrieve_ annotations whereas I want to
do that to _verify_ them.
Yes, but only after the annotated reflective proxy which is an instance
of ProxyTrust and RemoteMethodControl, has been verified. It can be
deserialized simply because it resolves to local classes.
I think this is a problem since this way you cannot turn this stuff off
altogether (for example for testing).
2. You want to automatically grant DownloadPermission to CodeSources you've
just retrieved
No, just a small misunderstanding, a CodeSource, is a URL and some
signer Certificates, it's the opposite way around, I want to know the
CodeSource I'm going to grant DownloadPermission to, so the jar file
referenced by the URL in the CodeSource can be downloaded. If I don't
grant DownloadPermission to the CodeSource, it can't be downloaded, at
least that's how PreferredClassLoader works.
I can also check if I trust the signers and if the URL supports
integrity constraints.
Remember this is after authenticating the proxy.
I think that is a problem since it means suppressing standard
DownloadPermission checks altogether. I would say - just use standard
PreferredClassProvider that does not do DownloadPermission checks.
3. You want to automatically grant GrantPermission(new DownloadPermission())
to new ClassLoaders
Well not quite ClassLoaders, to CodeSources, in order to make them
downloadable, but it might be pushing the trust boundary too far.
And that is something I would like to be conditional - the client has to have
a way to either allow or not allow a proxy to download more code without local
verification. But it must be possible to say: "I've got a proxy from you and I
trust you verified the code you are going to download to my address space - so
I won't check this code by myself"
I think your idea to annotate using an object that has only local code
and can be verified is pure Genius ;) I never would have thought of
that, you're definitely thinking outside the box.
However I'm wondering if a service is asking for too much client trust
to give a ClassLoader reference to a Module, obtained from a third party
ModuleAuthority.
I think we can take advantage of your idea to annotate an Object that
can be deserialized, it's class resolved using only local code.
That Object could be a Service that uses a java.lang.reflect.Proxy only
(smart proxy cannot be deserialized without code) Said Service is not
registered with any registrar, it is just an Exported Object that
implements ProxyTrust and RemoteMethodControl as well as an interface to
obtain the CodeSources.
Perhaps the annotation should just be a proxy that we can ask for the
CodeSources after it has been validated and authenticated.
We could simply have a CodeSourceExporter, which implements ProxyTrust
and RemoteMethodControl, this could be automatically generated from
local CodeSource information, or provided by the service specifically.
The CodeSource[] would be that required by the smart proxy.
interface CodeSourceExporter {
CodeSource[] getCodebase(Class[] urlStreamHandlerClasses) throws
IOException;
long getCodebaseSize() throws IOException;
}
We could simplify this to:
1. Annotate ObjectOutputStream's with a java.lang.reflect.Proxy that
must implement ProxyTrust, RemoteMethodControl and CodeSourceExporter
2. Then during unmarshalling, deserialize, verify and authenticate
the proxy.
3. Obtain the CodeSource's, the URL will be in the first matching
available URL format from the array of URLStreamHandler Class files.
4. Grant the CodeSource's DownloadPermission, because we trust the Proxy.
5. Use Gregg's CodebaseAccessClassLoader to load the smart proxy
class files.
6. Unmarshall the smart proxy, verify autenticate, add constraints etc.
We could also extend CodeSource to contain the Subject (or some unique
identifier?) of the Service, with CodeSourceExporter, to ensure that
ClassLoaders only load classes from one Service (Different Services
sharing classes poses a security risk), in case distinct services share
common URL's. (The Subject would be a private field in the CodeSource,
used only for hashCode and equals comparisons).
Then we could add a method to Gregg's CodebaseAccessClassLoader to load
classes using CodeSource[] rather than a URL String.
We could have a Caching URLHandler as per Sim's suggestion (and as Gregg
has done for years!), so we could have our cake and eat it too.
Gregg's CodebaseAccessClassLoader has been successfully used with OSGi.
Thoughts?
Cheers,
Peter.