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:41:46 GMT
What about the case where a Module depends on another Module?

I'm guessing that was the intent.

Regards,

Peter.

Peter Firmstone wrote:
> 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