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