/*++ /* NAME /* xsasl_client 3 /* SUMMARY /* Postfix SASL client plug-in interface /* SYNOPSIS /* #include /* /* XSASL_CLIENT_IMPL *xsasl_client_init(client_type, path_info) /* const char *client_type; /* const char *path_info; /* /* void xsasl_client_done(implementation) /* XSASL_CLIENT_IMPL *implementation; /* /* ARGV *xsasl_client_types() /* /* .in +4 /* typedef struct XSASL_CLIENT_CREATE_ARGS { /* VSTREAM *stream; /* const char *service; /* const char *server_name; /* const char *security_options; /* } XSASL_CLIENT_CREATE_ARGS; /* .in -4 /* /* XSASL_CLIENT *xsasl_client_create(implementation, create_args) /* XSASL_CLIENT_IMPL *implementation; /* XSASL_CLIENT_CREATE_ARGS *create_args; /* /* XSASL_CLIENT *XSASL_CLIENT_CREATE(implementation, create_args, /* stream = stream_val, /* ..., /* security_options = prop_val) /* XSASL_CLIENT_IMPL *implementation; /* XSASL_CLIENT_CREATE_ARGS *create_args; /* /* void xsasl_client_free(client) /* XSASL_CLIENT *client; /* /* int xsasl_client_first(client, stream, mech_list, username, /* password, auth_method, init_resp) /* XSASL_CLIENT *client; /* const char *mech_list; /* const char *username; /* const char *password; /* const char **auth_method; /* VSTRING *init_resp; /* /* int xsasl_client_next(client, server_reply, client_reply) /* XSASL_CLIENT *client; /* const char *server_reply; /* VSTRING *client_reply; /* DESCRIPTION /* The XSASL_CLIENT abstraction implements a generic interface /* to one or more SASL authentication implementations. /* /* xsasl_client_init() is called once during process initialization. /* It selects a SASL implementation by name, specifies the /* location of a configuration file or rendez-vous point, and /* returns an implementation handle that can be used to generate /* SASL client instances. This function is typically used to /* initialize the underlying implementation. /* /* xsasl_client_done() disposes of an implementation handle, /* and allows the underlying implementation to release resources. /* /* xsasl_client_types() lists the available implementation types. /* The result should be destroyed by the caller. /* /* xsasl_client_create() is called at the start of an SMTP /* session. It generates a Postfix SASL plug-in client instance /* for the specified service and server name, with the specified /* security properties. The stream handle is stored so that /* encryption can be turned on after successful negotiations. /* /* XSASL_CLIENT_CREATE() is a macro that provides an interface /* with named parameters. Named parameters do not have to /* appear in a fixed order. The parameter names correspond to /* the member names of the XSASL_CLIENT_CREATE_ARGS structure. /* /* xsasl_client_free() is called at the end of an SMTP session. /* It destroys a SASL client instance, and disables further /* read/write operations if encryption was turned on. /* /* xsasl_client_first() produces the client input for the AUTH /* command. The input is an authentication method list from /* an EHLO response, a username and a password. On return, the /* method argument specifies the authentication method; storage /* space is owned by the underlying implementation. The initial /* response and client non-error replies are BASE64 encoded. /* Client error replies are 7-bit ASCII text without control /* characters, and without BASE64 encoding. They are meant for /* the local application, not for transmission to the server. /* The client may negotiate encryption of the client-server /* connection. /* /* The result is one of the following: /* .IP XSASL_AUTH_OK /* Success. /* .IP XSASL_AUTH_FORM /* The server reply is incorrectly formatted. The client error /* reply explains why. /* .IP XSASL_AUTH_FAIL /* Other error. The client error reply explains why. /* .PP /* xsasl_client_next() supports the subsequent stages of the /* AUTH protocol. Both the client reply and client non-error /* responses are BASE64 encoded. See xsasl_client_first() for /* other details. /* /* Arguments: /* .IP client /* SASL plug-in client handle. /* .IP client_reply /* BASE64 encoded non-error client reply, or ASCII error /* description for the user. /* .IP client_type /* The name of a Postfix SASL client plug_in implementation. /* .IP client_types /* Null-terminated array of strings with SASL client plug-in /* implementation names. /* .IP init_resp /* The AUTH command initial response. /* .IP implementation /* Implementation handle that was obtained with xsasl_client_init(). /* .IP mech_list /* List of SASL mechanisms as announced by the server. /* .IP auth_method /* The AUTH command authentication method. /* .IP password /* Information from the Postfix SASL password file or equivalent. /* .IP path_info /* The value of the smtp_sasl_path parameter or equivalent. /* This specifies the implementation-dependent location of a /* configuration file, rendez-vous point, etc., and is passed /* unchanged to the plug-in. /* .IP security_options /* The value of the smtp_sasl_security_options parameter or /* equivalent. This is passed unchanged to the plug-in. /* .IP server_name /* The remote server fully qualified hostname. /* .IP server_reply /* BASE64 encoded server reply without SMTP reply code or /* enhanced status code. /* .IP service /* The service that is implemented by the local client (typically, /* "lmtp" or "smtp"). /* .IP stream /* The connection between client and server. /* When SASL encryption is negotiated, the plug-in will /* transparently intercept the socket read/write operations. /* .IP username /* Information from the Postfix SASL password file. /* SECURITY /* .ad /* .fi /* The caller does not sanitize the server reply. It is the /* responsibility of the underlying SASL client implementation /* to produce 7-bit ASCII without control characters as client /* non-error and error replies. /* DIAGNOSTICS /* In case of error, xsasl_client_init() and xsasl_client_create() /* log a warning and return a null pointer. /* /* Functions that normally return XSASL_AUTH_OK will log a warning /* and return an appropriate result value. /* /* Panic: interface violation. /* /* Fatal errors: out of memory. /* SEE ALSO /* cyrus_security(3) Cyrus SASL security features /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this /* software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /*--*/ /* System library. */ #include #include /* Utility library. */ #include #include /* SASL implementations. */ #include #include /* * Lookup table for available SASL client implementations. */ typedef struct { char *client_type; struct XSASL_CLIENT_IMPL *(*client_init) (const char *, const char *); } XSASL_CLIENT_IMPL_INFO; static const XSASL_CLIENT_IMPL_INFO client_impl_info[] = { #ifdef XSASL_TYPE_CYRUS XSASL_TYPE_CYRUS, xsasl_cyrus_client_init, #endif 0, }; /* xsasl_client_init - look up client implementation by name */ XSASL_CLIENT_IMPL *xsasl_client_init(const char *client_type, const char *path_info) { const XSASL_CLIENT_IMPL_INFO *xp; for (xp = client_impl_info; xp->client_type; xp++) if (strcmp(client_type, xp->client_type) == 0) return (xp->client_init(client_type, path_info)); msg_warn("unsupported SASL client implementation: %s", client_type); return (0); } /* xsasl_client_types - report available implementation types */ ARGV *xsasl_client_types(void) { const XSASL_CLIENT_IMPL_INFO *xp; ARGV *argv = argv_alloc(1); for (xp = client_impl_info; xp->client_type; xp++) argv_add(argv, xp->client_type, ARGV_END); return (argv); }