Hi all,

isync currently has two different SASL implementations in use.  Those
being the Cyrus SASL implementation (given by libsasl2) and a built-in
LOGIN-only implementation (yes, LOGIN technically isn't SASL, but it's
handled by the same logic).  These two implementations are intertwined
closely (and messily imo) in the program's IMAP authentication logic.

As such, I'd like to propose adding a single SASL interface for both
implementations.  That is, one set of functions with definitions
tailored for each implementation.  This has multiple advantages over the
current state:

- It can increase readability, particularly by replacing the scattered
  `#ifdef HAVE_LIBSASL`s and gotos with a unified interface.
- It allows much easier addition of other SASL implementations (e.g. GNU
  SASL) which may be preferable to many users (e.g. preferred licenses).
- It can make debugging easier by being able to quickly isolate bugs to
  a particular implementation.

This can be achieved by having a header (sasl_common.h) whose functions
are defined per implementation in source files (sasl_simple.c and
sasl_cyrus.c), where only the source file using the desired
implementation (simple/built-in or Cyrus) is added to compilation.

The logic present in the SASL code largely concerns filtering possible
SASL mechanisms based on the user configuration and IMAP capabilities.
So the SASL interface could act as an interface which takes lists of
mechanisms and keeps track of the mechanisms common to all given lists,
before of course performing the actual IMAP command construction using a
chosen shared mechanism.

Here's a draft of such an interface below.  Hopefully the functions are
self-explanatory, but I'm happy to clarify any if desired.

=== BEGIN DRAFT ===
/*
 * An opaque object representing the client-side of a SASL connection
 * over IMAP.  The contents of the structure will likely differ
 * depending on the SASL implementation used.
 */
typedef struct imap_sasl_client imap_sasl_client_t;

/*
 * A callback to obtain a particular SASL credential.  When called, it
 * is passed a user-specified pointer and should return the credential
 * as a string.
 */
typedef const char *(*imap_sasl_cred)( void * );

int imap_sasl_init( void );
void imap_sasl_cleanup( void );

imap_sasl_client_t *imap_sasl_new_client( void );
void imap_sasl_free_client( imap_sasl_client_t *client );

void imap_sasl_over_secure( imap_sasl_client_t *client );
void imap_sasl_using_saslir( imap_sasl_client_t *client );

void imap_sasl_username(
                imap_sasl_client_t *client,
                imap_sasl_cred callback,
                void *arg );
void imap_sasl_password(
                imap_sasl_client_t *client,
                imap_sasl_cred callback,
                void *arg );

void imap_sasl_filter_mech(
                imap_sasl_client_t *client,
                const string_list_t *mechs );

char *imap_sasl_create_cmd( imap_sasl_client_t *client );

int imap_sasl_cont(
                imap_sasl_client_t *client,
                const char *prompt,
                char **enc,
                uint *len );
void imap_sasl_done(
                imap_sasl_client_t *client,
                int resp_ok );
=== END DRAFT ===

Feel free to provide any thoughts on this proposal!

I should probably disclose that a personal motivating factor for this is
that I am one of the aforementioned users who perfers the license of GNU
SASL over Cyrus SASL, and would love to eventually be able to choose a
preferred implementation.  I'm unsure if this is meaningful, but it's
probably important to at least mention.

Take care,
        Seth McDonald.

-- 
E9D1 26A5 F0D4 9DF7 792B  C2E2 B4BF 4530 D39B 2D51


_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to