kim_selection_hints.h   [plain text]

/*
* Copyright 2005-2006 Massachusetts Institute of Technology.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission.  Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose.  It is provided "as is" without express
* or implied warranty.
*/

#ifndef KIM_SELECTION_HINTS_H
#define KIM_SELECTION_HINTS_H

#ifdef __cplusplus
extern "C" {
#endif

#include <Kerberos/kim_types.h>

/*!
* \page kim_selection_hints_overview KIM Selection Hints Overview
*
* \section kim_selection_hints_introduction Introduction
*
* Most users belong to multiple organizations and thus need
* to authenticate to multiple Kerberos realms.  Traditionally Kerberos sites
* solved this problem by setting up a cross-realm relationship, which allowed
* the user to use TGT credentials for their client identity in one realm
* to obtain credentials in another realm via cross-realm authentication.  As a
* result users could acquire credentials for a single client identity and use
* them everywhere.
*
* Setting up cross-realm requires that realms share a secret, so sites must
* coordinate with one another to set up a cross-realm relationship.  In
* addition, sites must set up authorization policies for users from other
* realms.  As Kerberos becomes increasingly wide-spread, many realms will
* not have cross-realm relationships, and users will need to
* manually obtain credentials for their client identity at each realm
* (eg: "user@BANK.COM", "user@UNIVERSITY.EDU", etc).  As a result, users
* will often have multiple credentials caches, one for each client identity.
*
* Unfortunately this presents a problem for applications which need to obtain
* service credentials.  Which client identity should they use?
* Rather than having each application to manually search the cache collection,
* KIM provides a selection hints API for choosing the best client identity.
* This API is intended to simplify the process of choosing credentials
* and provide consistent behavior across all applications.
*
* Searching the cache collection for credentials may be expensive if there
* are a large number of caches.  If credentials for the client identity
* are expired or not present, KIM may also wish to prompt the user for
* new credentials for the appropriate client identity.  As a result,
* applications might want to remember which client identity worked in
* the past and always request credentials using that identity.
*
*
* \section kim_selection_hints_creating Creating KIM Selection Hints
*
* A KIM selection hints object consists of an application identifier and one or
* more pieces of information about the service the client application will be
* contacting.  The application identifier is used by user preferences
* to control how applications share cache entries.  It is important to be
* consistent about what application identifier you provide.  Java-style
* identifiers are recommended to avoid collisions.
*
* \section kim_selection_hints_searching Selection Hint Search Behavior
*
* When using selection hints to search for an appropriate client identity,
* KIM uses a consistent hint search order.  This allows applications to specify
* potentially contradictory information without preventing KIM from locating a
* single ccache.  In addition the selection hint search order may change,
* especially if more hints are added.
*
* As a result, callers are encouraged to provide all relevant search hints,
* even if only a subset of those search hints are necessary to get reasonable
* behavior in the current implementation.  Doing so will provide the most
* user-friendly selection experience.
*
* Currently the search order looks like this:
*
* \li <B>Service Identity</B> The client identity which has obtained a service credential for this service identity.
* \li <B>Server</B> A client identity which has obtained a service credential for this server.
* \li <B>Service Realm</B> A client identity which has obtained a service credential for this realm.
* \li <B>Service</B> A client identity which has obtained a service credential for this service.
* \li <B>Client Realm</B> A client identity in this realm.
* \li <B>User</B> A client identity whose first component is this user string.
*
* For example, if you specify a service identity and a credential for
* that identity already exists in the ccache collection, KIM may use that
* ccache, even if your user and client realm entries in the selection hints would
* lead it to choose a different ccache.  If no credentials for the service identity
* exist then KIM will fall back on the user and realm hints.
*
* \note Due to performance and information exposure concerns, currently all
* searching is done by examining the cache collection.  In the future the KIM
* may also make network requests as part of its search algorithm.  For example
* it might check to see if the TGT credentials in each ccache can obtain
* credentials for the service identity specified by the selection hints.
*
* \section kim_selection_hints_selecting Selecting an Identity Using Selection Hints
*
* Once you have provided search criteria for selecting an identity, use
* #kim_selection_hints_get_identity() to obtain an identity object.
* You can then use #kim_identity_get_string() to obtain a krb5 principal
* string for use with gss_import_name() and gss_acquire_cred().  Alternatively,
* you can use #kim_ccache_create_from_client_identity() to obtain a ccache
* containing credentials for the identity.
*
* \note #kim_selection_hints_get_identity() obtains an identity based on
* the current state of the selection hints object.  If you change the
* selection hints object you must call #kim_selection_hints_get_identity()
* again.
*
* \section kim_selection_hints_caching Selection Hint Caching Behavior
*
* In addition to using selection hints to search for an appropriate client
* identity, KIM can also use them to remember which client identity worked.
* KIM maintains a per-user cache mapping selection hints to identities so
* that applications do not have to maintain their own caches or present
* user interface for selecting which cache to use.
*
* When #kim_selection_hints_get_identity() is called KIM looks up in the
* cache and returns the identity which the selection hints map to.  If
* there is not a preexisting cache entry for the selection hints then
* #kim_selection_hints_get_identity() will search for an identity and
* prompt the user if it cannot find an appropriate one.
*
* If the client identity returned by KIM authenticates and passes
* authorization checks, you should tell KIM to cache the identity by calling
* #kim_selection_hints_remember_identity().  This will create a cache entry
* for the mapping between your selection hints and the identity so that
* subsequent calls to #kim_selection_hints_get_identity() do not need to
* prompt the user.
*
* If the client identity returned by KIM fails to authenticate or fails
* authorization checks, you must call #kim_selection_hints_forget_identity()
* to remove any mapping that already exists.  After this function is called,
* future calls to #kim_selection_hints_get_identity() will search for an
* identity again.  You may also wish to call this function if the user
* changes your application preferences such that the identity might be
* invalidated.
*
* \note It is very important that you call #kim_selection_hints_forget_identity()
* if your application fails to successfully establish a connection with the
* server. Otherwise the user can get "stuck" using the same non-working
* identity if they chose the wrong one accidentally or if their identity
* information changes.  Because only your application understands the
* authorization checksof the protocol it uses, KIM cannot tell whether or not
* the identity worked.
*
* If you wish to search and prompt for an identity without using
* the cached mappings, you can turn off the cached mapping lookups using
* #kim_selection_hints_set_remember_identity().  This is not recommended
* for most applications since it will result in a lot of unnecessary
* searching and prompting for identities.
*
* \note Because cache entries key off of selection hints, it is important
* to always specify the same hints when contacting a particular
* service.  Otherwise KIM will not always find the cache entries.
*
* \section kim_selection_hints_prompt Selection Hint Prompting Behavior
*
* If valid credentials for identity in the selection hints cache are
* unavailable or if no identity could be found using searching or caching
* when #kim_selection_hints_get_identity() is called, KIM may present a
* GUI to ask the user to select an identity or acquire credentials for
* an identity.
*
* \note Because of the caching behavior described above the user will
* only be prompted to choose an identity when setting up the application
* or when their identity stops working.
*
* In order to let the user know why Kerberos needs their assistance, KIM
* displays the name of the application which requested the identity
* selection. Unfortunately, some platforms do not provide a runtime
* mechanism for determining the name of the calling process.  If your
* application runs on one of these platforms (or is cross-platform)
* you should provide a localized version of its name with
* the private function #kim_library_set_application_name().
*
* In many cases a single application may select different identities for
* different purposes.  For example an email application might use different
* identities to check mail for different accounts.  If your application
* has this property you may need to provide the user with a localized
* string describing how the identity will be used.  You can specify
* this string with #kim_selection_hints_get_explanation().  You can find
* out what string will be used with kim_selection_hints_set_explanation().
*
* Since the user may choose to acquire credentials when selection an
* identity, KIM also provides #kim_selection_hints_set_options() to
* set what credential acquisition options are used.
* #kim_selection_hints_get_options() returns the options which will be used.
*
* If you need to disable user interaction, use
* #kim_selection_hints_set_allow_user_interaction().  Use
* #kim_selection_hints_get_allow_user_interaction() to find out whether or
* not user interaction is enabled.  User interaction is enabled by default.
*
* See \ref kim_selection_hints_reference for information on specific APIs.
*/

/*!
* \defgroup kim_selection_hints_reference KIM Selection Hints Reference Documentation
* @{
*/

/*! A client identity in this realm.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_client_realm     "kim_hint_key_client_realm"

/*! A client identity whose first component is this user string.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_user             "kim_hint_key_user"

/*! A client identity which has obtained a service credential for this realm.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_service_realm    "kim_hint_key_service_realm"

/*! A client identity which has obtained a service credential for this service.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_service          "kim_hint_key_service"

/*! A client identity which has obtained a service credential for this server.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_server           "kim_hint_key_server"

/*! The client identity which has obtained a service credential for this service identity.
* See \ref kim_selection_hints_overview for more information */
#define kim_hint_key_service_identity "kim_hint_key_service_identity"

/*!
* \param out_selection_hints       on exit, a new selection hints object.
*                                  Must be freed with kim_selection_hints_free().
* \param in_application_identifier an application identifier string.  Java-style identifiers are recommended
*                                  to avoid cache entry collisions (eg: "com.example.MyApplication")
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Create a new selection hints object.
*/
kim_error kim_selection_hints_create (kim_selection_hints *out_selection_hints,
kim_string           in_application_identifier);

/*!
* \param out_selection_hints on exit, a new selection hints object which is a copy of in_selection_hints.
*                            Must be freed with kim_selection_hints_free().
* \param in_selection_hints  a selection hints object.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Copy a selection hints object.
*/
kim_error kim_selection_hints_copy (kim_selection_hints *out_selection_hints,
kim_selection_hints  in_selection_hints);

/*!
* \param io_selection_hints    a selection hints object to modify.
* \param in_hint_key           A string representing the type of hint to set.
* \param in_hint_string        A string representation of a hint for
*                              \a in_hint_key to set in \a in_selection_hints.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Set the string value of a hint used for identity selection.
* \sa kim_selection_hints_get_hint()
*/
kim_error kim_selection_hints_set_hint (kim_selection_hints io_selection_hints,
kim_string          in_hint_key,
kim_string          in_hint_string);

/*!
* \param in_selection_hints    a selection hints object.
* \param in_hint_key           A string representing the type of hint to
*                              obtain.
* \param out_hint_string       On exit, a string representation of the hint
*                              \a in_hint_key in \a in_selection_hints.
*                              If the hint is not set, sets the value pointed
*                              to by \a out_hint_string to NULL;
*                              Must be freed with kim_string_free().
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Get the string value of a hint used for identity selection.
* \sa kim_selection_hints_set_hint()
*/
kim_error kim_selection_hints_get_hint (kim_selection_hints  in_selection_hints,
kim_string           in_hint_key,
kim_string          *out_hint_string);

/*!
* \param io_selection_hints  a selection hints object to modify.
* \param in_explanation      a localized string describing why the caller needs the identity.
* \note If the application only does one thing (the reason it needs an identity is obvious)
* then you may not need to call this function.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Set the strings used to prompt the user to select the identity.
* \sa kim_selection_hints_get_explanation()
*/
kim_error kim_selection_hints_set_explanation (kim_selection_hints io_selection_hints,
kim_string          in_explanation);

/*!
* \param in_selection_hints   a selection hints object.
* \param out_explanation      on exit, the localized string specified in \a in_selection_hints
*                             which describes why the caller needs the identity.  May be NULL.
*                             If non-NULL, must be freed with kim_string_free().
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Get the strings used to prompt the user to select the identity.
* \sa kim_selection_hints_set_explanation()
*/
kim_error kim_selection_hints_get_explanation (kim_selection_hints  in_selection_hints,
kim_string          *out_explanation);

/*!
* \param io_selection_hints  a selection hints object to modify.
* \param in_options          options to control credential acquisition.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Set the options which will be used if credentials need to be acquired.
* \sa kim_selection_hints_get_options()
*/
kim_error kim_selection_hints_set_options (kim_selection_hints io_selection_hints,
kim_options         in_options);

/*!
* \param in_selection_hints a selection hints object.
* \param out_options        on exit, the options to control credential acquisition
*                           specified in \a in_selection_hints.  May be KIM_OPTIONS_DEFAULT.
*                           If not, must be freed with kim_options_free().
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Get the options which will be used if credentials need to be acquired.
* \sa kim_selection_hints_set_options()
*/
kim_error kim_selection_hints_get_options (kim_selection_hints  in_selection_hints,
kim_options         *out_options);

/*!
* \param in_selection_hints        a selection hints object to modify
* \param in_allow_user_interaction a boolean value specifying whether or not KIM should ask
*                                  the user to select an identity for \a in_selection_hints.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \note This setting defaults to TRUE.
* \brief Set whether or not KIM may interact with the user to select an identity.
* \sa kim_selection_hints_get_allow_user_interaction
*/
kim_error kim_selection_hints_set_allow_user_interaction (kim_selection_hints in_selection_hints,
kim_boolean         in_allow_user_interaction);

/*!
* \param in_selection_hints         a selection hints object to modify
* \param out_allow_user_interaction on exit, a boolean value specifying whether or not KIM
*                                   should ask the user to select an identity for
*                                   \a in_selection_hints.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \note This setting defaults to TRUE.
* \brief Get whether or not KIM may interact with the user to select an identity.
* \sa kim_selection_hints_set_allow_user_interaction
*/
kim_error kim_selection_hints_get_allow_user_interaction (kim_selection_hints  in_selection_hints,
kim_boolean         *out_allow_user_interaction);

/*!
* \param in_selection_hints    a selection hints object to modify
* \param in_remember_identity  a boolean value specifying whether or not KIM should use a cached
*                              mapping between \a in_selection_hints and a Kerberos identity.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \note This setting defaults to TRUE.
* \brief Set whether or not KIM will use cached mappings for this selection hints object.
* \sa kim_selection_hints_get_remember_identity
*/
kim_error kim_selection_hints_set_remember_identity (kim_selection_hints in_selection_hints,
kim_boolean         in_remember_identity);

/*!
* \param in_selection_hints     a selection hints object to modify
* \param out_remember_identity on exit, a boolean value specifying whether or not KIM will use a
*                               cached mapping between \a in_selection_hints and a Kerberos identity.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \note This setting defaults to TRUE.
* \brief Get whether or not KIM will use cache mappings for this selection hints object.
* \sa kim_selection_hints_set_remember_identity
*/
kim_error kim_selection_hints_get_remember_identity (kim_selection_hints  in_selection_hints,
kim_boolean         *out_remember_identity);

/*!
* \param in_selection_hints the selection hints to add to the cache.
* \param out_identity       the Kerberos identity \a in_selection_hints maps to.
*                           Must be freed with kim_identity_free().
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \note \a out_identity is the identity mapped to by the current state of \a in_selection_hints.
* This function may prompt the user via a GUI to choose that identity.
* Subsequent modifications to \a in_selection_hints will not change \a out_identity.
* \brief Choose a client identity based on selection hints.
*/

kim_error kim_selection_hints_get_identity (kim_selection_hints in_selection_hints,
kim_identity        *out_identity);

/*!
* \param in_selection_hints the selection hints to add to the cache.
* \param in_identity the Kerberos identity \a in_selection_hints maps to.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Add an entry for the selection hints to the selection hints cache,
* replacing any existing entry.
*/

kim_error kim_selection_hints_remember_identity (kim_selection_hints in_selection_hints,
kim_identity        in_identity);

/*!
* \param in_selection_hints the selection hints to remove from the cache.
* \return On success, #KIM_NO_ERROR.  On failure, an error code representing the failure.
* \brief Remove an entry for the selection hints from the selection hints cache.
*/

kim_error kim_selection_hints_forget_identity (kim_selection_hints in_selection_hints);

/*!
* \param io_selection_hints the selection hints object to be freed.  Set to NULL on exit.
* \brief Free memory associated with a selection hints object.
*/

void kim_selection_hints_free (kim_selection_hints *io_selection_hints);

/*!@}*/

#ifdef __cplusplus
}
#endif

#endif /* KIM_SELECTION_HINTS_H */