river-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michał Kłeczek <michal.klec...@xpro.biz>
Subject Re: Service lookup without unmarshalling - details
Date Sun, 14 Dec 2008 12:10:19 GMT
Hi,

This is a really interesting topic since it touches areas in River 
architecture that have some holes. So these some of my thoughts:

1. We cannot get rid of SecurityManager since then we would have an "all or 
nothing" security - once we say we trust downloaded code it is not 
constrained in any way. In Jini we only trust the service up to the level of 
the permissions we dynamically grant to it.

2. ServiceLookup can be seen a solution to the problem of memory consumption 
when processing large number of ServiceItems. But it cannot be seen as a 
solution to the more general problem in Jini security - the possibility of 
DoS type of attacks during deserialization. Even if we have something 
like "never preferred" classes there is still a possibility for a service to 
embed some data in an attribute that will cause the client to die (for 
example a 5GB name).
This looks really difficult to solve - on one hand you don't want to 
deserialize a proxy (or any other object) - on the other hand you cannot 
verify if you trust a proxy without deserializing it because you will not be 
able to get a bootstrap proxy.
Possible solutions:
a) In short - PKI: the client and the service have to understand common data 
formats, protocols and cryptographic algorithms and use them to verify 
downloaded code and data. But the idea behind Jini was "the end of 
protocols" - we just have to agree upon the Java interfaces we understand. Of 
course it is not possible right now with River but keeping the set of 
protocol/data formats definitions as small as possible is an important goal 
IMHO.
b) Get two objects from the lookup service - a proxy as a MarshalledObject and 
a trust verifier that is deserialized without downloading any code. The trust 
verifier would be used to verify (marshalled) real proxy. It could be done 
for example by checking the digest of the marshalled real proxy. The downside 
of this is that the client must know the data verification process so it 
actually is no different than a)

When thinking about it I came up with an idea that it can be solved by having 
a client use a third party to interact with a service. So the client would 
not download any code. It would pass it's own proxy to the third party and 
interact with the service there (since it cannot download a service proxy 
into its own VM). In it's simplest form this "third party" can be just 
another JVM process spawned by the client. The communication between the two 
can be implemented as a LocalProcessEndpoint using System.in/System.out and 
Process.getInputStream/Process.getOutputStream() to actually send data.

What do you think?

Michal

