GemTalk / RemoteServiceReplication

MIT License
0 stars 4 forks source link

Pluggable Instantiation Policy #124

Closed kurtkilpela closed 2 years ago

kurtkilpela commented 2 years ago

RSR does not have a means of restricting the set of Service classes that can be instantiated. If you share a Connection with another environment, RSR will happily replicate any Service you provide (assuming it is available in the other environment.)

With this setup, it is not possible for an application to safely implement application-level handshakes. If a user compromises a client, they could access functionality that they should otherwise have been restricted from accessing.

A pluggable reification strategy could help alleviate these problems.

When RSR is in the process of instantiating a Service received over the Connection, it can verify if the Service is available for instantiation. For instance, a developer can specify that Services A, B, and C can be created when received over the wire. If the framework receives a new instance of Service D, it would abort the reification process and alert the other side of the Connection that Service D is not allowed to be instantiated.

The pluggable means should allow the following:

  1. Specify the set of templates the other side is allowed to create and then replicate to us
  2. Allow a restricted object to be replicated, if and only if, it was provided to the remote side by the local side first
  3. Prevent the remote side of the Connection from instantiating any new objects
  4. Allow dynamic changing of the applied restrictions
kurtkilpela commented 2 years ago

This has evolved to describe a Policy object. The Policy is responsible for determining whether a specific Template is allowed in the conditions describe above. It allows the Resolver to find the appropriate Template. It's argument is the Template which was previously resolved via the Resolver.

kurtkilpela commented 2 years ago

RSR uses an instance of RsrRemoteException to report when an exception causes a message send terminate unexpectedly. This is a subclass of RsrReasonService. Disallowing this Service (and other potential future subclasses) would cause framework functionality to break.

Initially, if Policy rejects a Service, I'll additionally check if Template is a subclass of RsrReasonService. If it is, I'll allow it through. Ultimately, we may want to rethink RsrReasonService and associated subclasses.

martinmcclure commented 2 years ago

I suspect that eventually there may be a small number of service classes that are, like RsrReasonService, part of the RSR infrastructure. It seems likely to be more convenient to build these things as services, building on top of the base framework, than to build special cases into the base framework each time. In order for RSR to work correctly, no policy should be able to restrict instantiation of an infrastructure service. One way to do this would be to have template classes respond to a testing method, something like #isInfrastructure or perhaps #availableRegardlessOfPolicy. Any template that answers true is irrevocably available to be instantiated and handle remote messages, overriding any policy.

kurtkilpela commented 2 years ago

My thought is actually something a little different. The purpose of ReasonService is to provide a easy way of reporting back to the otherwise what happened. The list of reasons is small and static. Right now it consists of RemoteException. After Policy, we will add one additional Reason, PolicyRejectedService.

I'm thinking we should just have a binary format for each of the reasons. The data in them is base data types anyways. RemoteException hasn't changed since it was created.

kurtkilpela commented 2 years ago

I'd rather avoid making the Policy and enforcement more complicated. I would also hate to try and debug why a Service is replicating when you've explicitly prevented it from doing so via Policy.

kurtkilpela commented 2 years ago

See PR #126