Peter Firmstone wrote:
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;
}
This would be better:
interface CodeSouceExporter {
CodeSource[] getCodebase(String[] urlStreamHandlerClassNames) 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.