Exemple #1
0
krb5_error_code
k5_pwqual_load(krb5_context context, const char *dict_file,
               pwqual_handle **handles_out)
{
    krb5_error_code ret;
    krb5_plugin_initvt_fn *modules = NULL, *mod;
    size_t count;
    pwqual_handle *list = NULL, handle = NULL;

    *handles_out = NULL;

    ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_PWQUAL, &modules);
    if (ret != 0)
        goto cleanup;

    /* Allocate a large enough list of handles. */
    for (count = 0; modules[count] != NULL; count++);
    list = k5alloc((count + 1) * sizeof(*list), &ret);
    if (list == NULL)
        goto cleanup;

    /* For each module, allocate a handle, initialize its vtable, and bind the
     * dictionary filename. */
    count = 0;
    for (mod = modules; *mod != NULL; mod++) {
        handle = k5alloc(sizeof(*handle), &ret);
        if (handle == NULL)
            goto cleanup;
        ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt);
        if (ret != 0) {         /* Failed vtable init is non-fatal. */
            free(handle);
            handle = NULL;
            continue;
        }
        handle->data = NULL;
        if (handle->vt.open != NULL) {
            ret = handle->vt.open(context, dict_file, &handle->data);
            if (ret != 0)       /* Failed dictionary binding is fatal. */
                goto cleanup;
        }
        list[count++] = handle;
        list[count] = NULL;
        handle = NULL;
    }
    list[count] = NULL;

    ret = 0;
    *handles_out = list;
    list = NULL;

cleanup:
    free(handle);
    k5_plugin_free_modules(context, modules);
    k5_pwqual_free_handles(context, list);
    return ret;
}
krb5_error_code
k5_kadm5_hook_load(krb5_context context,
                   kadm5_hook_handle **handles_out)
{
    krb5_error_code ret;
    krb5_plugin_initvt_fn *modules = NULL, *mod;
    size_t count;
    kadm5_hook_handle *list = NULL, handle = NULL;

    *handles_out = NULL;

    ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KADM5_HOOK, &modules);
    if (ret != 0)
        goto cleanup;

    /* Allocate a large enough list of handles. */
    for (count = 0; modules[count] != NULL; count++);
    list = k5alloc((count + 1) * sizeof(*list), &ret);
    if (list == NULL)
        goto cleanup;

    /* For each module, allocate a handle, initialize its vtable, and
     * initialize the module. */
    count = 0;
    for (mod = modules; *mod != NULL; mod++) {
        handle = k5alloc(sizeof(*handle), &ret);
        if (handle == NULL)
            goto cleanup;
        ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt);
        if (ret != 0) {         /* Failed vtable init is non-fatal. */
            free(handle);
            handle = NULL;
            continue;
        }
        handle->data = NULL;
        if (handle->vt.init != NULL) {
            ret = handle->vt.init(context, &handle->data);
            if (ret != 0)       /* Failed initialization is fatal. */
                goto cleanup;
        }
        list[count++] = handle;
        list[count] = NULL;
        handle = NULL;
    }
    list[count] = NULL;

    ret = 0;
    *handles_out = list;
    list = NULL;

cleanup:
    free(handle);
    k5_plugin_free_modules(context, modules);
    k5_kadm5_hook_free_handles(context, list);
    return ret;
}
Exemple #3
0
/* Initialize context->hostrealm_handles with a list of module handles. */
static krb5_error_code
load_hostrealm_modules(krb5_context context)
{
    krb5_error_code ret;
    struct hostrealm_module_handle **list = NULL, *handle;
    krb5_plugin_initvt_fn *modules = NULL, *mod;
    size_t count;

    ret = get_modules(context, &modules);
    if (ret != 0)
        goto cleanup;

    /* Allocate a large enough list of handles. */
    for (count = 0; modules[count] != NULL; count++);
    list = k5alloc((count + 1) * sizeof(*list), &ret);
    if (list == NULL)
        goto cleanup;

    /* Initialize each module, ignoring ones that fail. */
    count = 0;
    for (mod = modules; *mod != NULL; mod++) {
        handle = k5alloc(sizeof(*handle), &ret);
        if (handle == NULL)
            goto cleanup;
        ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt);
        if (ret != 0) {
            TRACE_HOSTREALM_VTINIT_FAIL(context, ret);
            free(handle);
            continue;
        }

        handle->data = NULL;
        if (handle->vt.init != NULL) {
            ret = handle->vt.init(context, &handle->data);
            if (ret != 0) {
                TRACE_HOSTREALM_INIT_FAIL(context, handle->vt.name, ret);
                free(handle);
                continue;
            }
        }
        list[count++] = handle;
        list[count] = NULL;
    }
    list[count] = NULL;

    ret = 0;
    context->hostrealm_handles = list;
    list = NULL;

