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