1 /* saslint.h - internal SASL library definitions 2 * Rob Siemborski 3 * Tim Martin 4 */ 5 /* 6 * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any other legal 23 * details, please contact 24 * Carnegie Mellon University 25 * Center for Technology Transfer and Enterprise Creation 26 * 4615 Forbes Avenue 27 * Suite 302 28 * Pittsburgh, PA 15213 29 * (412) 268-7393, fax: (412) 268-7395 30 * innovation@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 /* A FQDN max len is 255 per RFC 1035, 116 * this means 253 chars max, we add one more for zero terminator */ 117 #define MAXFQDNLEN 254 118 119 /* Datatype Definitions */ 120 typedef struct { 121 const sasl_callback_t *callbacks; 122 const char *appname; 123 } sasl_global_callbacks_t; 124 125 typedef struct _sasl_external_properties 126 { 127 sasl_ssf_t ssf; 128 char *auth_id; 129 } _sasl_external_properties_t; 130 131 typedef struct sasl_string_list 132 { 133 const char *d; 134 struct sasl_string_list *next; 135 } sasl_string_list_t; 136 137 typedef struct buffer_info 138 { 139 char *data; 140 size_t curlen; 141 size_t reallen; 142 } buffer_info_t; 143 144 typedef int add_plugin_t(const char *, void *); 145 146 typedef struct add_plugin_list 147 { 148 const char *entryname; 149 add_plugin_t *add_plugin; 150 } add_plugin_list_t; 151 152 enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0, 153 SASL_CONN_SERVER = 1, 154 SASL_CONN_CLIENT = 2 }; 155 156 struct sasl_conn { 157 enum Sasl_conn_type type; 158 159 void (*destroy_conn)(sasl_conn_t *); /* destroy function */ 160 161 char *service; 162 163 unsigned int flags; /* flags passed to sasl_*_new */ 164 165 /* IP information. A buffer of size 52 is adequate for this in its 166 longest format (see sasl.h) */ 167 int got_ip_local, got_ip_remote; 168 char iplocalport[NI_MAXHOST + NI_MAXSERV]; 169 char ipremoteport[NI_MAXHOST + NI_MAXSERV]; 170 171 void *context; 172 sasl_out_params_t oparams; 173 174 sasl_security_properties_t props; 175 _sasl_external_properties_t external; 176 177 sasl_secret_t *secret; 178 179 int (*idle_hook)(sasl_conn_t *conn); 180 const sasl_callback_t *callbacks; 181 const sasl_global_callbacks_t *global_callbacks; /* global callbacks 182 * connection */ 183 char *serverFQDN; 184 185 /* Pointers to memory that we are responsible for */ 186 buffer_info_t *encode_buf; 187 188 int error_code; 189 char *error_buf, *errdetail_buf; 190 size_t error_buf_len, errdetail_buf_len; 191 char *mechlist_buf; 192 size_t mechlist_buf_len; 193 194 char *decode_buf; 195 196 char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1]; 197 198 /* Allocated by sasl_encodev if the output contains multiple SASL packet. */ 199 buffer_info_t multipacket_encoded_data; 200 }; 201 202 /* Server Conn Type Information */ 203 204 typedef struct mechanism 205 { 206 server_sasl_mechanism_t m; 207 struct mechanism *next; 208 } mechanism_t; 209 210 typedef struct mech_list { 211 const sasl_utils_t *utils; /* gotten from plug_init */ 212 213 void *mutex; /* mutex for this data */ 214 mechanism_t *mech_list; /* list of loaded mechanisms */ 215 int mech_length; /* number of loaded mechanisms */ 216 } mech_list_t; 217 218 typedef struct context_list 219 { 220 mechanism_t *mech; 221 void *context; /* if NULL, this mech is disabled for this connection 222 * otherwise, use this context instead of a call 223 * to mech_new */ 224 struct context_list *next; 225 } context_list_t; 226 227 typedef struct sasl_server_conn { 228 sasl_conn_t base; /* parts common to server + client */ 229 230 char *appname; /* application name buffer (for sparams) */ 231 char *user_realm; /* domain the user authenticating is in */ 232 int sent_last; /* Have we already done the last send? */ 233 int authenticated; 234 mechanism_t *mech; /* mechanism trying to use */ 235 sasl_server_params_t *sparams; 236 context_list_t *mech_contexts; 237 mechanism_t *mech_list; /* list of available mechanisms */ 238 int mech_length; /* number of available mechanisms */ 239 } sasl_server_conn_t; 240 241 /* Client Conn Type Information */ 242 243 typedef struct cmechanism 244 { 245 client_sasl_mechanism_t m; 246 struct cmechanism *next; 247 } cmechanism_t; 248 249 typedef struct cmech_list { 250 const sasl_utils_t *utils; 251 252 void *mutex; /* mutex for this data */ 253 cmechanism_t *mech_list; /* list of mechanisms */ 254 int mech_length; /* number of mechanisms */ 255 256 } cmech_list_t; 257 258 typedef struct sasl_client_conn { 259 sasl_conn_t base; /* parts common to server + client */ 260 261 cmechanism_t *mech; 262 sasl_client_params_t *cparams; 263 264 char *clientFQDN; 265 266 cmechanism_t *mech_list; /* list of available mechanisms */ 267 int mech_length; /* number of available mechanisms */ 268 } sasl_client_conn_t; 269 270 typedef struct sasl_allocation_utils { 271 sasl_malloc_t *malloc; 272 sasl_calloc_t *calloc; 273 sasl_realloc_t *realloc; 274 sasl_free_t *free; 275 } sasl_allocation_utils_t; 276 277 typedef struct sasl_mutex_utils { 278 sasl_mutex_alloc_t *alloc; 279 sasl_mutex_lock_t *lock; 280 sasl_mutex_unlock_t *unlock; 281 sasl_mutex_free_t *free; 282 } sasl_mutex_utils_t; 283 284 typedef struct sasl_log_utils_s { 285 sasl_log_t *log; 286 } sasl_log_utils_t; 287 288 typedef int sasl_plaintext_verifier(sasl_conn_t *conn, 289 const char *userid, 290 const char *passwd, 291 const char *service, 292 const char *user_realm); 293 294 struct sasl_verify_password_s { 295 char *name; 296 sasl_plaintext_verifier *verify; 297 }; 298 299 /* 300 * globals & constants 301 */ 302 /* 303 * common.c 304 */ 305 LIBSASL_API const sasl_utils_t *sasl_global_utils; 306 307 extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn); 308 extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn); 309 310 /* These return SASL_OK if we've actually finished cleanup, 311 * SASL_NOTINIT if that part of the library isn't initialized, and 312 * SASL_CONTINUE if we need to call them again */ 313 extern int (*_sasl_client_cleanup_hook)(void); 314 extern int (*_sasl_server_cleanup_hook)(void); 315 316 extern sasl_allocation_utils_t _sasl_allocation_utils; 317 extern sasl_mutex_utils_t _sasl_mutex_utils; 318 extern int _sasl_allocation_locked; 319 320 void sasl_common_done(void); 321 322 extern int _sasl_is_equal_mech(const char *req_mech, 323 const char *plug_mech, 324 size_t req_mech_len, 325 int *plus); 326 327 /* 328 * checkpw.c 329 */ 330 extern struct sasl_verify_password_s _sasl_verify_password[]; 331 332 /* 333 * server.c 334 */ 335 /* (this is a function call to ensure this is read-only to the outside) */ 336 extern int _is_sasl_server_active(void); 337 338 /* 339 * Allocation and Mutex utility macros 340 */ 341 #define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__))) 342 #define sasl_CALLOC(__nelem__, __size__) \ 343 (_sasl_allocation_utils.calloc((__nelem__), (__size__))) 344 #define sasl_REALLOC(__ptr__, __size__) \ 345 (_sasl_allocation_utils.realloc((__ptr__), (__size__))) 346 #define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__))) 347 348 #define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc()) 349 #define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__))) 350 #define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__))) 351 #define sasl_MUTEX_FREE(__mutex__) \ 352 (_sasl_mutex_utils.free((__mutex__))) 353 354 /* function prototypes */ 355 /* 356 * dlopen.c and staticopen.c 357 */ 358 /* 359 * The differences here are: 360 * _sasl_load_plugins loads all plugins from all files 361 * _sasl_get_plugin loads the LIBRARY for an individual file 362 * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2 363 * _sasl_locate_entry locates an entrypoint in a given library 364 */ 365 extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints, 366 const sasl_callback_t *getpath_callback, 367 const sasl_callback_t *verifyfile_callback); 368 extern int _sasl_get_plugin(const char *file, 369 const sasl_callback_t *verifyfile_cb, 370 void **libraryptr); 371 extern int _sasl_locate_entry(void *library, const char *entryname, 372 void **entry_point); 373 extern int _sasl_done_with_plugins(); 374 375 /* 376 * common.c 377 */ 378 extern const sasl_callback_t * 379 _sasl_find_getpath_callback(const sasl_callback_t *callbacks); 380 381 extern const sasl_callback_t * 382 _sasl_find_getconfpath_callback(const sasl_callback_t *callbacks); 383 384 extern const sasl_callback_t * 385 _sasl_find_verifyfile_callback(const sasl_callback_t *callbacks); 386 387 extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks); 388 389 extern 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); 399 extern void _sasl_conn_dispose(sasl_conn_t *conn); 400 401 extern sasl_utils_t * 402 _sasl_alloc_utils(sasl_conn_t *conn, 403 sasl_global_callbacks_t *global_callbacks); 404 extern int _sasl_free_utils(const sasl_utils_t ** utils); 405 406 extern int 407 _sasl_getcallback(sasl_conn_t * conn, 408 unsigned long callbackid, 409 sasl_callback_ft * pproc, 410 void **pcontext); 411 412 extern void 413 _sasl_log(sasl_conn_t *conn, 414 int level, 415 const char *fmt, 416 ...); 417 418 void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl); 419 int _sasl_add_string(char **out, size_t *alloclen, 420 size_t *outlen, const char *add); 421 422 /* More Generic Utilities in common.c */ 423 extern int _sasl_strdup(const char *in, char **out, size_t *outlen); 424 425 /* Basically a conditional call to realloc(), if we need more */ 426 int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen); 427 428 /* convert an iovec to a single buffer */ 429 int _iovec_to_buf(const struct iovec *vec, 430 unsigned numiov, buffer_info_t **output); 431 432 /* Convert between string formats and sockaddr formats */ 433 int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen, 434 char *out, unsigned outlen); 435 int _sasl_ipfromstring(const char *addr, struct sockaddr *out, 436 socklen_t outlen); 437 438 /* 439 * external plugin (external.c) 440 */ 441 int 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); 446 int 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 */ 453 int _sasl_build_mechlist(void); 454 int _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); 462 int _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 */ 470 sasl_string_list_t *_sasl_client_mechs(void); 471 sasl_string_list_t *_sasl_server_mechs(void); 472 473 /* 474 * config file declarations (config.c) 475 */ 476 extern const char *sasl_config_getstring(const char *key,const char *def); 477 478 /* checkpw.c */ 479 #ifdef DO_SASL_CHECKAPOP 480 extern 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) */ 488 extern 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 */ 497 extern int _sasl_auxprop_add_plugin(void *p, void *library); 498 extern void _sasl_auxprop_free(void); 499 extern int _sasl_auxprop_lookup(sasl_server_params_t *sparams, 500 unsigned flags, 501 const char *user, unsigned ulen); 502 503 /* 504 * canonusr.c 505 */ 506 void _sasl_canonuser_free(); 507 extern 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); 512 extern int _sasl_canon_user(sasl_conn_t *conn, 513 const char *user, 514 unsigned ulen, 515 unsigned flags, 516 sasl_out_params_t *oparams); 517 int _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 */ 526 int get_fqhostname( 527 char *name, 528 int namelen, 529 int abort_if_no_fqdn 530 ); 531 532 #ifndef HAVE_GETHOSTNAME 533 #ifdef sun 534 /* gotta define gethostname ourselves on suns */ 535 extern int gethostname(char *, int); 536 #endif 537 #endif /* HAVE_GETHOSTNAME */ 538 539 #ifdef WIN32 540 char* _sasl_wchar_to_utf8(WCHAR *str); 541 WCHAR* _sasl_utf8_to_wchar(const char *str); 542 #endif 543 544 #endif /* SASLINT_H */ 545