cleanup:
    k5_plugin_free_modules(context, modules);
    free_handles(context, list);
    return ret;
}
Exemple #4
0
int
main(int argc, char **argv)
{
    krb5_context ctx, ctx2;
    krb5_plugin_initvt_fn *mods;
    const krb5_enctype etypes1[] = { ENCTYPE_DES3_CBC_SHA1, 0 };
    const krb5_enctype etypes2[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
                                     ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 };
    krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD };

    /* Copy a default context and verify the result. */
    check(krb5_init_context(&ctx) == 0);
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    /* Set non-default values for all of the propagated fields in ctx. */
    ctx->allow_weak_crypto = TRUE;
    check(krb5_set_default_in_tkt_ktypes(ctx, etypes1) == 0);
    check(krb5_set_default_tgs_enctypes(ctx, etypes2) == 0);
    check(krb5_set_debugging_time(ctx, 1234, 5678) == 0);
    check(krb5_cc_set_default_name(ctx, "defccname") == 0);
    check(krb5_set_default_realm(ctx, "defrealm") == 0);
    ctx->clockskew = 18;
    ctx->kdc_req_sumtype = CKSUMTYPE_NIST_SHA;
    ctx->default_ap_req_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
    ctx->default_safe_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES256;
    ctx->kdc_default_options = KDC_OPT_FORWARDABLE;
    ctx->library_options = 0;
    ctx->profile_secure = TRUE;
    ctx->udp_pref_limit = 2345;
    ctx->use_conf_ktypes = TRUE;
    ctx->ignore_acceptor_hostname = TRUE;
    ctx->dns_canonicalize_hostname = CANONHOST_FALSE;
    free(ctx->plugin_base_dir);
    check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL);

    /* Also set some of the non-propagated fields. */
    ctx->prompt_types = ptypes;
    check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &mods) == 0);
    k5_plugin_free_modules(ctx, mods);
    k5_setmsg(ctx, ENOMEM, "nooooooooo");
    krb5_set_trace_callback(ctx, trace, ctx);

    /* Copy the intentionally messy context and verify the result. */
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    krb5_free_context(ctx);
    return 0;
}
Exemple #5
0
/* Create the per-krb5_context context. This means loading the modules
 * if we haven't done that yet (applications which never obtain initial
 * credentials should never hit this routine), breaking up the module's
 * list of support pa_types so that we can iterate over the modules more
 * easily, and copying over the relevant parts of the module's table. */
