b1c20effbd948638fcc6121361ab36ebeda82725
[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 /*
305  * checkpw.c
306  */
307 extern struct sasl_verify_password_s _sasl_verify_password[];
308
309 /*
310  * server.c
311  */
312 /* (this is a function call to ensure this is read-only to the outside) */
313 extern int _is_sasl_server_active(void);
314
315 /*
316  * Allocation and Mutex utility macros
317  */
318 #define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
319 #define sasl_CALLOC(__nelem__, __size__) \
320         (_sasl_allocation_utils.calloc((__nelem__), (__size__)))
321 #define sasl_REALLOC(__ptr__, __size__) \
322         (_sasl_allocation_utils.realloc((__ptr__), (__size__)))
323 #define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
324
325 #define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
326 #define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
327 #define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
328 #define sasl_MUTEX_FREE(__mutex__) \
329         (_sasl_mutex_utils.free((__mutex__)))
330
331 /* function prototypes */
332 /*
333  * dlopen.c and staticopen.c
334  */
335 /*
336  * The differences here are:
337  * _sasl_load_plugins loads all plugins from all files
338  * _sasl_get_plugin loads the LIBRARY for an individual file
339  * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
340  * _sasl_locate_entry locates an entrypoint in a given library
341  */
342 extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
343                                const sasl_callback_t *getpath_callback,
344                                const sasl_callback_t *verifyfile_callback);
345 extern int _sasl_get_plugin(const char *file,
346                             const sasl_callback_t *verifyfile_cb,
347                             void **libraryptr);
348 extern int _sasl_locate_entry(void *library, const char *entryname,
349                               void **entry_point);
350 extern int _sasl_done_with_plugins();
351
352
353 /*
354  * common.c
355  */
356 extern const sasl_callback_t *
357 _sasl_find_getpath_callback(const sasl_callback_t *callbacks);
358
359 extern const sasl_callback_t *
360 _sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
361
362 extern const sasl_callback_t *
363 _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
364
365 extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks);
366
367 extern int _sasl_conn_init(sasl_conn_t *conn,
368                            const char *service,
369                            unsigned int flags,
370                            enum Sasl_conn_type type,
371                            int (*idle_hook)(sasl_conn_t *conn),
372                            const char *serverFQDN,
373                            const char *iplocalport,
374                            const char *ipremoteport,
375                            const sasl_callback_t *callbacks,
376                            const sasl_global_callbacks_t *global_callbacks);
377 extern void _sasl_conn_dispose(sasl_conn_t *conn);
378
379 extern sasl_utils_t *
380 _sasl_alloc_utils(sasl_conn_t *conn,
381                   sasl_global_callbacks_t *global_callbacks);
382 extern int _sasl_free_utils(const sasl_utils_t ** utils);
383
384 extern int
385 _sasl_getcallback(sasl_conn_t * conn,
386                   unsigned long callbackid,
387                   int (**pproc)(),
388                   void **pcontext);
389
390 extern void
391 _sasl_log(sasl_conn_t *conn,
392           int level,
393           const char *fmt,
394           ...);
395
396 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
397 int _sasl_add_string(char **out, size_t *alloclen,
398                      size_t *outlen, const char *add);
399
400 /* More Generic Utilities in common.c */
401 extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
402
403 /* Basically a conditional call to realloc(), if we need more */
404 int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
405
406 /* convert an iovec to a single buffer */
407 int _iovec_to_buf(const struct iovec *vec,
408                   unsigned numiov, buffer_info_t **output);
409
410 /* Convert between string formats and sockaddr formats */
411 int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
412                      char *out, unsigned outlen);
413 int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
414                        socklen_t outlen);
415
416 /*
417  * external plugin (external.c)
418  */
419 int external_client_plug_init(const sasl_utils_t *utils,
420                               int max_version,
421                               int *out_version,
422                               sasl_client_plug_t **pluglist,
423                               int *plugcount);
424 int external_server_plug_init(const sasl_utils_t *utils,
425                               int max_version,
426                               int *out_version,
427                               sasl_server_plug_t **pluglist,
428                               int *plugcount);
429
430 /* Mech Listing Functions */
431 int _sasl_build_mechlist(void);
432 int _sasl_server_listmech(sasl_conn_t *conn,
433                           const char *user,
434                           const char *prefix,
435                           const char *sep,
436                           const char *suffix,
437                           const char **result,
438                           unsigned *plen,
439                           int *pcount);
440 int _sasl_client_listmech(sasl_conn_t *conn,
441                           const char *prefix,
442                           const char *sep,
443                           const char *suffix,
444                           const char **result,
445                           unsigned *plen,
446                           int *pcount);
447 /* Just create a straight list of them */
448 sasl_string_list_t *_sasl_client_mechs(void);
449 sasl_string_list_t *_sasl_server_mechs(void);
450
451 /*
452  * config file declarations (config.c)
453  */
454 extern int sasl_config_init(const char *filename);
455 extern const char *sasl_config_getstring(const char *key,const char *def);
456
457 /* checkpw.c */
458 #ifdef DO_SASL_CHECKAPOP
459 extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
460                                      const char *userstr,
461                                      const char *challenge,
462                                      const char *response,
463                                      const char *user_realm);
464 #endif /* DO_SASL_CHECKAPOP */
465
466 /* Auxprop Plugin (checkpw.c) */
467 extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
468                                     int max_version,
469                                     int *out_version,
470                                     sasl_auxprop_plug_t **plug,
471                                     const char *plugname);
472
473 /*
474  * auxprop.c
475  */
476 extern int _sasl_auxprop_add_plugin(void *p, void *library);
477 extern void _sasl_auxprop_free(void);
478 extern void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
479                                  unsigned flags,
480                                  const char *user, unsigned ulen);
481
482 /*
483  * canonusr.c
484  */
485 void _sasl_canonuser_free();
486 extern int internal_canonuser_init(const sasl_utils_t *utils,
487                                    int max_version,
488                                    int *out_version,
489                                    sasl_canonuser_plug_t **plug,
490                                    const char *plugname);
491 extern int _sasl_canon_user(sasl_conn_t *conn,
492                             const char *user, unsigned ulen,
493                             unsigned flags,
494                             sasl_out_params_t *oparams);
495
496 #endif /* SASLINT_H */