The following are notes describing the requirements of the Platform Specific code necessary for constructing a Portable CCAPI. Directory structure: lib/ccapi/client - platform independent client library lib/ccapi/common - platform independent common library lib/ccapi/include - platform independent header files lib/ccapi/mac - macosx specific headers, libraries, executables lib/ccapi/server - platform independent server library lib/ccapi/windows - windows specific headers, libraries, executables Platform Independent Design: The functionality of the Portable CCAPI is implemented in the platform independent libraries. The common library encapsulates the functions for managing generic lists, iterators, and messages as well as routines formarshalling and unmarshalling. The client library provides the client side routines for issuing requests to the ccapi server minus the platform dependent glue required for shared library initialization, cleanup, and interprocess communications. The server library provides server side functionality for managing credential cache collections, caches, credentials, iterators, and their handles minus the platform dependent glue for process initialization, interprocess communication, session security, and critical section enforcement. Platform Dependent Design Requirements: The platform dependent code is responsible for producing a shared client library: + the shared library is built from cc_client.lib and cc_common.lib plus platform dependent glue - [windows] link cc_client.lib and cc_common.lib with platform dependent routines and export list (.def) to produce krbcc32.{lib,dll} + initialization and cleanup - [windows] provide DllMain entry point providing Process and Thread attachment and detachment routines + implement cci_perform_rpc() function used by cc_client.lib cc_int32 cci_perform_rpc(cc_msg_t *request, cc_msg_t **response) - cci_perform_rpc() takes an input request cc_msg_t object, flattens it with cci_msg_flatten() and sends the contents of unsigned char buffer request->flat of length request->flat_len to the server utilizing a platform specific interprocess communication method. - upon IPC success, cci_perform_rpc() unflattens the response buffer with cci_msg_unflatten() and returns the new cc_msg_t response object to the caller. - cci_perform_rpc() is responsible for performing any necessary session security management. For example, on Windows the Logon Provider executes under the local machine's "SYSTEM" account within session 0 and not under the account of the user that is logging in nor within the session the user's desktop and applications will be running within. It is the responsibility of cci_perform_rpc() and the platform dependent IPC mechanism to communicate the user's security identifiers to the server. For Windows, this means that the platform specific IPC messaging allows a username and session identifier to be sent separate from the username and session identifier that will be obtained via the use of Local RPC. If the Local RPC authenticates the user as "SYSTEM" and session 0, then the communicated values (if provided) will be used instead. + implement client side of IPC routine. - [windows] the client side IPC routine is produced by compiling a IDL file. The IDL defines an interface with a single function: __int32 ccapi_Message ( [in] handle_t h, [in, string] unsigned char * client_name, [in] struct _LUID luid, [in] __int32 in_len, [in, string, size_is(in_len)] unsigned char * in_buf, [in] __int32 out_size, [out] __int32 * out_len, [out, string, size_is(out_size)] unsigned char out_buf[*]); The handle is a Local RPC specific handle used to identify the request. The client_name and luid are the override values for the username and session identifier for use during Windows login. The rest of the parameters provide the input and output buffers as well as allow communication of the actual length of the message data that is required by cci_msg_unflatten(). + if the CCAPI server is per-session, the shared client library is responsible for ensuring that an instance of the server is running in the current session. If not, the library must initiate an instance of the CCAPI server prior to performing any IPC requests. The platform dependent code is responsible for producing a server executable: + The server executable is built from cc_server.lib and cc_common.lib plus platform dependent glue. - [windows] The Windows CCAPI Server is being built using the per-system model. The platform specific code is responsible for providing NT Service Management routines for installation and removal as well as the NT Service Entry Points used when the process is started as an NT Service. link cc_server.lib and cc_common.lib with platform dependent routines to produce krbcc32s.exe. + Based upon the platform requirements, the server may be constructed to be per-session or per-system. The selected IPC mechanism must enforce the appropriate scoping. + The platform dependent startup routines will perform platform specific initialization including the IPC engine and call the platform independent initialization routine ccs_serv_initialize() + The platform dependent shutdown routines will perform platform specific cleanup including the IPC engine and call the platform independent function ccs_serv_cleanup() prior to process termination. + For each inbound CCAPI request, the server will unmarshall the request using cci_msg_unflatten() to produce a cc_msg_t object, construct cc_auth_info_t and cc_session_info_t objects to represent the platform dependent authentication and session data, call ccs_serv_process_msg() to process the request, call cci_msg_flatten() to marhall the response, transmit the response to the caller, and then cleanup the request and response cc_msg_t objects with cci_msg_destroy(). + The cc_auth_info_t and cc_session_info_t objects are structures storing opaque binary (data, length) representations of the authentication and session data. These are stored as part of ccache collection and ccaches. ccs_serv_process_msg() will perform a binary comparison of the stored data with the data provided in the current request. If they do not match, the request will be denied. It is necessary that the data generated data always be the same. If username strings are not case-sensitive, they should be normalized before being passed to ccs_serv_process_msg(). + The current cc_server.lib routines assume that one request at a time is being processed. If the IPC engine allows for more than one request to be simultaneously received in separate threads, then the call to ccs_serv_process_msg() must be wrapped by a critical section. Future enhancements to cc_server.lib will allow for per-object mutexes. When available the platform specific glue must provide functions to create, obtain, release, and destroy mutex objects.