1/* $NetBSD: xsasl_client.c,v 1.1.1.1 2009/06/23 10:09:02 tron Exp $ */ 2 3/*++ 4/* NAME 5/* xsasl_client 3 6/* SUMMARY 7/* Postfix SASL client plug-in interface 8/* SYNOPSIS 9/* #include <xsasl.h> 10/* 11/* XSASL_CLIENT_IMPL *xsasl_client_init(client_type, path_info) 12/* const char *client_type; 13/* const char *path_info; 14/* 15/* void xsasl_client_done(implementation) 16/* XSASL_CLIENT_IMPL *implementation; 17/* 18/* ARGV *xsasl_client_types() 19/* 20/* .in +4 21/* typedef struct XSASL_CLIENT_CREATE_ARGS { 22/* VSTREAM *stream; 23/* const char *service; 24/* const char *server_name; 25/* const char *security_options; 26/* } XSASL_CLIENT_CREATE_ARGS; 27/* .in -4 28/* 29/* XSASL_CLIENT *xsasl_client_create(implementation, create_args) 30/* XSASL_CLIENT_IMPL *implementation; 31/* XSASL_CLIENT_CREATE_ARGS *create_args; 32/* 33/* XSASL_CLIENT *XSASL_CLIENT_CREATE(implementation, create_args, 34/* stream = stream_val, 35/* ..., 36/* security_options = prop_val) 37/* XSASL_CLIENT_IMPL *implementation; 38/* XSASL_CLIENT_CREATE_ARGS *create_args; 39/* 40/* void xsasl_client_free(client) 41/* XSASL_CLIENT *client; 42/* 43/* int xsasl_client_first(client, stream, mech_list, username, 44/* password, auth_method, init_resp) 45/* XSASL_CLIENT *client; 46/* const char *mech_list; 47/* const char *username; 48/* const char *password; 49/* const char **auth_method; 50/* VSTRING *init_resp; 51/* 52/* int xsasl_client_next(client, server_reply, client_reply) 53/* XSASL_CLIENT *client; 54/* const char *server_reply; 55/* VSTRING *client_reply; 56/* DESCRIPTION 57/* The XSASL_CLIENT abstraction implements a generic interface 58/* to one or more SASL authentication implementations. 59/* 60/* xsasl_client_init() is called once during process initialization. 61/* It selects a SASL implementation by name, specifies the 62/* location of a configuration file or rendez-vous point, and 63/* returns an implementation handle that can be used to generate 64/* SASL client instances. This function is typically used to 65/* initialize the underlying implementation. 66/* 67/* xsasl_client_done() disposes of an implementation handle, 68/* and allows the underlying implementation to release resources. 69/* 70/* xsasl_client_types() lists the available implementation types. 71/* The result should be destroyed by the caller. 72/* 73/* xsasl_client_create() is called at the start of an SMTP 74/* session. It generates a Postfix SASL plug-in client instance 75/* for the specified service and server name, with the specified 76/* security properties. The stream handle is stored so that 77/* encryption can be turned on after successful negotiations. 78/* 79/* XSASL_CLIENT_CREATE() is a macro that provides an interface 80/* with named parameters. Named parameters do not have to 81/* appear in a fixed order. The parameter names correspond to 82/* the member names of the XSASL_CLIENT_CREATE_ARGS structure. 83/* 84/* xsasl_client_free() is called at the end of an SMTP session. 85/* It destroys a SASL client instance, and disables further 86/* read/write operations if encryption was turned on. 87/* 88/* xsasl_client_first() produces the client input for the AUTH 89/* command. The input is an authentication method list from 90/* an EHLO response, a username and a password. On return, the 91/* method argument specifies the authentication method; storage 92/* space is owned by the underlying implementation. The initial 93/* response and client non-error replies are BASE64 encoded. 94/* Client error replies are 7-bit ASCII text without control 95/* characters, and without BASE64 encoding. They are meant for 96/* the local application, not for transmission to the server. 97/* The client may negotiate encryption of the client-server 98/* connection. 99/* 100/* The result is one of the following: 101/* .IP XSASL_AUTH_OK 102/* Success. 103/* .IP XSASL_AUTH_FORM 104/* The server reply is incorrectly formatted. The client error 105/* reply explains why. 106/* .IP XSASL_AUTH_FAIL 107/* Other error. The client error reply explains why. 108/* .PP 109/* xsasl_client_next() supports the subsequent stages of the 110/* AUTH protocol. Both the client reply and client non-error 111/* responses are BASE64 encoded. See xsasl_client_first() for 112/* other details. 113/* 114/* Arguments: 115/* .IP client 116/* SASL plug-in client handle. 117/* .IP client_reply 118/* BASE64 encoded non-error client reply, or ASCII error 119/* description for the user. 120/* .IP client_type 121/* The name of a Postfix SASL client plug_in implementation. 122/* .IP client_types 123/* Null-terminated array of strings with SASL client plug-in 124/* implementation names. 125/* .IP init_resp 126/* The AUTH command initial response. 127/* .IP implementation 128/* Implementation handle that was obtained with xsasl_client_init(). 129/* .IP mech_list 130/* List of SASL mechanisms as announced by the server. 131/* .IP auth_method 132/* The AUTH command authentication method. 133/* .IP password 134/* Information from the Postfix SASL password file or equivalent. 135/* .IP path_info 136/* The value of the smtp_sasl_path parameter or equivalent. 137/* This specifies the implementation-dependent location of a 138/* configuration file, rendez-vous point, etc., and is passed 139/* unchanged to the plug-in. 140/* .IP security_options 141/* The value of the smtp_sasl_security_options parameter or 142/* equivalent. This is passed unchanged to the plug-in. 143/* .IP server_name 144/* The remote server fully qualified hostname. 145/* .IP server_reply 146/* BASE64 encoded server reply without SMTP reply code or 147/* enhanced status code. 148/* .IP service 149/* The service that is implemented by the local client (typically, 150/* "lmtp" or "smtp"). 151/* .IP stream 152/* The connection between client and server. 153/* When SASL encryption is negotiated, the plug-in will 154/* transparently intercept the socket read/write operations. 155/* .IP username 156/* Information from the Postfix SASL password file. 157/* SECURITY 158/* .ad 159/* .fi 160/* The caller does not sanitize the server reply. It is the 161/* responsibility of the underlying SASL client implementation 162/* to produce 7-bit ASCII without control characters as client 163/* non-error and error replies. 164/* DIAGNOSTICS 165/* In case of error, xsasl_client_init() and xsasl_client_create() 166/* log a warning and return a null pointer. 167/* 168/* Functions that normally return XSASL_AUTH_OK will log a warning 169/* and return an appropriate result value. 170/* 171/* Panic: interface violation. 172/* 173/* Fatal errors: out of memory. 174/* SEE ALSO 175/* cyrus_security(3) Cyrus SASL security features 176/* LICENSE 177/* .ad 178/* .fi 179/* The Secure Mailer license must be distributed with this 180/* software. 181/* AUTHOR(S) 182/* Wietse Venema 183/* IBM T.J. Watson Research 184/* P.O. Box 704 185/* Yorktown Heights, NY 10598, USA 186/*--*/ 187 188/* System library. */ 189 190#include <sys_defs.h> 191#include <string.h> 192 193/* Utility library. */ 194 195#include <msg.h> 196#include <mymalloc.h> 197 198/* SASL implementations. */ 199 200#include <xsasl.h> 201#include <xsasl_cyrus.h> 202#include <xsasl_saslc.h> 203 204 /* 205 * Lookup table for available SASL client implementations. 206 */ 207typedef struct { 208 char *client_type; 209 struct XSASL_CLIENT_IMPL *(*client_init) (const char *, const char *); 210} XSASL_CLIENT_IMPL_INFO; 211 212static const XSASL_CLIENT_IMPL_INFO client_impl_info[] = { 213#ifdef XSASL_TYPE_CYRUS 214 { XSASL_TYPE_CYRUS, xsasl_cyrus_client_init }, 215#endif 216#ifdef XSASL_TYPE_SASLC 217 { XSASL_TYPE_SASLC, xsasl_saslc_client_init }, 218#endif 219 { NULL, NULL } 220}; 221 222/* xsasl_client_init - look up client implementation by name */ 223 224XSASL_CLIENT_IMPL *xsasl_client_init(const char *client_type, 225 const char *path_info) 226{ 227 const XSASL_CLIENT_IMPL_INFO *xp; 228 229 for (xp = client_impl_info; xp->client_type; xp++) 230 if (strcmp(client_type, xp->client_type) == 0) 231 return (xp->client_init(client_type, path_info)); 232 msg_warn("unsupported SASL client implementation: %s", client_type); 233 return (0); 234} 235 236/* xsasl_client_types - report available implementation types */ 237 238ARGV *xsasl_client_types(void) 239{ 240 const XSASL_CLIENT_IMPL_INFO *xp; 241 ARGV *argv = argv_alloc(1); 242 243 for (xp = client_impl_info; xp->client_type; xp++) 244 argv_add(argv, xp->client_type, ARGV_END); 245 return (argv); 246} 247