Updating KClient 1.x to 3.0

| # Macintosh Development

[Home] [About Us] [People] [Information Systems]
[Kerberos for Macintosh] [Applications] [Miscellaneous Documentation]

| Updating KClient 1.x to 3.0

> KClient 3.0 is a completely rearchitected API from the original KClient API. This rearchitecting was done when KClient became a set of shared libraries on Mac OS 9 - and it is now part of the Kerberos framework on Mac OS X. The rearchitecting was necessary because the entire runtime interface changed, and the API used by KClient prior to the version 3.0 had several deficiencies.

> The new API is documented in the KClient 3.0 API reference. This document is intended for the developers who used KClient 1.x in their code, and are updating their code to work with KClient 3.0. If you are writing new code that uses KClient, you should read the KClient 3.0 API reference, and write to the new API.

> ### Why update?

> KClient 3.0 has several advantages. First of all, it is implemented as part of a Mac OS X framework (Mac OS X) or a set of shared libraries (Mac OS 9/Mac OS X CFM compatibility), rather than as a classic 68K driver. Classic 68K drivers are not supported on Mac OS X, except in the Classic environment. Therefore, for your code to be Carbon-compatible and to work under Mac OS X, you need to update to the KClient 3.0 API.

> In addition, the KClient 3.0 API is considerably simpler and more consistent. Where other APIs are adequate (CCache API, for example), KClient no longer tries to implement its own version of the API; instead, it provides easy ways of correctly using KClient with the other APIs. This also improves cross-platform compatibility, because those APIs are already cross-platform (Kerberos v4 API, Kerberos Profile API), or are designed to be cross-platform and will be implemented cross-platform in the future (Credentials Cache API v3); those API are standard parts of the MIT Kerberos distribution, or are becoming standard parts in the future.

> ### Options for updating

> Most existing code which uses KClient 1.x is based on the driver glue from KClient 1.x SDKs. The driver glue implements the KClient functions by calling into the driver to perform the required operations. There might be a few bodies of code that call the KClient driver directly; the suggested upgrade path for such code is to update to KClient 1.9 API first, and then proceed with the update to KClient 3.0.

> KClient 3.0 provides 2 APIs: the KClient 3.0 API, described in the KClient 3.0 API reference, and the KClient 1.x compatibility API. All future development will be on KClient 3.0 API and any new features will only appear in KClient 3.0 API. KClient 1.x compatibility API should be only used as an interim measure in updating your code to KClient 3.0 API.

> The functions in the 1.x compatibility layer can be divided into 3 groups:

> 1. unsupported functions: the functionality of these functions could not be provided in the compatibility layer
> 2. deprecated functions: these functions are supported in the compatibility layer, but they are in some way unsafe or incomplete, and their use should be avoided, as they may stop functioning properly at any point in time
> 3. supported functions: these functions are supported in the compatibility layer, and will continue to be supported for the foreseeable future

> The best thing you can do with your code is to update it to the KClient 3.0 API. That API will guarantee you the best future compatibility and you will be able to take advantage of new KClient features. However, that also requires the most work on your part.

> If you do not update your code to the KClient 3.0 API, you need to update your code to the KClient 1.x compatibility API, and that involves doing some of the following:

> 1. Remove all calls to unsupported functions. You must do this in order to be able to update your code to the compatibility API at all. There are only a few unsupported functions, and they shouldn't be used by many clients. They are listed below.
> 2. Change all calls to modified functions to their new interface. You must do this in order to be able to use the compatibility API. There are only a few modified functions, and they are listed below with instructions on how to call them in the compatibility API.
> 3. Replace all calls to deprecated functions with calls to other functions in the KClient API , or in other APIs. You should do this as soon as it's practical, because deprecated functions may break in the future.

> Ultimately, you should update to KClient 3.0 API, which additionally involves changing calls to all supported functions to their KClient 3.0 API equivalents.

