Michał Kłeczek wrote:
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.
This is a nice Java mechanism that Jini can make great use of, and the
DynamicPolicy and DynamicPolicyProvider in Jini make a lot of the actions of
DynamicPolicy granting possible/standardized.
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).
Yes, this is an important issue. ServiceLookup allows "code" to be controlled a
little more easily to manage the activation of "polite" service objects.
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.
The bootstrap proxy should always be in the classpath so that it is an object of
known behavior. The ProxyTrustVerifier is in jsk-platform.jar so that it is
visible from the classpath. There is a lot of explict environmental control in
this mechanism to manage verification securely.
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.
The httpmd: protocol handler lets you say, I only trust version X of you code
and that's the version I'll grant access to. And as in your other post, the
DownloadPermission check allows you to control the unmarshalling of anything
that uses a network based codebase.
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)
As I said above, the proxy verification mechanism takes steps to not allow
downloaded code to be used for the code running the verification steps.
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.
The Jini Surrogate standard (http://surrogate.dev.java.net) had support for some
of this to happen. It provides for a device to run a surrogate service on a
large processor where that process could use conventional TCP/IP connectivity to
utilize the Jini infrastructure. This standard was created prior to the
existance of JERI and a lot of the mechanisms in JERI eliminate the issue with
the old dependencies on RMI that drove some of the work in this standard.
But the total size of code and perhaps some security issues can still be better
handled for some types of environments using a surrogate service model.
Gregg Wonderly