Projects/Interposer Mechanism
This project is about creating a mechanism by which it is possible to intercept accepting and initializing a security context at the mechglue layer so that any mechanism can be ideally proxied to a separate application potentially running in a different security context.
Contents
Background
During the development of the GSS-Proxy project in connection with the Projects/ProxyGSSAPI a new GSSAPI Mechanism interface has emerged. We call this kind of mechanism an Interposer Mechanism as it intercept all function calls for a specific mechanism.
The Interposer Mechanism instructs the mechglue layer on what mechanisms it wants to interpose. Once a mechnism is interposed the mechglue will always call the interposer for any function related to interposed mechanism.
The interposer plugin is responsible for handling the requested functionality, it can proxy it to another process (for example to the GSS-Proxy daemon) or can short-circuit it back to the mechglue in order to call the original mechanism handler.
Requirements
The Interposer mechanism must be able to intercept any mechanism function. The Interposer mechanism must also be able to call back into the mechglue in order to execute code using the original mechanism. The interposer mechanism should be completely transparent to applications, in that pure gssapi application should not need any modification in order to work with the interposer mechanism nor need to issue any special call to use the interposer functionality.
Design
In order to allow interposer plugins to re-enter the mechglue we had to change their function signature so that the SPI does not match the GSSAPI function signatures, as interposer plugins are allowed to call back into GSSAPI. The interposer plugin SPI uses the gssi_ prefix (GSS Interposer) for all the mechglue functions it implements.
The interposer plugins are specified in the gss.conf file with a new option that identifies them as such. An interposer plugin specific initialization function is used by the mechglue to initialize the plugin and retrieve the list of mechanism the interposer plugin wants to interpose.
Interposer plugins create special mech oids by concatenating the interposer mechanism and the original interposed mechanism oid. This is needed in order to allow the interposer plugin to re-enter the mechglue avoiding loops. These special oids are passed as input to gssapi functions that accept mechanism oids in input instad of the original mechanism oid.
The mechglue makes sure these oids are never leaked to applications, by providing a mapping back to normal public oids before they are returned to applications.
Limitations
Currently the mechglue code can handle only one interposer plugin per-mechanism.
New APIs
Internal mechglue functions:
- gssint_select_mech_type()
- gssint_get_public_oid()
- gssint_make_public_oid_set()
Interposer initialization:
- gss_mech_interposer()
New mechanism functions:
- gssspi_import_sec_context_by_mech()
- gssspi_import_name_by_mech()
- gssspi_import_creD_by_mech()
Modified structures:
- gss_mech_info
Internal mechglue functions
These new functions are used to aid the mechglue in finding the correct mechanism to use when an interposer plugin is configured to intercept real mechanisms.
gssint_select_mech_type()
This funciton is now called in the mechglue each time a mech oid is used as input into a GSSAPI function. It correctly handles looking up by special OID (if a interposer plugin is configured and returns the actual mechanism oid to be used in case a mechanism has been interposed (typically the interposer plugin mechanism).
gssint_get_public_oid()
This function always return the appropriate public oid associated with the input oid which can be an actual public oid or a special interposer oid.
gssint_make_public_oid_set()
As the above but for oid sets.
Interposer initialization
gss_mech_interposer()
This function is looked up right after an interposer plugin is dlopen()ed and is called to initialize the plugin. It returns a list of mechanism to interpose. The mechglue uses this information to properly set up information in the gss_mech_info structure of the plugin and on the structures of the interposed mechanisms.
New mechanism functions
These functions are required to properly pass information to interposer plugins. In particular the original functions did not pass to the interposer plugin the oid of the mechanism these functions are supposed to act on. This is a problem for an interposer plugin that can intercept multiple mechanisms as it has no way to understand which mechanism it is supposed to interpose on a specific request. By passing in the public mechanism oid the mechglue intended to use interposer plugins can properly handle the request.
gssspi_import_sec_context_by_mech()
Same as gss_import_sec_context() but specifies the mechanism to use.
gssspi_import_name_by_mech()
Same as gss_import_name() but specifies the mechanism to use.
gssspi_import_cred_by_mech()
Same as gss_import_cred() but specifies the mechanism to use.
Modified structures
Only one structure needed modifications:
gss_mech_info
This is the structure that describes internally a mechanism. In order to allow GSSAPI to handle interposition this structure has now 3 new members:
- is_interposer
a boolean flag that is used to mark a mechanism as an interposer mechanism and not a real mechanism
- ine_mech_type
the oid of the interposer mechanism, it is set on real mechanisms
- int_mech
pointer to the interposer mechanism vtable
New Functions Signatures
OM_uint32 gssint_select_mech_type( OM_uint32 *minor, gss_const_OID oid, gss_OID *selected_oid );
gss_OID gssint_get_public_oid( gss_const_OID oid );
OM_uint32 gssint_make_public_oid_set( OM_uint32 *minor_status, gss_OID oids, int count, gss_OID_set *public_set );
OM_uint32 gssspi_import_sec_context_by_mech( OM_uint32 *minor_status, gss_OID desired_mech, gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle );
OM_uint32 gssspi_import_name_by_mech( OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t input_name_buffer, gss_OID input_name_type, gss_name_t *output_name );
OM_uint32 gssspi_import_cred_by_mech( OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t token, gss_cred_id_t *cred_handle );
gss_OID_set gss_mech_interposer( gss_OID mech_type );
Testing
An interposer plugin with a test program is being worked on as part of the GSS-Proxy project. that work will be used as a template for internal tests once it is complete. The internal test will simply loopback into gssapi. Thi will guarantee no regressions are introduced in the interposer interface.