> The rest of this document describes what is involved in updating to KClient 3.0 API, followed by a quick reference guide to all KClient 1.x API functions and their state in the compatibility layer.

> ### How much work will it be?

> The following step-by-step procedure will help you ascertain how much work you need to do to update your code to the KClient 1.x compatibility API. Further below, going from the KClient 1.x compatibility API to the KClient 3.0 API is discussed.

> To update from KClient 1.x driver libraries to KClient 1.x compatibility API shared libraries:

> 1. Remove KClient.c from your project or Makefile, and replace it with KClientCompatLib and KClientDeprecatedLib.
> 2. Try to compile and linking your project.
>    1. If the compilation failed because a function wasn't recognized (an unknown identifier error), you are probably using some of the unsupported functions. Determine which ones, and follow the instructions below.
>    2. If the compilation failed because a function was given the incorrent number of parameters, you are probably using some of the modified functions. Determine which ones, and follow the instructions below.
>    3. If the compilation and linking succeeded, proceed to the next step
> 3. Remove KClientDeprecatedLib from your project or Makefile
> 4. Try to compile and link your project
>    1. If the project failed to link, you are probably using some deprecated functions. Determine which ones, and follow the instructions below.
>    2. If the the compilation and linking succeeded, proceed to the next step
> 5. Your project is now successfully linking with the KClient 1.x compatibility API, without using any deprecated functions

> Please note that this procedure only works if your compiler does correct function prototype checks; if prototype checking is unavailable or disabled, you may not notice if you are using modified or unsupported functions, and your program will likely crash when trying to call them. In that case, you can search for them by their names by hand (see the list below).

> If any of these steps fail for reasons other than the ones listed above, you likely found a bug in the compatibility interfaces. Please contact us at macdev@mit.edu.

> After you have done the above, if you want to update your code to the KClient 3.0 API, you need to do two things:

> 1. replace your calls to deprecated functions with calls to supported equivalents
> 2. change your calls to modified functions to their new prototypes and semantics

> Most of the work is in the first step, because in order to remove the dependencies on the deprecated functions, you will have to use APIs other than the KClient API (the Credentials Cache API, the Kerberos Profile API, and the Kerberos v4 API). After that, the second step will be easy, since most supported and modified functions in the compatibility API map directly to one or two calls in the KClient 3.0 API.

> Unfortunately, it's in general not possible to mix the 1.x compatibility API and the 3.0 API in the same code, so once you decide to do either of those two steps, you will have to do both. Fortunately, one of them is very simple, and, even better, it's the one that will be the most common -- most clients should not have used the deprecated functions in the first place.

> # Detailed Function Listing

> ## Unsupported functions

> The following functions are not supported in the KClient 1.x compatibility API: `KClientAddSpecial()`, `KClientDeleteSpecial()`, `KClientGetNumSpecials()`, `KClientGetNthSpecial()`, `KClientSetOption()`, `KClientGetOption()`, and `KClientSetPrompt()`.

> #### KClientAddSpecial, KClientDeleteSpecial, KClientGetNumSpecials, and KClientGetNthSpecial

> The functions `KClientAddSpecial()`, `KClientDeleteSpecial()`, `KClientGetNumSpecials()`, and `KClientGetNthSpecial()` were used to configure "special" services. This functionality is now obsolete, and these functions are consequently unsupported. If you have a reason to believe you need to use these functions, please contact macdev@mit.edu.

> #### KClientSetOption and KClientGetOption

> The functions `KClientSetOption()` and `KClientGetOption()` were used to read and write various KClient settings. They should never have been used by anyone other than the KClient control panel itself. However, most of the functionality of those options is now publically available in the Kerberos Login API, and if you used these functions, you should use the Kerberos Login API instead. Please contact macdev@mit.edu with any questions you might have about these functions.

> #### KClientSetPrompt

