xref: /netbsd-src/external/ibm-public/postfix/dist/src/xsasl/xsasl_server.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: xsasl_server.c,v 1.2 2020/03/18 19:05:22 christos 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 response 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 addr_family
132 /*	The network address family: AF_INET6 or AF_INET.
133 /* .IP auth_method
134 /*	AUTH command authentication method.
135 /* .IP client_addr
136 /*	IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
137 /*	or zero-length string if unavailable.
138 /* .IP client_port
139 /*	TCP port or zero-length string if unavailable.
140 /* .IP init_resp
141 /*	AUTH command initial response or null pointer.
142 /* .IP implementation
143 /*	Implementation handle that was obtained with xsasl_server_init().
144 /* .IP path_info
145 /*	The value of the smtpd_sasl_path parameter or equivalent.
146 /*	This specifies the implementation-dependent location of a
147 /*	configuration file, rendez-vous point, etc., and is passed
148 /*	unchanged to the plug-in.
149 /* .IP security_options
150 /*	The value of the smtpd_security_options parameter or
151 /*	equivalent. This is passed unchanged to the plug-in.
152 /* .IP server
153 /*	SASL plug-in server handle.
154 /* .IP server_addr
155 /*	IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
156 /*	or zero-length string if unavailable.
157 /* .IP server_port
158 /*	TCP port or zero-length string if unavailable.
159 /* .IP server_reply
160 /*	BASE64 encoded server non-error reply (without SMTP reply
161 /*	code or enhanced status code), or ASCII error description.
162 /* .IP server_type
163 /*	The name of a Postfix SASL server plug_in implementation.
164 /* .IP server_types
165 /*	Null-terminated array of strings with SASL server plug-in
166 /*	implementation names.
167 /* .IP service
168 /*	The service that is implemented by the local server, typically
169 /*	"smtp" or "lmtp".
170 /* .IP stream
171 /*	The connection between client and server.  When SASL
172 /*	encryption is negotiated, the plug-in will transparently
173 /*	intercept the socket read/write operations.
174 /* .IP user_realm
175 /*	Authentication domain or null pointer.
176 /* SECURITY
177 /* .ad
178 /* .fi
179 /*	The caller does not sanitize client input. It is the
180 /*	responsibility of the underlying SASL server implementation
181 /*	to produce 7-bit ASCII without control characters as server
182 /*	non-error and error replies, and as the result from
183 /*	xsasl_server_method() and xsasl_server_username().
184 /* DIAGNOSTICS
185 /*	In case of failure, xsasl_server_init(), xsasl_server_create(),
186 /*	xsasl_server_get_mechanism_list() and xsasl_server_get_username()
187 /*	log a warning and return a null pointer.
188 /*
189 /*	Functions that normally return XSASL_AUTH_OK will log a warning
190 /*	and return an appropriate result value.
191 /*
192 /*	Fatal errors: out of memory.
193 /*
194 /*	Panic: interface violations.
195 /* SEE ALSO
196 /*	cyrus_security(3) Cyrus SASL security features
197 /* LICENSE
198 /* .ad
199 /* .fi
200 /*	The Secure Mailer license must be distributed with this
201 /*	software.
202 /* AUTHOR(S)
203 /*	Wietse Venema
204 /*	IBM T.J. Watson Research
205 /*	P.O. Box 704
206 /*	Yorktown Heights, NY 10598, USA
207 /*
208 /*	Wietse Venema
209 /*	Google, Inc.
210 /*	111 8th Avenue
211 /*	New York, NY 10011, USA
212 /*--*/
213 
214 /* System library. */
215 
216 #include <sys_defs.h>
217 #include <string.h>
218 
219 /* Utility library. */
220 
221 #include <msg.h>
222 #include <mymalloc.h>
223 
224 /* SASL implementations. */
225 
226 #include <xsasl.h>
227 #include <xsasl_cyrus.h>
228 #include <xsasl_dovecot.h>
229 
230  /*
231   * Lookup table for available SASL server implementations.
232   */
233 typedef struct {
234     char   *server_type;
235     struct XSASL_SERVER_IMPL *(*server_init) (const char *, const char *);
236 } XSASL_SERVER_IMPL_INFO;
237 
238 static const XSASL_SERVER_IMPL_INFO server_impl_info[] = {
239 #ifdef XSASL_TYPE_CYRUS
240     {XSASL_TYPE_CYRUS, xsasl_cyrus_server_init},
241 #endif
242 #ifdef XSASL_TYPE_DOVECOT
243     {XSASL_TYPE_DOVECOT, xsasl_dovecot_server_init},
244 #endif
245     {0, 0}
246 };
247 
248 /* xsasl_server_init - look up server implementation by name */
249 
xsasl_server_init(const char * server_type,const char * path_info)250 XSASL_SERVER_IMPL *xsasl_server_init(const char *server_type,
251 				             const char *path_info)
252 {
253     const XSASL_SERVER_IMPL_INFO *xp;
254 
255     for (xp = server_impl_info; xp->server_type; xp++)
256 	if (strcmp(server_type, xp->server_type) == 0)
257 	    return (xp->server_init(server_type, path_info));
258     msg_warn("unsupported SASL server implementation: %s", server_type);
259     return (0);
260 }
261 
262 /* xsasl_server_types - report available implementation types */
263 
xsasl_server_types(void)264 ARGV   *xsasl_server_types(void)
265 {
266     const XSASL_SERVER_IMPL_INFO *xp;
267     ARGV   *argv = argv_alloc(1);
268 
269     for (xp = server_impl_info; xp->server_type; xp++)
270 	argv_add(argv, xp->server_type, ARGV_END);
271     return (argv);
272 }
273