Projects/ProxyGSSAPI
This project is about creating a mechanism by which it is possible to proxy accepting and initializing a security context to a separate trusted system service without giving access to long term keys to an application. The proxy would be created at the mechglue layer so that any mechanism can be proxied.
Contents
Background
We have identified two main scenarios that benefit from this approach.
One is the ability to lock long term keys (especially the host/ key when the krb5 mechanism is used) into a trusted service on the system so that "less" trusted applications do not have direct access to the keys. This is a form of privilege separation that allows better control of the keys and reduces the attack surface of the system when it comes to gaining access to such keys.
The other is about trusting data being carried through, for example, krb5 tickets. In systems that use signed authorization data, it is fundamental for a "trusted" service to directly handle accepting a context so that it is impossible for an application to "fake" Authorization data by having access to the host keys and therefore being able to sign authorization data blobs. As an example think of a user accessing a FTP daemon and sending a user credentials (MS-PAC/PAD) in the ticket. A trusted service need to be able to verify that the KDC actually did sign this data in order to trust its authenticity and allow the system to create a user out of this data. A way to fully trust this data when it is signed by the long term key is to not allow the FTP service to have access to the long term keys, so that a subverted service is not allowed to create fake data and sign it in order to perform privilege elevation attacks.
Requirements
In order to be able to implement this proxy it is fundamental to be able to create an IPC mechanism to transfer data from the process handling the GSSAPI exchange to the trusted service holding the keys and negotiating the security context.
This IPC mechanism should use a defined protocol so that independent implementations of the trusted service can be created.
Interface stability either at an API level (if an endpoint library is created) or at the protocol level is highly desirable but not fundamental.
Considerations on the design
There are a few challenges that need to be considered for this project.
Access privileges
Currently access to credentials is determined base on file permissions. If the user/application have access to the keytab/credentials then it is allowed to use them for any purpose. By adding an IPC mechanism we need to also add a mechanism to determine what privileges the calling in process have.
One way to do this is by replicating the permission model on keytab files as permission on the directories containing the unix socket. One directory per credential/keytab with file system permissions et so only processes belonging to the user owner can access the IPC pipe. On some systems it is also possible to inspect the credentials of the connecting process via special system calls on the socket. On those systems it is possible to decide to use a single socket and perform access control in the daemon.
What to proxy ?
There are a few ways the proxy code can be designed.
a) Proxy everything unconditionally in any case b) Have a flag or method call that can tell which mechanisms to proxy c) Proxy on a per application based on per application configuration
Each of them may be desirable but there are a few drawbacks with each approach:
With (a) it may turn out that the mechanism will need access to long term secrets even after the security context has been established. That could be handled by passing in the long term keys with the export/import credentials function that is needed to transfer session keys. This would render privilege separation useless though. Another option would be to provide extensions so mechanism can delegate these operation to the proxy, but this looks tricky.
With (b), mechanisms that cannot easily be proxied could be marked as such and not proxied. The issue here is that there are meta-mechs like SPNEGO that would have to deal with the saem flags and change behavior dynamically based on which mech is being probed. It is not unconceivable to make meta-mechs smart enough to do that but probably too much for a first release.
The problem with (c) is that it may require application changes to add the desired option, and in general you want a global policy. However a simplistic method to check whether to proxy or not could be for the GSSAPI to check if direct access to credentials is available and skip proxying in case direct access is possible.
RPC mechanism
In order to proxy data around the IPC pipes need to be able to (un)marshal data back and forth. There are a few options I can see to handle messaging.
a) Stick all data in a flat structure that uses no pointers and just shove a copy of the structure down the socket. If proper alignment is used for the structure than even hybrid32/64 bit systems should be able to exchange data between 32 bit and 64 bit processes without issues. On the other hand it is very easy to break such a protocol by simply changing the structure. It is also somewhat difficult to deal with variable size buffers and optional values.
b) Manually (un)marshal data in a custom crafted protocol. Not really appealing unless the data to be transfered is really simple and the variations/type of messages are very few and well defined.
c) Use an RPC library that has an IDL compiler/stub generator and all the tools necessary to automatically serialize structures and data. This is definitely the preferred solution when complex structures need to be passed around. Unfortunately the current MIT libraries lack an IDL compiler, so some updates/new dependencies would need to be introduced.
d) Defer the actual RPC mechanism by offloading data transfer to a pluggable library mechanism. This would offload the problem on the trusted service implementers. But it would also mean problems with interoperability and problems with testing in tree. Testing is especially important in order to prevent breakage.
The GSSAPI interfaces include some complex structures like channel bindings and session crdentials that need to be passed back and forth. So option (c) looks like the soundest approach.
Milestones
- Introduce new RPC library with stub generator/IDL compiler
- Define the RPC interfaces to be implemented
- Introduce a new meta-mechanism that implements the client side of the proxy
- Create a simple server program for testing purposes
Documentation
TBD
Dependencies
TBD, potentially needs to rupdate the RPC code.
Goal
Have a working prototype for the 1.11 release
Testing Plan
TBD