> This function was used to set the prompt string in the KClient login dialog. This functionality is not available in any library at this time. If you believe that you need this functionality, contact macdev@mit.edu, and we may consider adding the funtionality to the Login API, which encapsulates the login user interface.

> ## Deprecated functions

> The functions listed below are present in the KClient 1.x compatibility interface, but they are likely to break in the future, and therefore should be avoided at all costs.

> Note that in order to remove the dependency on the deprecated functions, you will have to update your code to the KClient 3.0 API. Since it is impossible to mix the KClient 1.x compatibility API and the KClient 3.0 API, once you decide to remove the deprecated functions you will have to update the supported functions to the KClient 3.0 API. Fortunately, most of the work of upgrading to the KClient 3.0 API is, in fact, in removing dependencies on the deprecated 1.x functions, so once you do that, updating the rest of the functions will be very simple -- see instructions below on updating the supported functions.

> ### Credentials cache management functions

> The following functions are deprecated because they implement an incomplete and not forward-looking credentials cache management API: `KClientGetNumSessions()`, `KClientGetNthSession()`, `KClientDeleteSession()`, `KClientGetCredentials()`, `KClientAddCredentials()`, `KClientDeleteCredentials()`, `KClientGetNumCredentials()`, `KClientGetNthCredential()`, and `KClientGetUserName()`.

> These functions are typically used to sequentially access all credentials, in order to display them to the user, or to find a specific credentials. The interface these functions present is not compatible with Kerberos v5, as they provide no way to access Kerberos v5 credentials in the credentials cache, which is needed in a mixed Kerberos v4/v5 environment. The iteration facility of these functions is based on indices, which makes them unsafe, because in a preemptive environment they cannot guarantee a coherent view of the credentials cache.

> Because of that, these functions are deprecated and will be removed in the future. The same functionality is available in the CCache API. Code that uses these functions should be replaced with code that uses the CCache API:

> - If the purpose of the code is to look at (and possibly delete) the Kerberos v4 credentials in the credentials cache of the user of the KClient session, then the code should use `KClientGetCCacheHandle()` in KClient 3.0 API to get a reference to the credentials cache for that user, and then use CCache API credentials iterators to list all the credentials.
> - If the purpose of the code if to add Kerberos v4 credentials to the credentials cache of the user of the KClient session, the the code should use `KClientGetCCacheHandle()` in KClient 3.0 API to get a reference to the credentials cache for that user, and then use `cc_ccache_store_credentials()` to store the credentials
> - If the purpose of the code is to look at the credentials caches for all currently logged-in users, the code should use CCache API credentials cache iterators to list all the credentials caches.
> - `KClientGetUserName()` should be replaced with `krb_tkt_string()` (to get the name of the default application credentials cache) and `cc_context_open_ccache()`, or `cc_context_open_default_ccache()` (to open the system default credentials cache), followed by `cc_ccache_get_principal()` to get the principal corresponding to the default credentials cache. Note, however, that if you want to get the principal corresponding to the KClient session you are manipulating, you should use `KClientGetSessionUserName()` instead.

> Please consult the CCache API documentation for details on using the API.

> ### Realms configuration management functions

> The following functions are deprecated because they implement an incomplete and inconsistent realms configuration management API: `KClientGetLocalRealm()`, `KClientSetLocalRealm()`, `KClientAddRealmMap()`, `KClientDeleteRealmMap()`, `KClientGetNthRealmMap()`, `KClientGetNthServer()`, `KClientAddServerMap()`, `KClientDeleteServerMap()`, `KClientGetNthServerMap()`, `KClientGetNthServerPort()`, `KClientSetNthServerPort()`.

> These function are typically used to read or modify the realm configuration. The interface provided by these functions is not compatible with Kerberos v5, as they do not provide for various additional information about realm configuration available with Kerberos v5. The iteration facility provided by these functions is based on indices, which makes them unsafe in a preemptive environment; real iterators allow a consistent view of the realms configuration.

