1/* saslplug.h -- API for SASL plug-ins 2 */ 3 4#ifndef SASLPLUG_H 5#define SASLPLUG_H 1 6 7#ifndef MD5GLOBAL_H 8#include "md5global.h" 9#endif 10#ifndef MD5_H 11#include "md5.h" 12#endif 13#ifndef HMAC_MD5_H 14#include "hmac-md5.h" 15#endif 16#ifndef PROP_H 17#include "prop.h" 18#endif 19 20#ifdef __cplusplus 21extern "C" { 22#endif 23 24/* callback to lookup a sasl_callback_t for a connection 25 * input: 26 * conn -- the connection to lookup a callback for 27 * callbacknum -- the number of the callback 28 * output: 29 * pproc -- pointer to the callback function (set to NULL on failure) 30 * pcontext -- pointer to the callback context (set to NULL on failure) 31 * returns: 32 * SASL_OK -- no error 33 * SASL_FAIL -- unable to find a callback of the requested type 34 * SASL_INTERACT -- caller must use interaction to get data 35 */ 36typedef int (*sasl_callback_ft)(); // APPLE: remove void 37typedef int sasl_getcallback_t(sasl_conn_t *conn, 38 unsigned long callbackid, 39 sasl_callback_ft * pproc, 40 void **pcontext); 41 42/* The sasl_utils structure will remain backwards compatible unless 43 * the SASL_*_PLUG_VERSION is changed incompatibly 44 * higher SASL_UTILS_VERSION numbers indicate more functions are available 45 */ 46#define SASL_UTILS_VERSION 4 47 48/* utility function set for plug-ins 49 */ 50typedef struct sasl_utils { 51 int version; 52 53 /* contexts */ 54 sasl_conn_t *conn; 55 sasl_rand_t *rpool; 56 void *getopt_context; 57 58 /* option function */ 59 sasl_getopt_t *getopt; 60 61 /* allocation functions: */ 62 sasl_malloc_t *malloc; 63 sasl_calloc_t *calloc; 64 sasl_realloc_t *realloc; 65 sasl_free_t *free; 66 67 /* mutex functions: */ 68 sasl_mutex_alloc_t *mutex_alloc; 69 sasl_mutex_lock_t *mutex_lock; 70 sasl_mutex_unlock_t *mutex_unlock; 71 sasl_mutex_free_t *mutex_free; 72 73 /* MD5 hash and HMAC functions */ 74 void (*MD5Init)(MD5_CTX *); 75 void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len); 76 void (*MD5Final)(unsigned char [16], MD5_CTX *); 77 void (*hmac_md5)(const unsigned char *text, int text_len, 78 const unsigned char *key, int key_len, 79 unsigned char [16]); 80 void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len); 81 /* hmac_md5_update() is just a call to MD5Update on inner context */ 82 void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); 83 void (*hmac_md5_precalc)(HMAC_MD5_STATE *, 84 const unsigned char *key, int len); 85 void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); 86 87 /* mechanism utility functions (same as above): */ 88 int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, 89 unsigned hostflag); 90 int (*utf8verify)(const char *str, unsigned len); 91 void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); 92 void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); 93 94 /* This allows recursive calls to the sasl_checkpass() routine from 95 * within a SASL plug-in. This MUST NOT be used in the PLAIN mechanism 96 * as sasl_checkpass MAY be a front-end for the PLAIN mechanism. 97 * This is intended for use by the non-standard LOGIN mechanism and 98 * potentially by a future mechanism which uses public-key technology to 99 * set up a lightweight encryption layer just for sending a password. 100 */ 101 int (*checkpass)(sasl_conn_t *conn, 102 const char *user, unsigned userlen, 103 const char *pass, unsigned passlen); 104 105 /* Access to base64 encode/decode routines */ 106 int (*decode64)(const char *in, unsigned inlen, 107 char *out, unsigned outmax, unsigned *outlen); 108 int (*encode64)(const char *in, unsigned inlen, 109 char *out, unsigned outmax, unsigned *outlen); 110 111 /* erase a buffer */ 112 void (*erasebuffer)(char *buf, unsigned len); 113 114 /* callback to sasl_getprop() and sasl_setprop() */ 115 int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue); 116 int (*setprop)(sasl_conn_t *conn, int propnum, const void *value); 117 118 /* callback function */ 119 sasl_getcallback_t *getcallback; 120 121 /* format a message and then pass it to the SASL_CB_LOG callback 122 * 123 * use syslog()-style formatting (printf with %m as a human readable text 124 * (strerror()) for the error specified as the parameter). 125 * The implementation may use a fixed size buffer not smaller 126 * than 512 octets if it securely truncates the message. 127 * 128 * level is a SASL_LOG_* level (see sasl.h) 129 */ 130 void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...); 131 132 /* callback to sasl_seterror() */ 133 void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...); 134 135 /* spare function pointer */ 136 int *(*spare_fptr)(void); 137 138 /* auxiliary property utilities */ 139 struct propctx *(*prop_new)(unsigned estimate); 140 int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx); 141 int (*prop_request)(struct propctx *ctx, const char **names); 142 const struct propval *(*prop_get)(struct propctx *ctx); 143 int (*prop_getnames)(struct propctx *ctx, const char **names, 144 struct propval *vals); 145 void (*prop_clear)(struct propctx *ctx, int requests); 146 void (*prop_dispose)(struct propctx **ctx); 147 int (*prop_format)(struct propctx *ctx, const char *sep, int seplen, 148 char *outbuf, unsigned outmax, unsigned *outlen); 149 int (*prop_set)(struct propctx *ctx, const char *name, 150 const char *value, int vallen); 151 int (*prop_setvals)(struct propctx *ctx, const char *name, 152 const char **values); 153 void (*prop_erase)(struct propctx *ctx, const char *name); 154 int (*auxprop_store)(sasl_conn_t *conn, 155 struct propctx *ctx, const char *user); 156 157 /* for additions which don't require a version upgrade; set to 0 */ 158 int (*spare_fptr1)(void); 159 int (*spare_fptr2)(void); 160} sasl_utils_t; 161 162/* 163 * output parameters from SASL API 164 * 165 * created / destroyed by the glue code, though probably filled in 166 * by a combination of the plugin, the glue code, and the canon_user callback. 167 * 168 */ 169typedef struct sasl_out_params { 170 unsigned doneflag; /* exchange complete */ 171 172 const char *user; /* canonicalized user name */ 173 const char *authid; /* canonicalized authentication id */ 174 175 unsigned ulen; /* length of canonicalized user name */ 176 unsigned alen; /* length of canonicalized authid */ 177 178 /* security layer information */ 179 unsigned maxoutbuf; /* Maximum buffer size, which will 180 produce buffer no bigger than the 181 negotiated SASL maximum buffer size */ 182 sasl_ssf_t mech_ssf; /* Should be set non-zero if negotiation of a 183 * security layer was *attempted*, even if 184 * the negotiation failed */ 185 void *encode_context; 186 int (*encode)(void *context, const struct iovec *invec, unsigned numiov, 187 const char **output, unsigned *outputlen); 188 void *decode_context; 189 int (*decode)(void *context, const char *input, unsigned inputlen, 190 const char **output, unsigned *outputlen); 191 192 /* Pointer to delegated (client's) credentials, if supported by 193 the SASL mechanism */ 194 void *client_creds; 195 196 /* for additions which don't require a version upgrade; set to 0 */ 197 /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */ 198 union { 199 void *spare_ptr2; 200 const void *gss_peer_name; 201 }; 202 union { 203 void *spare_ptr3; 204 const void *gss_local_name; 205 }; 206 union { 207 void *spare_ptr4; 208 const char *cbindingname; /* channel binding name from packet */ 209 }; 210 int (*spare_fptr1)(); 211 int (*spare_fptr2)(); 212 union { 213 int spare_int1; 214 unsigned int cbindingdisp; /* channel binding disposition from client */ 215 }; 216 int spare_int2; 217 int spare_int3; 218 int spare_int4; 219 220 /* set to 0 initially, this allows a plugin with extended parameters 221 * to work with an older framework by updating version as parameters 222 * are added. 223 */ 224 int param_version; 225} sasl_out_params_t; 226 227 228 229/* Used by both client and server side plugins */ 230typedef enum { 231 SASL_INFO_LIST_START = 0, 232 SASL_INFO_LIST_MECH, 233 SASL_INFO_LIST_END 234} sasl_info_callback_stage_t; 235 236/****************************** 237 * Channel binding macros ** 238 ******************************/ 239 240typedef enum { 241 SASL_CB_DISP_NONE = 0, /* client did not support CB */ 242 SASL_CB_DISP_WANT, /* client supports CB, thinks server does not */ 243 SASL_CB_DISP_USED /* client supports and used CB */ 244} sasl_cbinding_disp_t; 245 246/* TRUE if channel binding is non-NULL */ 247#define SASL_CB_PRESENT(params) ((params)->cbinding != NULL) 248/* TRUE if channel binding is marked critical */ 249#define SASL_CB_CRITICAL(params) (SASL_CB_PRESENT(params) && \ 250 (params)->cbinding->critical) 251 252/****************************** 253 * Client Mechanism Functions * 254 ******************************/ 255 256/* 257 * input parameters to client SASL plugin 258 * 259 * created / destroyed by the glue code 260 * 261 */ 262typedef struct sasl_client_params { 263 const char *service; /* service name */ 264 const char *serverFQDN; /* server fully qualified domain name */ 265 const char *clientFQDN; /* client's fully qualified domain name */ 266 const sasl_utils_t *utils; /* SASL API utility routines -- 267 * for a particular sasl_conn_t, 268 * MUST remain valid until mech_free is 269 * called */ 270 const sasl_callback_t *prompt_supp; /* client callback list */ 271 const char *iplocalport; /* server IP domain literal & port */ 272 const char *ipremoteport; /* client IP domain literal & port */ 273 274 unsigned servicelen; /* length of service */ 275 unsigned slen; /* length of serverFQDN */ 276 unsigned clen; /* length of clientFQDN */ 277 unsigned iploclen; /* length of iplocalport */ 278 unsigned ipremlen; /* length of ipremoteport */ 279 280 /* application's security requirements & info */ 281 sasl_security_properties_t props; 282 sasl_ssf_t external_ssf; /* external SSF active */ 283 284 /* for additions which don't require a version upgrade; set to 0 */ 285 /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */ 286 union { 287 void *spare_ptr1; 288 const void *gss_creds; /* GSS credential handle */ 289 }; 290 union { 291 void *spare_ptr2; 292 const sasl_channel_binding_t *cbinding; /* client channel binding */ 293 }; 294 union { 295 void *spare_ptr3; 296 const sasl_http_request_t *http_request;/* HTTP Digest request method */ 297 }; 298 void *spare_ptr4; 299 300 /* Canonicalize a user name from on-wire to internal format 301 * added rjs3 2001-05-23 302 * Must be called once user name aquired if canon_user is non-NULL. 303 * conn connection context 304 * in user name from wire protocol (need not be NUL terminated) 305 * len length of user name from wire protocol (0 = strlen(user)) 306 * flags for SASL_CU_* flags 307 * oparams the user, authid, ulen, alen, fields are 308 * set appropriately after canonicalization/copying and 309 * authorization of arguments 310 * 311 * responsible for setting user, ulen, authid, and alen in the oparams 312 * structure 313 * 314 * default behavior is to strip leading and trailing whitespace, as 315 * well as allocating space for and copying the parameters. 316 * 317 * results: 318 * SASL_OK -- success 319 * SASL_NOMEM -- out of memory 320 * SASL_BADPARAM -- invalid conn 321 * SASL_BADPROT -- invalid user/authid 322 */ 323 int (*canon_user)(sasl_conn_t *conn, 324 const char *in, unsigned len, 325 unsigned flags, 326 sasl_out_params_t *oparams); 327 328 int (*spare_fptr1)(void); 329 330 union { 331 int spare_int1; 332 unsigned int cbindingdisp; 333 }; 334 int spare_int2; 335 int spare_int3; 336 337 /* flags field as passed to sasl_client_new */ 338 unsigned flags; 339 340 /* set to 0 initially, this allows a plugin with extended parameters 341 * to work with an older framework by updating version as parameters 342 * are added. 343 */ 344 int param_version; 345} sasl_client_params_t; 346 347/* features shared between client and server */ 348/* These allow the glue code to handle client-first and server-last issues */ 349 350/* This indicates that the mechanism prefers to do client-send-first 351 * if the protocol allows it. */ 352#define SASL_FEAT_WANT_CLIENT_FIRST 0x0002 353 354/* This feature is deprecated. Instead, plugins should set *serverout to 355 * non-NULL and return SASL_OK intelligently to allow flexible use of 356 * server-last semantics 357#define SASL_FEAT_WANT_SERVER_LAST 0x0004 358*/ 359 360/* This feature is deprecated. Instead, plugins should correctly set 361 * SASL_FEAT_SERVER_FIRST as needed 362#define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008 363*/ 364 365/* This indicates that the plugin is server-first only. 366 * Not defining either of SASL_FEAT_SERVER_FIRST or 367 * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism 368 * will handle the client-first situation internally. 369 */ 370#define SASL_FEAT_SERVER_FIRST 0x0010 371 372/* This plugin allows proxying */ 373#define SASL_FEAT_ALLOWS_PROXY 0x0020 374 375/* server plugin don't use cleartext userPassword attribute */ 376#define SASL_FEAT_DONTUSE_USERPASSWD 0x0080 377 378/* Underlying mechanism uses GSS framing */ 379#define SASL_FEAT_GSS_FRAMING 0x0100 380 381/* Underlying mechanism supports channel binding */ 382#define SASL_FEAT_CHANNEL_BINDING 0x0800 383 384/* This plugin can be used for HTTP authentication */ 385#define SASL_FEAT_SUPPORTS_HTTP 0x1000 386 387/* client plug-in features */ 388#define SASL_FEAT_NEEDSERVERFQDN 0x0001 389 390/* a C object for a client mechanism 391 */ 392typedef struct sasl_client_plug { 393 /* mechanism name */ 394 const char *mech_name; 395 396 /* best mech additional security layer strength factor */ 397 sasl_ssf_t max_ssf; 398 399 /* best security flags, as defined in sasl_security_properties_t */ 400 unsigned security_flags; 401 402 /* features of plugin */ 403 unsigned features; 404 405 /* required prompt ids, NULL = user/pass only */ 406 const unsigned long *required_prompts; 407 408 /* global state for mechanism */ 409 void *glob_context; 410 411 /* create context for mechanism, using params supplied 412 * glob_context -- from above 413 * params -- params from sasl_client_new 414 * conn_context -- context for one connection 415 * returns: 416 * SASL_OK -- success 417 * SASL_NOMEM -- not enough memory 418 * SASL_WRONGMECH -- mech doesn't support security params 419 */ 420 int (*mech_new)(void *glob_context, 421 sasl_client_params_t *cparams, 422 void **conn_context); 423 424 /* perform one step of exchange. NULL is passed for serverin on 425 * first step. 426 * returns: 427 * SASL_OK -- success 428 * SASL_INTERACT -- user interaction needed to fill in prompts 429 * SASL_BADPROT -- server protocol incorrect/cancelled 430 * SASL_BADSERV -- server failed mutual auth 431 */ 432 int (*mech_step)(void *conn_context, 433 sasl_client_params_t *cparams, 434 const char *serverin, 435 unsigned serverinlen, 436 sasl_interact_t **prompt_need, 437 const char **clientout, 438 unsigned *clientoutlen, 439 sasl_out_params_t *oparams); 440 441 /* dispose of connection context from mech_new 442 */ 443 void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); 444 445 /* free all global space used by mechanism 446 * mech_dispose must be called on all mechanisms first 447 */ 448 void (*mech_free)(void *glob_context, const sasl_utils_t *utils); 449 450 /* perform precalculations during a network round-trip 451 * or idle period. conn_context may be NULL 452 * returns 1 if action taken, 0 if no action taken 453 */ 454 int (*idle)(void *glob_context, 455 void *conn_context, 456 sasl_client_params_t *cparams); 457 458 /* for additions which don't require a version upgrade; set to 0 */ 459 int (*spare_fptr1)(void); 460 int (*spare_fptr2)(void); 461} sasl_client_plug_t; 462 463#define SASL_CLIENT_PLUG_VERSION 4 464 465/* plug-in entry point: 466 * utils -- utility callback functions 467 * max_version -- highest client plug version supported 468 * returns: 469 * out_version -- client plug version of result 470 * pluglist -- list of mechanism plug-ins 471 * plugcount -- number of mechanism plug-ins 472 * results: 473 * SASL_OK -- success 474 * SASL_NOMEM -- failure 475 * SASL_BADVERS -- max_version too small 476 * SASL_BADPARAM -- bad config string 477 * ... 478 */ 479typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, 480 int max_version, 481 int *out_version, 482 sasl_client_plug_t **pluglist, 483 int *plugcount); 484 485 486/* add a client plug-in 487 */ 488LIBSASL_API int sasl_client_add_plugin(const char *plugname, 489 sasl_client_plug_init_t *cplugfunc); 490 491typedef struct client_sasl_mechanism 492{ 493 int version; 494 495 char *plugname; 496 const sasl_client_plug_t *plug; 497} client_sasl_mechanism_t; 498 499typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m, 500 sasl_info_callback_stage_t stage, 501 void *rock); 502 503/* Dump information about available client plugins */ 504LIBSASL_API int sasl_client_plugin_info (const char *mech_list, 505 sasl_client_info_callback_t *info_cb, 506 void *info_cb_rock); 507 508 509/******************** 510 * Server Functions * 511 ********************/ 512 513/* log message formatting routine */ 514typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...); 515 516/* 517 * input parameters to server SASL plugin 518 * 519 * created / destroyed by the glue code 520 * 521 */ 522typedef struct sasl_server_params { 523 const char *service; /* NULL = default service for user_exists 524 and setpass */ 525 const char *appname; /* name of calling application */ 526 const char *serverFQDN; /* server default fully qualified domain name 527 * (e.g., gethostname) */ 528 const char *user_realm; /* realm for user (NULL = client supplied) */ 529 const char *iplocalport; /* server IP domain literal & port */ 530 const char *ipremoteport; /* client IP domain literal & port */ 531 532 unsigned servicelen; /* length of service */ 533 unsigned applen; /* length of appname */ 534 unsigned slen; /* length of serverFQDN */ 535 unsigned urlen; /* length of user_realm */ 536 unsigned iploclen; /* length of iplocalport */ 537 unsigned ipremlen; /* length of ipremoteport */ 538 539 /* This indicates the level of logging desired. See SASL_LOG_* 540 * in sasl.h 541 * 542 * Plug-ins can ignore this and just pass their desired level to 543 * the log callback. This is primarily used to eliminate logging which 544 * might be a performance problem (e.g., full protocol trace) and 545 * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives 546 */ 547 int log_level; 548 549 const sasl_utils_t *utils; /* SASL API utility routines -- 550 * for a particular sasl_conn_t, 551 * MUST remain valid until mech_free is 552 * called */ 553 const sasl_callback_t *callbacks; /* Callbacks from application */ 554 555 /* application's security requirements */ 556 sasl_security_properties_t props; 557 sasl_ssf_t external_ssf; /* external SSF active */ 558 559 /* Pointer to the function which takes the plaintext passphrase and 560 * transitions a user to non-plaintext mechanisms via setpass calls. 561 * (NULL = auto transition not enabled/supported) 562 * 563 * If passlen is 0, it defaults to strlen(pass). 564 * returns 0 if no entry added, 1 if entry added 565 */ 566 int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen); 567 568 /* Canonicalize a user name from on-wire to internal format 569 * added cjn 1999-09-21 570 * Must be called once user name acquired if canon_user is non-NULL. 571 * conn connection context 572 * user user name from wire protocol (need not be NUL terminated) 573 * ulen length of user name from wire protocol (0 = strlen(user)) 574 * flags for SASL_CU_* flags 575 * oparams the user, authid, ulen, alen, fields are 576 * set appropriately after canonicalization/copying and 577 * authorization of arguments 578 * 579 * responsible for setting user, ulen, authid, and alen in the oparams 580 * structure 581 * 582 * default behavior is to strip leading and trailing whitespace, as 583 * well as allocating space for and copying the parameters. 584 * 585 * results: 586 * SASL_OK -- success 587 * SASL_NOMEM -- out of memory 588 * SASL_BADPARAM -- invalid conn 589 * SASL_BADPROT -- invalid user/authid 590 */ 591 int (*canon_user)(sasl_conn_t *conn, 592 const char *user, unsigned ulen, 593 unsigned flags, 594 sasl_out_params_t *oparams); 595 596 /* auxiliary property context (see definitions in prop.h) 597 * added cjn 2000-01-30 598 * 599 * NOTE: these properties are the ones associated with the 600 * canonicalized "user" (user to login as / authorization id), not 601 * the "authid" (user whose credentials are used / authentication id) 602 * Prefix the property name with a "*" if a property associated with 603 * the "authid" is interesting. 604 */ 605 struct propctx *propctx; 606 607 /* for additions which don't require a version upgrade; set to 0 */ 608 /* APPLE: unions for compatibility with 2.1.22 and 2.1.26 */ 609 union { 610 void *spare_ptr1; 611 const void *gss_creds; /* GSS credential handle */ 612 }; 613 union { 614 void *spare_ptr2; 615 const sasl_channel_binding_t *cbinding; /* server channel binding */; 616 }; 617 union { 618 void *spare_ptr3; 619 const sasl_http_request_t *http_request;/* HTTP Digest request method */ 620 }; 621 void *spare_ptr4; 622 int (*spare_fptr1)(void); 623 int (*spare_fptr2)(void); 624 int spare_int1; 625 int spare_int2; 626 int spare_int3; 627 628 /* flags field as passed to sasl_server_new */ 629 unsigned flags; 630 631 /* set to 0 initially, this allows a plugin with extended parameters 632 * to work with an older framework by updating version as parameters 633 * are added. 634 */ 635 int param_version; 636} sasl_server_params_t; 637 638/* logging levels (more levels may be added later, if necessary): 639 */ 640#define SASL_LOG_NONE 0 /* don't log anything */ 641#define SASL_LOG_ERR 1 /* log unusual errors (default) */ 642#define SASL_LOG_FAIL 2 /* log all authentication failures */ 643#define SASL_LOG_WARN 3 /* log non-fatal warnings */ 644#define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ 645#define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ 646#define SASL_LOG_TRACE 6 /* traces of internal protocols */ 647#define SASL_LOG_PASS 7 /* traces of internal protocols, including 648 * passwords */ 649 650/* additional flags for setpass() function below: 651 */ 652/* SASL_SET_CREATE create user if pass non-NULL */ 653/* SASL_SET_DISABLE disable user */ 654#define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ 655 656/* features for server plug-in 657 */ 658#define SASL_FEAT_SERVICE 0x0200 /* service-specific passwords supported */ 659#define SASL_FEAT_GETSECRET 0x0400 /* sasl_server_{get,put}secret_t callbacks 660 * required by plug-in */ 661 662/* a C object for a server mechanism 663 */ 664typedef struct sasl_server_plug { 665 /* mechanism name */ 666 const char *mech_name; 667 668 /* best mech additional security layer strength factor */ 669 sasl_ssf_t max_ssf; 670 671 /* best security flags, as defined in sasl_security_properties_t */ 672 unsigned security_flags; 673 674 /* features of plugin */ 675 unsigned features; 676 677 /* global state for mechanism */ 678 void *glob_context; 679 680 /* create a new mechanism handler 681 * glob_context -- global context 682 * sparams -- server config params 683 * challenge -- server challenge from previous instance or NULL 684 * challen -- length of challenge from previous instance or 0 685 * out: 686 * conn_context -- connection context 687 * errinfo -- error information 688 * 689 * returns: 690 * SASL_OK -- successfully created mech instance 691 * SASL_* -- any other server error code 692 */ 693 int (*mech_new)(void *glob_context, 694 sasl_server_params_t *sparams, 695 const char *challenge, 696 unsigned challen, 697 void **conn_context); 698 699 /* perform one step in exchange 700 * 701 * returns: 702 * SASL_OK -- success, all done 703 * SASL_CONTINUE -- success, one more round trip 704 * SASL_* -- any other server error code 705 */ 706 int (*mech_step)(void *conn_context, 707 sasl_server_params_t *sparams, 708 const char *clientin, 709 unsigned clientinlen, 710 const char **serverout, 711 unsigned *serveroutlen, 712 sasl_out_params_t *oparams); 713 714 /* dispose of a connection state 715 */ 716 void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); 717 718 /* free global state for mechanism 719 * mech_dispose must be called on all mechanisms first 720 */ 721 void (*mech_free)(void *glob_context, const sasl_utils_t *utils); 722 723 /* set a password (optional) 724 * glob_context -- global context 725 * sparams -- service, middleware utilities, etc. props ignored 726 * user -- user name 727 * pass -- password/passphrase (NULL = disable/remove/delete) 728 * passlen -- length of password/passphrase 729 * oldpass -- old password/passphrase (NULL = transition) 730 * oldpasslen -- length of password/passphrase 731 * flags -- see above 732 * 733 * returns: 734 * SASL_NOCHANGE -- no change was needed 735 * SASL_NOUSER -- no entry for user 736 * SASL_NOVERIFY -- no mechanism compatible entry for user 737 * SASL_PWLOCK -- password locked 738 * SASL_DIABLED -- account disabled 739 * etc. 740 */ 741 int (*setpass)(void *glob_context, 742 sasl_server_params_t *sparams, 743 const char *user, 744 const char *pass, unsigned passlen, 745 const char *oldpass, unsigned oldpasslen, 746 unsigned flags); 747 748 /* query which mechanisms are available for user 749 * glob_context -- context 750 * sparams -- service, middleware utilities, etc. props ignored 751 * user -- NUL terminated user name 752 * maxmech -- max number of strings in mechlist (0 = no output) 753 * output: 754 * mechlist -- an array of C string pointers, filled in with 755 * mechanism names available to the user 756 * 757 * returns: 758 * SASL_OK -- success 759 * SASL_NOMEM -- not enough memory 760 * SASL_FAIL -- lower level failure 761 * SASL_DISABLED -- account disabled 762 * SASL_NOUSER -- user not found 763 * SASL_BUFOVER -- maxmech is too small 764 * SASL_NOVERIFY -- user found, but no mechanisms available 765 */ 766 int (*user_query)(void *glob_context, 767 sasl_server_params_t *sparams, 768 const char *user, 769 int maxmech, 770 const char **mechlist); 771 772 /* perform precalculations during a network round-trip 773 * or idle period. conn_context may be NULL (optional) 774 * returns 1 if action taken, 0 if no action taken 775 */ 776 int (*idle)(void *glob_context, 777 void *conn_context, 778 sasl_server_params_t *sparams); 779 780 /* check if mechanism is available 781 * optional--if NULL, mechanism is available based on ENABLE= in config 782 * 783 * If this routine sets conn_context to a non-NULL value, then the call 784 * to mech_new will be skipped. This should not be done unless 785 * there's a significant performance benefit, since it can cause 786 * additional memory allocation in SASL core code to keep track of 787 * contexts potentially for multiple mechanisms. 788 * 789 * This is called by the first call to sasl_listmech() for a 790 * given connection context, thus for a given protocol it may 791 * never be called. Note that if mech_avail returns SASL_NOMECH, 792 * then that mechanism is considered disabled for the remainder 793 * of the session. If mech_avail returns SASL_NOTDONE, then a 794 * future call to mech_avail may still return either SASL_OK 795 * or SASL_NOMECH. 796 * 797 * returns SASL_OK on success, 798 * SASL_NOTDONE if mech is not available now, but may be later 799 * (e.g. EXTERNAL w/o auth_id) 800 * SASL_NOMECH if mech disabled 801 */ 802 int (*mech_avail)(void *glob_context, 803 sasl_server_params_t *sparams, 804 void **conn_context); 805 806 /* for additions which don't require a version upgrade; set to 0 */ 807 int (*spare_fptr2)(void); 808} sasl_server_plug_t; 809 810#define SASL_SERVER_PLUG_VERSION 4 811 812/* plug-in entry point: 813 * utils -- utility callback functions 814 * plugname -- name of plug-in (may be NULL) 815 * max_version -- highest server plug version supported 816 * returns: 817 * out_version -- server plug-in version of result 818 * pluglist -- list of mechanism plug-ins 819 * plugcount -- number of mechanism plug-ins 820 * results: 821 * SASL_OK -- success 822 * SASL_NOMEM -- failure 823 * SASL_BADVERS -- max_version too small 824 * SASL_BADPARAM -- bad config string 825 * ... 826 */ 827typedef int sasl_server_plug_init_t(const sasl_utils_t *utils, 828 int max_version, 829 int *out_version, 830 sasl_server_plug_t **pluglist, 831 int *plugcount); 832 833/* 834 * add a server plug-in 835 */ 836LIBSASL_API int sasl_server_add_plugin(const char *plugname, 837 sasl_server_plug_init_t *splugfunc); 838 839 840typedef struct server_sasl_mechanism 841{ 842 int version; 843 int condition; /* set to SASL_NOUSER if no available users; 844 set to SASL_CONTINUE if delayed plugin loading */ 845 char *plugname; /* for AUTHSOURCE tracking */ 846 const sasl_server_plug_t *plug; 847 char *f; /* where should i load the mechanism from? */ 848} server_sasl_mechanism_t; 849 850typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m, 851 sasl_info_callback_stage_t stage, 852 void *rock); 853 854 855/* Dump information about available server plugins (separate functions are 856 used for canon and auxprop plugins) */ 857LIBSASL_API int sasl_server_plugin_info (const char *mech_list, 858 sasl_server_info_callback_t *info_cb, 859 void *info_cb_rock); 860 861 862/********************************************************* 863 * user canonicalization plug-in -- added cjn 1999-09-29 * 864 *********************************************************/ 865 866typedef struct sasl_canonuser { 867 /* optional features of plugin (set to 0) */ 868 int features; 869 870 /* spare integer (set to 0) */ 871 int spare_int1; 872 873 /* global state for plugin */ 874 void *glob_context; 875 876 /* name of plugin */ 877 char *name; 878 879 /* free global state for plugin */ 880 void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils); 881 882 /* canonicalize a username 883 * glob_context -- global context from this structure 884 * sparams -- server params, note user_realm&propctx elements 885 * user -- user to login as (may not be NUL terminated) 886 * len -- length of user name (0 = strlen(user)) 887 * flags -- for SASL_CU_* flags 888 * out -- buffer to copy user name 889 * out_max -- max length of user name 890 * out_len -- set to length of user name 891 * 892 * note that the output buffers MAY be the same as the input buffers. 893 * 894 * returns 895 * SASL_OK on success 896 * SASL_BADPROT username contains invalid character 897 */ 898 int (*canon_user_server)(void *glob_context, 899 sasl_server_params_t *sparams, 900 const char *user, unsigned len, 901 unsigned flags, 902 char *out, 903 unsigned out_umax, unsigned *out_ulen); 904 905 int (*canon_user_client)(void *glob_context, 906 sasl_client_params_t *cparams, 907 const char *user, unsigned len, 908 unsigned flags, 909 char *out, 910 unsigned out_max, unsigned *out_len); 911 912 /* for additions which don't require a version upgrade; set to 0 */ 913 int (*spare_fptr1)(void); 914 int (*spare_fptr2)(void); 915 int (*spare_fptr3)(void); 916} sasl_canonuser_plug_t; 917 918#define SASL_CANONUSER_PLUG_VERSION 5 919 920/* default name for canonuser plug-in entry point is "sasl_canonuser_init" 921 * similar to sasl_server_plug_init model, except only returns one 922 * sasl_canonuser_plug_t structure; 923 */ 924typedef int sasl_canonuser_init_t(const sasl_utils_t *utils, 925 int max_version, 926 int *out_version, 927 sasl_canonuser_plug_t **plug, 928 const char *plugname); 929 930/* add a canonuser plugin 931 */ 932LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname, 933 sasl_canonuser_init_t *canonuserfunc); 934 935/****************************************************** 936 * auxiliary property plug-in -- added cjn 1999-09-29 * 937 ******************************************************/ 938 939typedef struct sasl_auxprop_plug { 940 /* optional features of plugin (none defined yet, set to 0) */ 941 int features; 942 943 /* spare integer, must be set to 0 */ 944 int spare_int1; 945 946 /* global state for plugin */ 947 void *glob_context; 948 949 /* free global state for plugin (OPTIONAL) */ 950 void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils); 951 952 /* fill in fields of an auxiliary property context 953 * last element in array has id of SASL_AUX_END 954 * elements with non-0 len should be ignored. 955 */ 956 // APPLE: union for v4 auxprop plugins 957 union { 958 int (*auxprop_lookup)(void *glob_context, 959 sasl_server_params_t *sparams, 960 unsigned flags, 961 const char *user, unsigned ulen); 962 void (*auxprop_lookup_v4)(void *glob_context, 963 sasl_server_params_t *sparams, 964 unsigned flags, 965 const char *user, unsigned ulen); 966 }; 967 968 /* name of the auxprop plugin */ 969 char *name; 970 971 /* store the fields/values of an auxiliary property context (OPTIONAL) 972 * 973 * if ctx is NULL, just check if storing properties is enabled 974 * 975 * returns 976 * SASL_OK on success 977 * SASL_FAIL on failure 978 */ 979 int (*auxprop_store)(void *glob_context, 980 sasl_server_params_t *sparams, 981 struct propctx *ctx, 982 const char *user, unsigned ulen); 983} sasl_auxprop_plug_t; 984 985/* auxprop lookup flags */ 986#define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties 987 * with non-zero len field. If set, 988 * override value of those properties */ 989#define SASL_AUXPROP_AUTHZID 0x02 /* if clear, we are looking up the 990 * authid flags (prefixed with *), otherwise 991 * we are looking up the authzid flags 992 * (no prefix) */ 993 994/* NOTE: Keep in sync with SASL_CU_<XXX> flags */ 995#define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10 996 997 998#define SASL_AUXPROP_PLUG_VERSION 8 999#define SASL_AUXPROP_PLUG_MIN_VERSION 4 1000 1001/* default name for auxprop plug-in entry point is "sasl_auxprop_init" 1002 * similar to sasl_server_plug_init model, except only returns one 1003 * sasl_auxprop_plug_t structure; 1004 */ 1005typedef int sasl_auxprop_init_t(const sasl_utils_t *utils, 1006 int max_version, 1007 int *out_version, 1008 sasl_auxprop_plug_t **plug, 1009 const char *plugname); 1010 1011/* add an auxiliary property plug-in 1012 */ 1013LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname, 1014 sasl_auxprop_init_t *auxpropfunc); 1015/* APPLE */ 1016LIBSASL_API int sasl_auxprop_add_plugin_nolog(const char *plugname, 1017 sasl_auxprop_init_t *auxpropfunc); 1018 1019typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m, 1020 sasl_info_callback_stage_t stage, 1021 void *rock); 1022 1023/* Dump information about available auxprop plugins (separate functions are 1024 used for canon and server authentication plugins) */ 1025LIBSASL_API int auxprop_plugin_info (const char *mech_list, 1026 auxprop_info_callback_t *info_cb, 1027 void *info_cb_rock); 1028 1029#ifdef __cplusplus 1030} 1031#endif 1032 1033#endif /* SASLPLUG_H */ 1034