Difference between revisions of "Projects/Interposer Mechanism"
(→Interposer initialization) |
|||
(11 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | {{project- |
+ | {{project-rel|1.11}} |
− | This project is about creating a |
+ | This project is about creating a means to intercept GSSAPI operations at the mechglue layer, so that any mechanism can be proxied to a separate application. |
= Background = |
= Background = |
||
− | During the development of the [https://fedorahosted.org/gss-proxy GSS-Proxy project] in connection with |
+ | During the development of the [https://fedorahosted.org/gss-proxy GSS-Proxy project] in connection with [[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 |
+ | The interposer mechanism instructs the mechglue layer on what mechanisms it wants to interpose. Once a mechanism 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 |
+ | The interposer plugin is responsible for handling the requested functionality. It can proxy it to another process (such as a GSS-Proxy daemon) or it can short-circuit it back to the mechglue in order to call the original mechanism handler. |
= Requirements = |
= Requirements = |
||
− | + | * Interposer mechanisms must be able to intercept any mechanism function. |
|
− | + | * Interposer mechanisms must also be able to call back into the mechglue in order to execute code using the original mechanism. |
|
− | + | * Interposer mechanisms must be completely transparent to applications. A 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. |
|
− | = Architecture = |
||
+ | = Design = |
||
− | + | Since interposer module are expected to re-enter the mechglue, it would be inconvenient for such modules to define the same function names as the mechglue does. Therefore, interposer modules are expected to define symbols using the gssi_ prefix instead of the gss_ prefix. |
|
− | + | ||
+ | An interposer mechanism is specified in the /etc/gss/mech file with the string "<interposer>" following the module path. This instructs the mechglue to load the module immediately (rather than when the mechanism is needed) and to use a special loader function to initialize the mechanism. The interposer loader function retrieves the list of interposed mechanisms from the module and adds appropriate state to the table entries for those mechanisms. |
||
+ | |||
+ | Interposer modules create special mech OIDs by concatenating the DER representation of the interposer mechanism OID and that of the original interposed mechanism OID. A concatenated OID is interpreted by the mechglue as a request to invoke the original mechanism's function table. The mechglue makes does not expose special OIDs to applications. |
||
+ | |||
+ | = Limitations = |
||
+ | |||
+ | Currently the mechglue code can handle only one interposer module per real mechanism. |
||
+ | |||
+ | = New APIs = |
||
+ | |||
+ | Interposer initialization: |
||
+ | * gss_mech_interposer() |
||
+ | |||
+ | New mechanism functions: |
||
+ | * gssspi_import_sec_context_by_mech() |
||
+ | * gssspi_import_name_by_mech() |
||
+ | * gssspi_import_cred_by_mech() |
||
+ | |||
+ | == Interposer initialization == |
||
+ | |||
+ | === gss_mech_interposer() === |
||
+ | |||
+ | This function is defined by an interposer module, and is used during module initialization. It takes one argument, which is the OID of the interposer mechanism as specified in /etc/gss/mech, and returns a gss_OID_set giving the list of mechanisms to interpose. The list is freed with the mechglue's gss_release_oid_set, so should be created with the mechglue's gss_create_empty_oid_set and gss_add_oid_set_member functions. |
||
+ | |||
+ | == New mechanism functions == |
||
+ | |||
+ | These functions are required for interposer modules to import GSSAPI objects. The original functions do not include a mechanism OID and do not include the OID tag in the token to be imported. Since an interposer module is expected to intercept multiple mechanisms, it can't know what kind of object to import. |
||
+ | |||
+ | === 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. |
||
+ | |||
+ | = Internal design outline = |
||
+ | |||
+ | Internal mechglue functions: |
||
+ | * gssint_select_mech_type() |
||
+ | * gssint_get_public_oid() |
||
+ | * gssint_make_public_oid_set() |
||
+ | |||
+ | Modified structures: |
||
+ | * gss_mech_info |
||
+ | |||
+ | === gssint_select_mech_type() === |
||
+ | |||
+ | This function is now called in the mechglue each time a mech OID is used as input into a GSSAPI function. For a normal mech OID, it returns the special interposer OID if the mechanism is interposed. For a special OID, it returns the original mechanism OID. |
||
+ | |||
+ | === gssint_get_public_oid() === |
||
+ | |||
+ | This function always returns the real mech OID corresponding to either the real or special OID of the mech. |
||
+ | |||
+ | === gssint_make_public_oid_set() === |
||
+ | |||
+ | As the above but for oid sets. |
||
+ | |||
+ | == 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 [https://fedorahosted.org/gss-proxy 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. This will guarantee no regressions are introduced in the interposer interface. |
||
+ | |||
+ | = Release notes = |
||
+ | |||
+ | Developer experience: |
||
+ | |||
+ | * Add a plugin interface for GSSAPI interposer mechanisms. |
Latest revision as of 17:20, 24 October 2012
This project is about creating a means to intercept GSSAPI operations at the mechglue layer, so that any mechanism can be proxied to a separate application.
Contents
Background
During the development of the GSS-Proxy project in connection with 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 mechanism 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 (such as a GSS-Proxy daemon) or it can short-circuit it back to the mechglue in order to call the original mechanism handler.
Requirements
- Interposer mechanisms must be able to intercept any mechanism function.
- Interposer mechanisms must also be able to call back into the mechglue in order to execute code using the original mechanism.
- Interposer mechanisms must be completely transparent to applications. A 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
Since interposer module are expected to re-enter the mechglue, it would be inconvenient for such modules to define the same function names as the mechglue does. Therefore, interposer modules are expected to define symbols using the gssi_ prefix instead of the gss_ prefix.
An interposer mechanism is specified in the /etc/gss/mech file with the string "<interposer>" following the module path. This instructs the mechglue to load the module immediately (rather than when the mechanism is needed) and to use a special loader function to initialize the mechanism. The interposer loader function retrieves the list of interposed mechanisms from the module and adds appropriate state to the table entries for those mechanisms.
Interposer modules create special mech OIDs by concatenating the DER representation of the interposer mechanism OID and that of the original interposed mechanism OID. A concatenated OID is interpreted by the mechglue as a request to invoke the original mechanism's function table. The mechglue makes does not expose special OIDs to applications.
Limitations
Currently the mechglue code can handle only one interposer module per real mechanism.
New APIs
Interposer initialization:
- gss_mech_interposer()
New mechanism functions:
- gssspi_import_sec_context_by_mech()
- gssspi_import_name_by_mech()
- gssspi_import_cred_by_mech()
Interposer initialization
gss_mech_interposer()
This function is defined by an interposer module, and is used during module initialization. It takes one argument, which is the OID of the interposer mechanism as specified in /etc/gss/mech, and returns a gss_OID_set giving the list of mechanisms to interpose. The list is freed with the mechglue's gss_release_oid_set, so should be created with the mechglue's gss_create_empty_oid_set and gss_add_oid_set_member functions.
New mechanism functions
These functions are required for interposer modules to import GSSAPI objects. The original functions do not include a mechanism OID and do not include the OID tag in the token to be imported. Since an interposer module is expected to intercept multiple mechanisms, it can't know what kind of object to import.
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.
Internal design outline
Internal mechglue functions:
- gssint_select_mech_type()
- gssint_get_public_oid()
- gssint_make_public_oid_set()
Modified structures:
- gss_mech_info
gssint_select_mech_type()
This function is now called in the mechglue each time a mech OID is used as input into a GSSAPI function. For a normal mech OID, it returns the special interposer OID if the mechanism is interposed. For a special OID, it returns the original mechanism OID.
gssint_get_public_oid()
This function always returns the real mech OID corresponding to either the real or special OID of the mech.
gssint_make_public_oid_set()
As the above but for oid sets.
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. This will guarantee no regressions are introduced in the interposer interface.
Release notes
Developer experience:
- Add a plugin interface for GSSAPI interposer mechanisms.