/** * gsasl_callback: * @ctx: handle received from gsasl_init(), may be NULL to derive it * from @sctx. * @sctx: session handle. * @prop: enumerated value of Gsasl_property type. * * Invoke the application callback. The @prop value indicate what the * callback is expected to do. For example, for * GSASL_ANONYMOUS_TOKEN, the function is expected to invoke * gsasl_property_set(SCTX, GSASL_ANONYMOUS_TOKEN, "token") where * "token" is the anonymous token the application wishes the SASL * mechanism to use. See the manual for the meaning of all * parameters. * * Note that if no callback has been set by the application, but the * obsolete callback interface has been used, this function will * translate the old callback interface into the new. This interface * should be sufficient to invoke all callbacks, both new and old. * * Return value: Returns whatever the application callback return, or * GSASL_NO_CALLBACK if no application was known. * * Since: 0.2.0 **/ int gsasl_callback (Gsasl * ctx, Gsasl_session * sctx, Gsasl_property prop) { if (ctx == NULL && sctx == NULL) return GSASL_NO_CALLBACK; if (ctx == NULL) ctx = sctx->ctx; if (ctx->cb) return ctx->cb (ctx, sctx, prop); #ifndef GSASL_NO_OBSOLETE { /* Call obsolete callbacks. Remove this when the obsolete * callbacks are no longer supported. */ Gsasl_server_callback_anonymous cb_anonymous; Gsasl_server_callback_external cb_external; Gsasl_server_callback_securid cb_securid; Gsasl_server_callback_gssapi cb_gssapi; Gsasl_server_callback_validate cb_validate; Gsasl_server_callback_retrieve cb_retrieve; char buf[BUFSIZ]; size_t buflen = BUFSIZ - 1; int res; switch (prop) { case GSASL_VALIDATE_ANONYMOUS: if (!sctx->anonymous_token) break; cb_anonymous = gsasl_server_callback_anonymous_get (sctx->ctx); if (!cb_anonymous) break; res = cb_anonymous (sctx, sctx->anonymous_token); return res; break; case GSASL_VALIDATE_EXTERNAL: cb_external = gsasl_server_callback_external_get (sctx->ctx); if (!cb_external) break; res = cb_external (sctx); return res; break; case GSASL_VALIDATE_SECURID: cb_securid = gsasl_server_callback_securid_get (sctx->ctx); if (!cb_securid) break; res = cb_securid (sctx, sctx->authid, sctx->authzid, sctx->passcode, sctx->pin, buf, &buflen); if (buflen > 0 && buflen < BUFSIZ - 1) { buf[buflen] = '\0'; gsasl_property_set (sctx, GSASL_SUGGESTED_PIN, buf); } return res; break; case GSASL_VALIDATE_GSSAPI: cb_gssapi = gsasl_server_callback_gssapi_get (sctx->ctx); if (!cb_gssapi) break; res = cb_gssapi (sctx, sctx->gssapi_display_name, sctx->authzid); return res; break; case GSASL_VALIDATE_SIMPLE: cb_validate = gsasl_server_callback_validate_get (sctx->ctx); if (!cb_validate) break; res = cb_validate (sctx, sctx->authzid, sctx->authid, sctx->password); return res; break; case GSASL_PASSWORD: cb_retrieve = gsasl_server_callback_retrieve_get (sctx->ctx); if (!cb_retrieve) break; res = cb_retrieve (sctx, sctx->authid, sctx->authzid, sctx->hostname, &buf, &buflen); if (res == GSASL_OK) gsasl_property_set_raw (sctx, GSASL_PASSWORD, buf, buflen); /* FIXME else if (res == GSASL_TOO_SMALL_BUFFER)... */ return res; break; default: break; } } #endif return GSASL_NO_CALLBACK; }
static int callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop) { int rc = GSASL_OK; struct sasl_data *pdata; const char *user; char *string; switch (prop) { case GSASL_PASSWORD: pdata = gsasl_callback_hook_get(ctx); user = pdata->username; if (!user) { user = gsasl_property_get(sctx, GSASL_AUTHID); if (!user) { dico_log(L_ERR, 0, _("user name not supplied")); return GSASL_NO_AUTHID; } pdata->username = user; } if (dico_udb_get_password(user_db, user, &string)) { dico_log(L_ERR, 0, _("failed to get password for `%s' from the database"), user); return GSASL_NO_PASSWORD; } gsasl_property_set(sctx, prop, string); free(string); break; case GSASL_SERVICE: gsasl_property_set(sctx, prop, sasl_service); break; case GSASL_REALM: gsasl_property_set(sctx, prop, sasl_realm ? sasl_realm : hostname); break; case GSASL_HOSTNAME: gsasl_property_set(sctx, prop, hostname); break; case GSASL_VALIDATE_SIMPLE: rc = cb_validate(ctx, sctx); break; #if 0 FIXME: case GSASL_VALIDATE_EXTERNAL: case GSASL_VALIDATE_SECURID: #endif case GSASL_VALIDATE_ANONYMOUS: pdata = gsasl_callback_hook_get(ctx); user = gsasl_property_get(sctx, GSASL_ANONYMOUS_TOKEN); pdata->username = user; pdata->anon = 1; break; case GSASL_VALIDATE_GSSAPI: pdata = gsasl_callback_hook_get(ctx); user = gsasl_property_get(sctx, GSASL_AUTHZID); pdata->username = user; break; default: rc = GSASL_NO_CALLBACK; /*dico_log(L_NOTICE, 0, _("Unsupported callback property %d"), prop);*/ break; } return rc; }