move more CB selection logic to libsasl
[cyrus-sasl.git] / lib / saslint.h
1 /* saslint.h - internal SASL library definitions
2  * Rob Siemborski
3  * Tim Martin
4  * $Id: saslint.h,v 1.60 2006/04/18 20:25:45 mel Exp $
5  */
6 /* 
7  * Copyright (c) 1998-2003 Carnegie Mellon University.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer. 
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. The name "Carnegie Mellon University" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For permission or any other legal
24  *    details, please contact  
25  *      Office of Technology Transfer
26  *      Carnegie Mellon University
27  *      5000 Forbes Avenue
28  *      Pittsburgh, PA  15213-3890
29  *      (412) 268-4387, fax: (412) 268-7395
30  *      tech-transfer@andrew.cmu.edu
31  *
32  * 4. Redistributions of any form whatsoever must retain the following
33  *    acknowledgment:
34  *    "This product includes software developed by Computing Services
35  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36  *
37  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44  */
45
46 #ifndef SASLINT_H
47 #define SASLINT_H
48
49 #include <config.h>
50 #include "sasl.h"
51 #include "saslplug.h"
52 #include "saslutil.h"
53 #include "prop.h"
54
55 /* #define'd constants */
56 #define CANON_BUF_SIZE 1024
57
58 /* Error Handling Foo */
59 /* Helpful Hints:
60  *  -Error strings are set as soon as possible (first function in stack trace
61  *   with a pointer to the sasl_conn_t.
62  *  -Error codes are set as late as possible (only in the sasl api functions),
63  *   though "as often as possible" also comes to mind to ensure correctness
64  *  -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be
65  *   memory errors.
66  *  -Only errors (error codes < SASL_OK) should be remembered
67  */
68 #define RETURN(conn, val) { if(conn && (val) < SASL_OK) \
69                                (conn)->error_code = (val); \
70                             return (val); }
71 #define MEMERROR(conn) {\
72     if(conn) sasl_seterror( (conn), 0, \
73                    "Out of Memory in " __FILE__ " near line %d", __LINE__ ); \
74     RETURN(conn, SASL_NOMEM) }
75 #define PARAMERROR(conn) {\
76     if(conn) sasl_seterror( (conn), SASL_NOLOG, \
77                   "Parameter error in " __FILE__ " near line %d", __LINE__ ); \
78     RETURN(conn, SASL_BADPARAM) }
79 #define INTERROR(conn, val) {\
80     if(conn) sasl_seterror( (conn), 0, \
81                    "Internal Error %d in " __FILE__ " near line %d", (val),\
82                    __LINE__ ); \
83     RETURN(conn, (val)) }
84
85 #ifndef PATH_MAX
86 # ifdef WIN32
87 #  define PATH_MAX MAX_PATH
88 # else
89 #  ifdef _POSIX_PATH_MAX
90 #   define PATH_MAX _POSIX_PATH_MAX
91 #  else
92 #   define PATH_MAX 1024         /* arbitrary; probably big enough.
93                                   * will probably only be 256+64 on
94                                   * pre-posix machines */
95 #  endif /* _POSIX_PATH_MAX */
96 # endif /* WIN32 */
97 #endif
98
99 /* : Define directory delimiter in SASL_PATH/SASL_CONF_PATH variables */
100 #ifdef WIN32
101 #define PATHS_DELIMITER ';'
102 #else
103 #define PATHS_DELIMITER ':'
104 #endif
105
106 /* Datatype Definitions */
107 typedef struct {
108   const sasl_callback_t *callbacks;
109   const char *appname;
110 } sasl_global_callbacks_t;
111
112 extern sasl_global_callbacks_t global_callbacks;
113
114 typedef struct _sasl_external_properties 
115 {
116     sasl_ssf_t ssf;
117     char *auth_id;
118 } _sasl_external_properties_t;
119
120 typedef struct sasl_string_list
121 {
122     const char *d;
123     struct sasl_string_list *next;
124 } sasl_string_list_t;
125
126 typedef struct buffer_info
127
128     char *data;
129     size_t curlen;
130     size_t reallen;
131 } buffer_info_t;
132
133 typedef int add_plugin_t(const char *, void *);
134
135 typedef struct add_plugin_list 
136 {
137     const char *entryname;
138     add_plugin_t *add_plugin;
139 } add_plugin_list_t;
140
141 enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0,
142                       SASL_CONN_SERVER = 1,
143                       SASL_CONN_CLIENT = 2 };
144
145 struct sasl_conn {
146   enum Sasl_conn_type type;
147
148   void (*destroy_conn)(sasl_conn_t *); /* destroy function */
149
150   char *service;
151
152   unsigned int flags;  /* flags passed to sasl_*_new */
153
154   /* IP information.  A buffer of size 52 is adequate for this in its
155      longest format (see sasl.h) */
156   int got_ip_local, got_ip_remote;
157   char iplocalport[NI_MAXHOST + NI_MAXSERV];
158   char ipremoteport[NI_MAXHOST + NI_MAXSERV];
159
160   void *context;
161   sasl_out_params_t oparams;
162
163   sasl_security_properties_t props;
164   _sasl_external_properties_t external;
165
166   sasl_secret_t *secret;
167
168   int (*idle_hook)(sasl_conn_t *conn);
169   const sasl_callback_t *callbacks;
170   const sasl_global_callbacks_t *global_callbacks; /* global callbacks
171                                                     * connection */
172   char *serverFQDN;
173
174   /* Pointers to memory that we are responsible for */
175   buffer_info_t *encode_buf;
176
177   int error_code;
178   char *error_buf, *errdetail_buf;
179   size_t error_buf_len, errdetail_buf_len;
180   char *mechlist_buf;
181   size_t mechlist_buf_len;
182
183   char *decode_buf;
184
185   char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1];
186
187   /* Allocated by sasl_encodev if the output contains multiple SASL packet. */
188   buffer_info_t multipacket_encoded_data;
189 };
190
191 /* Server Conn Type Information */
192
193 typedef struct mechanism
194 {
195     server_sasl_mechanism_t m;
196     struct mechanism *next;
197 } mechanism_t;
198
199 typedef struct mech_list {
200   const sasl_utils_t *utils;  /* gotten from plug_init */
201
202   void *mutex;            /* mutex for this data */ 
203   mechanism_t *mech_list; /* list of mechanisms */
204   int mech_length;       /* number of mechanisms */
205 } mech_list_t;
206
207 typedef struct context_list 
208 {
209     mechanism_t *mech;
210     void *context;     /* if NULL, this mech is disabled for this connection
211                         * otherwise, use this context instead of a call
212                         * to mech_new */
213     struct context_list *next;
214 } context_list_t;
215
216 typedef struct sasl_server_conn {
217     sasl_conn_t base; /* parts common to server + client */
218
219     char *appname; /* application name buffer (for sparams) */
220     char *user_realm; /* domain the user authenticating is in */
221     int sent_last; /* Have we already done the last send? */
222     int authenticated;
223     mechanism_t *mech; /* mechanism trying to use */
224     sasl_server_params_t *sparams;
225     context_list_t *mech_contexts;
226 } sasl_server_conn_t;
227
228 /* Client Conn Type Information */
229
230 typedef struct cmechanism
231 {
232     client_sasl_mechanism_t m;
233     struct cmechanism *next;  
234 } cmechanism_t;
235
236 typedef struct cmech_list {
237   const sasl_utils_t *utils; 
238
239   void *mutex;            /* mutex for this data */ 
240   cmechanism_t *mech_list; /* list of mechanisms */
241   int mech_length;       /* number of mechanisms */
242
243 } cmech_list_t;
244
245 typedef struct sasl_client_conn {
246   sasl_conn_t base; /* parts common to server + client */
247
248   cmechanism_t *mech;
249   sasl_client_params_t *cparams;
250
251   char *clientFQDN;
252
253 } sasl_client_conn_t;
254
255 typedef struct sasl_allocation_utils {
256   sasl_malloc_t *malloc;
257   sasl_calloc_t *calloc;
258   sasl_realloc_t *realloc;
259   sasl_free_t *free;
260 } sasl_allocation_utils_t;
261
262 typedef struct sasl_mutex_utils {
263   sasl_mutex_alloc_t *alloc;
264   sasl_mutex_lock_t *lock;
265   sasl_mutex_unlock_t *unlock;
266   sasl_mutex_free_t *free;
267 } sasl_mutex_utils_t;
268
269 typedef struct sasl_log_utils_s {
270   sasl_log_t *log;
271 } sasl_log_utils_t;
272
273 typedef int sasl_plaintext_verifier(sasl_conn_t *conn,
274                                     const char *userid,
275                                     const char *passwd,
276                                     const char *service,
277                                     const char *user_realm);
278
279 struct sasl_verify_password_s {
280     char *name;
281     sasl_plaintext_verifier *verify;
282 };
283
284 /*
285  * globals & constants
286  */
287 /*
288  * common.c
289  */
290 LIBSASL_API const sasl_utils_t *sasl_global_utils;
291
292 extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn);
293 extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn);
294
295 /* These return SASL_OK if we've actually finished cleanup, 
296  * SASL_NOTINIT if that part of the library isn't initialized, and
297  * SASL_CONTINUE if we need to call them again */
298 extern int (*_sasl_client_cleanup_hook)(void);
299 extern int (*_sasl_server_cleanup_hook)(void);
300
301 extern sasl_allocation_utils_t _sasl_allocation_utils;
302 extern sasl_mutex_utils_t _sasl_mutex_utils;
303
304 extern int _sasl_is_equal_mech(const char *req_mech,
305                                const char *plug_mech,
306                                int *plus);
307
308 /*
309  * checkpw.c
310  */
311 extern struct sasl_verify_password_s _sasl_verify_password[];
312
313 /*
314  * server.c
315  */
316 /* (this is a function call to ensure this is read-only to the outside) */
317 extern int _is_sasl_server_active(void);
318
319 /*
320  * Allocation and Mutex utility macros
321  */
322 #define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
323 #define sasl_CALLOC(__nelem__, __size__) \
324         (_sasl_allocation_utils.calloc((__nelem__), (__size__)))
325 #define sasl_REALLOC(__ptr__, __size__) \
326         (_sasl_allocation_utils.realloc((__ptr__), (__size__)))
327 #define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
328
329 #define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
330 #define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
331 #define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
332 #define sasl_MUTEX_FREE(__mutex__) \
333         (_sasl_mutex_utils.free((__mutex__)))
334
335 /* function prototypes */
336 /*
337  * dlopen.c and staticopen.c
338  */
339 /*
340  * The differences here are:
341  * _sasl_load_plugins loads all plugins from all files
342  * _sasl_get_plugin loads the LIBRARY for an individual file
343  * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
344  * _sasl_locate_entry locates an entrypoint in a given library
345  */
346 extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
347                                const sasl_callback_t *getpath_callback,
348                                const sasl_callback_t *verifyfile_callback);
349 extern int _sasl_get_plugin(const char *file,
350                             const sasl_callback_t *verifyfile_cb,
351                             void **libraryptr);
352 extern int _sasl_locate_entry(void *library, const char *entryname,
353                               void **entry_point);
354 extern int _sasl_done_with_plugins();
355
356
357 /*
358  * common.c
359  */
360 extern const sasl_callback_t *
361 _sasl_find_getpath_callback(const sasl_callback_t *callbacks);
362
363 extern const sasl_callback_t *
364 _sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
365
366 extern const sasl_callback_t *
367 _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
368
369 extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks);
370
371 extern int _sasl_conn_init(sasl_conn_t *conn,
372                            const char *service,
373                            unsigned int flags,
374                            enum Sasl_conn_type type,
375                            int (*idle_hook)(sasl_conn_t *conn),
376                            const char *serverFQDN,
377                            const char *iplocalport,
378                            const char *ipremoteport,
379                            const sasl_callback_t *callbacks,
380                            const sasl_global_callbacks_t *global_callbacks);
381 extern void _sasl_conn_dispose(sasl_conn_t *conn);
382
383 extern sasl_utils_t *
384 _sasl_alloc_utils(sasl_conn_t *conn,
385                   sasl_global_callbacks_t *global_callbacks);
386 extern int _sasl_free_utils(const sasl_utils_t ** utils);
387
388 extern int
389 _sasl_getcallback(sasl_conn_t * conn,
390                   unsigned long callbackid,
391                   int (**pproc)(),
392                   void **pcontext);
393
394 extern void
395 _sasl_log(sasl_conn_t *conn,
396           int level,
397           const char *fmt,
398           ...);
399
400 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
401 int _sasl_add_string(char **out, size_t *alloclen,
402                      size_t *outlen, const char *add);
403
404 /* More Generic Utilities in common.c */
405 extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
406
407 /* Basically a conditional call to realloc(), if we need more */
408 int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
409
410 /* convert an iovec to a single buffer */
411 int _iovec_to_buf(const struct iovec *vec,
412                   unsigned numiov, buffer_info_t **output);
413
414 /* Convert between string formats and sockaddr formats */
415 int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
416                      char *out, unsigned outlen);
417 int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
418                        socklen_t outlen);
419
420 /*
421  * external plugin (external.c)
422  */
423 int external_client_plug_init(const sasl_utils_t *utils,
424                               int max_version,
425                               int *out_version,
426                               sasl_client_plug_t **pluglist,
427                               int *plugcount);
428 int external_server_plug_init(const sasl_utils_t *utils,
429                               int max_version,
430                               int *out_version,
431                               sasl_server_plug_t **pluglist,
432                               int *plugcount);
433
434 /* Mech Listing Functions */
435 int _sasl_build_mechlist(void);
436 int _sasl_server_listmech(sasl_conn_t *conn,
437                           const char *user,
438                           const char *prefix,
439                           const char *sep,
440                           const char *suffix,
441                           const char **result,
442                           unsigned *plen,
443                           int *pcount);
444 int _sasl_client_listmech(sasl_conn_t *conn,
445                           const char *prefix,
446                           const char *sep,
447                           const char *suffix,
448                           const char **result,
449                           unsigned *plen,
450                           int *pcount);
451 /* Just create a straight list of them */
452 sasl_string_list_t *_sasl_client_mechs(void);
453 sasl_string_list_t *_sasl_server_mechs(void);
454
455 /*
456  * config file declarations (config.c)
457  */
458 extern int sasl_config_init(const char *filename);
459 extern const char *sasl_config_getstring(const char *key,const char *def);
460
461 /* checkpw.c */
462 #ifdef DO_SASL_CHECKAPOP
463 extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
464                                      const char *userstr,
465                                      const char *challenge,
466                                      const char *response,
467                                      const char *user_realm);
468 #endif /* DO_SASL_CHECKAPOP */
469
470 /* Auxprop Plugin (checkpw.c) */
471 extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
472                                     int max_version,
473                                     int *out_version,
474                                     sasl_auxprop_plug_t **plug,
475                                     const char *plugname);
476
477 /*
478  * auxprop.c
479  */
480 extern int _sasl_auxprop_add_plugin(void *p, void *library);
481 extern void _sasl_auxprop_free(void);
482 extern void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
483                                  unsigned flags,
484                                  const char *user, unsigned ulen);
485
486 /*
487  * canonusr.c
488  */
489 void _sasl_canonuser_free();
490 extern int internal_canonuser_init(const sasl_utils_t *utils,
491                                    int max_version,
492                                    int *out_version,
493                                    sasl_canonuser_plug_t **plug,
494                                    const char *plugname);
495 extern int _sasl_canon_user(sasl_conn_t *conn,
496                             const char *user, unsigned ulen,
497                             unsigned flags,
498                             sasl_out_params_t *oparams);
499
500 #endif /* SASLINT_H */