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