Subject: Using SASL C API from a library

From: Greg Hudson <[email-masked]>
Date: Sun, 29 Jun 2003 09:00:15 -0700

Hi.  I'd like to point two deficiencies in the SASL C API as
documented in draft-newman-sasl-c-api-01.txt and implement in Cyrus
SASL.  First, the API includes functions:

  int sasl_client_init(const sasl_callback_t *callbacks);
  int sasl_server_init(const sasl_callback_t *callbacks,
                       const char *appname);
  static void sasl_done(void);

These are reasonable for using SASL from within an application, such
as sendmail, but involve too much global state to safely use SASL from
within a library, such as a Subversion repository access mechanism.
If I use the SASL C API from within my library, any application which
uses my library must not use the same API itself, nor can it link
against any other library which wants to use that API.

(There are some exceptional cases where things might work:

  * Using the API in a non-interleaved fashion, e.g. library A calls
    sasl_client_init(), creates and tears down some connections, and
    calls sasl_done(), then library B does the same thing.

  * Using the APIs in an interleaved fashion, but using a NULL
    default callbacks structure and never calling sasl_done().

But in the general case, the interaction won't succeed.)

Second, according to the draft, the sasl_client_init functions must be
called for the first time in a single-threaded environment.  A library
does not necessarily have the luxury of performing any calls from a
single-threaded environment.

I don't have a specific recommendation for fixing these problems.  But
they mean I can't in good conscience use the SASL C APIs from within a
library; I will either have to do that work within a subprocess,
implement my own SASL mechanisms, or abandon SASL for my protocol.