> Because of that, and since the Kerberos Profile API is a considerably more general API also used by Kerberos v5, these functions are deprecated and will be removed in the future. Code that uses these functions should be replaced with code that uses the Kerberos Profile API. Consult the Kerberos profile API documentation for details on using the API.

> The function `KClientGetRealm()` is available in the Kerberos v4 API as `krb_realmofhost()`. To avoid API reduncancy, and to improve portability of the code, `KClientGetRealm()` is deprecated, and `krb_realmofhost()` should be used instead.

> ### KClientErrorText

> `KClientGetErrorText()` is deprecated, because it has an unsafe interface (a buffer of an unknown size is passed into the function).

> You should replace this function with a call to the Error Library; see the Error Library API reference for more information.

> ### KClientSetUserName

> This function was used to set the default username that appears in the KClient login dialog. The use of the function was primarily to hint to the user which principal to authenticate as, but it was never possible to require the user to login as a specific principal.

> You should replace this function with `KClientSetClientPrincipal().`

> # Updating to KClient 3.0 API from the KClient 1.x compatibility API

> To update your code from the KClient 1.x API to the KClient 3.0 API, you need to change three things:

> - change to new variable types
> - change to new function names and prototypes
> - change to new session semantics

> ### New types

> The new types in the 3.0 API are:

> - `KClientSession`: must be used instead of `KClientSessinInfo`
> - `KClientPrincipal`: must be used whereever a `char*` was used for a Kerberos principal
> - `KClientAddress`: must be used whereever two integers were used for a network address and port
> - `KClientFile`: must be used whereever a `char*` was used for a key file path

> The `KeyClientKey` type is unchanged.

> ### New function names and prototypes

> Updating function calls requires two parts:

> - Remove dependencies on deprecated functions -- see the section about deprecated functions above
> - Change calls to supported functions from the compatibility API

> The second step is described in detail below, for every function. Since almost all of the functions in KClient 3.0 API take one of the new API types, it is assumed below you are converting the types to the new types at the same time. Only changes that involve calling new functions or old functions with new arguments are listed.

> ### New session semantics

> Starting with KClient 3.0, it is not possible to recycle a KClient session in order to authenticate more than one user or to more than one service.

> The KClient 1.x API allowed the caller to create a single session and call, for example, `KClientGetTicketForService()` repeatedly to get tickets for different services. The KClient 3.0 API, on the other hand, does not allow this. Once a session is created and authenticated, the client and the service principal and address are remembered until the session is destroyed. To authenticate a different client, or to authenticate to a different server, a new session has to be created.

> This allows KClient to prevent the previously common failure case when an application's service ticket expires, and the application asks for new service ticket, causing the user to type in a name and a password. If the user selects a different principal from before, the application winds up with the service tickets for a different principal, and usually gets confused (for example, gets mail for the second principal into the first user's mailbox).

> If you are currently using the KClient 1.x API and you are recycling KClient sessions in this way, you need to change your code so that it uses one session per client/service pair that you are authenticating.

> ## Supported and modified functions

> #### KClientDecrypt, KClientDisposeSession, KClientEncrypt, KClientGetSessionKey, KClientProtectIntegrity, KClientVerifyIntegrity, KClientVerifyReplyTicket, KClientVerifyUnencryptedReplyTicket, KServerGetReplyTicket

> In order to update these 9 functions to the KClient 3.0 API, the first argument has to be changed from the type `KClientSessionInfo*` to `KClientSession`. Also, the following functions names have changed:

> Old name | New name
> `KClientVerifyReplyTicket` | `KClientVerifyEncryptedServiceReply`
> `KClientVerifyUnencryptedReplyTicket` | `KClientVerifyProtectedServiceReply`
> `KServerGetReplyTicket` | `KClientGetEncryptedServiceReply`

> Also note the presence of the new function, `KClientGetProtectedServiceReply()`, as a counterpart to `KClientGetEncryptedServiceReply()`. See the KClient API 3.0 specification for more details.

