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 21 extern "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 */ 36 typedef int (*sasl_callback_ft)(void); 37 typedef 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 */ 50 typedef 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, ...) __attribute__((format(printf, 3, 4))); 131 132 /* callback to sasl_seterror() */ 133 void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...) __attribute__((format(printf, 3, 4))); 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 */ 169 typedef 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 const void *gss_peer_name; 198 const void *gss_local_name; 199 const char *cbindingname; /* channel binding name from packet */ 200 int (*spare_fptr1)(void); 201 int (*spare_fptr2)(void); 202 unsigned int cbindingdisp; /* channel binding disposition from client */ 203 int spare_int2; 204 int spare_int3; 205 int spare_int4; 206 207 /* set to 0 initially, this allows a plugin with extended parameters 208 * to work with an older framework by updating version as parameters 209 * are added. 210 */ 211 int param_version; 212 } sasl_out_params_t; 213 214 215 216 /* Used by both client and server side plugins */ 217 typedef enum { 218 SASL_INFO_LIST_START = 0, 219 SASL_INFO_LIST_MECH, 220 SASL_INFO_LIST_END 221 } sasl_info_callback_stage_t; 222 223 /****************************** 224 * Channel binding macros ** 225 ******************************/ 226 227 typedef enum { 228 SASL_CB_DISP_NONE = 0, /* client did not support CB */ 229 SASL_CB_DISP_WANT, /* client supports CB, thinks server does not */ 230 SASL_CB_DISP_USED /* client supports and used CB */ 231 } sasl_cbinding_disp_t; 232 233 /* TRUE if channel binding is non-NULL */ 234 #define SASL_CB_PRESENT(params) ((params)->cbinding != NULL) 235 /* TRUE if channel binding is marked critical */ 236 #define SASL_CB_CRITICAL(params) (SASL_CB_PRESENT(params) && \ 237 (params)->cbinding->critical) 238 239 /****************************** 240 * Client Mechanism Functions * 241 ******************************/ 242 243 /* 244 * input parameters to client SASL plugin 245 * 246 * created / destroyed by the glue code 247 * 248 */ 249 typedef struct sasl_client_params { 250 const char *service; /* service name */ 251 const char *serverFQDN; /* server fully qualified domain name */ 252 const char *clientFQDN; /* client's fully qualified domain name */ 253 const sasl_utils_t *utils; /* SASL API utility routines -- 254 * for a particular sasl_conn_t, 255 * MUST remain valid until mech_free is 256 * called */ 257 const sasl_callback_t *prompt_supp; /* client callback list */ 258 const char *iplocalport; /* server IP domain literal & port */ 259 const char *ipremoteport; /* client IP domain literal & port */ 260 261 unsigned servicelen; /* length of service */ 262 unsigned slen; /* length of serverFQDN */ 263 unsigned clen; /* length of clientFQDN */ 264 unsigned iploclen; /* length of iplocalport */ 265 unsigned ipremlen; /* length of ipremoteport */ 266 267 /* application's security requirements & info */ 268 sasl_security_properties_t props; 269 sasl_ssf_t external_ssf; /* external SSF active */ 270 271 /* for additions which don't require a version upgrade; set to 0 */ 272 const void *gss_creds; /* GSS credential handle */ 273 const sasl_channel_binding_t *cbinding; /* client channel binding */ 274 const sasl_http_request_t *http_request;/* HTTP Digest request method */ 275 void *spare_ptr4; 276 277 /* Canonicalize a user name from on-wire to internal format 278 * added rjs3 2001-05-23 279 * Must be called once user name aquired if canon_user is non-NULL. 280 * conn connection context 281 * in user name from wire protocol (need not be NUL terminated) 282 * len length of user name from wire protocol (0 = strlen(user)) 283 * flags for SASL_CU_* flags 284 * oparams the user, authid, ulen, alen, fields are 285 * set appropriately after canonicalization/copying and 286 * authorization of arguments 287 * 288 * responsible for setting user, ulen, authid, and alen in the oparams 289 * structure 290 * 291 * default behavior is to strip leading and trailing whitespace, as 292 * well as allocating space for and copying the parameters. 293 * 294 * results: 295 * SASL_OK -- success 296 * SASL_NOMEM -- out of memory 297 * SASL_BADPARAM -- invalid conn 298 * SASL_BADPROT -- invalid user/authid 299 */ 300 int (*canon_user)(sasl_conn_t *conn, 301 const char *in, unsigned len, 302 unsigned flags, 303 sasl_out_params_t *oparams); 304 305 int (*spare_fptr1)(void); 306 307 unsigned int cbindingdisp; 308 int spare_int2; 309 int spare_int3; 310 311 /* flags field as passed to sasl_client_new */ 312 unsigned flags; 313 314 /* set to 0 initially, this allows a plugin with extended parameters 315 * to work with an older framework by updating version as parameters 316 * are added. 317 */ 318 int param_version; 319 } sasl_client_params_t; 320 321 /* features shared between client and server */ 322 /* These allow the glue code to handle client-first and server-last issues */ 323 324 /* This indicates that the mechanism prefers to do client-send-first 325 * if the protocol allows it. */ 326 #define SASL_FEAT_WANT_CLIENT_FIRST 0x0002 327 328 /* This feature is deprecated. Instead, plugins should set *serverout to 329 * non-NULL and return SASL_OK intelligently to allow flexible use of 330 * server-last semantics 331 #define SASL_FEAT_WANT_SERVER_LAST 0x0004 332 */ 333 334 /* This feature is deprecated. Instead, plugins should correctly set 335 * SASL_FEAT_SERVER_FIRST as needed 336 #define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008 337 */ 338 339 /* This indicates that the plugin is server-first only. 340 * Not defining either of SASL_FEAT_SERVER_FIRST or 341 * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism 342 * will handle the client-first situation internally. 343 */ 344 #define SASL_FEAT_SERVER_FIRST 0x0010 345 346 /* This plugin allows proxying */ 347 #define SASL_FEAT_ALLOWS_PROXY 0x0020 348 349 /* server plugin don't use cleartext userPassword attribute */ 350 #define SASL_FEAT_DONTUSE_USERPASSWD 0x0080 351 352 /* Underlying mechanism uses GSS framing */ 353 #define SASL_FEAT_GSS_FRAMING 0x0100 354 355 /* Underlying mechanism supports channel binding */ 356 #define SASL_FEAT_CHANNEL_BINDING 0x0800 357 358 /* This plugin can be used for HTTP authentication */ 359 #define SASL_FEAT_SUPPORTS_HTTP 0x1000 360 361 /* client plug-in features */ 362 #define SASL_FEAT_NEEDSERVERFQDN 0x0001 363 364 /* a C object for a client mechanism 365 */ 366 typedef struct sasl_client_plug { 367 /* mechanism name */ 368 const char *mech_name; 369 370 /* best mech additional security layer strength factor */ 371 sasl_ssf_t max_ssf; 372 373 /* best security flags, as defined in sasl_security_properties_t */ 374 unsigned security_flags; 375 376 /* features of plugin */ 377 unsigned features; 378 379 /* required prompt ids, NULL = user/pass only */ 380 const unsigned long *required_prompts; 381 382 /* global state for mechanism */ 383 void *glob_context; 384 385 /* create context for mechanism, using params supplied 386 * glob_context -- from above 387 * params -- params from sasl_client_new 388 * conn_context -- context for one connection 389 * returns: 390 * SASL_OK -- success 391 * SASL_NOMEM -- not enough memory 392 * SASL_WRONGMECH -- mech doesn't support security params 393 */ 394 int (*mech_new)(void *glob_context, 395 sasl_client_params_t *cparams, 396 void **conn_context); 397 398 /* perform one step of exchange. NULL is passed for serverin on 399 * first step. 400 * returns: 401 * SASL_OK -- success 402 * SASL_INTERACT -- user interaction needed to fill in prompts 403 * SASL_BADPROT -- server protocol incorrect/cancelled 404 * SASL_BADSERV -- server failed mutual auth 405 */ 406 int (*mech_step)(void *conn_context, 407 sasl_client_params_t *cparams, 408 const char *serverin, 409 unsigned serverinlen, 410 sasl_interact_t **prompt_need, 411 const char **clientout, 412 unsigned *clientoutlen, 413 sasl_out_params_t *oparams); 414 415 /* dispose of connection context from mech_new 416 */ 417 void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); 418 419 /* free all global space used by mechanism 420 * mech_dispose must be called on all mechanisms first 421 */ 422 void (*mech_free)(void *glob_context, const sasl_utils_t *utils); 423 424 /* perform precalculations during a network round-trip 425 * or idle period. conn_context may be NULL 426 * returns 1 if action taken, 0 if no action taken 427 */ 428 int (*idle)(void *glob_context, 429 void *conn_context, 430 sasl_client_params_t *cparams); 431 432 /* for additions which don't require a version upgrade; set to 0 */ 433 int (*spare_fptr1)(void); 434 int (*spare_fptr2)(void); 435 } sasl_client_plug_t; 436 437 #define SASL_CLIENT_PLUG_VERSION 4 438 439 /* plug-in entry point: 440 * utils -- utility callback functions 441 * max_version -- highest client plug version supported 442 * returns: 443 * out_version -- client plug version of result 444 * pluglist -- list of mechanism plug-ins 445 * plugcount -- number of mechanism plug-ins 446 * results: 447 * SASL_OK -- success 448 * SASL_NOMEM -- failure 449 * SASL_BADVERS -- max_version too small 450 * SASL_BADPARAM -- bad config string 451 * ... 452 */ 453 typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, 454 int max_version, 455 int *out_version, 456 sasl_client_plug_t **pluglist, 457 int *plugcount); 458 459 460 /* add a client plug-in 461 */ 462 LIBSASL_API int sasl_client_add_plugin(const char *plugname, 463 sasl_client_plug_init_t *cplugfunc); 464 465 typedef struct client_sasl_mechanism 466 { 467 int version; 468 469 char *plugname; 470 const sasl_client_plug_t *plug; 471 } client_sasl_mechanism_t; 472 473 typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m, 474 sasl_info_callback_stage_t stage, 475 void *rock); 476 477 /* Dump information about available client plugins */ 478 LIBSASL_API int sasl_client_plugin_info (const char *mech_list, 479 sasl_client_info_callback_t *info_cb, 480 void *info_cb_rock); 481 482 483 /******************** 484 * Server Functions * 485 ********************/ 486 487 /* log message formatting routine */ 488 typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...) __attribute__((format(printf, 2, 3))); 489 490 /* 491 * input parameters to server SASL plugin 492 * 493 * created / destroyed by the glue code 494 * 495 */ 496 typedef struct sasl_server_params { 497 const char *service; /* NULL = default service for user_exists 498 and setpass */ 499 const char *appname; /* name of calling application */ 500 const char *serverFQDN; /* server default fully qualified domain name 501 * (e.g., gethostname) */ 502 const char *user_realm; /* realm for user (NULL = client supplied) */ 503 const char *iplocalport; /* server IP domain literal & port */ 504 const char *ipremoteport; /* client IP domain literal & port */ 505 506 unsigned servicelen; /* length of service */ 507 unsigned applen; /* length of appname */ 508 unsigned slen; /* length of serverFQDN */ 509 unsigned urlen; /* length of user_realm */ 510 unsigned iploclen; /* length of iplocalport */ 511 unsigned ipremlen; /* length of ipremoteport */ 512 513 /* This indicates the level of logging desired. See SASL_LOG_* 514 * in sasl.h 515 * 516 * Plug-ins can ignore this and just pass their desired level to 517 * the log callback. This is primarily used to eliminate logging which 518 * might be a performance problem (e.g., full protocol trace) and 519 * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives 520 */ 521 int log_level; 522 523 const sasl_utils_t *utils; /* SASL API utility routines -- 524 * for a particular sasl_conn_t, 525 * MUST remain valid until mech_free is 526 * called */ 527 const sasl_callback_t *callbacks; /* Callbacks from application */ 528 529 /* application's security requirements */ 530 sasl_security_properties_t props; 531 sasl_ssf_t external_ssf; /* external SSF active */ 532 533 /* Pointer to the function which takes the plaintext passphrase and 534 * transitions a user to non-plaintext mechanisms via setpass calls. 535 * (NULL = auto transition not enabled/supported) 536 * 537 * If passlen is 0, it defaults to strlen(pass). 538 * returns 0 if no entry added, 1 if entry added 539 */ 540 int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen); 541 542 /* Canonicalize a user name from on-wire to internal format 543 * added cjn 1999-09-21 544 * Must be called once user name acquired if canon_user is non-NULL. 545 * conn connection context 546 * user user name from wire protocol (need not be NUL terminated) 547 * ulen length of user name from wire protocol (0 = strlen(user)) 548 * flags for SASL_CU_* flags 549 * oparams the user, authid, ulen, alen, fields are 550 * set appropriately after canonicalization/copying and 551 * authorization of arguments 552 * 553 * responsible for setting user, ulen, authid, and alen in the oparams 554 * structure 555 * 556 * default behavior is to strip leading and trailing whitespace, as 557 * well as allocating space for and copying the parameters. 558 * 559 * results: 560 * SASL_OK -- success 561 * SASL_NOMEM -- out of memory 562 * SASL_BADPARAM -- invalid conn 563 * SASL_BADPROT -- invalid user/authid 564 */ 565 int (*canon_user)(sasl_conn_t *conn, 566 const char *user, unsigned ulen, 567 unsigned flags, 568 sasl_out_params_t *oparams); 569 570 /* auxiliary property context (see definitions in prop.h) 571 * added cjn 2000-01-30 572 * 573 * NOTE: these properties are the ones associated with the 574 * canonicalized "user" (user to login as / authorization id), not 575 * the "authid" (user whose credentials are used / authentication id) 576 * Prefix the property name with a "*" if a property associated with 577 * the "authid" is interesting. 578 */ 579 struct propctx *propctx; 580 581 /* for additions which don't require a version upgrade; set to 0 */ 582 const void *gss_creds; /* GSS credential handle */ 583 const sasl_channel_binding_t *cbinding; /* server channel binding */ 584 const sasl_http_request_t *http_request;/* HTTP Digest request method */ 585 void *spare_ptr4; 586 int (*spare_fptr1)(void); 587 int (*spare_fptr2)(void); 588 int spare_int1; 589 int spare_int2; 590 int spare_int3; 591 592 /* flags field as passed to sasl_server_new */ 593 unsigned flags; 594 595 /* set to 0 initially, this allows a plugin with extended parameters 596 * to work with an older framework by updating version as parameters 597 * are added. 598 */ 599 int param_version; 600 } sasl_server_params_t; 601 602 /* logging levels (more levels may be added later, if necessary): 603 */ 604 #define SASL_LOG_NONE 0 /* don't log anything */ 605 #define SASL_LOG_ERR 1 /* log unusual errors (default) */ 606 #define SASL_LOG_FAIL 2 /* log all authentication failures */ 607 #define SASL_LOG_WARN 3 /* log non-fatal warnings */ 608 #define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ 609 #define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ 610 #define SASL_LOG_TRACE 6 /* traces of internal protocols */ 611 #define SASL_LOG_PASS 7 /* traces of internal protocols, including 612 * passwords */ 613 614 /* additional flags for setpass() function below: 615 */ 616 /* SASL_SET_CREATE create user if pass non-NULL */ 617 /* SASL_SET_DISABLE disable user */ 618 #define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ 619 620 /* features for server plug-in 621 */ 622 #define SASL_FEAT_SERVICE 0x0200 /* service-specific passwords supported */ 623 #define SASL_FEAT_GETSECRET 0x0400 /* sasl_server_{get,put}secret_t callbacks 624 * required by plug-in */ 625 626 /* a C object for a server mechanism 627 */ 628 typedef struct sasl_server_plug { 629 /* mechanism name */ 630 const char *mech_name; 631 632 /* best mech additional security layer strength factor */ 633 sasl_ssf_t max_ssf; 634 635 /* best security flags, as defined in sasl_security_properties_t */ 636 unsigned security_flags; 637 638 /* features of plugin */ 639 unsigned features; 640 641 /* global state for mechanism */ 642 void *glob_context; 643 644 /* create a new mechanism handler 645 * glob_context -- global context 646 * sparams -- server config params 647 * challenge -- server challenge from previous instance or NULL 648 * challen -- length of challenge from previous instance or 0 649 * out: 650 * conn_context -- connection context 651 * errinfo -- error information 652 * 653 * returns: 654 * SASL_OK -- successfully created mech instance 655 * SASL_* -- any other server error code 656 */ 657 int (*mech_new)(void *glob_context, 658 sasl_server_params_t *sparams, 659 const char *challenge, 660 unsigned challen, 661 void **conn_context); 662 663 /* perform one step in exchange 664 * 665 * returns: 666 * SASL_OK -- success, all done 667 * SASL_CONTINUE -- success, one more round trip 668 * SASL_* -- any other server error code 669 */ 670 int (*mech_step)(void *conn_context, 671 sasl_server_params_t *sparams, 672 const char *clientin, 673 unsigned clientinlen, 674 const char **serverout, 675 unsigned *serveroutlen, 676 sasl_out_params_t *oparams); 677 678 /* dispose of a connection state 679 */ 680 void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); 681 682 /* free global state for mechanism 683 * mech_dispose must be called on all mechanisms first 684 */ 685 void (*mech_free)(void *glob_context, const sasl_utils_t *utils); 686 687 /* set a password (optional) 688 * glob_context -- global context 689 * sparams -- service, middleware utilities, etc. props ignored 690 * user -- user name 691 * pass -- password/passphrase (NULL = disable/remove/delete) 692 * passlen -- length of password/passphrase 693 * oldpass -- old password/passphrase (NULL = transition) 694 * oldpasslen -- length of password/passphrase 695 * flags -- see above 696 * 697 * returns: 698 * SASL_NOCHANGE -- no change was needed 699 * SASL_NOUSER -- no entry for user 700 * SASL_NOVERIFY -- no mechanism compatible entry for user 701 * SASL_PWLOCK -- password locked 702 * SASL_DIABLED -- account disabled 703 * etc. 704 */ 705 int (*setpass)(void *glob_context, 706 sasl_server_params_t *sparams, 707 const char *user, 708 const char *pass, unsigned passlen, 709 const char *oldpass, unsigned oldpasslen, 710 unsigned flags); 711 712 /* query which mechanisms are available for user 713 * glob_context -- context 714 * sparams -- service, middleware utilities, etc. props ignored 715 * user -- NUL terminated user name 716 * maxmech -- max number of strings in mechlist (0 = no output) 717 * output: 718 * mechlist -- an array of C string pointers, filled in with 719 * mechanism names available to the user 720 * 721 * returns: 722 * SASL_OK -- success 723 * SASL_NOMEM -- not enough memory 724 * SASL_FAIL -- lower level failure 725 * SASL_DISABLED -- account disabled 726 * SASL_NOUSER -- user not found 727 * SASL_BUFOVER -- maxmech is too small 728 * SASL_NOVERIFY -- user found, but no mechanisms available 729 */ 730 int (*user_query)(void *glob_context, 731 sasl_server_params_t *sparams, 732 const char *user, 733 int maxmech, 734 const char **mechlist); 735 736 /* perform precalculations during a network round-trip 737 * or idle period. conn_context may be NULL (optional) 738 * returns 1 if action taken, 0 if no action taken 739 */ 740 int (*idle)(void *glob_context, 741 void *conn_context, 742 sasl_server_params_t *sparams); 743 744 /* check if mechanism is available 745 * optional--if NULL, mechanism is available based on ENABLE= in config 746 * 747 * If this routine sets conn_context to a non-NULL value, then the call 748 * to mech_new will be skipped. This should not be done unless 749 * there's a significant performance benefit, since it can cause 750 * additional memory allocation in SASL core code to keep track of 751 * contexts potentially for multiple mechanisms. 752 * 753 * This is called by the first call to sasl_listmech() for a 754 * given connection context, thus for a given protocol it may 755 * never be called. Note that if mech_avail returns SASL_NOMECH, 756 * then that mechanism is considered disabled for the remainder 757 * of the session. If mech_avail returns SASL_NOTDONE, then a 758 * future call to mech_avail may still return either SASL_OK 759 * or SASL_NOMECH. 760 * 761 * returns SASL_OK on success, 762 * SASL_NOTDONE if mech is not available now, but may be later 763 * (e.g. EXTERNAL w/o auth_id) 764 * SASL_NOMECH if mech disabled 765 */ 766 int (*mech_avail)(void *glob_context, 767 sasl_server_params_t *sparams, 768 void **conn_context); 769 770 /* for additions which don't require a version upgrade; set to 0 */ 771 int (*spare_fptr2)(void); 772 } sasl_server_plug_t; 773 774 #define SASL_SERVER_PLUG_VERSION 4 775 776 /* plug-in entry point: 777 * utils -- utility callback functions 778 * plugname -- name of plug-in (may be NULL) 779 * max_version -- highest server plug version supported 780 * returns: 781 * out_version -- server plug-in version of result 782 * pluglist -- list of mechanism plug-ins 783 * plugcount -- number of mechanism plug-ins 784 * results: 785 * SASL_OK -- success 786 * SASL_NOMEM -- failure 787 * SASL_BADVERS -- max_version too small 788 * SASL_BADPARAM -- bad config string 789 * ... 790 */ 791 typedef int sasl_server_plug_init_t(const sasl_utils_t *utils, 792 int max_version, 793 int *out_version, 794 sasl_server_plug_t **pluglist, 795 int *plugcount); 796 797 /* 798 * add a server plug-in 799 */ 800 LIBSASL_API int sasl_server_add_plugin(const char *plugname, 801 sasl_server_plug_init_t *splugfunc); 802 803 804 typedef struct server_sasl_mechanism 805 { 806 int version; 807 int condition; /* set to SASL_NOUSER if no available users; 808 set to SASL_CONTINUE if delayed plugin loading */ 809 char *plugname; /* for AUTHSOURCE tracking */ 810 const sasl_server_plug_t *plug; 811 char *f; /* where should i load the mechanism from? */ 812 } server_sasl_mechanism_t; 813 814 typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m, 815 sasl_info_callback_stage_t stage, 816 void *rock); 817 818 819 /* Dump information about available server plugins (separate functions are 820 used for canon and auxprop plugins) */ 821 LIBSASL_API int sasl_server_plugin_info (const char *mech_list, 822 sasl_server_info_callback_t *info_cb, 823 void *info_cb_rock); 824 825 826 /********************************************************* 827 * user canonicalization plug-in -- added cjn 1999-09-29 * 828 *********************************************************/ 829 830 typedef struct sasl_canonuser { 831 /* optional features of plugin (set to 0) */ 832 int features; 833 834 /* spare integer (set to 0) */ 835 int spare_int1; 836 837 /* global state for plugin */ 838 void *glob_context; 839 840 /* name of plugin */ 841 char *name; 842 843 /* free global state for plugin */ 844 void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils); 845 846 /* canonicalize a username 847 * glob_context -- global context from this structure 848 * sparams -- server params, note user_realm&propctx elements 849 * user -- user to login as (may not be NUL terminated) 850 * len -- length of user name (0 = strlen(user)) 851 * flags -- for SASL_CU_* flags 852 * out -- buffer to copy user name 853 * out_max -- max length of user name 854 * out_len -- set to length of user name 855 * 856 * note that the output buffers MAY be the same as the input buffers. 857 * 858 * returns 859 * SASL_OK on success 860 * SASL_BADPROT username contains invalid character 861 */ 862 int (*canon_user_server)(void *glob_context, 863 sasl_server_params_t *sparams, 864 const char *user, unsigned len, 865 unsigned flags, 866 char *out, 867 unsigned out_umax, unsigned *out_ulen); 868 869 int (*canon_user_client)(void *glob_context, 870 sasl_client_params_t *cparams, 871 const char *user, unsigned len, 872 unsigned flags, 873 char *out, 874 unsigned out_max, unsigned *out_len); 875 876 /* for additions which don't require a version upgrade; set to 0 */ 877 int (*spare_fptr1)(void); 878 int (*spare_fptr2)(void); 879 int (*spare_fptr3)(void); 880 } sasl_canonuser_plug_t; 881 882 #define SASL_CANONUSER_PLUG_VERSION 5 883 884 /* default name for canonuser plug-in entry point is "sasl_canonuser_init" 885 * similar to sasl_server_plug_init model, except only returns one 886 * sasl_canonuser_plug_t structure; 887 */ 888 typedef int sasl_canonuser_init_t(const sasl_utils_t *utils, 889 int max_version, 890 int *out_version, 891 sasl_canonuser_plug_t **plug, 892 const char *plugname); 893 894 /* add a canonuser plugin 895 */ 896 LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname, 897 sasl_canonuser_init_t *canonuserfunc); 898 899 /****************************************************** 900 * auxiliary property plug-in -- added cjn 1999-09-29 * 901 ******************************************************/ 902 903 typedef struct sasl_auxprop_plug { 904 /* optional features of plugin (none defined yet, set to 0) */ 905 int features; 906 907 /* spare integer, must be set to 0 */ 908 int spare_int1; 909 910 /* global state for plugin */ 911 void *glob_context; 912 913 /* free global state for plugin (OPTIONAL) */ 914 void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils); 915 916 /* fill in fields of an auxiliary property context 917 * last element in array has id of SASL_AUX_END 918 * elements with non-0 len should be ignored. 919 */ 920 int (*auxprop_lookup)(void *glob_context, 921 sasl_server_params_t *sparams, 922 unsigned flags, 923 const char *user, unsigned ulen); 924 925 /* name of the auxprop plugin */ 926 char *name; 927 928 /* store the fields/values of an auxiliary property context (OPTIONAL) 929 * 930 * if ctx is NULL, just check if storing properties is enabled 931 * 932 * returns 933 * SASL_OK on success 934 * SASL_FAIL on failure 935 */ 936 int (*auxprop_store)(void *glob_context, 937 sasl_server_params_t *sparams, 938 struct propctx *ctx, 939 const char *user, unsigned ulen); 940 } sasl_auxprop_plug_t; 941 942 /* auxprop lookup flags */ 943 #define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties 944 * with non-zero len field. If set, 945 * override value of those properties */ 946 #define SASL_AUXPROP_AUTHZID 0x02 /* if clear, we are looking up the 947 * authid flags (prefixed with *), otherwise 948 * we are looking up the authzid flags 949 * (no prefix) */ 950 951 /* NOTE: Keep in sync with SASL_CU_<XXX> flags */ 952 #define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10 953 954 955 #define SASL_AUXPROP_PLUG_VERSION 8 956 957 /* default name for auxprop plug-in entry point is "sasl_auxprop_init" 958 * similar to sasl_server_plug_init model, except only returns one 959 * sasl_auxprop_plug_t structure; 960 */ 961 typedef int sasl_auxprop_init_t(const sasl_utils_t *utils, 962 int max_version, 963 int *out_version, 964 sasl_auxprop_plug_t **plug, 965 const char *plugname); 966 967 /* add an auxiliary property plug-in 968 */ 969 LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname, 970 sasl_auxprop_init_t *auxpropfunc); 971 972 typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m, 973 sasl_info_callback_stage_t stage, 974 void *rock); 975 976 /* Dump information about available auxprop plugins (separate functions are 977 used for canon and server authentication plugins) */ 978 LIBSASL_API int auxprop_plugin_info (const char *mech_list, 979 auxprop_info_callback_t *info_cb, 980 void *info_cb_rock); 981 982 #ifdef __cplusplus 983 } 984 #endif 985 986 #endif /* SASLPLUG_H */ 987