On Saturday, 13 of December 2008 20:44:11 Wade Chandler wrote:
> ----- Original Message ----
>
> > From: Gregg Wonderly <gregg@wonderly.org>
> > To: river-dev@incubator.apache.org
> > Sent: Friday, December 12, 2008 1:57:28 PM
> > Subject: Service lookup without unmarshalling - details
> >
> > Wade Chandler wrote:
> > > Heh heh, yes, there needs to be a way to inspect the service, some
> >
> > credentials,
> >
> > > without unmarshalling. A way to ask for all services out there, the
> > > class or
> >
> > interface they implement, along with other user identification
> > information such as a displayable name, description, version, etc I would
> > think. What about this
> >
> > > list? Anyone have a link to an archive? I want to find your other email
> > > Gregg and see what you wrote about there.
> >
> > I was just in my list of things I still wanted to put back into River.  I
> > did this about 2-3 years ago, and have been using it since then.  The
> > Reggie architecture makes it easy to do.  I want it to be an optional
> > interface supported by lookup services.
> >
> > As an example, the current definition of lookup(ServiceTemplate,int) in
> > the Reggie proxy is shown here.
> >
> >     // Inherit javadoc
> >     public ServiceMatches lookup(ServiceTemplate tmpl, int maxMatches)
> >     throws RemoteException
> >     {
> >     return server.lookup(new Template(tmpl), maxMatches).get();
> >     }
> >
> > If you look closely, you will see the "get()" on the end of the line,
> > above, which does the unmarshalling.  So, just before it gives you the
> > results, they are unmarshalled.
> >
> > The following method is one of the ones that I added which is in the
> > ServiceLookup interface API.
> >
> >     public RemoteIteratorlookupEntries( ServiceTemplate tmpl,
> >             int maxMatches ) throws RemoteException {
> >         return new LocalEntryIterator( server.lookup(new Template(tmpl),
> >         maxMatches ) );
> >     }
> >
> > So, it's possible for Reggie to have a simple conversion done to provide
> > this capability.  However, I don't think it's realistic to ask that all
> > ServiceRegistrar instances support this as the Primary mechanism.
> >
> > What I've done so far, works.  Are the names and relationships exactly
> > what I'd want to see in a production system?  Perhaps not.  Below is an
> > example usage of the API.
> >
> > If you had a ServiceRegistrar instance which also implemented
> > ServiceLookup, you'd do something like the following to perform a lookup
> > and get a name for all the service instances and add them to a list via
> > addService().
> >
> > // make sure no downloading occurs to resolve these classes
> > ClassLoading.neverPrefer( Name.class );
> > ClassLoading.neverPrefer( ServiceInfo.class );
> >
> > ServiceTemplate tmpl = ...
> > ServiceRegistrar reg = ...
> > if( reg instanceof ServiceLookup ) {
> >     ServiceLookup lu = (ServiceLookup)reg;
> >     RemoteIteratorents = lu.lookupEntries( tmpl );
> >     for( ServiceEntry ent : ents ) {
> >         Set> accs =
> >             ent.getMarshalledAttributeSets();
> >         String name = null;
> >         for( ServiceDataAccessentacc : accs ) {
> >             if( entacc.getDataClassNames().
> >                 contains(Name.class.getName() ) {
> >                 // Will resolve to local VM class
> >                 name = ((Name)entacc.getData()).getName();
> >             // Prefer Name, but allow ServiceInfo
> >             } else if( entacc.getDataClassNames().
> >                 contains(ServiceInfo.class.getName() &&
> >                     name == null ) {
> >                 // Will resolve to local VM class
> >                 name = ((ServiceInfo)
> >                     entacc.getData()).getName();
> >             }
> >         }
> >         if( name == null )
> >             name = ...find a name from classes...
> >         addService( name, ent );
> >     }
> > } else {
> >     // you can do regular lookup here and get live objects, or
> >     // you can ignore all instances that don't support
> >     // access to the marhalled results.
> > }
> >
> > So in this case, only the Entry values for a Name instance of a
> > ServiceInfo instance will ever be instantiated.  My changes to
> > ClassLoading, to provide the ability to short circuit
> > PreferredClassLoader from downloading the first jar in the codebase to
> > find the PREFERRED.LIST to see how to resolve the classes being
> > unmarshalled, keep unneeded code from being unmarshalled.  Imagine what
> > would happen to your VM where 200 developers are working on the same
> > project, all running netbeans, and using a service proxy that unmarshalls
> > into a 1MB class instance.  Suddenly, you do a lookup and 200MB goes
> > aways!
>
> Yes, something like that. Using common types such as Name, Location,
> ServiceInfo, Comment, etc and maybe defining a few more and if any of those
> are available use them. Then, only load and use any more complex types in
> some automated system or something of that nature. Seems to be able to have
> that RemoteIterator to remotely iterate over the services over the network
> would be good so that limited memory systems can inspect all services
> without loading all that at one time. Too, to be able to set limits on how
> much information a given class can contain before we want to look at it in
> this context would be nice as well; thinking about very memory limited
> devices or systems here.
>
> I was thinking of some XML type descriptors which could be returned by
> services etc, but maybe that isn't needed as long as we can inspect all the
> marshalled information and dig out what we need. Some use of XML
> descriptors though might help simplify the join and discovery process
> though as that can be examined to determine if signatures, types, etc match
> without marshalling of objects though. It all starts to run together with
> marshalled objects and formats when talking of XML descriptors.
>
> Essentially we can glean the same things from specific interfaces, but what
> we don't have as much control over is the serialized size of that
> information as we can with XML schemas and restrictions. Though we can
> always do some checks on both sides and limit things as needed as it
> relates to size and performance I suppose. I'm interested in talking about
> the possibility to lookup an XML stream which contains service descriptions
> though. I feel some things could be simplified that way though that does
> add some over head for smaller devices with less processing capabilities.
> Does any of MTOMs new features support binary and indexed XML to make that
> type of thing faster?
>
> > Nicalas, and others desires to have a no-network environment could help
> > deal with some of the issues of rogue code.  At some point, you will want
> > to not have all of the services running on your computer when you are
> > testing a client. You might in fact not be able to run the server on your
> > computer.  Both network and non-network environments are interesting to
> > explore.  My investigation into these issues and how to get away from
> > downloading anything, until you use it, has been very revealing of the
> > issues to me.
>
> Security is where I need to understand Jini much better, but it seems if we
> had or used some signing mechanisms this could all be simpler. Essentially
> a signature gets sent in the protocols with each set of information and at
> different levels. Much seems supported now. Looking at everything I see
> some ways to do insecure activities and I see ways to do secure activities.
>
> Looking in discovery and join there are some things for security which can
> be tied to user activities and automated activities given a security
> repository or configuration:
>
> http://www.jini.org/wiki/Jini_Discovery_and_Join_Specification#The_net.jini
>.discovery.x500.SHA1withDSA_Format
>
> Signatures can be used for multi-cast to short circuit before unicast ever
> comes into play, though this may not be as important. Essentially, a server
> or client a like can ignore anyone know in the trusted keystore. As it
> relates to user actions in an IDE they can could be given tools to do all
> this through a UI, define server security configuration and client alike
> and import keys and certs etc.
>
> http://www.jini.org/wiki/Jini_Discovery_and_Join_Specification#The_net.jini
>.discovery.ssl_Format
>
> Using SSL or Kerberos one can secure a system to only use verified and
> trusted or imported certificates from a specific
> group/domain/company/entity. Then, when a service is to be accessed only
> allowed servers can be used period. The same thing for joining a group, a
> server can check to see if they are allowed to allow someone to publish
> services. Again, in IDE tooling this can all be setup for the user through
> UIs to make getting going safely much easier.
>
> In all of the above, if we install a module in NetBeans or Eclipse, then
> certificates can be generated at that point to allow for unique and
> protected development keys and certs for the developer, and those can be
> shared by teams or what ever. Too, they can be created as needed.
>
> Now, that takes care of high level security. I need to better understand,
> and I'm working on it, what Jini configurations are supported at this
> level, if any, or if this is all just JVM level stuff basically outside of
> the Jini unless a custom HTTPS or other SSL authentication class is setup.
> Regardless, DSA and RSA will have to be done at the Jini level, and I don't
> know what configuration is available for that yet, but will
> soon...relatively soon :-D
>
> Seems JERI (extensible) and Jini security packages also support extensions
> to security. Seems then we start to get down to finer grained security:
> http://www.jini.org/files/specs/porter/api/net/jini/security/Security.html#
>verifyCodebaseIntegrity(java.lang.String,%20java.lang.ClassLoader)
> http://www.jini.org/files/specs/porter/api/net/jini/security/Security.html#
>verifyObjectTrust(java.lang.Object,%20java.lang.ClassLoader,%20java.util.Col
>lection) others
>
> Both of these things seem pluggable. For the marshelling etc
> IntegrityVerifiers that tie into tooling or automatic systems can be setup.
> Then one can configure specifically allowed signers to always allow their
> code to execute, and that can be done though a UI in user environments and
> through configuration in automated systems either through files, JMX beans,
> etc. Of course, I bet many extensions already do a lot of this, and maybe
> the default services in River do; at least I'm guessing, but I haven't
> gotten to look into everythings sources at this point, at least not as much
> as I need to.
>
> So, given all of the above, and getting back to tooling and IDEs to hook it
> all together, including your ideas on accessing attributes (entries) and
> displaying things to the user, I don't see where the security manager in
> something like NetBeans matters. We can add what ever we need as pluggable
> components to the core and specific modules for different IDEs. Too, as
> long as those things allow us to affect the given classloader in a module,
> as NB does, then we won't be hampered there. Essentially the Jini stuff
> running in some IDE modules will make the determination whether to show
> this or that service or not and individually if used in RCP type
> applications those modules can load whatever remote classes they need
> through Jini and any dependent modules can still work against those modules
> fine.
>
> I see all of the above as good places for improvements in security from a
> good set of standard items to use in the core to a good set of common
> classes we can use in NetBeans and Eclipse for tooling. Of course the UIs
> will be different as one is Swing and the other SWT. I don't know much
> about SWT and Swing interaction, so that will need to be sorted out for
> JavaBeans with user interfaces, components, in them. i.e. a service has
> some SWT UIs in it or Swing UIs in it then those won't work in NB or
> Eclipse respectfully.
>
> Wade
>
> ==================
> Wade Chandler, CCE
> Software Engineer and Developer, Certified Forensic Computer Examiner,
> NetBeans Dream Team Member, and NetBeans Board Member
> http://www.certified-computer-examiner.com
> http://wiki.netbeans.org/wiki/view/NetBeansDreamTeam
> http://www.netbeans.org



Mime
View raw message