void KRB5_CALLCONV
krb5_init_preauth_context(krb5_context kcontext)
{
    int n_tables, n_modules, i, count;
    krb5_plugin_initvt_fn *plugins = NULL, *pl;
    struct krb5_clpreauth_vtable_st *vtables = NULL, *vt;
    struct krb5_preauth_context_module_st *mod;
    krb5_preauth_context *context = NULL;
    krb5_clpreauth_moddata moddata;
    krb5_preauthtype pa_type, *pat;
    krb5_boolean first;
    krb5_clpreauth_modreq *rcpp;

    /* Only do this once for each krb5_context */
    if (kcontext->preauth_context != NULL)
        return;

    /* Auto-register built-in modules. */
    k5_plugin_register_dyn(kcontext, PLUGIN_INTERFACE_CLPREAUTH, "pkinit",
                           "preauth");
    k5_plugin_register(kcontext, PLUGIN_INTERFACE_CLPREAUTH,
                       "encrypted_challenge",
                       clpreauth_encrypted_challenge_initvt);
    k5_plugin_register(kcontext, PLUGIN_INTERFACE_CLPREAUTH,
                       "encrypted_timestamp",
                       clpreauth_encrypted_timestamp_initvt);
    k5_plugin_register(kcontext, PLUGIN_INTERFACE_CLPREAUTH, "sam2",
                       clpreauth_sam2_initvt);
    k5_plugin_register(kcontext, PLUGIN_INTERFACE_CLPREAUTH, "otp",
                       clpreauth_otp_initvt);

    /* Get all available clpreauth vtables. */
    if (k5_plugin_load_all(kcontext, PLUGIN_INTERFACE_CLPREAUTH, &plugins))
        return;
    for (count = 0; plugins[count] != NULL; count++);
    vtables = calloc(count, sizeof(*vtables));
    if (vtables == NULL)
        goto cleanup;
    for (pl = plugins, n_tables = 0; *pl != NULL; pl++) {
        if ((*pl)(kcontext, 1, 2, (krb5_plugin_vtable)&vtables[n_tables]) == 0)
            n_tables++;
    }

    /* Count how many modules we ended up loading, and how many preauth
     * types we may claim to support as a result. */
    n_modules = 0;
    for (i = 0; i < n_tables; i++) {
        for (count = 0; vtables[i].pa_type_list[count] > 0; count++);
        n_modules += count;
    }

    /* Allocate the space we need. */
    context = malloc(sizeof(*context));
    if (context == NULL)
        goto cleanup;
    context->modules = calloc(n_modules, sizeof(*context->modules));
    if (context->modules == NULL)
        goto cleanup;

    /* fill in the structure */
    n_modules = 0;
    for (i = 0; i < n_tables; i++) {
        vt = &vtables[i];
        if ((vt->pa_type_list != NULL) && (vt->process != NULL)) {
            moddata = NULL;
            if (vt->init != NULL && vt->init(kcontext, &moddata) != 0) {
#ifdef DEBUG
                fprintf(stderr, "init err, skipping module \"%s\"\n",
                        vt->name);
#endif
                continue;
            }

            rcpp = NULL;
            for (pat = vt->pa_type_list, first = TRUE; *pat > 0;
                 pat++, first = FALSE) {
                pa_type = *pat;
                mod = &context->modules[n_modules];
                mod->pa_type = pa_type;
                mod->enctypes = vt->enctype_list;
                mod->moddata = moddata;
                /* Only call client_fini once per plugin */
                if (first)
                    mod->client_fini = vt->fini;
                else
                    mod->client_fini = NULL;
                mod->name = vt->name;
                mod->flags = (*vt->flags)(kcontext, pa_type);
                mod->use_count = 0;
                mod->client_prep_questions = vt->prep_questions;
                mod->client_process = vt->process;
                mod->client_tryagain = vt->tryagain;
                mod->client_supply_gic_opts = first ? vt->gic_opts : NULL;
                mod->modreq = NULL;
                /*
                 * Only call request_init and request_fini once per plugin.
                 * Only the first module within each plugin will ever
                 * have request_context filled in.  Every module within
                 * the plugin will have its request_context_pp pointing
                 * to that entry's request_context.  That way all the
                 * modules within the plugin share the same request_context
                 */
                if (first) {
                    mod->client_req_init = vt->request_init;
                    mod->client_req_fini = vt->request_fini;
                    rcpp = &mod->modreq;
                } else {
                    mod->client_req_init = NULL;
                    mod->client_req_fini = NULL;
                }
                mod->modreq_p = rcpp;
#ifdef DEBUG
                fprintf(stderr, "init module \"%s\", pa_type %d, flag %d\n",
                        mod->name, mod->pa_type, mod->flags);
#endif
                n_modules++;
            }
        }
    }
    context->n_modules = n_modules;

    /* Place the constructed preauth context into the krb5 context. */
    kcontext->preauth_context = context;
    context = NULL;

cleanup:
    if (context)
        free(context->modules);
    free(context);
    k5_plugin_free_modules(kcontext, plugins);
    free(vtables);
}