Network Working Group C. Newman Internet Draft: SASL C API Innosoft Document: draft-newman-sasl-c-api-00.txt A. Melnikov MessagingDirect October 2002 Expires in six months Simple Authentication and Security Layer C API Status of this memo This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026 [RFC2026]. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. Abstract Almost every protocol needs authentication. However, there does not exist an authentication mechanism suitable for all organizations, nor is it likely that a small fixed set of authentication mechanisms will remain suitable. SASL [SASL] provides the on-the-wire framework for authentication (and a security layer) which separates the design of authentication mechanisms from the protocols in which they're used. The SASL protocol model suggests a software architecture where application protocols call a generic API to authenticate which in turn calls a generic plug-in interface for extensible authentication modules. This memo documents the API used in one implementation of this architecture in the hope that it will be useful to others. An associated memo documenting the plug-in interface is forthcoming. 1. Conventions Used in this Memo Newman et al. Expires: March 2003 FORMFEED[Page 1] INTERNET DRAFT SASL C API October 2002 The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as defined in "Key words for use in RFCs to Indicate Requirement Levels" [KEYWORDS]. This assumes familiarity the SASL [SASL] specification. 1.1. Concepts The following concepts are necessary to understand this specification. realm A realm is a name (usually a domain-style name) associated with a set of users on a server. One realm may span multiple servers. Alternatively, a single server may have multiple realms. Thus there may be multiple users with the username "chris" on the same server, each in a different realm. Some authentication mechanisms have a special field for the realm (e.g., DIGEST-MD5). For other mechanisms, a realm can be specified by the client by using the syntax "username@realm" in the username field. service A service is a basic function provided by one or more protocols. The GSSAPI service name registry is available at: This registry is used by SASL and the SASL API. The service name may be used for service-specific passwords for advanced users, or advanced authentication mechanisms may restrict the services a given server may offer. virtual domain When a single server has multiple realms and there is a DNS server entry for each realm pointing to the same server IP address, then those realms are "virtual domains". Virtual domains are extremely popular with web hosting services and are becoming more popular with POP mail services. The key to providing virtual domain sup- port is that the client informs the server of the domain it believes it is speaking to either through a special protocol ele- ment or by using a username of the form "user@realm". 2. Overview of the SASL C API The SASL API is initialized once at process startup and the various plug-ins are added. The sasl_server_init() and sasl_client_init() Newman et al. Expires: March 2003 FORMFEED[Page 2] INTERNET DRAFT SASL C API October 2002 functions provide basic initialization. When a network connection occurs where SASL will be used, a connec- tion-specific context is created for authentication with sasl_client_new() or sasl_server_new(). The API implementation must support multi-threaded servers and clients by creating the connection context in a thread-safe fashion permitting multiple contexts in a given process. At this point, the caller may adjust security policy for the context, and the set of mechanisms which are enabled is determined by requirements from the configuration or by the caller. The server end of the API may request a list of enabled authentica- tion mechanisms either in general or for a specific user. The client may either select a single mechanism or request a list from the server (if the SASL profile for the protocol in question supports that) and pass the list to the API for automated mechanism selection by configured policy. The SASL exchange begins with sasl_client_start() which determines if one of the desired mechanisms is available on the client and may gen- erate an initial client response. The client then sends the appro- priate protocol message to initiate the SASL exchange that the server passes to sasl_server_start(). The SASL exchange continues with calls to sasl_client_step() and sasl_server_step(), until the server indicates completion or the client cancels the exchange. The server queries the user name and user realm resulting from the exchange with the sasl_getprop() routine. A connection context is released with sasl_dispose() and process ter- mination is indicated with sasl_done(). There are a number of utility functions and customization functions available in the API for additional services. 3. Basic SASL API Routines This section describes the types and functions likely to be used by every caller of the SASL API. 3.1. Basic SASL API Data Structures The following datastructures are basic to the SASL API. 3.1.1. sasl_callback_t Newman et al. Expires: March 2003 FORMFEED[Page 3] INTERNET DRAFT SASL C API October 2002 The sasl_callback_t structure is used for the caller of the SASL API to provide services to both the core SASL API and SASL plug-ins via callbacks. The most important callback is the "getopt" callback (see section 3.3.3) which is used to retrieve security policy option set- tings from the caller's preferences. typedef struct sasl_callback { unsigned long id; int (*proc)(); void *context; } sasl_callback_t; id is the label for the callback (XXX IANA registry needed), proc is a function pointer whose type is determined by the id, and context is a context variable which will be passed to the callback (usually as the first argument). The last callback in the list of callbacks is indicated with an id of SASL_CB_LIST_END. 3.1.2. sasl_secret_t The sasl_secret_t structure is used to hold text or binary passwords for the client API. typedef struct sasl_secret { unsigned long len; unsigned char data[1]; } sasl_secret_t; The len field holds the length of the password, while the data field holds the actual data. The structure is variable sized: enough space must be reserved after the data field to hold the desired password. An additional that binary passwords are permitted to contain '\0' characters. 3.1.3. sasl_conn_t The sasl_conn_t data type is an opaque data type which reflects the SASL context for a single server connection. Only one SASL API call using a given sasl_conn_t as an argument may be active at a time. However, each sasl_conn_t is independent and thus the SASL API may be used in a true multi-processor multi-threaded environment. 3.1.4. sasl_interact_t The sasl_interact_t structure is used by sasl_client_start and sasl_client_step to request certain information interactively from the user when no corresponding callback was provided by the client application. For example, SASL_CB_PASS callback Newman et al. Expires: March 2003 FORMFEED[Page 4] INTERNET DRAFT SASL C API October 2002 typedef struct sasl_interact { unsigned long id; const char *challenge; const char *prompt; const char *defresult; const void *result; unsigned len; } sasl_interact_t; The id field holds the value of the callback ID. The prompt field contains a string that should be presented to the user. If non-NULL, challenge is a NUL-terminated string that will allow the user to pre- sent a specific credential when prompted. This is different from the prompt in that the prompt is more like a label for a text box (for example "Response:" while challenge is a string that tells the user what specifically is required by the response (for example, an OTP challenge string). The defresult field contains a default value, if any. Upon return from sasl_client_* the "result" field points to the defresult. The client must present the information in the challenge and the prompt to the user and store the result and its length in the result and the len fields respectively. For example, SASL_CB_PASS interaction may contain the following information: id - SASL_CB_PASS challenge - NULL prompt - "Password:" defresult - NULL (no default). 3.2. Basic SASL API Client Routines This section discusses the functions likely to be used by every client caller of the SASL API. 3.2.1. sasl_client_init function Arguments: sasl_callback_t *callbacks Results: SASL_OK -- Success SASL_NOMEM -- Not enough memory SASL_BADVERS -- Mechanism version mismatch SASL_BADPARAM -- error in config file This function initializes the client routines for the SASL API. The callbacks argument is the default list of callbacks (see Newman et al. Expires: March 2003 FORMFEED[Page 5] INTERNET DRAFT SASL C API October 2002 section 3.1.1 for definition of sasl_callback_t structure) and SHOULD include the sasl_getopt_t callback (see section 3.3.3). The callbacks may be NULL. On success, SASL_OK is returned, and on failure a SASL C API error code such as the ones listed above is returned. This function may be called a second time to change the default callbacks used for new connections, but the first call must be made in a single-threaded environment. The data refer- enced by the sasl_callback_t structure must persist until sasl_done() is called. 3.2.2. sasl_client_new function Arguments: const char *service, const char *serverFQDN, const char *iplocalport, const char *ipremoteport, const sasl_callback_t *prompt_supp, unsigned int flags, sasl_conn_t **pconn Results: SASL_OK -- Success SASL_NOTINIT -- SASL API not initialized SASL_NOMECH -- No mechanisms available SASL_NOMEM -- Not enough memory This function creates a client connection context variable. As long as each thread uses its own connection context, the SASL C API is thread-safe. The service argument is an IANA registered GSSAPI service element as defined above. It should not be NULL; an implementation of the SASL API is permitted to refuse to authenticate without a service name. The serverFQDN is the fully qualified domain name of the server to which the client is connecting. NULL may be used for serverFQDN, but may result in advanced mechanisms such as Kerberos being unavailable. The iplocalport is the string with the client IPv4/IPv6 address, followed by ";" and than by port number. NULL may be used for iplocalport, but may result in mechanisms requiring IP address being unavailable. The ipremoteport is the string with the server IPv4/IPv6 address, followed by ";" and than by port number. NULL may be used for Newman et al. Expires: March 2003 FORMFEED[Page 6] INTERNET DRAFT SASL C API October 2002 ipremoteport, but may result in mechanisms requiring IP address being unavailable. The prompt_supp is a list of supported user prompting callbacks discussed in the section 3.1.1. The flags argument represents client-supported security flags. The only values currently supported are SASL_SECURITY_LAYER to indicate the client supports the SASL security layer, or 0 to indicate it doesn't. The pconn argument is set to point to the newly created connection context. The sasl_conn_t type is opaque to the calling applica- tion. User input to the SASL C API may be provided either by supplying callbacks to this function, or by using an interaction model with the sasl_client_step function. The former is suitable for machines with pre-emptive multitasking and the latter may be more suitable for event-loop based programming. The prompt_supp argu- ment MAY be NULL, but only if the prompt_need argument to sasl_client_start and sasl_client_step is not NULL. 3.2.3. sasl_client_start function Arguments: sasl_conn_t *conn, const char *mechlist, sasl_interact_t **prompt_need, const char **clientout, unsigned int *clientoutlen, const char **mech Results: SASL_NOTINIT -- SASL API not initialized SASL_BADPARAM -- conn or mechlist is NULL SASL_NOMECH -- No matching mechanisms available SASL_NOMEM -- Not enough memory SASL_INTERACT -- User interaction needed to continue (see prompt_need description below) SASL_OK -- Success This selects an authentication mechanism to use and optionally generates an initial client response. The conn argument is the connection context from sasl_client_new. The mechlist argument is a '\0' terminated string containing one Newman et al. Expires: March 2003 FORMFEED[Page 7] INTERNET DRAFT SASL C API October 2002 or more SASL mechanism names. All characters in the string that are not permitted in a SASL mechanism name [SASL] are ignored except for the purposes of delimiting mechanism names (this per- mits passing direct results from many protocol capability lists unparsed). Unknown mechanism names are ignored (although SASL_NOMECH is returned if no known mechanisms are found). Mecha- nisms are tried in an implementation-dependent order. Implementa- tions SHOULD try to use the most secure mechanism possible, within the constraints specified by the application (e.g. SSF value). If a previous call to sasl_client_start was made using the same con- nection context, then a subsequent call to sasl_client_start with a NULL mechlist parameter indicates the desire to restart the same mechanism selected previously after discarding cached information (e.g., username and password). <> The prompt_need argument is set to NULL by clients which provided appropriate callbacks to sasl_client_new or sasl_client_init. Otherwise, if the mechanism selected needs information from the user such as the username and password, then prompt_need will be set to a list of required information and SASL_INTERACT will be returned. The prompt_need list is terminated with the entry with id SASL_CB_LIST_END. After that the client must fill in the requested information and call this function again with the same parameters. The clientout and clientoutlen parameters are set to the initial client response, if any. If a protocol's SASL profile uses base64 encoding, this represents the data prior to the encoding (see sasl_encode64). If a protocol's SASL profile doesn't include an optional initial client response, then these may be NULL and 0 respectively. The memory used by clientout is interally managed by the SASL API and may be overwritten on the next call to sasl_client_step or a call to sasl_dispose. The mech argument is set to point to a '\0' terminated string specifying the mechanism actually selected using all uppercase letters. It may be NULL if the client does not care which mecha- nism was selected from mechlist. If sasl_client_start is called a second time using the same con- nection context, it will discard any cached information (e.g., the username and password) and restart the exchange from the begin- ning. <> 3.2.4. sasl_client_step function Newman et al. Expires: March 2003 FORMFEED[Page 8] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_conn_t *conn, const char *serverin, unsigned int serverinlen, sasl_interact_t **prompt_need, const char **clientout, unsigned int *clientoutlen Results: SASL_NOTINIT -- SASL API not initialized SASL_NOMECH -- sasl_client_start not called SASL_BADPROT -- server protocol incorrect/cancelled SASL_BADSERV -- server failed mutual auth SASL_INTERACT -- user interaction needed SASL_OK -- success This routine performs one step in an authentication sequence. The conn argument must be a connection context created by sasl_client_new and used in a previous call to sasl_client_start. The serverin and serverinlen parameters hold the SASL octet string received from the server. Note that for those SASL profiles which base64 encode the exchange, this is the result after the removal of the base64 encoding (see the sasl_decode64 routine below). The serverin MUST have a terminating NUL character not counted by serverinlen The prompt_need argument is the same as for sasl_client_start. The clientout and clientoutlen parameters hold the SASL octet string to encode (if necessary) and send to the server. 3.2.5. sasl_pass2secret function Newman et al. Expires: March 2003 FORMFEED[Page 9] INTERNET DRAFT SASL C API October 2002 Arguments: const char *user, const char *pass, int passlen, const char *mech, sasl_secret_t **psecret Results: SASL_NOTINIT -- SASL library not initialized SASL_BADPARAM -- invalid parameter SASL_NOMEM -- out of memory SASL_OK -- success This routine converts a username (in UTF-8) and a password to a library internal representation which may be encoded or encrypted. The passlen parameter specifies the length of the password. If a passlen of 0 is included, that indicates the password is NUL ter- minated. If the mech parameter is supplied, then the library may generate a secret only suitable for that particular mechanism. The structure of sasl_secret_t is opaque to the caller. 3.2.6. sasl_free_secret function Arguments: sasl_secret_t **psecret Results: none This frees the secret pointed to by *psecret, and sets psecret to NULL. It takes care to erase the underlying memory prior to free- ing it. 3.2.7. sasl_setprop function Arguments: sasl_conn_t *conn, int propnum, const void *value Results: SASL_OK -- property set SASL_BADPARAM -- invalid propnum or value SASL_NOMEM -- not enough memory to perform operation This sets a property in a connection context. The SASL_SECRET property is used to set the secret associated with a connection. If SASL_SECRET is used there is no need to call sasl_free_secret. Newman et al. Expires: March 2003 FORMFEED[Page 10] INTERNET DRAFT SASL C API October 2002 See the section on properties below for additional properties. SASL_COPY_SECRET may be used if the same secret is going to be used for more than one connection. Commonly used properties with their descriptions are listed below: SASL_SSF_EXTERNAL Security layer strength factor (SSF) -- an unsigned integer usable by the caller to specify approximate security layer strength desired. It roughly corresponds to the effective key length for encryption, e.g. 0 = no protection 1 = integrity protection only >1 = key lenght of the cipher SASL_SSF_EXTERNAL property denotes SSF of the external security layer (e.g. provided by TLS). The value parameter points to sasl_ssf_t, that is described as follows: typedef unsigned sasl_ssf_t; SASL_SEC_PROPS The value parameter for SASL_SEC_PROPS points to sasl_secu- rity_properties_t structure defined below. A particular implemen- tation may extend it with additional fields. typedef struct sasl_security_properties { sasl_ssf_t min_ssf; sasl_ssf_t max_ssf; unsigned maxbufsize; /* bitfield for attacks to protect against */ unsigned security_flags; } sasl_security_properties_t; The min_ssf and the max_ssf define the minimal and the maximal acceptable SSF. The maxbufsize specifies the biggest buffer size that the client/server is able to decode. 0 means that security layer is not supported. The security_flags is a bitmask of the various security flags Newman et al. Expires: March 2003 FORMFEED[Page 11] INTERNET DRAFT SASL C API October 2002 described below: NOPLAINTEXT -- don't permit mechanisms susceptible to simple passive attack (e.g., PLAIN, LOGIN) NOACTIVE -- protection from active (non-dictionary) attacks during authentication exchange. Authenticates server. NODICTIONARY -- don't permit mechanisms susceptible to passive dictionary attack FORWARD_SECRECY -- require forward secrecy between sessions (breaking one won't help break next) NOANONYMOUS -- don't permit mechanisms that allow anonymous login PASS_CREDENTIALS -- require mechanisms which pass client credentials, and allow mechanisms which can pass credentials to do so MUTUAL_AUTH -- require mechanisms which provide mutual authentication SASL_AUTH_EXTERNAL The value parameter for SASL_AUTH_EXTERNAL property points to the external authentication ID as provided by external authentication method, e.g. TLS, PPP or IPSec. 3.3. Basic SASL API Callback Routines This section describes the basic callback functions needed for a simple client implementation. See the definition of sasl_call- back_t in section 3.1.1 for a description of the basic callback structure. 3.3.1. sasl_getsimple_t Arguments: void *context, int id, const char **result, unsigned *len Results: none This callback is used by the SASL API to request a simple constant string from the application. This is used with id SASL_CB_USER for the username, SASL_CB_AUTHNAME for the authentication name (if different), and SASL_CB_LANGUAGE for a comma separated list of RFC 1766 language tags. Newman et al. Expires: March 2003 FORMFEED[Page 12] INTERNET DRAFT SASL C API October 2002 The context is the context variable from the sasl_callback_t structure, the id is the id from the sasl_callback_t structure, and the callback is expected to set the result to a constant string and the len to the length of that string. The result and len parameters are never NULL. 3.3.2. sasl_getsecret_t Arguments: sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret Results: none This callback is expected to create, prompt or locate a secret and set it in the connection context with sasl_setprop. The conn argument is the connection context, the context and id parameters are from the sasl_callback_t structure. The id SASL_CB_PASS is used to request a clear text password. 3.3.3. sasl_getopt_t Arguments: void *context, const char *plugin_name, const char *option, const char **result, unsigned int *len Results: SASL_OK -- success SASL_FAIL -- error This callback is used by the SASL API to read options from the application. This allows a SASL configuration to be encapsulated in the caller's configuration system. Some implementations may use default config file(s), if this is omitted. Configuration items may be plugin-specific and are arbitrary strings. The context is the context variable from the sasl_callback_t structure, the plugin_name is the name of plugin (or NULL), the option is the option name, and the callback is expected to set the result to a string valid till next call to sasl_getopt_t in the same thread and the len to the length of that string. The result and len parameters are never NULL. If the name of plugin is NULL, Newman et al. Expires: March 2003 FORMFEED[Page 13] INTERNET DRAFT SASL C API October 2002 a general SASL option is requested, otherwise a plugin specific version. 3.4. Basic SASL C API Utility Routines This section describes utility functions provided as part of the SASL API which may be used both by clients and servers. 3.4.1. sasl_decode64 function Arguments: const char *in, unsigned int inlen, char *out, unsigned int outmax, unsigned int *outlen Results: SASL_BUFOVER -- output buffer too small SASL_BADPROT -- invalid base64 SASL_OK -- successful decode This utility routine converts a base64 string into an octet string. It is useful for SASL profiles which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] profiles. The output is NUL terminated and the length is placed in the outlen parameter if outlen is non-NULL. 3.4.2. sasl_encode64 function Arguments: const char *in, unsigned int inlen, char *out, unsigned int outmax, unsigned int *outlen Results: SASL_BUFOVER -- output buffer too small SASL_BADPROT -- invalid base64 SASL_OK -- successful decode This utility routine converts an octet string into a base64 string. It is useful for SASL profiles which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] profiles. The output is NUL terminated and the length is placed in the outlen parameter if outlen is non-NULL. Newman et al. Expires: March 2003 FORMFEED[Page 14] INTERNET DRAFT SASL C API October 2002 3.4.3. sasl_errstring function Arguments: int saslerr, const char *langlist, const char **outlang Results: const char * This converts a SASL error number into a constant string. The second argument MAY be NULL for the default language, or a comma- separated list of RFC 1766 language tags. The final parameter is set to the RFC 1766 language tag of the string returned which will be "i-default" if no matching language is found. The strings are UTF-8. This requires no context so it may be used for the result of an sasl_*_init or sasl_*_new result code. 3.4.4. sasl_errdetail function Arguments: sasl_conn_t *conn Results: const char * This converts the last SASL error code that occured on a connec- tion to UTF8 string. It uses the SASL_CB_LANGUAGE callback (see section 3.3.1) to determine the language to use. It may return more detailed information than sasl_errstring does. 3.5. Basic SASL C API Server Routines This section describes the basic routines for a server implementa- tion of a SASL profile. 3.5.1. sasl_server_init function Newman et al. Expires: March 2003 FORMFEED[Page 15] INTERNET DRAFT SASL C API October 2002 Arguments: const sasl_callback_t *callbacks, const char *appname Results: SASL_BADPARAM -- error in config file SASL_NOMEM -- out of memory SASL_BADVERS -- Plug-in version mismatch SASL_OK -- success This function initializes the server routines for the SASL C API. The callbacks argument is the default list of callbacks (see sec- tion 3.1.1 for definition of sasl_callback_t structure) and SHOULD include the sasl_getopt_t callback (see section 3.3.3). The call- backs may be NULL. The appname argument is the name of the calling application and may be used by server plug-ins for logging. On success, SASL_OK is returned, and on failure a SASL C API error code is returned. This function may be called a second time to change the default callbacks, but the first call must be made in a single-threaded environment. (<>) The data referenced by the sasl_callback_t structure must persist until sasl_done() is called. 3.5.2. sasl_server_new function Arguments: const char *service, const char *serverFQDN, const char *user_domain, const char *callbacks, unsigned int flags, sasl_conn_t **pconn Results: SASL_OK -- success SASL_NOTINIT -- SASL API not initialized SASL_BADPARAM -- Invalid parameter supplied SASL_NOMECH -- No mechanisms available SASL_NOMEM -- Not enough memory This function creates a server connection context variable. As long as each thread uses its own connection context, the SASL C API is thread-safe. The service argument is an IANA registered GSSAPI service element [GSSAPI] listed at it must not be NULL. The serverFQDN is the fully qualified name of the server. NULL means use gethost- name() or equivalent. The user_realm is a string used to determine Newman et al. Expires: March 2003 FORMFEED[Page 16] INTERNET DRAFT SASL C API October 2002 the set of users on the system for systems which support multiple user communities ("realms"). NULL is the recommended value. The iplocalport is the string with the server IPv4/IPv6 address, fol- lowed by ";" and than by port number. NULL may be used for iplo- calport, but may result in mechanisms requiring IP address being unavailable. The ipremoteport is the string with the client IPv4/IPv6 address, followed by ";" and than by port number. NULL may be used for ipremoteport, but may result in mechanisms requir- ing IP address being unavailable. The callbacks argument is a set of server callbacks which may include a connection-specific sasl_getopt_t and/or an authoriza- tion routine. The flags argument represents server-supported secu- rity flags. The only values currently supported are SASL_SECU- RITY_LAYER to indicate the server supports the SASL security layer, or 0 to indicate it doesn't. The pconn argument is set to point to the newly created connection context. 3.5.3. sasl_server_start function Arguments: sasl_conn_t *conn, const char *mech, const char *clientin, insigned int clientinlen, const char **serverout, unsigned int *serveroutlen Results: SASL_CONTINUE -- Another authentication step required SASL_OK -- Authentication Complete SASL_NOTINIT -- SASL API not initialized SASL_BADPARAM -- Invalid parameter supplied SASL_BADPROT -- Client protocol error SASL_NOMECH -- Mechanism not supported SASL_NOVERIFY -- User exists, but no verifier exists for the mechanism SASL_TRANS -- A password transition is needed to use mechanism This begins an authentication exchange and is called after the client sends the initial authentication command. The mech argu- ment is the mechanism name the client is requesting. If the client includes an optional initial-response, it is passed in the clientin and clientinlen fields. Otherwise NULL and 0 are passed for those arguments. The serverout and serveroutlen are filled in with the server response, if any. If SASL_CONTINUE is returned, the server will need to wait for another client message and call sasl_server_step. If SASL_OK is returned, the authentication is Newman et al. Expires: March 2003 FORMFEED[Page 17] INTERNET DRAFT SASL C API October 2002 completed successfully, although server out data may be supplied. 3.5.4. sasl_server_step function Arguments: sasl_conn_t *conn, const char *clientin, insigned int clientinlen, const char **serverout, unsigned int *serveroutlen Results: SASL_CONTINUE -- Another authentication step required SASL_OK -- Authentication Complete SASL_NOTINIT -- SASL API not initialized SASL_NOMECH -- sasl_server_start not called SASL_BADPARAM -- Invalid parameter supplied SASL_BADPROT -- Client protocol error SASL_NOVERIFY -- User exists, but no verifier exists for the mechanism SASL_TRANS -- A password transition is needed to use mechanism This routine performs one step in an authentication sequence. The conn argument must be a connection context created by sasl_server_new and used in a previous call to sasl_server_start. The clientin and clientinlen parameters hold the SASL octet string received from the client. Note that for those SASL profiles which base64 encode the exchange, this is the result after the removal of the base64 encoding (see the sasl_decode64 routine). The cli- entin MUST have a terminating NUL character not counted by serverinlen. The serverout and serveroutlen parameters hold the SASL octet string to encode (if necessary) and send to the client. If SASL_CONTINUE is returned, the server will need to wait for another client message and call sasl_server_step. If SASL_OK is returned, the authentication is completed successfully, although server out data may be supplied. 3.5.5. sasl_getprop function Newman et al. Expires: March 2003 FORMFEED[Page 18] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_conn_t *conn, int propnum, const void **pvalue Results: SASL_OK -- Success SASL_NOTDONE -- Authentication exchange must complete prior to retrieving this attribute SASL_BADPARAM -- bad property number This requests a pointer to a constant property available through the SASL API. The most common use by servers is to get the SASL_USERNAME property which returns the authorization identity (user to login as) from the SASL mechanism as a UTF-8 string in the pvalue parameter. Additional properties are listed in section 6. 3.5.6. sasl_listmech function Arguments: sasl_conn_t *conn, const char *user, const char *prefix, const char *sep, const char *suffix, char **result, unsigned int *plen, unsigned *pcount Results: SASL_OK -- Success SASL_NOMEM -- Not enough memory SASL_NOMECH -- No enabled mechanisms This returns a list of enabled SASL mechanisms in a NUL-terminated string. The list is constructed by placing the prefix string at the beginning, placing the sep string between any pair of mechan- sisms and placing the suffix string at the end. This function returns the list of client side SASL mechanisms, if the conn was created by sasl_client_new and the list of server side mechanisms, if the conn was created by sasl_server_new. 3.5.7. sasl_free_listmech function Newman et al. Expires: March 2003 FORMFEED[Page 19] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_conn_t *conn, char **result Results: none This disposes of the result string returned by sasl_listmech. 3.6. Common SASL API Routines This section describes the routines that are common for both clients and servers. 3.6.1. sasl_dispose function Arguments: sasl_conn_t **pconn Results: none This function disposes of the connection state created with sasl_client_new or sasl_server_new, and sets the pointer to NULL. If the pconn is already NULL the function does nothing. 3.6.1. sasl_done function Arguments: none Results: none A SASL client/server willing to stop using SASL API must call this function. This function forces all SASL plugins to unload and frees all internal SASL library state. After this call most of the SASL API function will return SASL_NOTINIT error code. Connection states MUST be disposed of with sasl_dispose before calling this function. 4. SASL Security Layer Routines This section describes the routines need to support a security layer. 4.1. sasl_encode function Newman et al. Expires: March 2003 FORMFEED[Page 20] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_conn_t *conn, const char *input, unsigned int inputlen, const char **output, unsigned int *outputlen Results: SASL_OK -- Success (returns input if no layer negotiated) SASL_NOTDONE -- Security layer negotiation not finished SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF property This function encodes a block of data for transmission using secu- rity layer (if any). The output and outputlen are filled in with the encoded data and its length respectively. If there is no secu- rity layer the input buffer is returned in the output. The output is only valid until a next call to sasl_encode. 4.1. sasl_decode function Arguments: sasl_conn_t *conn, const char *input, unsigned int inputlen, const char **output, unsigned int *outputlen Results: SASL_OK -- Success (returns input if no layer negotiated) SASL_NOTDONE -- Security layer negotiation not finished SASL_BADMAC -- Bad message integrity check This function decodes a block of data received using security layer (if any). The output and outputlen are filled in with the decoded data and its length respectively. If there is no security layer the input buffer is returned in the output. The output is only valid until a next call to sasl_decode. 5. Advanced SASL API Routines This section describes the less frequently used functions avail- able in the SASL API. 5.1. Additional Initialization Routines 5.1.1. sasl_set_mutex function Newman et al. Expires: March 2003 FORMFEED[Page 21] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_mutex_alloc_t *mutex_alloc, sasl_mutex_lock_t *mutex_lock, sasl_mutex_unlock_t *mutex_unlock, sasl_mutex_free_t *mutex_free Results: None The sasl_set_mutex call sets the callbacks which the SASL API and plug-ins will use whenever exclusive access to a process shared resource is needed. A single-threaded client or server need not call this. The types are designed to be compatible with the LDAP API [LDAP-API]: typedef void *sasl_mutex_alloc_t(void); On success, this returns a pointer to an allocated and initialized mutex structure. On failure, it returns NULL. typedef int sasl_mutex_lock_t(void *mutex); This will block the current thread until it is possible to get an exclusive lock on a mutex allocated by the mutex_alloc callback. On success it returns 0, on failure due to deadlock or bad parame- ter, it returns -1. typedef int sasl_mutex_unlock_t(void *mutex); This releases a lock on a mutex allocated by the mutex_alloc call- back. On success it returns 0, on failure due to an already unlocked mutex, or bad parameter, it returns -1. typedef void sasl_mutex_free_t(void *mutex); This disposes of a mutex allocated by mutex_alloc. 5.1.2. sasl_set_alloc function Newman et al. Expires: March 2003 FORMFEED[Page 22] INTERNET DRAFT SASL C API October 2002 Arguments: sasl_malloc_t *malloc, sasl_calloc_t *calloc, sasl_realloc_t *realloc, sasl_free_t *free Results: None This sets the memory allocation functions which the SASL API will use. The SASL API will use its own routines (usually the standard C library) if these are not set. typedef void *sasl_malloc_t(unsigned long mem_size); This allocates memory mem_size bytes of memory. The memory is not initialized to any particular value. It returns NULL on failure. typedef void *sasl_calloc_t(unsigned long elem_size, unsigned long num_elem); This allocates elem_size * num_elem bytes of memory. The memory is initialized to 0. It returns NULL on failure. typedef void *sasl_realloc_t(void *mem_ptr, unsigned long new_size); This changes the size of memory previously allocated by malloc or calloc, and returns a pointer to the new location (which may be different from mem_ptr). If mem_ptr is NULL, it is identical to the malloc function. It returns NULL on failure. typedef void sasl_free_t(void *mem_ptr); This releases the memory in mem_ptr that was allocated by malloc or calloc or resized by realloc. The contents of the memory may be altered by this call. 6. Additional Properties <> SASL_SSF -- security layer security strength factor, if 0, call to sasl_encode, sasl_decode unnecessary SASL_MAXOUTBUF -- security layer max output buf unsigned SASL_DEFUSERREALM -- default realm passed to sasl_server_new or set with sasl_setprop SASL_GETOPTCTX -- context for getopt callback SASL_CALLBACK -- current callback function list Newman et al. Expires: March 2003 FORMFEED[Page 23] INTERNET DRAFT SASL C API October 2002 SASL_IPLOCALPORT -- iplocalport string passed to sasl_server_new/ sasl_client_new SASL_IPREMOTEPORT -- ipremoteport string passed to sasl_server_new/ sasl_client_new SASL_SERVICE -- service passed to sasl_*_new SASL_SERVERFQDN -- serverFQDN passed to sasl_*_new SASL_AUTHSOURCE -- name of the active plugin, if any SASL_MECHNAME -- active SASL mechanism name, if any SASL_AUTHUSER -- authentication/admin user (authorization id?) 7. References [IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4rev1", RFC 2060, University of Washington, December 1996. [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, Harvard University, March 1997. [POP3] Myers, J., Rose, M., "Post Office Protocol - Version 3", RFC 1939, Carnegie Mellon, Dover Beach Consulting, Inc., May 1996. [POP-AUTH] Myers, "POP3 AUTHentication command", RFC 1734, Carnegie Mellon, December 1994. [SASL] Myers, "Simple Authentication and Security Layer (SASL)", RFC 2222, Netscape Communications, October 1997. 8. Acknowledgements The editor would like to thank Rob Siemborski and Ken Murchison for providing useful feedback and suggestions. 9. Author's and Editor's Addresses Author: Chris Newman Innosoft International, Inc. 1050 Lakes Drive West Covina, CA 91790 USA Email: chris.newman@innosoft.com Editor: Alexey Melnikov Newman et al. Expires: March 2003 FORMFEED[Page 24] INTERNET DRAFT SASL C API October 2002 ACI WorldWide/MessagingDirect 59 Clarendon Road Watford, Hertfordshire, WD17 1FQ, UK Email: mel@messagingdirect.com 10. Full Copyright Statement Copyright (C) The Internet Society (2002). All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this doc- ument itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of develop- ing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MER- CHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Acknowledgement Funding for the RFC Editor function is currently provided by the Internet Society. A. Appendix A -- Design Goals The design goals of the SASL C API are as follows: o To be simple and practical to use. o To provide related utility services in addition to core SASL func- tionality. Newman et al. Expires: March 2003 FORMFEED[Page 25] INTERNET DRAFT SASL C API October 2002 o To be reasonably extensible. o To be suitable for use in a multi-threaded server or client. o To avoid dependancies on a specific memory allocation system, thread package or network model. o To be an independent service rather than a new layer. o To avoid extensive and confusing features which may be desired in a full service security API. B. SASL API Index <> Newman et al. Expires: March 2003 FORMFEED[Page 26]