river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Firmstone <j...@zeus.net.au>
Subject Re: Towards Internet Jini Services (trust)
Date Mon, 11 Oct 2010 13:34:53 GMT
Edited slightly note: <edit-remove>for the Subject</edit-remove>

Peter Firmstone wrote:
> Ok,
>
> The ModuleServiceProvider adds a step:
>
>   1. A ModuleServiceProvider is deserialized (reflective proxy only)
>      (consider it a Module Factory, could rename it to that too).
>   2. Deserialized ModuleServiceProvider is verified
>   3. A Module cache is checked using the ModuleServiceProvider as a key
>      (weakly referenced).
>   4. If a Module exists in the cache, then that is used instead, goto 6.
>   5. If a Module doesn't exist in the cache <edit-remove>for the 
> Subject</edit-remove> a new
>      Module will be created using the ModuleServiceProvider
>         1. CodeSource[] is obtained for the Module using the
>            ModuleServiceProvider
>         2. DownloadPermission is dynamically granted to all CodeSource
>            in the array CodeSource[] only.
>         3. DownloadPermission is only required to load the jar files
>            for the Module, via overriding
>            SecureClassLoader.getPermissions(CodeSource cs) as per
>            PreferredClassLoader.
>         4. The Module is deserialized, using the CodeSource[] URL's in
>            a new ClassLoader instance.
>         5. The Module is verified.
>         6. The Module is granted GrantPermission(DownloadPermission)
>         7. The Module knows which CodeSources require
>            DownloadPermission and grant's these dynamically on an as
>            needed basis.
>         8. The Module needs a guard to check the caller has sufficient
>            permission to use it, this would be created during module
>            construction, we need to define a standard guard permissions
>            for each method.
>         9. The Module is stored in the cache associated with the
>            ModuleServiceProvider.
>   6. The Service Proxy is unmarshalled.
>   7. The service is verified (it has to authenticate with the same
>      Subject as the ModuleServiceProvider).
>   8. The service is used. (Constraints ensure the service authenticates
>      every method invocation).
>
> Note: The ModuleServiceProvider has the same Subject as the Service 
> Proxy.
>
> Module needs an additional method:
>
> ClassLoader getClassLoader(Subject s);
>
> The Module needs to have a Subject parameter added to it's other 
> methods too, the Module already know's the Codebase URL's, since this 
> is it's responsibility, however it needs to ensure that different 
> Subject's don't share ClassLoaders, in case multiple Subjects are 
> using one Module with identical CodeSource, in the case where the 
> Module Service provides for a number of Subjects.
>
> The Module Service, knows which jar files, module / package versions 
> are in use for the requested classes.
>
> If Service Proxy's had OSGi embedded, they could be shutdown and 
> reloaded with new Module versions, this would be synchronous with the 
> Module Service.
>
> Ordinary services might simply be stopped and re looked up with 
> updated jar files and annotated with a new ModuleServiceProvider 
> instance.
>
> We can choose to limit other permission's also like SocketPermission's 
> to particular domains.
>
> Can we cache jar files somehow based on their URL?
>
> I'm not certain if this is right, what do you think?
>
> Cheers,
>
> Peter.
>
>
> Michal Kleczek wrote:
>> 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
>>>>>         
>>
>>   
>
>


Mime
View raw message