1/* saslint.h - internal SASL library definitions
2 * Rob Siemborski
3 * Tim Martin
4 * $Id: saslint.h,v 1.8 2006/02/03 22:33:14 snsimon 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#ifndef INLINE
56#if defined (WIN32)
57/* Visual Studio: "inline" keyword is not available in C, only in C++ */
58#define INLINE __inline
59#else
60#define INLINE  inline
61#endif
62#endif
63
64/* #define'd constants */
65#define CANON_BUF_SIZE 1024
66
67/* Error Handling Foo */
68/* Helpful Hints:
69 *  -Error strings are set as soon as possible (first function in stack trace
70 *   with a pointer to the sasl_conn_t.
71 *  -Error codes are set as late as possible (only in the sasl api functions),
72 *   though "as often as possible" also comes to mind to ensure correctness
73 *  -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be
74 *   memory errors.
75 *  -Only errors (error codes < SASL_OK) should be remembered
76 */
77#define RETURN(conn, val) { if(conn && (val) < SASL_OK) \
78                               (conn)->error_code = (val); \
79                            return (val); }
80#define MEMERROR(conn) {\
81    if(conn) sasl_seterror( (conn), 0, \
82                   "Out of Memory in " __FILE__ " near line %d", __LINE__ ); \
83    RETURN(conn, SASL_NOMEM) }
84#define PARAMERROR(conn) {\
85    if(conn) sasl_seterror( (conn), SASL_NOLOG, \
86                  "Parameter error in " __FILE__ " near line %d", __LINE__ ); \
87    RETURN(conn, SASL_BADPARAM) }
88#define INTERROR(conn, val) {\
89    if(conn) sasl_seterror( (conn), 0, \
90                   "Internal Error %d in " __FILE__ " near line %d", (val),\
91		   __LINE__ ); \
92    RETURN(conn, (val)) }
93
94#ifndef PATH_MAX
95# ifdef WIN32
96#  define PATH_MAX MAX_PATH
97# else
98#  ifdef _POSIX_PATH_MAX
99#   define PATH_MAX _POSIX_PATH_MAX
100#  else
101#   define PATH_MAX 1024         /* arbitrary; probably big enough.
102                                  * will probably only be 256+64 on
103                                  * pre-posix machines */
104#  endif /* _POSIX_PATH_MAX */
105# endif /* WIN32 */
106#endif
107
108/* : Define directory delimiter in SASL_PATH/SASL_CONF_PATH variables */
109#ifdef WIN32
110#define PATHS_DELIMITER	';'
111#else
112#define PATHS_DELIMITER	':'
113#endif
114
115/* Datatype Definitions */
116typedef struct {
117  const sasl_callback_t *callbacks;
118  const char *appname;
119} sasl_global_callbacks_t;
120
121typedef struct _sasl_external_properties
122{
123    sasl_ssf_t ssf;
124    char *auth_id;
125} _sasl_external_properties_t;
126
127typedef struct sasl_string_list
128{
129    const char *d;
130    struct sasl_string_list *next;
131} sasl_string_list_t;
132
133typedef struct buffer_info
134{
135    char *data;
136    size_t curlen;
137    size_t reallen;
138} buffer_info_t;
139
140typedef int add_plugin_t(const char *, void *);
141
142typedef struct add_plugin_list
143{
144    const char *entryname;
145    add_plugin_t *add_plugin;
146} add_plugin_list_t;
147
148enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0,
149		      SASL_CONN_SERVER = 1,
150                      SASL_CONN_CLIENT = 2 };
151
152struct sasl_conn {
153  enum Sasl_conn_type type;
154
155  void (*destroy_conn)(sasl_conn_t *); /* destroy function */
156
157  char *service;
158
159  unsigned int flags;  /* flags passed to sasl_*_new */
160
161  /* IP information.  A buffer of size 52 is adequate for this in its
162     longest format (see sasl.h) */
163  int got_ip_local, got_ip_remote;
164  char iplocalport[NI_MAXHOST + NI_MAXSERV];
165  char ipremoteport[NI_MAXHOST + NI_MAXSERV];
166
167  void *context;
168  sasl_out_params_t oparams;
169
170  sasl_security_properties_t props;
171  _sasl_external_properties_t external;
172
173  sasl_secret_t *secret;
174
175  int (*idle_hook)(sasl_conn_t *conn);
176  const sasl_callback_t *callbacks;
177  const sasl_global_callbacks_t *global_callbacks; /* global callbacks
178						    * connection */
179  char *serverFQDN;
180
181  /* Pointers to memory that we are responsible for */
182  buffer_info_t *encode_buf;
183
184  int error_code;
185  char *error_buf, *errdetail_buf;
186  size_t error_buf_len, errdetail_buf_len;
187  char *mechlist_buf;
188  size_t mechlist_buf_len;
189
190  char *decode_buf;
191
192  char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1];
193
194  /* Allocated by sasl_encodev if the output contains multiple SASL packet. */
195  buffer_info_t multipacket_encoded_data;
196};
197
198/* Server Conn Type Information */
199
200typedef struct mechanism
201{
202    server_sasl_mechanism_t m;
203    struct mechanism *next;
204} mechanism_t;
205
206typedef struct mech_list {
207  const sasl_utils_t *utils;  /* gotten from plug_init */
208
209  void *mutex;            /* mutex for this data */
210  mechanism_t *mech_list; /* list of loaded mechanisms */
211  int mech_length;        /* number of loaded mechanisms */
212} mech_list_t;
213
214typedef struct context_list
215{
216    mechanism_t *mech;
217    void *context;     /* if NULL, this mech is disabled for this connection
218			* otherwise, use this context instead of a call
219			* to mech_new */
220    struct context_list *next;
221} context_list_t;
222
223typedef struct sasl_server_conn {
224    sasl_conn_t base; /* parts common to server + client */
225
226    char *appname; /* application name buffer (for sparams) */
227    char *user_realm; /* domain the user authenticating is in */
228    int sent_last; /* Have we already done the last send? */
229    int authenticated;
230    mechanism_t *mech; /* mechanism trying to use */
231    sasl_server_params_t *sparams;
232    context_list_t *mech_contexts;
233    mechanism_t *mech_list; /* list of available mechanisms */
234    int mech_length;        /* number of available mechanisms */
235} sasl_server_conn_t;
236
237/* Client Conn Type Information */
238
239typedef struct cmechanism
240{
241    client_sasl_mechanism_t m;
242    struct cmechanism *next;
243} cmechanism_t;
244
245typedef struct cmech_list {
246  const sasl_utils_t *utils;
247
248  void *mutex;            /* mutex for this data */
249  cmechanism_t *mech_list; /* list of mechanisms */
250  int mech_length;       /* number of mechanisms */
251
252} cmech_list_t;
253
254typedef struct sasl_client_conn {
255  sasl_conn_t base; /* parts common to server + client */
256
257  cmechanism_t *mech;
258  sasl_client_params_t *cparams;
259
260  char *clientFQDN;
261
262  cmechanism_t *mech_list; /* list of available mechanisms */
263  int mech_length;	   /* number of available mechanisms */
264} sasl_client_conn_t;
265
266typedef struct sasl_allocation_utils {
267  sasl_malloc_t *malloc;
268  sasl_calloc_t *calloc;
269  sasl_realloc_t *realloc;
270  sasl_free_t *free;
271} sasl_allocation_utils_t;
272
273typedef struct sasl_mutex_utils {
274  sasl_mutex_alloc_t *alloc;
275  sasl_mutex_lock_t *lock;
276  sasl_mutex_unlock_t *unlock;
277  sasl_mutex_free_t *free;
278} sasl_mutex_utils_t;
279
280typedef struct sasl_log_utils_s {
281  sasl_log_t *log;
282} sasl_log_utils_t;
283
284typedef int sasl_plaintext_verifier(sasl_conn_t *conn,
285				    const char *userid,
286				    const char *passwd,
287				    const char *service,
288				    const char *user_realm);
289
290struct sasl_verify_password_s {
291    char *name;
292    sasl_plaintext_verifier *verify;
293};
294
295/*
296 * globals & constants
297 */
298/*
299 * common.c
300 */
301LIBSASL_API const sasl_utils_t *sasl_global_utils;
302
303extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn);
304extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn);
305
306/* These return SASL_OK if we've actually finished cleanup,
307 * SASL_NOTINIT if that part of the library isn't initialized, and
308 * SASL_CONTINUE if we need to call them again */
309extern int (*_sasl_client_cleanup_hook)(void);
310extern int (*_sasl_server_cleanup_hook)(void);
311
312extern sasl_allocation_utils_t _sasl_allocation_utils;
313extern sasl_mutex_utils_t _sasl_mutex_utils;
314extern int _sasl_allocation_locked;
315
316void sasl_common_done(void);
317
318extern int _sasl_is_equal_mech(const char *req_mech,
319                               const char *plug_mech,
320                               size_t req_mech_len,
321                               int *plus);
322
323/*
324 * checkpw.c
325 */
326extern struct sasl_verify_password_s _sasl_verify_password[];
327
328/*
329 * server.c
330 */
331/* (this is a function call to ensure this is read-only to the outside) */
332extern int _is_sasl_server_active(void);
333
334/*
335 * Allocation and Mutex utility macros
336 */
337#define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
338#define sasl_CALLOC(__nelem__, __size__) \
339	(_sasl_allocation_utils.calloc((__nelem__), (__size__)))
340#define sasl_REALLOC(__ptr__, __size__) \
341	(_sasl_allocation_utils.realloc((__ptr__), (__size__)))
342#define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
343
344#define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
345#define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
346#define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
347#define sasl_MUTEX_FREE(__mutex__) \
348	(_sasl_mutex_utils.free((__mutex__)))
349
350/* function prototypes */
351/*
352 * dlopen.c and staticopen.c
353 */
354/*
355 * The differences here are:
356 * _sasl_load_plugins loads all plugins from all files
357 * _sasl_get_plugin loads the LIBRARY for an individual file
358 * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
359 * _sasl_locate_entry locates an entrypoint in a given library
360 */
361extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
362			       const sasl_callback_t *getpath_callback,
363			       const sasl_callback_t *verifyfile_callback);
364/* APPLE */
365extern int _sasl_load_plugins_alt(const add_plugin_list_t *entrypoints,
366			       const sasl_callback_t *getpath_callback,
367			       const sasl_callback_t *verifyfile_callback);
368extern int _sasl_get_plugin(const char *file,
369			    const sasl_callback_t *verifyfile_cb,
370			    void **libraryptr);
371extern int _sasl_locate_entry(void *library, const char *entryname,
372                              void **entry_point);
373extern int _sasl_done_with_plugins();
374
375/*
376 * common.c
377 */
378extern const sasl_callback_t *
379_sasl_find_getpath_callback(const sasl_callback_t *callbacks);
380
381extern const sasl_callback_t *
382_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
383
384extern const sasl_callback_t *
385_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
386
387extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks);
388
389extern int _sasl_conn_init(sasl_conn_t *conn,
390			   const char *service,
391			   unsigned int flags,
392			   enum Sasl_conn_type type,
393			   int (*idle_hook)(sasl_conn_t *conn),
394			   const char *serverFQDN,
395			   const char *iplocalport,
396			   const char *ipremoteport,
397			   const sasl_callback_t *callbacks,
398			   const sasl_global_callbacks_t *global_callbacks);
399extern void _sasl_conn_dispose(sasl_conn_t *conn);
400
401extern sasl_utils_t *
402_sasl_alloc_utils(sasl_conn_t *conn,
403		  sasl_global_callbacks_t *global_callbacks);
404extern int _sasl_free_utils(const sasl_utils_t ** utils);
405
406extern int
407_sasl_getcallback(sasl_conn_t * conn,
408		  unsigned long callbackid,
409		  sasl_callback_ft * pproc,
410		  void **pcontext);
411
412extern void
413_sasl_log(sasl_conn_t *conn,
414	  int level,
415	  const char *fmt,
416	  ...);
417
418void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
419int _sasl_add_string(char **out, size_t *alloclen,
420		     size_t *outlen, const char *add);
421
422/* More Generic Utilities in common.c */
423extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
424
425/* Basically a conditional call to realloc(), if we need more */
426int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
427
428/* convert an iovec to a single buffer */
429int _iovec_to_buf(const struct iovec *vec,
430		  unsigned numiov, buffer_info_t **output);
431
432/* Convert between string formats and sockaddr formats */
433int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
434		     char *out, unsigned outlen);
435int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
436		       socklen_t outlen);
437
438/*
439 * external plugin (external.c)
440 */
441int external_client_plug_init(const sasl_utils_t *utils,
442			      int max_version,
443			      int *out_version,
444			      sasl_client_plug_t **pluglist,
445			      int *plugcount);
446int external_server_plug_init(const sasl_utils_t *utils,
447			      int max_version,
448			      int *out_version,
449			      sasl_server_plug_t **pluglist,
450			      int *plugcount);
451
452/* Mech Listing Functions */
453int _sasl_build_mechlist(void);
454int _sasl_server_listmech(sasl_conn_t *conn,
455			  const char *user,
456			  const char *prefix,
457			  const char *sep,
458			  const char *suffix,
459			  const char **result,
460			  unsigned *plen,
461			  int *pcount);
462int _sasl_client_listmech(sasl_conn_t *conn,
463			  const char *prefix,
464			  const char *sep,
465			  const char *suffix,
466			  const char **result,
467			  unsigned *plen,
468			  int *pcount);
469/* Just create a straight list of them */
470sasl_string_list_t *_sasl_client_mechs(void);
471sasl_string_list_t *_sasl_server_mechs(void);
472
473/*
474 * config file declarations (config.c)
475 */
476extern const char *sasl_config_getstring(const char *key,const char *def);
477
478/* checkpw.c */
479#ifdef DO_SASL_CHECKAPOP
480extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
481				     const char *userstr,
482				     const char *challenge,
483				     const char *response,
484				     const char *user_realm);
485#endif /* DO_SASL_CHECKAPOP */
486
487/* Auxprop Plugin (sasldb.c) */
488extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
489				    int max_version,
490				    int *out_version,
491				    sasl_auxprop_plug_t **plug,
492				    const char *plugname);
493
494/*
495 * auxprop.c
496 */
497extern int _sasl_auxprop_add_plugin(void *p, void *library);
498extern void _sasl_auxprop_free(void);
499extern int _sasl_auxprop_lookup(sasl_server_params_t *sparams,
500				 unsigned flags,
501				 const char *user, unsigned ulen);
502
503/*
504 * canonusr.c
505 */
506void _sasl_canonuser_free();
507extern int internal_canonuser_init(const sasl_utils_t *utils,
508				   int max_version,
509				   int *out_version,
510				   sasl_canonuser_plug_t **plug,
511				   const char *plugname);
512extern int _sasl_canon_user(sasl_conn_t *conn,
513			    const char *user,
514			    unsigned ulen,
515			    unsigned flags,
516			    sasl_out_params_t *oparams);
517int _sasl_canon_user_lookup (sasl_conn_t *conn,
518			    const char *user,
519			    unsigned ulen,
520			    unsigned flags,
521			    sasl_out_params_t *oparams);
522
523/*
524 * saslutil.c
525 */
526int get_fqhostname(
527  char *name,
528  int namelen,
529  int abort_if_no_fqdn
530  );
531
532#endif /* SASLINT_H */
533