> #### KClientErrorText, KClientLogout, KClientPasswordToKey

> To update these 3 functions to the KClient 3.0 API, they need to take a `KClientSession` as their first argument. Also, `KClientErrorText()` has been renamed to `KClientGetErrorText()`.

> #### KClientGetSessionUserName

> This function has been replaced with `KClientGetClientPrincipal()` (for client sessions) and `KClientGetServerPrincipal()` (for server sessions). Since those two functions return `KClientPrincipal`, which can subsequently be converted to several different representations of the principal, they do not need a name type argument, which has therefore been removed.

> See the section about the `KClientPrincipal` type in the KClient 3.0 API specification to see how to convert a `KClientPrincipal` to different string representations.

> #### KClientGetTicketForService

> This function no longer has a service argument; to specify which service to use for a client session, use the `KClientSetServerPrincipal()` function before calling `KClientGetTicketForService()`. A new argument, checksum, has been added. See the KClient 3.0 API specification for details on using the new argument; the KClient 1.x compatibility API implicitly used the checksum of 0, so if you don't care about it, pass in 0.

> #### KClientLogin, KClientPasswordLogin

> These functions no longer return user's private key.

> These functions have a new behavior; if `KClientSetClientPrincipal()` is called before either of them, the user will be required to authenticate as the principal specified to `KClientSetPrincipal()`. This functionality was previously not available in KClient API. If `KClientSetClientPrincipal()` is not called, the behavior is the same as the behavior from KClient 1.x API.

> #### KClientMakeSendAuth

> This function has been renamed to `KClientGetAuthenticatorForService()`, and no longer takes a service argument. Just as with `KClientGetTicketForService()`, call `KClientSetServerPrincipal()` before calling `KClientGetAuthenticationForService()` to specify the service.

> #### KClientNewSession, KServerNewSession

> These two functions have been renamed to `KClientNewClientSession()` and `KClientNewServerSession()`, respectively.

> The addresses these functions take are now of the `KClientAddress` type, instead of two integer arguments. See the `KClientAddress` section of the KClient 3.0 API specification for more information.

> The service principal taken by `KClientNewServerSession()` is now of the type `KClientPrincipal`; see the `KClientPrincipal` section of the KClient 3.0 API specification for more information.

> #### KClientStatus, KServerGetSessionTimeRemaining

> These two functions have been consolidated into one function, `KClientGetSessionTimeRemaining()`, which returns the time remaining on the tickets for both client and server sessions. See the KClient 3.0 API specification for more information.

> #### KClientVersion

> The version string argument of this function has been changed from `char*` to const `char**`. The string is no longer returned in a caller-provided buffer; instead, the string is internal to the library, and a read-only pointer to it is returned.

> #### KServerAddKey, KServerGetKey, KServerVerifyTicket

> These functions have been renamed as follows:

> Old name | New name
> `KServerAddKey` | `KClientAddServiceKey`
> `KServerGetKey` | `KClientGetServiceKey`
> `KServerVerifyTicket` | `KClientVerifyAuthenticator`

> None of them take a key file argument any longer. If you want to use a non-default key file, use the `KClientSetKeyFile()` function before calling any of these functions.

> Additionally, `KClientAddServiceKey()` and `KClientGetServiceKey()` no longer take a service argument. The service is specified when the session is created with `KClientNewServerSession()`, or later with `KClientSetServerPrincipal()`.

> # KClient APIs at a glance

> The following table lists all KClient 1.x API functions alphabetically, and indicates their status.

