/* * Copyright 2005-2006 Massachusetts Institute of Technology. * All Rights Reserved. * * 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_CREDENTIAL_H #define KIM_CREDENTIAL_H #ifdef __cplusplus extern "C" { #endif #include <kim/kim_types.h> #include <krb5.h> /*! * \addtogroup kim_types_reference * @{ */ /*! * Possible credential states. Credentials may be: * \li valid - The credential can be used. * \li expired - The credential's lifetime has been exceeded. * \li not_yet_valid - The credential is post dated and the time when * it becomes valid has not yet been reached. * \li needs_validation - The credential is post-dated and although * the time when it becomes valid has been reached * it has not yet been validated. * \li address_mismatch - The credential contains IP address(es) which do * not match the host's local address(es). */ enum kim_credential_state_enum { kim_credentials_state_valid = 0, kim_credentials_state_expired = 1, kim_credentials_state_not_yet_valid = 2, kim_credentials_state_needs_validation = 3, kim_credentials_state_address_mismatch = 4 }; /*! * The state of a credential. See #kim_credential_state_enum for * possible values. */ typedef int kim_credential_state_t; /*! @} */ /*! * \page kim_credential_overview KIM Credential Overview * * \section kim_credential_introduction Introduction * * A Kerberos credential (also called a "Kerberos ticket") is a time-limited * token issued by a KDC which authenticates the entity named by the credential's * client identity to the service named by the credential's service identity. * * The kim_credential_t object contains a single Kerberos credential. KIM credentials * objects are always copies of credentials, not references to credentials * stored in the cache collection. Modifying credential objects in the ccache * collection will not change any existing KIM credential objects. * * KIM credential APIs are intended for applications and system * tools which manage credentials for the user. They are not a substitute for * krb5 and GSSAPI functions which obtain service credentials for the purpose * of authenticating a client to an application server. * * \note Many of the APIs listed below have equivalent functions which * operate on ccaches. In most cases applications will want to use the * ccache versions of these APIs since they automatically store any * newly created credentials. See \ref kim_ccache_overview for more * information. * * * \section kim_credential_acquire_new Acquiring New Credentials * * KIM provides the #kim_credential_create_new() API for acquiring new * credentials. Credentials can either be obtained for a specific * client identity or by specifying #KIM_IDENTITY_ANY to allow * the user to choose. Typically callers of this API obtain the client * identity using #kim_selection_hints_get_identity(). Depending on the * kim_options specified, #kim_credential_create_new() may present a * GUI or command line prompt to obtain information from the user. * * KIM provides the #kim_credential_create_from_keytab() to create credentials * using a keytab. A keytab is an on-disk copy of a client identity's secret * key. Typically sites use keytabs for client identities that identify a * machine or service and protect the keytab with disk permissions. Because * a keytab is sufficient to obtain credentials, keytabs will normally only * be readable by root, Administrator or some other privileged account. * Typically applications use credentials obtained from keytabs to obtain * credentials for batch processes. These keytabs and credentials are usually * for a special identity used for the batch process rather than a user * identity. * * * \section kim_credential_validate Validating Credentials * * A credential with a start time in the future (ie: after the issue date) * is called a post-dated credential. Because the KDC administrator may * wish to disable a identity, once the start time is reached, all post-dated * credentials must be validated before they can be used. Otherwise an * attacker using a compromised account could acquire lots of post-dated * credentials to circumvent the acccount being disabled. * * KIM provides the #kim_credential_validate() API to validate a credential. * Note that this API replaces the credential object with a new validated * credential object. If you wish to store this API in the ccache collection * you must either call #kim_credential_store() on the validated credential * or use #kim_ccache_validate() instead. * * * \section kim_credential_renew Renewing Credentials * * A renewable credential can be used to obtain a new identical credential * without resending secret information (such as a password) to the KDC. * A credential may only be renewed during its renewal lifetime and while * valid. * * KIM provides the #kim_credential_renew() API to renew a credential. * Note that this API replaces the credential object with a new renewed * credential object. If you wish to store this API in the ccache collection * you must either call #kim_credential_store() on the renewed credential * or use #kim_ccache_renew() instead. * * * \section kim_credential_storing Storing Credentials in the Cache Collection * * KIM credential objects may be stored in the ccache collection using * #kim_credential_store(). This function runs any KIM authentication * plugins on the credential and if the plugins return successfully, creates a * new ccache for the credential's client identity in the cache collection * and stores the credential in that ccache. Any existing ccaches and credentials * for that client identity will be overwritten. #kim_credential_store() may * optionally return a kim_ccache_t object for the new ccache if you need to perform * further operations on the new ccache. * * Most of the time if you plan to store the credentials you are manipulating, you * should use one of KIM ccache APIs. These functions perform the same operations * except that they also call #kim_credential_store() any time the credential object * changes. See \ref kim_ccache_overview for more information. * * * \section kim_credential_iterator_t Iterating over the Credentials in a CCache * * KIM provides a simple iterator API for iterating over the credentials * in a ccache. First, call #kim_credential_iterator_create() to obtain * an iterator for a ccache. Then loop calling #kim_credential_iterator_next() * until either you find the credential you are looking for or the API * returns a NULL credential, indicating that there are no more * credentials in the ccache. When you are done with the iterator, call * #kim_credential_iterator_free(). * * \note #kim_credential_iterator_next() returns credential objects which * must be freed with #kim_credential_free() to avoid leaking memory. * * * \section kim_credential_verify Verifying Credentials * * When a program acquires TGT credentials for the purpose of authenticating * itself to the machine it is running on, it is insufficient for the machine * to assume that the caller is authorized just because it got credentials. * Instead, the credentials must be verified using a key the local machine. * The reason this is necessary is because an attacker can trick the * machine into obtaining credentials from any KDC, including malicious ones * with the same realm name as the local machine's realm. This exploit is * called the Zanarotti attack. * * In order to avoid the Zanarotti attack, the local machine must authenticate * the process in the same way an application server would authenticate a client. * Like an application server, the local machine must have its own identity in * its realm and a keytab for that identity on its local disk. However, * rather than forcing system daemons to use the network-oriented calls in the * krb5 and GSS APIs, KIM provides the #kim_credential_verify() API to * verify credentials directly. * * The most common reason for using #kim_credential_verify() is user login. * If the local machine wants to use Kerberos to verify the username and password * provided by the user, it must call #kim_credential_verify() on the credentials * it obtains to make sure they are really from a KDC it trusts. Another common * case is a server which is only using Kerberos internally. For example an * LDAP or web server might use a username and password obtained over the network * to get Kerberos credentials. In order to make sure they aren't being tricked * into talking to the wrong KDC, these servers must also call * #kim_credential_verify(). * * The Zanarotti attack is only a concern if the act of accessing the machine * gives the process special access. Thus a managed cluster machine with * Kerberos-authenticated networked home directories does not need to call * #kim_credential_verify(). Even though an attacker can log in as any user on * the cluster machine, the attacker can't actually access any of the user's data * or use any of their privileges because those are all authenticated via * Kerberized application servers (and thus require actually having credentials * for the real local realm). * * #kim_credential_verify() provides an option to * return success even if the machine's host key is not present. This option * exists for sites which have a mix of different machines, some of which are * vulnerable to the Zanarotti attack and some are not. If this option is used, * it is the responsiblity of the machine's maintainer to obtain a keytab * for their machine if it needs one. * * * \section kim_credential_properties Examining Credential Properties * * \li #kim_credential_get_client_identity() * returns the credential's client identity. * * \li #kim_credential_get_service_identity() * returns the credential's service identity. * * \li #kim_credential_is_tgt() * returns whether the credential is a TGT (ie: "ticket-granting ticket"). TGTs are * credentials for the krbtgt service: a service identity of the form "krbtgt/<REALM>@<REALM>". * These credentials allow the entity named by the client identity to obtain * additional service credentials without resending shared secrets (such as a password) * to the KDC. Kerberos uses TGTs to provide single sign-on authentication. * * \li #kim_credential_is_valid() * returns whether the credential is valid and if not why the credential is not valid. * * \li #kim_credential_get_start_time() * returns when the credential will become valid. * Credentials may be "post-dated" which means that their lifetime starts sometime * in the future. Note that when a post-dated credential's start time is reached, * the credential must be validated. See \ref kim_credential_validate for more information. * * \li #kim_credential_get_expiration_time() * returns when the credential will expire. * Credentials are time limited by the lifetime of the credential. While you can * request a credential of any lifetime, the KDC limits the credential lifetime * to a administrator-defined maximum. Typically credential lifetime range from 10 * to 21 hours. * * \li #kim_credential_get_renewal_expiration_time() * returns when the credential will no longer be renewable. * Valid credentials may be renewed up until their renewal expiration time. * Renewing credentials acquires a fresh set of credentials with a full lifetime * without resending secrets to the KDC (such as a password). If credentials are * not renewable, this function will return an error. * * * See \ref kim_credential_reference and \ref kim_credential_iterator_reference for * information on specific APIs. */ /*! * \defgroup kim_credential_iterator_reference KIM Credential Iterator Reference Documentation * @{ */ /*! * \param out_credential_iterator on exit, a credential iterator object for \a in_ccache. * Must be freed with kim_credential_iterator_free(). * \param in_ccache a ccache object. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get a credential iterator to enumerate credentials in a ccache. */ kim_error_t kim_credential_iterator_create (kim_credential_iterator_t *out_credential_iterator, kim_ccache_t in_ccache); /*! * \param in_credential_iterator a credential iterator object. * \param out_credential on exit, the next credential in the ccache iterated by * \a in_credential_iterator. Must be freed with * kim_credential_free(). If there are no more credentials * this argument will be set to NULL. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the next credential in a ccache. */ kim_error_t kim_credential_iterator_next (kim_credential_iterator_t in_credential_iterator, kim_credential_t *out_credential); /*! * \param io_credential_iterator a credential iterator object to be freed. Set to NULL on exit. * \brief Free memory associated with a credential iterator. */ void kim_credential_iterator_free (kim_credential_iterator_t *io_credential_iterator); /*!@}*/ /*! * \defgroup kim_credential_reference KIM Credential Reference Documentation * @{ */ /*! * \param out_credential on exit, a new credential object containing a newly acquired * initial credential. Must be freed with kim_credential_free(). * \param in_client_identity a client identity to obtain a credential for. Specify NULL to * allow the user to choose the identity * \param in_options options to control credential acquisition. * \note Depending on the kim_options specified, #kim_credential_create_new() may * present a GUI or command line prompt to obtain information from the user. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Acquire a new initial credential. * \sa kim_ccache_create_new */ kim_error_t kim_credential_create_new (kim_credential_t *out_credential, kim_identity_t in_client_identity, kim_options_t in_options); /*! * \param out_credential on exit, a new credential object containing an initial credential * for \a in_identity obtained using \a in_keytab. * Must be freed with kim_credential_free(). * \param in_identity a client identity to obtain a credential for. Specify NULL for * the first identity in the keytab. * \param in_options options to control credential acquisition. * \param in_keytab a path to a keytab. Specify NULL for the default keytab location. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Acquire a new initial credential from a keytab. * \sa kim_ccache_create_from_keytab */ kim_error_t kim_credential_create_from_keytab (kim_credential_t *out_credential, kim_identity_t in_identity, kim_options_t in_options, kim_string_t in_keytab); /*! * \param out_credential on exit, a new credential object which is a copy of \a in_krb5_creds. * Must be freed with kim_credential_free(). * \param in_krb5_creds a krb5 credential object. * \param in_krb5_context the krb5 context used to create \a in_krb5_creds. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Copy a credential from a krb5 credential object. */ kim_error_t kim_credential_create_from_krb5_creds (kim_credential_t *out_credential, krb5_creds *in_krb5_creds, krb5_context in_krb5_context); /*! * \param out_credential on exit, a new credential object which is a copy of \a in_credential. * Must be freed with kim_credential_free(). * \param in_credential a credential object. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Copy a credential object. */ kim_error_t kim_credential_copy (kim_credential_t *out_credential, kim_credential_t in_credential); /*! * \param in_credential a credential object. * \param in_krb5_context a krb5 context which will be used to create \a out_krb5_creds. * \param out_krb5_creds on exit, a new krb5 creds object which is a copy of \a in_credential. * Must be freed with krb5_free_creds(). * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get a krb5 credentials object for a credential object. */ kim_error_t kim_credential_get_krb5_creds (kim_credential_t in_credential, krb5_context in_krb5_context, krb5_creds **out_krb5_creds); /*! * \param in_credential a credential object. * \param out_client_identity on exit, an identity object containing the client identity of * \a in_credential. Must be freed with kim_identity_free(). * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the client identity of a credential object. */ kim_error_t kim_credential_get_client_identity (kim_credential_t in_credential, kim_identity_t *out_client_identity); /*! * \param in_credential a credential object. * \param out_service_identity on exit, an identity object containing the service identity of * \a in_credential. Must be freed with kim_identity_free(). * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the service identity of a credential object. */ kim_error_t kim_credential_get_service_identity (kim_credential_t in_credential, kim_identity_t *out_service_identity); /*! * \param in_credential a credential object. * \param out_is_tgt on exit, whether or not the credential is a TGT. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Check if a credential is a ticket granting ticket. */ kim_error_t kim_credential_is_tgt (kim_credential_t in_credential, kim_boolean_t *out_is_tgt); /*! * \param in_credential a credential object. * \param out_state on exit, the state of the credential. See #kim_credential_state_enum * for the possible values of \a out_state. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Check the state of a credential (valid, expired, postdated, etc). */ kim_error_t kim_credential_get_state (kim_credential_t in_credential, kim_credential_state_t *out_state); /*! * \param in_credential a credential object. * \param out_start_time on exit, the time when \a in_credential becomes valid. * May be in the past or future. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the time when the credentials become valid. * \sa kim_ccache_get_start_time */ kim_error_t kim_credential_get_start_time (kim_credential_t in_credential, kim_time_t *out_start_time); /*! * \param in_credential a credential object. * \param out_expiration_time on exit, the time when \a in_credential will expire. * May be in the past or future. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the time when the credentials will expire. * \sa kim_ccache_get_expiration_time */ kim_error_t kim_credential_get_expiration_time (kim_credential_t in_credential, kim_time_t *out_expiration_time); /*! * \param in_credential a credential object. * \param out_renewal_expiration_time on exit, the time when \a in_credential will no longer * be renewable. May be in the past or future. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Get the time when the credentials will no longer be renewable. * \sa kim_ccache_get_renewal_expiration_time */ kim_error_t kim_credential_get_renewal_expiration_time (kim_credential_t in_credential, kim_time_t *out_renewal_expiration_time); /*! * \param in_credential a credential object. * \param in_client_identity a client identity. * \param out_ccache on exit, a ccache object containing \a in_credential with the client * identity \a in_client_identity. Must be freed with kim_ccache_free(). * Specify NULL if you don't want this return value. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Store a credential in a ccache in the cache collection. */ kim_error_t kim_credential_store (kim_credential_t in_credential, kim_identity_t in_client_identity, kim_ccache_t *out_ccache); /*! * \param in_credential a TGT credential to be verified. * \param in_service_identity a service identity to look for in the keytab. Specify * KIM_IDENTITY_ANY to use the default service identity * (usually host/<host's FQDN>@<host's local realm>). * \param in_keytab a path to a keytab. Specify NULL for the default keytab location. * \param in_fail_if_no_service_key whether or not the absence of a key for \a in_service_identity * in the host's keytab will cause a failure. * \note specifying FALSE for \a in_fail_if_no_service_key may expose the calling program to * the Zanarotti attack if the host has no keytab installed. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Verify a TGT credential. * \sa kim_ccache_verify */ kim_error_t kim_credential_verify (kim_credential_t in_credential, kim_identity_t in_service_identity, kim_string_t in_keytab, kim_boolean_t in_fail_if_no_service_key); /*! * \param io_credential a TGT credential to be renewed. On exit, the old credential * object will be freed and \a io_credential will be replaced * with a new renewed credential. The new credential must be freed * with kim_credential_free(). * \param in_options initial credential options. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Renew a TGT credential. * \sa kim_ccache_renew */ kim_error_t kim_credential_renew (kim_credential_t *io_credential, kim_options_t in_options); /*! * \param io_credential a credential object to be validated. On exit, the old credential * object will be freed and \a io_credential will be replaced * with a new validated credential. The new credential must be freed * with kim_credential_free(). * \param in_options initial credential options. * \return On success, #KIM_NO_ERROR. On failure, an error object representing the failure. * \brief Validate a TGT credential. * \sa kim_ccache_validate */ kim_error_t kim_credential_validate (kim_credential_t *io_credential, kim_options_t in_options); /*! * \param io_credential the credential object to be freed. Set to NULL on exit. * \brief Free memory associated with a credential object. */ void kim_credential_free (kim_credential_t *io_credential); /*!@}*/ #ifdef __cplusplus } #endif #endif /* KIM_CREDENTIAL_H */