Sam Hartman wrote: > > One long-running aspect of our release process is that the trunk is > allowed to take advantage of features on the trunk. In particular > this means things like as we get new implementations of CCAPI, KIM and > other APIs available, we'll want to start using them. And we don't > generally support backward compatibility for this sort of change. > > One consequence of this is that we may start running into cases where > specific changes to KFW will end up depending on the 1.7 release or > at least the 1.7 release branch. I'd expect to get to a point in a > few months where any significant changes to KFW would depend on 1.7. I would recommend that parallel development take place on a branch cut from 1.6.
I am attaching a document that describes the work that has been performed on NIM 2.0 and that partially describes what remains to be accomplished. The redesign work on the NIM API in order to maintain backward compatibility with existing credential providers shipped by third parties and to anticipate future needs has obviously taken longer than expected. Asanka will follow up next week with a more detailed description of the remaining pieces that must be developed. In my opinion, it is perfectly acceptable for the initial X.509 identity provider to be shipped as an add-on to KFW. Jeffrey Altman
Design Specifications and Status of Network Identity Manager 2.0
----------------------------------------------------------------
1. Identity Providers
Network Identity Manager versions prior to 2.0 only supported a
single identity provider. This was always Krb5Ident, which is the
Kerberos v5 identity provider. NIM 2.0 supports multiple identity
providers. As such, the role and the interface between identity
providers and NIM needed to be changed significantly.
Two additional source files were introduced in order to manage
and interface with identity providers. These are :
src/windows/identity/kcreddb/identpro.c and
src/windows/identity/kcreddb/identpro.h
These source files implement the following APIs along with other
support functions:
kcdb_identpro_find();
kcdb_identpro_get_name();
kcdb_identpro_get_type();
kcdb_identpro_hold();
kcdb_identpro_release();
kcdb_identpro_begin_enum();
kcdb_identpro_get_default();
The following APIs are not marked for export. They are only
visible to the NIM application and the NIM library.
kcdb_identpro_validate_name_ex();
kcdb_identpro_validate_name();
kcdb_identpro_canon_name();
kcdb_identpro_canon_name_ex();
kcdb_identpro_compare_name();
kcdb_identpro_compare_name_ex();
kcdb_identpro_set_default_identity();
kcdb_identpro_get_default_identity();
kcdb_identpro_update();
kcdb_identpro_get_ui_cb();
kcdb_identpro_get_ui_cb_ex();
kcdb_identpro_notify_create();
kcdb_identity_set_provider(), kcdb_identity_set_type(),
kcdb_identity_get_provider() and kcdb_identity_get_type() have
been moved from identity.c to identpro.c and remain backwards
compatible.
1.1 Registration
Identity providers do not have to be explicitly registered. If
the type of the plug-in is set to KHM_PITYPE_IDENT, then the
plug-in manager handles the task of notifying the framework at
the time the plug-in is loaded.
When loading an identity provider plug-in, the plug-in manager
calls kcdb_identity_set_provider() with the plug-in message
subscription. This function creates an identity provider record
based on the plug-in record and adds it to the identity provider
collection.
The name of an identity provider will always be the name of the
plug-in that provides it. The framework does not intend to
support scenarios where more than one identity provider may be
registered by a single plug-in.
When adding a plug-in to the collection, an ordering is enforced
based on an ordered list of provider names that is read from the
configuration. The first provider in the list will become the
default identity provider and will be used for backwards
compatibility. It is the intention that MIT KFW distributions
will configure the krb5 provider as the first entry in the list.
During identity provider plug-in initialization, the plug-in
notifies the framework which credentials type the identity provider
considers to be its identity credentials type. The purpose of
the identity credentials type is to allow the NIM application to
determine which credentials belonging to an identity define it.
Identity provider plug-ins are not required to have an associated
credentials provider although at the current time there is no
expectation that identity providers would ever be implemented
that do not.
1.2 Relation to Identities
When there is more than one identity provider, the provider that
an identity is associated with is no longer implicit. Hence, the
data structure that defines identities ( kcdb_identity ) will
indicate the associated identity provider.
The provider associated with an identity needs to be determined at
the time an identity is created. As such,
kcdb_identity_create_ex() has been introduced that replaces
kcdb_identity_create(). The new function takes a handle to an
identity provider that is to be associated with the newly created
identity. Calls to kcdb_identity_create() will use the provider
specified by the identity name prefix or the default identity
provider if no identity name prefix is specified.
1.2.1 Default Identity
Since the identity providers are expected to be relatively
independent from each other, having a single default identity will
no suffice. Therefore, each identity provider maintains its own
default identity. When setting a default using
kcdb_identity_set_default() or kcdb_identity_set_default_int(),
the specified identity will become the default for the provider it
is associated with. Other providers will be unaffected.
kcdb_identity_get_default() will return the default identity for
the default provider, while the new function
kcdb_identity_get_default_ex() can be used to query the default
identity for any provider.
If there is an interdependence on the default identities of
different providers, the provider plug-ins may listen for
<KMSG_KCDB,KMSG_KCDB_IDENT> messages for changes to the default
identities of other providers and adjust its own default
accordingly.
2. UI Resources
2.1 Resources by Context
The API for NIM versions prior to 2.0 severely limited the ability
of plug-ins to provide UI resources to the NIM application.
For example, the short description for a credentials type is used
in the following ways in NIM 1.x:
i) The description of the credentials type associated with the
identity provider is used as the name of the identity type.
ii) As the description of a credential belonging to the type.
iii) As the description of the credential type.
For Kerberos v5, it would be more accurate if i) was "Kerberos v5
Principal", ii) was "Kerberos v5 Ticket" and iii) was "Kerberos
v5". While this is not a critical issue for Kerberos v5, it may
cause usability issues for other providers.
Resource specification is a necessity in NIM 2.0 where identity
providers need to provide strings to describe themselves in
different contexts as well as custom icons to represent individual
identities or identities that are associated with a particular
provider.
In order to allow credentials and identity providers to specify
such resources based on context, the new API kcdb_get_resource()
was introduced. This function takes a handle to an identity,
identity provider or a credentials type and a resource identifier
along with a set of flags to query credentials and identity
providers for resource strings and icons for the specified object.
KHMEXP khm_int32 KHMAPI
kcdb_get_resource(khm_handle h, kcdb_resource_id r_id,
khm_int32 flags, khm_int32 *prflags,
void * vparam,
void * buf, khm_size * pcb_buf)
The implementation of the function queries the plug-in that
provides the specified object for the resource using a synchronous
<KMSG_CRED,KMSG_CRED_GET_RESOURCE> message if applicable. If the
plug-in does not support this message, the function will fail
over and use the description strings and resources specified at
the time the credentials provider was registered.
2.2 Display Strings
Identity names and credential names are no longer required to be
localized and user friendly. Instead, a new attribute,
KCDB_ATTR_DISPLAY_NAME was introduced to assocate a localized user
friendly display name by which the identity or credential can be
presented to the user.
The internal name of the identity must be unique among identities
associated with a specific provider and the triple [identity,
credential type, credential name] must be globally unique for
credentials. Having a separate display name for identities and
credentials allows plug-ins to use convenient internal names for
these objects while not compromising usability. At the same
time, this makes it possible to set the names of these objects
independent of locale.
When trying to obtain the display name of an identity using
kcdb_get_resource(), if the KCDB_ATTR_DISPLAY_NAME attribute is
not present, the name of the object will be used as the
display name.
2.3 Resource Caching
Since querying plug-ins for resources can be an expensive
operation, the implementation uses a resource cache. The NIM 1.x
API did contain a simple resource cache that was intended to cache
bitmaps and their metadata, however it was not put to use. In NIM
2.0, this resource cache has been extended to support caching
strings, icons and bitmaps for credential objects as well as
modules. New code has been added to
src/windows/identity/rescache.c to manage and perform cleanup for
these resources.
The unused functions khui_cache_bitmap() and
khui_get_cached_bitmap() have been removed. They were not
documented to be part of the API. The new functions are:
KHMEXP khm_int32 KHMAPI
khui_cache_add_resource(khm_handle owner, khm_int32 id,
khm_restype type,
void * buf, khm_size cb_buf);
KHMEXP khm_int32 KHMAPI
khui_cache_get_resource(khm_handle owner, khm_int32 id, khm_restype type,
void * buf, khm_size *pcb_buf);
KHMEXP khm_int32 KHMAPI
khui_cache_del_resource(khm_handle owner, khm_int32 id, khm_restype type);
KHMEXP khm_int32 KHMAPI
khui_cache_del_by_owner(khm_handle owner);
These are currently not marked for export. In other words, these
are not visible for use by third-party plug-ins and are only used
by the NIM application and the NIM library.
3. Handle Management and Enumeration
NIM 2.0 adds identity provider handles as another handle type.
The NIM 1.x API defined a set of functions that can be used on
credential or identity handles to query for attributes. This lets
users of the NIM library to operate on KCDB objects using the same
set of functions. NIM 2.0 extends these generic functions to
support enumeration and handle type checking.
In NIM 1.x, enumerating identities involved obtaining a multi-
string containing the names of all the identities that match a set
of criteria and then manually walking through the list. NIM 2.0
adds a generic enumeration mechanism that can be used to enumerate
collections of identities and identity providers. As an example:
{
kcdb_enumeration e = NULL;
khm_size n_id;
khm_handle h_id = NULL;
if (KHM_SUCCEEDED(kcdb_identity_begin_enum(KCDB_IDENT_FLAG_STICKY,
KCDB_IDENT_FLAG_STICKY,
&e, &n_id))) {
// Now n_id has the number of sticky active identities that were
// included in the enumeration, although we won't be using it.
// Note that h_id is initialized to NULL above.
while (KHM_SUCCEEDED(kcdb_enum_next(e, &h_id))) {
// Do something with h_id
// The handle in h_id will be automatically released during
// the next call to kcdb_enum_next().
}
kcdb_enum_end(e);
// h_id is guaranteed to be NULL at this point, since the last
// call to kcdb_enum_next() failed.
}
} else {
// The call to kcdb_identity_begin_enum() failed. Typically this
// means that there were no identities to enumerate.
}
The functions kcdb_identity_begin_enum() and
kcdb_identpro_begin_enum() both return a kcdb_enumeration handle.
This handle can be used with the new functions kcdb_enum_next(),
and kcdb_enum_end() as above.
There are two other new functions, kcdb_enum_reset() and
kcdb_enum_sort().
kcdb_enum_reset() resets the state of the enumeration handle so
that the caller can enumerate the collection from the beginning.
kcdb_enum_sort() can be used to sort the order in which objects
appear in the collection if the objects are to be returned in a
particular order.
4. General Changes to the API
4.1 Computed Properties
In NIM 1.x, computed properties were only supported for
credentials. These properties allow plug-ins to specify
properties whose values were derived from other properties. An
example is KCDB_ATTR_TIMELEFT, which returns the remaining
lifetime of a credential. It is calculated by taking the
difference between the current time and the time specified in
KCDB_ATTR_EXPIRE.
Along with handle type checking and generic access to KCDB
objects, NIM 2.0 adds support for custom properties in identities
as well. Earlier, the remaining lifetime of an identity had to be
calculated manually because KCDB_ATTR_EXPIRE was not defined for
identities. However, now this value can be computed automatically
using the same code used to generate computed properties in
credentials as long as the identity provider has set the
KCDB_ATTR_EXPIRE property for the identity.
NIM 2.0 uses computed properties for identities for other purposes
as described below.
4.2 Additional Properties
The NIM 1.x application maintained several statistics for each
active identity such as the number of credentials that are
associated with the identity, the number of identity credentials
and the number of initial credentials. With the addition of
custom property support for identities in NIM 2.0, the task of
maintaining these statistics has been transferred to the KCDB.
These statistics are exposed using the following additional
properties:
/*! \brief Number of credentials
Number of credentials in the root credentials set that are
associated with this identity.
- \b Type: INT32
- \b Flags: SYSTEM, COMPUTED, PROPERTY
*/
#define KCDB_ATTR_N_CREDS (KCDB_ATTR_MIN_PROP_ID + 0)
/*! \brief Number of identity credentials
Number of identity credentials in the root credentials set that are
associated with this identity.
An identity credential is a credential that is of the identity
credentials type.
- \b Type: INT32
- \b Flags: SYSTEM, COMPUTED, PROPERTY
*/
#define KCDB_ATTR_N_IDCREDS (KCDB_ATTR_MIN_PROP_ID + 1)
/*! \brief Number of initial credentials
Number of identity credentials in the root credentials set that are
associated with this identity and are marked as initial credentials.
- \b Type: INT32
- \b Flags: SYSTEM, COMPUTED, PROPERTY
*/
#define KCDB_ATTR_N_INITCREDS (KCDB_ATTR_MIN_PROP_ID + 2)
These were made necessary because NIM 2.0 aims to provider a
richer representation of identities to the user. As such,
statistics like the above are queried more frequently and
in more places than in NIM 1.x.
4.3 Deprecation
Several functions that should no longer be used have been
deprecated. The API header files mark each of these functions and
macros with a #pragma deprecated() directive that will generate
compile time warnings if they are used in code. While the code
has been re-written to be backwards compatible for the moment,
eventually these should be removed.
4.4 Backwards Compatibility
Credentials providers built for NIM 1.x are binary compatible with
NIM 2.0. However, attempting to build code written for NIM 1.x
using the NIM 2.0 SDK may result in compiler warnings if any
deprecated functions were used.
Identity providers are not backwards compatible. However, since
the only identity provider that existed for NIM 1.x was Krb5Ident
and a replacement is included with NIM 2.0, this is not expected
to be a problem.
4.4.1 Configuration
NIM 1.x stored per-identity configuration in a registry key with
the same name as the identity. However, since identity names are
only required to be unique for a given identity provider, this
convention can no longer be applied.
Instead, the name of the identity will be prefixed by the name of
the identity provider. For example, if an identity name 'I' is
associated with a provider name 'P', then the configuration space
used to store the per-identity configuration will be 'P:I'. For
backwards compatibility, the prefix will not be used when the
identity provider is 'Krb5Ident'.
5. New Credentials Dialog
As proposed earlier, much of the work outlined above was done to
support multiple identity provider support in preparation of the
changes to the New Credentials dialog user experience in NIM 2.0.
The new credentials dialog is implemented as a wizard. The main
wizard interface is a blank dialog on which the identity
selection, main interaction panel, identity specification panel
and the navigation panel will be positioned as child dialogs.
5.1 Identity Specification Panel
In NIM 1.x, identity specification involved querying the identity
provider for a set of controls that the NIM application laid out
in a suitable fashion. This was done because identity
specification had to be done in multiple dialogs; not just the new
credentials dialog, and due to the way custom prompting was
supported, a layout manager already existed.
NIM 2.0 allows identity providers to specify a single control
instead of a set. The single control will be positioned to cover
the entire area that is available for interacting with the user
for the purpose of specifying the identity. Using this mechanism,
providers can create a child dialog that contains the controls
necessary for identity specification and pass the child dialog to
the NIM application. This gives complete control of the child
dialog behavior to the provider while making it simpler for the
NIM application to manage the overall dialog behavior.
5.2 Dynamic Layouts
Dynamic layouts are still supported and can be used when preparing
the privileged interaction panel. This is still necessary for
supporting custom prompting in Kerberos v5. However, unlike NIM
1.x, plug-ins are no longer restricted to using dynamic layouts.
5.3 Basic and Advanced Views
The New Credentials wizard in NIM 2.0 can switch between the
basic and advanced views. When switching between modes, instead
of repositioning controls in code, NIM 2.0 replaces the main panel
with dialog created from a template that specifies the new layout
and reparents and repositions any controls onto the new dialog.
In other words, when switching between basic and advanced modes,
the positions of controls are not computed in code. Instead, they
are taken from a dialog template.
5.4 Privileged Interaction
Credentials providers can request to perform privileged
interaction with the user. Privileged interaction is only meant
to ask the user for privileged information such as passwords and
responses to challenges.
NIM 1.x had only one privileged interaction panel. NIM 2.0
supports multiple panels which will be queued and presented to the
user as the wizard progresses.
Each panel can either host a single control specified by the
credentials provider, or can be a dynamically laid out set of
prompts. The functions khui_cw_clear_prompts(),
khui_cw_begin_custom_prompts(), khui_cw_add_prompt(),
khui_cw_get_prompt() functions will work the same way they do in
NIM 1.x and automatically create a dynamically laid out
interaction panel. Alternatively, the new function
khui_cw_set_prompt_panel() can be used to specify a single control
that will take the place of the interaction panel.
5.4 Workflow
Since the primary identity for the New Credentials dialog is not
known at the time the new credentials operation begins, all
credentials providers and identity providers are expected to
participate in the operation initially. Once a primary identity
has been selected, individual credentials providers will be
notified via a WMNC_IDENTITY_CHANGE message. Each provider is
then expected to determine whether it wants to participate in
obtaining credentials for the selected identity and notify the NIM
application by calling khui_nc_enable_type(). Only the
credentials types that are enabled for the selected identity will
be able to interact with the user and receive KMSG_CRED_PROCESS
messages.
5.5 Progress
Plug-ins that are participating in the new credentials operation
are expected to call kherr_set_progress() periodically to indicate
the progress if the credentials acquisition is expected to take a
more than a few seconds. The New Credentials wizard will end with
the Progress Page, where the user will be shown the progress of
each provider.
The progress information is queried using kherr_get_progress()
from the NIM application during new credentials acquisition. The
KHERR framework maintains progress information for each thread
that is handling a particular message, in addition to collecting
log and error messages generated during the operation. This
framework is already present in NIM 1.x, though not fully
utilized.
If the user aborts the new credentials operation, the
corresponding instance of the KMSG_CRED_PROCESS message will be
marked as aborted. Plug-ins that are handling the message are
expected to call kmq_is_call_aborted() to check for this condition
and act accordingly. The New Credentials wizard cannot forcefully
abort a plug-in.
6. Modifications to Kerberos v5 Plug-ins
The Kerberos v5 Identity Provider needs to be updated to:
- Support <KMSG_CRED, KMSG_CRED_GET_RESOURCE>.
- Support display names for identities.
- Use a dialog template for identity specification.
- Stop using deprecated functions and use the corresponding new
functions for identity management and enumeration.
The identity provider management operations are transparent to the
identity providers.
The Kerberos v5 Credentials Provider needs to be updated to:
- Use display names for credentials
- Stop using deprecated functions and use the corresponding new
functions.
7. Other UI Modifications
- Identity configuration panels:
- Support custom icons
- Not all credentials type panels will be applicable for every
identity. When the configuration UI attempts to initialize a
credentials type panel, the panel should check if the type is
applicable to the selected identity and fail if not.
- Per-identity actions and configuration nodes are currently
registered using a name derived from the identity name. This
scheme will need to be changed to use a name derived from the
provider as well as the identity name.
- Menu items that include identity names should also include the
provider name.
8. Samples
8.1 Sample Identity Provider
A sample identity provider should be introduced. Currently, no
identity provider sample is included in the SDK.
8.2 Sample Credentials Provider
The sample credentials provider should be updated to use the new
API and handle the new messages.
9. Status
9.1 Completed Work
The work mentioned in sections 1..4 have been completed. More
testing needs to be done to make sure the back-end code is working
properly.
In section 5, the dialog templates and the associated code for
instantiating the templates and laying out the individual dialogs
is in place. The wizard workflow has been outlined, but only
partially implemented.
9.2 To-do
The work in sections 6, 7 and 8 remains to be done.
smime.p7s
Description: S/MIME Cryptographic Signature
_______________________________________________ kfwdev mailing list [email protected] http://mailman.mit.edu/mailman/listinfo/kfwdev
