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