> Function | Status | 1.x compatibility comment | 3.0 update comment
> `KClientAddCredentials` | Deprecated |  | Use Credentials Cache API
> `KClientAddRealmMap` | Deprecated |  | Use Kerberos Profile API
> `KClientAddServerMap` | Deprecated |  | Use Kerberos Profile API
> `KClientAddSpecial` | Unsupported |  |
> `KClientCacheInitialTicket` | Deprecated | Only the special case of a ticket-granting ticket is implemented. |
> `KClientDecrypt` | Supported |  | Argument change
> `KClientDeleteCredentials` | Deprecated |  | Use Credentials Cache API
> `KClientDeleteRealmMap` | Deprecated |  | Use Kerberos Profile API
> `KClientDeleteServerMap` | Deprecated |  | Use Kerberos Profile API
> `KClientDeleteSession` | Deprecated |  | Use Credentials Cache API
> `KClientDeleteSpecial` | Unsupported |  |
> `KClientDisposeSession` | Supported |  | Argument change
> `KClientEncrypt` | Supported |  | Argument change
> `KClientErrorText` | Deprecated |  | Use Error Library API
> `KClientGetCredentials` | Deprecated |  | Use Credentials Cache API
> `KClientGetLocalRealm` | Deprecated |  | Use Kerberos Profile API
> `KClientGetNthCredential` | Deprecated |  | Use Credentials Cache API
> `KClientGetNthRealmMap` | Deprecated |  | Use Kerberos Profile API
> `KClientGetNthServer` | Deprecated |  | Use Kerberos Profile API
> `KClientGetNthServerMap` | Deprecated |  | Use Kerberos Profile API
> `KClientGetNthServerPort` | Deprecated |  | Use Kerberos Profile API
> `KClientGetNthSession` | Deprecated |  | Use Credentials Cache API
> `KClientGetNthSpecial` | Unsupported |  |
> `KClientGetNumCredentials` | Deprecated |  | Use Credentials Cache API
> `KClientGetNumSessions` | Deprecated |  | Use Credentials Cache API
> `KClientGetNumSpecials` | Unsupported |  |
> `KClientGetOption` | Unsupported |  |
> `KClientGetRealm` | Deprecated |  | Use Kerberos v4 API
> `KClientGetSessionKey` | Supported |  | Argument change
> `KClientGetSessionUserName` | Supported |  | Argument and name change
> `KClientGetTicketForService` | Supported |  | Argument change
> `KClientGetUserName` | Deprecated |  | Use Credentials Cache API
> `KClientKeyLogin` | Unsupported |  |
> `KClientLogin` | Supported |  | Argument change
> `KClientLogout` | Supported |  | Argument change
> `KClientMakeSendAuth` | Supported |  | Argument and name change
> `KClientNewSession` | Supported |  | Argument and name change
> `KClientPasswordLogin` | Supported |  | Argument change
> `KClientPasswordToKey` | Unsupported |  |
> `KClientProtectIntegrity` | Supported |  | Argument change
> `KClientSetLocalRealm` | Deprecated |  | Use Kerberos Profile API
> `KClientSetNthServerPort` | Deprecated |  | Use Kerberos Profile API
> `KClientSetOption` | Unsupported |  |
> `KClientSetPrompt` | Unsupported |  |
> `KClientSetUserName` | Modified |  | Argument and semantics change
> `KClientStatus` | Modified |  | Use KClientGetExpirationTime
> `KClientVerifyIntegrity` | Supported |  | Argument change
> `KClientVerifyReplyTicket` | Supported |  | Argument and name change
> `KClientVerifyUnencryptedReplyTicket` | Supported |  | Argument and name change
> `KClientVersion` | Modified |  | Name and argument change
> `KServerAddKey` | Supported |  | Argument and name change
> `KServerGetKey` | Supported |  | Argument and name change
> `KServerGetReplyTicket` | Supported |  | Argument and name change
> `KServerGetSessionTimeRemaining` | Modified |  | Use KClientGetExpirationTime
> `KServerNewSession` | Supported |  | Argument and name change
> `KServerVerifyTicket` | Supported |  | Argument and name change

Questions or comments? Send mail to macdev@mit.edu
Last updated on $Date: 2003/11/18 21:12:14 $
Last modified by $Author: smcguire $