Thanks for the tips on using Guard and subclassing Permission - I will update
the code.
But I am not completely sure I follow your idea of ModuleServiceProvider.
I'll try to explain why I think two permissions are needed.
Let's imagine a simple scenario:
1. A client gets a service proxy.
2. Before actually downloading any code and deserializing the proxy the client
wants to verify a Module that it received as annotation.
3. After the proxy is deserialized the client wants to grant the proxy a
permission to deserialize other objects that possibly will require other
Modules to be downloaded.
So the following steps are performed:
1. A Module is deserialized
2. Deserialized Module is verified
3. A service proxy is deserialized
4. The service proxy is verified
5. DownloadPermission is granted to the proxy ClassLoader (note that it is a
different ClassLoader than Module's ClassLoader)
But how can we implement conditional Module verification?
We can have a locally installed verifier that just checks if currently
executing code has DownloadPermission and if that's the case consider any
Module trusted. But - of course - the client itself has DownloadPermission, so
this verifier would cause suppressing of Module verification alltogether.
The idea is to have another permission that only the client has - the verifier
would check that permission and if the calling code has it - consider Modules
untrusted.
So now the sequence is as follows:
1. A Module is deserialized
2. DelegatedModuleTrustVerifier checks for SuppressModuleInstallPermission.
3. The client has it so DelegatedModuleTrustVerifier returns false
4. The Module is verified using standard ProxyTrustVerifier
5. A proxy is deserialized
6. The proxy is verified
7. The proxy is granted DownloadPermission
8. The proxy tries to deserialize a subsequent object (annotated with another
Module)
9. A Module is desecialized
10. DelegatedModuleTrustVerifier checks for SuppressModuleInstallPermission.
Calling code does not have it so DelegatedModuleTrustVerifier checks for
DownloadPermission. Calling code does have DownloadPermission (see p. 7) so we
consider this Module trusted
11. We're done :)
Michal
On Monday 11 of October 2010 13:06:18 Peter Firmstone wrote:
> I don't completely follow, why do you need the additional permission?
>
> Perhaps we could have ModuleServiceProvider that only allows a
> reflective proxy? We can authenticate a reflective proxy because
> there's no downloaded code.
>
> interface ModuleServiceProvider {
> CodeSource[] getModuleCodeSources();
> Module getModule();
> }
>
> Setting up the Module from the ModuleServiceProvider, we can obtain the
> CodeSource URL and Certificate's before downloading any jar files for
> the module and check if a Module ClassLoader has been registered for the
> Subject.
>
> We can then dynamically grant Permissions to that ClassLoader (using the
> Module's class) with the Subject's Principals[], so it only has the
> necessary Permission's when run as the Subject of the Service.
>
> A marshalled smart proxy could be annotated with the
> ModuleServiceProvider, which is authenticated, and has constraints set,
> prior to instantiating a ClassLoader with the URL[]'s(if it doesn't
> already exist), then deserialize the Module into it (by setting the
> context ClassLoader) and use the new Module to provision the smart
> proxy's jar archives.
>
> Have a look at Gregg Wonderly's CodebaseAccessClassLoader too.
>
> http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/loader
> /?pathrev=934258
>
> Some Permission Tips:
>
> 1. For simple Permission classes, extend Permission instead of
> BasicPermission if you can, if you don't need implement your own
> PermissionCollection, the Policy will provide an implementation
> for you (I provide a multi read PermissionCollection with my
> Policy Provider for better concurrency).
> 2. Try using Guard installModule = new InstallModulePermission();
> Then instead of calling the AccessController or SecurityManager,
> call installModule.checkGuard() instead, it gets the security
> manager for you and checks the Permission, when I've got the
> InternetSecurityManager finished, this will speed up your
> permission check for repeated checks.
>
> try {
> installModule.checkGuard(this);
> return true;
> } catch (SecurityException ex) {
> return false;
> }
>
>
> Cheers,
>
> Peter.
>
> Michal Kleczek wrote:
> > Of course we need something more since the client has
> > InstallModulePermission it would suppress trust verification
> > alltogether. The simple fix is to have two permissions and suppress
> > trust verification only when we only have one of them. The client has
> > both, so we are going to verify trust.
> >
> > class InstallModulePermission extends BasicPermission {
> > }
> >
> > class SuppressInstallModulePermission extends BasicPermission {
> > }
> >
> > public class DelegatedModuleTrustVerifier implements TrustVerifier {
> >
> > private static final InstallModulePermission
> > INSTALL_MODULE_PERMISSION =
> >
> > new InstallModulePermission();
> >
> > private static final SuppressModuleTrustDelegationPermission
> >
> > SUPPRESS_MODULE_TRUST_DELEGATION_PERMISSION =
> >
> > new SuppressModuleTrustDelegationPermission();
> >
> > @Override
> > public boolean isTrustedObject(Object o, Context cntxt) {
> >
> > if (o instanceof Module) {
> >
> > try {
> >
> > AccessController.checkPermission(SUPPRESS_MODULE_TRUST_DE
> > LEGATION_PERMISSION); return false;
> >
> > }
> > catch (SecurityException suppressEx) {
> >
> > try {
> >
> > AccessController.checkPermission(INSTALL_MODULE_PERMI
> > SSION); return true;
> >
> > }
> > catch (SecurityException installEx) {
> >
> > return false;
> >
> > }
> >
> > }
> >
> > }
> >
> > return false;
> >
> > }
> >
> > }
> >
> >
> > Michal
> >
> > On Monday 11 of October 2010 08:24:19 Michal Kleczek wrote:
> >> On Monday 11 of October 2010 05:27:31 Peter Firmstone wrote:
> >>> 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.
> >>
> >> Thanks for the hint.
> >> I think Module trust delegation can be achieved in a really simple way:
> >>
> >> class InstallModulePermission extends Permission {
> >> }
> >>
> >> //this TrustVerifier is installed locally on the client
> >> //so that delegation of Module trust verification can be done
> >> //by granting a service InstallModulePermission
> >>
> >> public class InstallModulePermissionVerifier implements TrustVerifier {
> >>
> >> private static final InstallModulePermission PERM =
> >>
> >> new InstallModulePermission()
> >>
> >> public boolean isTrustedObject(Object o, Context ctx) {
> >>
> >> try {
> >>
> >> if (o instanceof Module) {
> >>
> >> AccessController.checkPermission(PERM);
> >> return true;
> >>
> >> }
> >>
> >> return false;
> >>
> >> }
> >> catch (SecurityException e) {
> >>
> >> return false;
> >>
> >> }
> >>
> >> }
> >>
> >> }
> >>
> >> What do you think?
> >>
> >> Michal