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