예제 #1
0
/*! \internal
  \brief Initialize a plugin

  \note If kmmint_init_plugin() is called on a plugin, then kmmint_exit_plugin()
      \b must be called for the plugin.

  \note Should only be called from the context of the registrar thread */
void kmmint_init_plugin(kmm_plugin_i * p) {
    DWORD dummy;
    khm_handle csp_plugin   = NULL;
    khm_handle csp_plugins  = NULL;
    khm_int32 t;

    /* the following will be undone in kmmint_exit_plugin() */
    kmm_hold_plugin(kmm_handle_from_plugin(p));

    EnterCriticalSection(&cs_kmm);
    if(p->state != KMM_PLUGIN_STATE_REG &&
        p->state != KMM_PLUGIN_STATE_HOLD)
    {
        LeaveCriticalSection(&cs_kmm);
        goto _exit;
    }

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_IP_TASK_DESC, _cstr(p->p.name));
    _describe();

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        /* if this plugin was held, then we already had a hold
           from the initial attempt to start the plugin.  Undo
           the hold we did a few lines earlier. */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        /* same for the plugin count for the module. */
#ifdef DEBUG
        assert(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT);
#endif
        p->module->plugin_count--;
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;
    }

    p->state = KMM_PLUGIN_STATE_PREINIT;

    kmmint_delist_plugin(p);
    kmmint_list_plugin(p);

    LeaveCriticalSection(&cs_kmm);

    if(KHM_FAILED(kmm_get_plugins_config(0, &csp_plugins))) {
        _report_mr0(KHERR_ERROR, MSG_IP_GET_CONFIG);

        p->state = KMM_PLUGIN_STATE_FAIL_UNKNOWN;
        goto _exit;
    }

    if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
        if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
        
        if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
    }

    if (KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"Disabled", &t)) && t) {
        p->flags |= KMM_PLUGIN_FLAG_DISABLED;
        p->state = KMM_PLUGIN_STATE_FAIL_DISABLED;
        goto _exit;
    }

#if 0
    /*TODO: check the failure count and act accordingly */
    if(KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"FailureCount", &t)) && (t > 0)) {
    }
#endif

    EnterCriticalSection(&cs_kmm);

    p->n_depends = 0;
    p->n_unresolved = 0;
    
    do {
        wchar_t * deps = NULL;
        wchar_t * d;
        khm_size sz = 0;

        if(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                 NULL, &sz) != KHM_ERROR_TOO_LONG)
            break;

        deps = PMALLOC(sz);
        if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                            deps, &sz))) {
            if(deps)
                PFREE(deps);
            break;
        }

        for(d = deps; d && *d; d = multi_string_next(d)) {
            kmm_plugin_i * pd;
            int i;

            pd = kmmint_get_plugin_i(d);

            if(pd->state == KMM_PLUGIN_STATE_NONE) {
                /* the dependant was not previously known */
                pd->state = KMM_PLUGIN_STATE_PLACEHOLDER;
            }

            for(i=0; i < pd->n_dependants; i++) {
                if(pd->dependants[i] == p)
                    break;
            }

            if(i >= pd->n_dependants) {
                if( pd->n_dependants >= KMM_MAX_DEPENDANTS ) {
                    /*TODO: handle this gracefully */
                    RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL);
                }

                /* released in kmmint_free_plugin() */
                kmm_hold_plugin(kmm_handle_from_plugin(p));
                pd->dependants[pd->n_dependants] = p;
                pd->n_dependants++;
            }

            p->n_depends++;

            if(pd->state != KMM_PLUGIN_STATE_RUNNING) {
                p->n_unresolved++;
            }
        }

        if(p->n_unresolved > 0) {
            p->state = KMM_PLUGIN_STATE_HOLD;
        }

        PFREE(deps);

    } while(FALSE);

#ifdef DEBUG
    assert(!(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT));
#endif
    p->flags |= KMM_PLUGIN_FLAG_IN_MODCOUNT;
    p->module->plugin_count++;

    LeaveCriticalSection(&cs_kmm);

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        _report_mr1(KHERR_INFO, MSG_IP_HOLD, _dupstr(p->p.name));

        goto _exit_post;
    }

    kmmint_add_to_plugin_queue(p);

    p->ht_thread = CreateThread(NULL,
                                0,
                                kmmint_plugin_broker,
                                (LPVOID) p,
                                CREATE_SUSPENDED,
                                &dummy);

    p->state = KMM_PLUGIN_STATE_INIT;

    ResumeThread(p->ht_thread);

_exit_post:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);

    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_INFO, MSG_IP_STATE, 
                _dupstr(p->p.name), _int32(p->state));

    _end_task();
    
    return;

    /* jump here if an error condition happens before the plugin
       broker thread starts and the plugin should be unloaded */

_exit:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);
    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_WARNING, MSG_IP_EXITING, 
                _dupstr(p->p.name), _int32(p->state));
    _end_task();


#ifdef ASYNC_PLUGIN_UNLOAD_ON_FAILURE

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p);

#else

    kmmint_exit_plugin(p);

#endif
}
예제 #2
0
/*! \internal
  \brief Initialize a module

  \a m is not in the linked list yet.

  \note Should only be called from the context of the registrar thread. */
void kmmint_init_module(kmm_module_i * m) {
    HMODULE hm;
    init_module_t p_init_module;
    kmm_plugin_i * pi;
    khm_int32 rv;
    khm_handle csp_mod = NULL;
    khm_handle csp_mods = NULL;
    khm_size sz;
    khm_int32 i;

    /* error condition handling */
    BOOL exit_module = FALSE;
    BOOL release_module = TRUE;
    BOOL record_failure = FALSE;

    /* failure handling */
    khm_int32 max_fail_count = 0;
    khm_int64 fail_reset_time = 0;

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_INIT_MODULE, _cstr(m->name));
    _describe();

    kmm_hold_module(kmm_handle_from_module(m));

    if(KHM_FAILED(kmm_get_modules_config(0, &csp_mods))) {
        _report_mr0(KHERR_ERROR, MSG_IM_GET_CONFIG);
        _location(L"kmm_get_modules_config()");

        m->state = KMM_MODULE_STATE_FAIL_UNKNOWN;
        goto _exit;
    }

    khc_read_int32(csp_mods, L"ModuleMaxFailureCount", &max_fail_count);
    khc_read_int64(csp_mods, L"ModuleFailureCountResetTime", &fail_reset_time);

    /* If the module is not in the pre-init state, we can't
       initialize it. */
    if(m->state != KMM_MODULE_STATE_PREINIT) {
        _report_mr1(KHERR_INFO, MSG_IM_NOT_PREINIT, _int32(m->state));
        goto _exit;
    }

    if(KHM_FAILED(kmm_get_module_config(m->name, 0, &csp_mod))) {
        _report_mr0(KHERR_ERROR, MSG_IM_NOT_REGISTERED);

        m->state = KMM_MODULE_STATE_FAIL_NOT_REGISTERED;
        goto _exit;
    }

    if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"Disabled", &i)) && i) {
        _report_mr0(KHERR_INFO, MSG_IM_DISABLED);

        m->state = KMM_MODULE_STATE_FAIL_DISABLED;
        goto _exit;
    }

    if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"NoUnload", &i)) && i) {
        m->flags |= KMM_MODULE_FLAG_NOUNLOAD;
    }

    if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"FailureCount", &i))) {
        khm_int64 tm;
        khm_int64 ct;
        FILETIME fct;
        khm_int32 last_reason = 0;

        /* reset the failure count if the failure count reset time
           period has elapsed */
        tm = 0;
        khc_read_int64(csp_mod, L"FailureTime", &tm);
        GetSystemTimeAsFileTime(&fct);

        ct = (FtToInt(&fct) - tm) / 10000000i64;

        if(tm > 0 && 
           ct > fail_reset_time) {
            i = 0;
            khc_write_int32(csp_mod, L"FailureCount", 0);
            khc_write_int64(csp_mod, L"FailureTime", 0);
        }

        khc_read_int32(csp_mod, L"FailureReason", &last_reason);

        /* did we exceed the max failure count?  However, we ignore
           the max failure count if the reason why it didn't load the
           last time was because the module wasn't found. */
        if(i > max_fail_count && 
           last_reason != KMM_MODULE_STATE_FAIL_NOT_FOUND) {
            /* failed too many times */
            _report_mr0(KHERR_INFO, MSG_IM_MAX_FAIL);

            m->state = KMM_MODULE_STATE_FAIL_MAX_FAILURE;
            goto _exit;
        }
    }

    if(khc_read_string(csp_mod, L"ImagePath", NULL, &sz) == 
       KHM_ERROR_TOO_LONG) {
        if(m->path)
            PFREE(m->path);
        m->path = PMALLOC(sz);
        khc_read_string(csp_mod, L"ImagePath", m->path, &sz);
    } else {
        _report_mr0(KHERR_ERROR, MSG_IM_NOT_REGISTERED);

        m->state = KMM_MODULE_STATE_FAIL_NOT_REGISTERED;
        goto _exit;
    }

    rv = kmmint_read_module_info(m);

    if (KHM_FAILED(rv)) {
        if (rv == KHM_ERROR_INCOMPATIBLE) {
            _report_mr0(KHERR_ERROR, MSG_IM_INCOMPATIBLE);

            m->state = KMM_MODULE_STATE_FAIL_INCOMPAT;
        } else if (rv == KHM_ERROR_NOT_FOUND) {
            _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path));

            m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND;
        } else {
            _report_mr0(KHERR_ERROR, MSG_IM_INVALID_MODULE);

            m->state = KMM_MODULE_STATE_FAIL_INV_MODULE;
        }
        goto _exit;
    }

    /* check again */
    if(m->state != KMM_MODULE_STATE_PREINIT) {
        _report_mr0(KHERR_ERROR, MSG_IM_NOT_PREINIT);

        goto _exit;
    }

    /* from this point on, we must record any failure codes */
    record_failure = TRUE;

    hm = LoadLibrary(m->path);
    if(!hm) {
        m->h_module = NULL;
        m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND;

        _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path));

        goto _exit;
    }

    /* from this point on, we need to discard the module through
       exit_module */
    ResetEvent(evt_exit);

    kmm_active_modules++;

    release_module = FALSE;
    exit_module = TRUE;

    m->flags |= KMM_MODULE_FLAG_LOADED;
    m->h_module = hm;

    /* TODO: check signatures */

    p_init_module = (init_module_t) GetProcAddress(hm, EXP_INIT_MODULE);

    if(!p_init_module) {
        _report_mr1(KHERR_ERROR, MSG_IM_NO_ENTRY, _cstr(EXP_INIT_MODULE));

        m->state = KMM_MODULE_STATE_FAIL_INVALID;
        goto _exit;
    }

    m->state = KMM_MODULE_STATE_INIT;

    /* call init_module() */
    rv = (*p_init_module)(kmm_handle_from_module(m));

    m->flags |= KMM_MODULE_FLAG_INITP;

    if(KHM_FAILED(rv)) {
        _report_mr1(KHERR_ERROR, MSG_IM_INIT_FAIL, _int32(rv));

        m->state = KMM_MODULE_STATE_FAIL_LOAD;
        goto _exit;
    }

    if(!m->plugins) {
        _report_mr0(KHERR_ERROR, MSG_IM_NO_PLUGINS);

        m->state = KMM_MODULE_STATE_FAIL_NO_PLUGINS;
        record_failure = FALSE;
        goto _exit;
    }

    m->state = KMM_MODULE_STATE_INITPLUG;

    do {
        LPOP(&(m->plugins), &pi);
        if(pi) {
            pi->flags &= ~KMM_PLUGIN_FLAG_IN_MODLIST;
            kmmint_init_plugin(pi);

            /* release the hold obtained in kmm_provide_plugin() */
            kmm_release_plugin(kmm_handle_from_plugin(pi));
        }
    } while(pi);

    if(!m->plugin_count) {
        /* We don't want to report this case.  This usually means that
           the plugins that were provided by the module were
           disabled. */
#ifdef REPORT_EMPTY_MODULES
        _report_mr0(KHERR_ERROR, MSG_IM_NO_PLUGINS);

        m->state = KMM_MODULE_STATE_FAIL_NO_PLUGINS;
#endif
        record_failure = FALSE;
        goto _exit;
    }

    m->state = KMM_MODULE_STATE_RUNNING;

    exit_module = FALSE;
    record_failure = FALSE;

 _exit:
    if(csp_mod) {
        if(record_failure) {
            FILETIME fct;

            i = 0;
            khc_read_int32(csp_mod, L"FailureCount", &i);
            i++;
            khc_write_int32(csp_mod, L"FailureCount", i);

            if(i==1) { /* first fault */
                GetSystemTimeAsFileTime(&fct);
                khc_write_int64(csp_mod, L"FailureTime", FtToInt(&fct));
            }

            khc_write_int32(csp_mod, L"FailureReason", m->state);
        }
        khc_close_space(csp_mod);
    }

    if(csp_mods)
        khc_close_space(csp_mods);

    _report_mr2(KHERR_INFO, MSG_IM_MOD_STATE, 
                _dupstr(m->name), _int32(m->state));

    kmmint_remove_from_module_queue();

    /* if something went wrong after init_module was called on the
       module code, we need to call exit_module */
    if(exit_module)
        kmmint_exit_module(m);

    if(release_module)
        kmm_release_module(kmm_handle_from_module(m));

    if (kherr_is_error()) {
        kherr_context * c;
        kherr_event * err_e = NULL;
        kherr_event * warn_e = NULL;
        kherr_event * e;

        c = kherr_peek_context();
        err_e = kherr_get_err_event(c);
        for(e = kherr_get_first_event(c);
            e;
            e = kherr_get_next_event(e)) {
            if (e != err_e &&
                e->severity == KHERR_WARNING) {
                warn_e = e;
                break;
            }
        }

        kherr_evaluate_event(err_e);
        if (warn_e)
            kherr_evaluate_event(warn_e);

        kherr_clear_error();

        e = kherr_report(KHERR_ERROR,
                         (wchar_t *) MSG_IMERR_TITLE,
                         KHERR_FACILITY,
                         NULL,
                         err_e->long_desc,
                         ((warn_e)? (wchar_t *)MSG_IMERR_SUGGEST: NULL),
                         KHERR_FACILITY_ID,
                         KHERR_SUGGEST_NONE,
                         _cstr(m->name),
                         ((warn_e)? _cstr(warn_e->long_desc):_vnull()),
                         _vnull(),_vnull(),
                         KHERR_RF_MSG_SHORT_DESC |
                         ((warn_e)? KHERR_RF_MSG_SUGGEST: 0),
                         KHERR_HMODULE);

        kherr_evaluate_event(e);

        kherr_release_context(c);
    }

    _end_task();
}
예제 #3
0
static void
write_params_ident(ident_data * d) {
    khm_handle csp_ident;

    if (d->saved.monitor == d->work.monitor &&
        d->saved.auto_renew == d->work.auto_renew &&
        d->saved.sticky == d->work.sticky &&
        !d->removed)
        return;

    if (KHM_FAILED(kcdb_identity_get_config(d->ident, KHM_PERM_WRITE,
                                            &csp_ident))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        return;
    }

    if (d->removed) {
        khm_handle h = NULL;
        khm_int32 flags = 0;

        khc_remove_space(csp_ident);

        /* calling kcdb_identity_get_config() will update the
           KCDB_IDENT_FLAG_CONFIG flag for the identity to reflect the
           fact that it nolonger has a configuration. */
        kcdb_identity_get_config(d->ident, 0, &h);
        if (h) {
            /* what the ? */
#ifdef DEBUG
            assert(FALSE);
#endif
            khc_close_space(h);
        }
#ifdef DEBUG
        kcdb_identity_get_flags(d->ident, &flags);
        assert(!(flags & KCDB_IDENT_FLAG_CONFIG));
#endif

    } else {

        if (d->saved.monitor != d->work.monitor)
            khc_write_int32(csp_ident, L"Monitor", !!d->work.monitor);

        if (d->saved.auto_renew != d->work.auto_renew)
            khc_write_int32(csp_ident, L"AllowAutoRenew",
                            !!d->work.auto_renew);

        if (d->saved.sticky != d->work.sticky) {
            kcdb_identity_set_flags(d->ident,
                                    (d->work.sticky)?KCDB_IDENT_FLAG_STICKY:0,
                                    KCDB_IDENT_FLAG_STICKY);
        }
    }

    khc_close_space(csp_ident);

    d->saved = d->work;

    d->applied = TRUE;

    if (d->hwnd)
        PostMessage(d->hwnd, KHUI_WM_CFG_NOTIFY,
                    MAKEWPARAM(0, WMCFG_UPDATE_STATE), 0);

    khm_refresh_config();
}
예제 #4
0
static kcdb_identpro_i *
identpro_create_with_plugin(kmm_plugin plugin, khm_handle sub)
{
    kmm_plugin_info pi;
    kcdb_identpro_i * p;
    size_t len;

    ZeroMemory(&pi, sizeof(pi));
    if (KHM_FAILED(kmm_get_plugin_info_i(plugin, &pi)))
        return NULL;

    if (pi.reg.type != KHM_PITYPE_IDENT) {
        kmm_release_plugin_info_i(&pi);
#ifdef DEBUG
        assert(FALSE);
#endif
        return NULL;
    }

    if (FAILED(StringCbLength(pi.reg.name, KMM_MAXCB_NAME, &len)))
        return NULL;
    len += sizeof(wchar_t);

    /* we need to check if the plug-in is already there, both in the
       current and the deleted lists */
    EnterCriticalSection(&cs_identpro);
    for (p = QTOP(&id_providers); p; p = QNEXT(p)) {
        if (p->plugin == plugin)
            break;
    }

    if (p == NULL)
        for (p = deleted_id_providers; p; p = LNEXT(p)) {
            if (p->plugin == plugin ||
                !wcscmp(p->name, pi.reg.name))
                break;
        }

    if (p)
        identpro_hold(p);

    if (p == NULL) {
        p = PMALLOC(sizeof(*p));
        ZeroMemory(p, sizeof(*p));

        p->magic = KCDB_IDENTPRO_MAGIC;
        p->name = PMALLOC(len);
        StringCbCopy(p->name, len, pi.reg.name);
        p->sub = sub;
        p->plugin = plugin;
        kmm_hold_plugin(plugin);

        p->refcount = 1;            /* initially held */

        QPUT(&id_providers, p);

        n_id_providers++;
        kcdbint_identpro_post_message(KCDB_OP_INSERT, p);

    } else if (p->flags & KCDB_IDENTPRO_FLAG_DELETED) {

        LDELETE(&deleted_id_providers, p);
        p->flags &= ~KCDB_IDENTPRO_FLAG_DELETED;
        if (p->plugin != plugin) {
            /* can happen if the plug-in was reloaded */
            if (p->plugin)
                kmm_release_plugin_info_i(p->plugin);
            p->plugin = plugin;
            kmm_hold_plugin(plugin);
        }

        if (p->sub) {
            kmq_delete_subscription(p->sub);
        }

        p->sub = sub;

        QPUT(&id_providers, p);
        n_id_providers++;
    }

    identpro_check_and_set_default_provider();
    LeaveCriticalSection(&cs_identpro);

    kmm_release_plugin_info_i(&pi);

    return p;
}
예제 #5
0
static krb5_error_code KRB5_CALLCONV
kinit_prompter(krb5_context context,
               void *data,
               const char *name,
               const char *banner,
               int num_prompts,
               krb5_prompt prompts[])
{
    int i;
    k5_kinit_task * kt;
    khm_size ncp;
    krb5_error_code code = 0;
    BOOL new_prompts = TRUE;
    khm_handle csp_prcache = NULL;

    kt = (k5_kinit_task *) data;
    assert(kt && kt->magic == K5_KINIT_TASK_MAGIC);

    EnterCriticalSection(&kt->cs);

    if (kt->state == K5_KINIT_STATE_ABORTED) {
        LeaveCriticalSection(&kt->cs);
        return KRB5_LIBOS_PWDINTR;
    }

#ifdef DEBUG
    assert(kt->state == K5_KINIT_STATE_INCALL ||
           kt->state == K5_KINIT_STATE_CONFIRM);

    _reportf(L"k5_kinit_prompter() received %d prompts with name=[%S] banner=[%S]",
             num_prompts,
             name, banner);
    for (i=0; i < num_prompts; i++) {
        _reportf(L"Prompt[%d]: string[%S]", i, prompts[i].prompt);
    }
#endif

    /* we got prompts?  Then we assume that the principal is valid */

    if (!kt->is_valid_principal) {
        kt->is_valid_principal = TRUE;

        /* if the flags that were used to call kinit were restricted
           because we didn't know the validity of the principal, then
           we need to go back and retry the call with the correct
           flags. */
        if (kt->params.forwardable ||
            kt->params.proxiable ||
            kt->params.renewable) {

            _reportf(L"Retrying kinit call due to restricted flags on first call.");
            kt->state = K5_KINIT_STATE_RETRY;
            LeaveCriticalSection(&kt->cs);

            return KRB5_LIBOS_PWDINTR;
        }
    }

    /* check if we are already showing the right prompts */
    khui_cw_get_prompt_count(kt->nc, &ncp);

    if (num_prompts != (int) ncp && num_prompts != 0)
        goto _show_new_prompts;

    for (i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khui_new_creds_prompt * p;

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = L'\0';
        }

        if (KHM_FAILED(khui_cw_get_prompt(kt->nc, i, &p)))
            break;

        if (                    /* if we received a prompt string,
                                   then it should be the same as the
                                   one that is displayed */
            (wprompt[0] != L'\0' &&
             (p->prompt == NULL ||
              wcscmp(wprompt, p->prompt))) ||

                                /* if we didn't receive one, then
                                   there shouldn't be one displayed.
                                   This case really shouldn't happen
                                   in reality, but we check anyway. */
            (wprompt[0] == L'\0' &&
             p->prompt != NULL) ||

                                /* the type should match */
            (prompts[i].type != p->type) ||

                                /* if this prompt should be hidden,
                                   then it must also be so */
            (prompts[i].hidden &&
             !(p->flags & KHUI_NCPROMPT_FLAG_HIDDEN)) ||
            (!prompts[i].hidden &&
             (p->flags & KHUI_NCPROMPT_FLAG_HIDDEN))
            )

            break;
    }

    if (i >= num_prompts) {

        new_prompts = FALSE;

        /* ok. looks like we are already showing the same set of
           prompts that we were supposed to show.  Sync up the values
           and go ahead. */
        goto _process_prompts;
    }

 _show_new_prompts:
    if (num_prompts == 0) {

        assert(FALSE);

        khui_cw_notify_identity_state(kt->nc,
                                      kt->nct->hwnd_panel,
                                      NULL,
                                      KHUI_CWNIS_READY |
                                      KHUI_CWNIS_NOPROGRESS |
                                      KHUI_CWNIS_VALIDATED, 0);

        code = 0;
        kt->is_null_password = TRUE;
        goto _process_prompts;
    }

    /* in addition to showing new prompts, we also cache the first set
       of prompts. */
    if (kt->prompt_set_index == 0) {
        khm_handle csp_idconfig = NULL;
        khm_handle csp_idk5 = NULL;

        kcdb_identity_get_config(kt->identity,
                                 KHM_FLAG_CREATE,
                                 &csp_idconfig);

        if (csp_idconfig != NULL)
            khc_open_space(csp_idconfig,
                           CSNAME_KRB5CRED,
                           KHM_FLAG_CREATE,
                           &csp_idk5);

        if (csp_idk5 != NULL)
            khc_open_space(csp_idk5,
                           CSNAME_PROMPTCACHE,
                           KHM_FLAG_CREATE,
                           &csp_prcache);

        khc_close_space(csp_idconfig);
        khc_close_space(csp_idk5);
    }

    {
        wchar_t wbanner[KHUI_MAXCCH_BANNER];
        wchar_t wname[KHUI_MAXCCH_PNAME];

        if(banner)
            AnsiStrToUnicode(wbanner, sizeof(wbanner), banner);
        else
            wbanner[0] = L'\0';

        if(name)
            AnsiStrToUnicode(wname, sizeof(wname), name);
        else
            LoadString(hResModule, IDS_PNAME_PW, wname, ARRAYLENGTH(wname));

        khui_cw_clear_prompts(kt->nc);

        khui_cw_begin_custom_prompts(kt->nc, num_prompts, wbanner, wname);

        if (csp_prcache) {
            FILETIME current;
            FILETIME lifetime;
            FILETIME expiry;
            khm_int64 iexpiry;
            khm_int32 t = 0;

            khc_write_string(csp_prcache, L"Banner", wbanner);
            khc_write_string(csp_prcache, L"Name", (name)? wname: L"");
            khc_write_int32(csp_prcache, L"PromptCount", (khm_int32) num_prompts);

            GetSystemTimeAsFileTime(&current);
#ifdef USE_PROMPT_CACHE_LIFETIME
            khc_read_int32(csp_params, L"PromptCacheLifetime", &t);
            if (t == 0)
                t = 172800;         /* 48 hours */
#else
            khc_read_int32(csp_params, L"MaxRenewLifetime", &t);
            if (t == 0)
                t = 2592000;    /* 30 days */
            t += 604800;        /* + 7 days */
#endif
            TimetToFileTimeInterval(t, &lifetime);
            expiry = FtAdd(&current, &lifetime);
            iexpiry = FtToInt(&expiry);

            khc_write_int64(csp_prcache, L"ExpiresOn", iexpiry);
        }
    }

    for(i=0; i < num_prompts; i++) {
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];

        if(prompts[i].prompt) {
            AnsiStrToUnicode(wprompt, sizeof(wprompt),
                             prompts[i].prompt);
        } else {
            wprompt[0] = 0;
        }

        khui_cw_add_prompt(kt->nc, prompts[i].type,
                           wprompt, NULL,
                           (prompts[i].hidden?KHUI_NCPROMPT_FLAG_HIDDEN:0));

        if (csp_prcache) {
            khm_handle csp_p = NULL;
            wchar_t wnum[8];    /* should be enough for 10
                                   million prompts */

            wnum[0] = 0;
            StringCbPrintf(wnum, sizeof(wnum), L"%d", i);

            khc_open_space(csp_prcache, wnum, KHM_FLAG_CREATE, &csp_p);

            if (csp_p) {
                khc_write_string(csp_p, L"Prompt", wprompt);
                khc_write_int32(csp_p, L"Type", prompts[i].type);
                khc_write_int32(csp_p, L"Flags",
                                (prompts[i].hidden?
                                 KHUI_NCPROMPT_FLAG_HIDDEN:0));

                khc_close_space(csp_p);
            }
        }
    }

    if (csp_prcache) {
        khc_close_space(csp_prcache);
        csp_prcache = NULL;
    }

 _process_prompts:
    if (new_prompts) {
        kt->state = K5_KINIT_STATE_WAIT;

        kcdb_identity_set_flags(kt->identity,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT,
                                KCDB_IDENT_FLAG_VALID | KCDB_IDENT_FLAG_KEY_EXPORT);
        khui_cw_notify_identity_state(kt->nc, kt->nct->hwnd_panel, L"",
                                      KHUI_CWNIS_VALIDATED |
                                      KHUI_CWNIS_READY, 0);

        SetEvent(kt->h_parent_wait);
        LeaveCriticalSection(&kt->cs);
        WaitForSingleObject(kt->h_task_wait, INFINITE);
        EnterCriticalSection(&kt->cs);
    }

    /* we get here after the user selects an action that either
       cancels the credentials acquisition operation or triggers the
       actual acquisition of credentials. */
    if (kt->state != K5_KINIT_STATE_INCALL &&
        kt->state != K5_KINIT_STATE_CONFIRM) {
        code = KRB5_LIBOS_PWDINTR;
        goto _exit;
    }

    kt->is_null_password = FALSE;

    /* otherwise, we need to get the data back from the UI and return
       0 */

    khui_cw_sync_prompt_values(kt->nc);

    for(i=0; i<num_prompts; i++) {
        krb5_data * d;
        wchar_t wbuf[512];
        khm_size cbbuf;
        size_t cch;

        d = prompts[i].reply;

        cbbuf = sizeof(wbuf);
        if(KHM_SUCCEEDED(khui_cw_get_prompt_value(kt->nc, i, wbuf, &cbbuf))) {
            UnicodeStrToAnsi(d->data, d->length, wbuf);
            if(SUCCEEDED(StringCchLengthA(d->data, d->length, &cch)))
                d->length = (unsigned int) cch;
            else
                d->length = 0;
        } else {
            assert(FALSE);
            d->length = 0;
        }

        if (prompts[i].type == KRB5_PROMPT_TYPE_PASSWORD &&
            d->length == 0)

            kt->is_null_password = TRUE;
    }

    if (khui_cw_get_persist_private_data(kt->nc) &&
        num_prompts == 1 &&
	prompts[0].type == KRB5_PROMPT_TYPE_PASSWORD &&
        prompts[0].reply->length != 0) {
        k5_reply_to_acqpriv_id_request(kt->nc, prompts[0].reply);
    }

 _exit:

    kt->prompt_set_index++;

    LeaveCriticalSection(&kt->cs);

    /* entering a NULL password is equivalent to cancelling out */
    if (kt->is_null_password)
        return KRB5_LIBOS_PWDINTR;
    else
        return code;
}
예제 #6
0
static ident_data *
find_ident_by_node(khui_config_node node) {
    khm_size cb;
    wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
    int i;
    khm_handle ident = NULL;

    cb = sizeof(idname);
    khui_cfg_get_name(node, idname, &cb);

    for (i=0; i < (int)cfg_idents.n_idents; i++) {
        if (!wcscmp(cfg_idents.idents[i].idname, idname))
            break;
    }

    if (i < (int)cfg_idents.n_idents)
        return &cfg_idents.idents[i];

    /* there is no identity data for this configuration node.  We try
       to create it. */
    if (KHM_FAILED(kcdb_identity_create(idname, 0, &ident)))
        return NULL;

    if (cfg_idents.n_idents >= cfg_idents.nc_idents) {
        cfg_idents.nc_idents = UBOUNDSS(cfg_idents.n_idents + 1,
                                        IDENTS_DATA_ALLOC_INCR,
                                        IDENTS_DATA_ALLOC_INCR);
#ifdef DEBUG
        assert(cfg_idents.nc_idents > cfg_idents.n_idents);
#endif
        cfg_idents.idents = PREALLOC(cfg_idents.idents,
                                     sizeof(*cfg_idents.idents) *
                                     cfg_idents.nc_idents);
#ifdef DEBUG
        assert(cfg_idents.idents);
#endif
        ZeroMemory(&(cfg_idents.idents[cfg_idents.n_idents]),
                   sizeof(*cfg_idents.idents) *
                   (cfg_idents.nc_idents - cfg_idents.n_idents));
    }

    i = (int) cfg_idents.n_idents;

    StringCbLength(idname, KCDB_IDENT_MAXCB_NAME, &cb);
    cb += sizeof(wchar_t);

    cfg_idents.idents[i].idname = PMALLOC(cb);
#ifdef DEBUG
    assert(cfg_idents.idents[i].idname);
#endif
    StringCbCopy(cfg_idents.idents[i].idname, cb, idname);

    cfg_idents.idents[i].ident = ident;
    cfg_idents.idents[i].removed = FALSE;

    kcdb_identity_get_flags(ident, &cfg_idents.idents[i].flags);
#ifdef DEBUG
    assert(cfg_idents.idents[i].flags & KCDB_IDENT_FLAG_CONFIG);
#endif

    read_params_ident(&cfg_idents.idents[i]);

    cfg_idents.n_idents++;

    /* leave ident held. */

    return &cfg_idents.idents[i];
}
예제 #7
0
/* Completion handler for KMSG_CRED messages.  We control the overall
   logic of credentials acquisition and other operations here.  Once a
   credentials operation is triggered, each successive message
   completion notification will be used to dispatch the messages for
   the next step in processing the operation. */
void KHMAPI 
kmsg_cred_completion(kmq_message *m)
{
    khui_new_creds * nc;

#ifdef DEBUG
    assert(m->type == KMSG_CRED);
#else
    if(m->type != KMSG_CRED)
        return; /* huh? */
#endif

    switch(m->subtype) {
    case KMSG_CRED_PASSWORD:
        /* fallthrough */
    case KMSG_CRED_NEW_CREDS:
        /* Cred types have attached themselves.  Trigger the next
           phase. */
        kmq_post_message(KMSG_CRED, KMSG_CRED_DIALOG_SETUP, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_RENEW_CREDS:
        nc = (khui_new_creds *) m->vparam;

        /* khm_cred_dispatch_process_message() deals with the case
           where there are no credential types that wants to
           participate in this operation. */
        khm_cred_dispatch_process_message(nc);
        break;

    case KMSG_CRED_DIALOG_SETUP:
        nc = (khui_new_creds *) m->vparam;

        khm_prep_newcredwnd(nc->hwnd);
            
        /* all the controls have been created.  Now initialize them */
        if (nc->n_types > 0) {
            kmq_post_subs_msg(nc->type_subs, 
                              nc->n_types, 
                              KMSG_CRED, 
                              KMSG_CRED_DIALOG_PRESTART, 
                              0, 
                              m->vparam);
        } else {
            PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                        MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0);
        }
        break;

    case KMSG_CRED_DIALOG_PRESTART:
        /* all prestart stuff is done.  Now to activate the dialog */
        nc = (khui_new_creds *) m->vparam;
        khm_show_newcredwnd(nc->hwnd);
        
        kmq_post_subs_msg(nc->type_subs,
                          nc->n_types,
                          KMSG_CRED, 
                          KMSG_CRED_DIALOG_START, 
                          0, 
                          m->vparam);
        /* at this point, the dialog window takes over.  We let it run
           the show until KMSG_CRED_DIALOG_END is posted by the dialog
           procedure. */
        break;

    case KMSG_CRED_PROCESS:
        /* a wave of these messages have completed.  We should check
           if there's more */
        nc = (khui_new_creds *) m->vparam;

        /* if we are done processing all the plug-ins, then check if
           there were any errors reported.  Otherwise we dispatch
           another set of messages. */
        if(!khm_cred_dispatch_process_level(nc)) {

            if(kherr_is_error()) {
                khui_alert * alert;
                kherr_event * evt;
                kherr_context * ctx;
                wchar_t ws_tfmt[512];
                wchar_t w_idname[KCDB_IDENT_MAXCCH_NAME];
                wchar_t ws_title[ARRAYLENGTH(ws_tfmt) + KCDB_IDENT_MAXCCH_NAME];
                khm_size cb;

                /* For renewals, we suppress the error message for the
                   following case:

                   - The renewal was for an identity

                   - There are no identity credentials for the
                     identity (no credentials that have the same type
                     as the identity provider). */

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.scope == KHUI_SCOPE_IDENT &&
                    nc->ctx.identity != NULL) {
                    khm_handle tcs = NULL; /* credential set */
                    khm_size count = 0;
                    khm_int32 id_ctype = KCDB_CREDTYPE_INVALID;
                    khm_int32 delta = 0;

                    kcdb_identity_get_type(&id_ctype);
                    kcdb_credset_create(&tcs);
                    kcdb_credset_collect(tcs, NULL,
                                         nc->ctx.identity,
                                         id_ctype,
                                         &delta);
                    kcdb_credset_get_size(tcs, &count);
                    kcdb_credset_delete(tcs);

                    if (count == 0) {
                        goto done_with_op;
                    }
                }

                ctx = kherr_peek_context();
                evt = kherr_get_err_event(ctx);
                kherr_evaluate_event(evt);

                khui_alert_create_empty(&alert);

                if (nc->subtype == KMSG_CRED_NEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_ACQUIREFAIL);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        /* an identity could not be determined */
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_PASSWORD) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_CHPW);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_RENEWFAIL);

                    cb = sizeof(w_idname);
                    if (nc->ctx.identity == NULL ||
                        KHM_FAILED(kcdb_identity_get_name(nc->ctx.identity,
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->ctx.identity,
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else {
#ifdef DEBUG
                    assert(FALSE);
#endif
                }

                khui_alert_set_title(alert, ws_title);
                khui_alert_set_severity(alert, evt->severity);

                if(!evt->long_desc)
                    khui_alert_set_message(alert, evt->short_desc);
                else
                    khui_alert_set_message(alert, evt->long_desc);

                if(evt->suggestion)
                    khui_alert_set_suggestion(alert, evt->suggestion);

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.identity != NULL) {

                    khm_int32 n_cmd;

                    n_cmd = khm_get_identity_new_creds_action(nc->ctx.identity);

                    if (n_cmd != 0) {
                        khui_alert_add_command(alert, n_cmd);
                        khui_alert_add_command(alert, KHUI_PACTION_CLOSE);

                        khui_alert_set_flags(alert, KHUI_ALERT_FLAG_DISPATCH_CMD,
                                             KHUI_ALERT_FLAG_DISPATCH_CMD);
                    }
                }

                khui_alert_show(alert);
                khui_alert_release(alert);

                kherr_release_context(ctx);

                kherr_clear_error();
            }

        done_with_op:

            if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
                kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, 
                                 m->vparam);
            } else {
                PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                            MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE),
                            0);
            }
        }
        break;

    case KMSG_CRED_END:
        /* all is done. */
        {
            khui_new_creds * nc;
            khm_boolean continue_cmdline = TRUE;

            nc = (khui_new_creds *) m->vparam;

            if (nc->subtype == KMSG_CRED_NEW_CREDS ||
                nc->subtype == KMSG_CRED_PASSWORD) {

                khm_cred_end_dialog(nc);

            } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                /* if this is a renewal that was triggered while we
                   were processing the commandline, then we need to
                   update the pending renewal count. */

                if (khm_startup.processing) {
                    LONG renewals;
                    renewals = InterlockedDecrement(&khm_startup.pending_renewals);

                    if (renewals != 0) {
                        continue_cmdline = FALSE;
                    }
                }
            }

            khui_cw_destroy_cred_blob(nc);

            kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

            if (continue_cmdline)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

        /* property sheet stuff */

    case KMSG_CRED_PP_BEGIN:
        /* all the pages should have been added by now.  Just send out
           the precreate message */
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_PRECREATE, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_PP_END:
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_DESTROY, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_DESTROY_CREDS:
#ifdef DEBUG
        assert(m->vparam != NULL);
#endif
        khui_context_release((khui_action_context *) m->vparam);
        PFREE(m->vparam);

        kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

        kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        break;

    case KMSG_CRED_IMPORT:
        {
            khm_boolean continue_cmdline = FALSE;
            LONG pending_renewals;

            /* once an import operation ends, we have to trigger a
               renewal so that other plug-ins that didn't participate
               in the import operation can have a chance at getting
               the necessary credentials.

               If we are in the middle of processing the commandline,
               we have to be a little bit careful.  We can't issue a
               commandline conituation message right now because the
               import action is still ongoing (since the renewals are
               part of the action).  Once the renewals have completed,
               the completion handler will automatically issue a
               commandline continuation message.  However, if there
               were no identities to renew, then we have to issue the
               message ourselves.
            */

            InterlockedIncrement(&khm_startup.pending_renewals);

            khm_cred_renew_all_identities();

            pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals);

            if (pending_renewals == 0 && khm_startup.processing)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

    case KMSG_CRED_REFRESH:
        kcdb_identity_refresh_all();
        break;
    }
}
예제 #8
0
KHMEXP khm_int32 KHMAPI
kcdb_credset_extract_filtered(khm_handle destcredset,
			      khm_handle sourcecredset,
			      kcdb_cred_filter_func filter,
			      void * rock)
{
    khm_int32 code = KHM_ERROR_SUCCESS;
    kcdb_credset * dest;
    kcdb_credset * src;
    int isRoot = 0;
    khm_size srcSize = 0;
    int i;

    if(!kcdb_credset_is_credset(destcredset))
        return KHM_ERROR_INVALID_PARAM;

    if(sourcecredset) {
        if(!kcdb_credset_is_credset(sourcecredset))
            return KHM_ERROR_INVALID_PARAM;
    } else {
        sourcecredset = kcdb_root_credset;
        isRoot = 1;
    }

    src = (kcdb_credset *) sourcecredset;
    dest = (kcdb_credset *) destcredset;

    if (kcdb_credset_is_sealed(dest))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(src->cs));
    EnterCriticalSection(&(dest->cs));

#ifdef DEBUG
    assert(!(dest->flags & KCDB_CREDSET_FLAG_ENUM));
#endif

    if(KHM_FAILED(kcdb_credset_get_size(sourcecredset, &srcSize))) {
        code = KHM_ERROR_UNKNOWN;
        goto _exit;
    }

    kcdb_cred_lock_read();

    dest->flags |= KCDB_CREDSET_FLAG_ENUM;

    for(i=0; i < (int) srcSize; i++) {
        kcdb_cred * c;

        c = src->clist[i].cred;
        if(kcdb_cred_is_active_cred((khm_handle) c) &&
            filter(c, 0, rock))
        {
            if(isRoot) {
                khm_handle newcred;

                kcdb_cred_unlock_read();
                kcdb_cred_dup((khm_handle) c, &newcred);
                kcdb_credset_add_cred(destcredset, newcred, -1);
                kcdb_cred_release(newcred);
                kcdb_cred_lock_read();
            } else {
                kcdb_cred_unlock_read();
                kcdb_credset_add_cred(destcredset, (khm_handle) c, -1);
                kcdb_cred_lock_read();
            }
        }
    }

    dest->flags &= ~KCDB_CREDSET_FLAG_ENUM;

    kcdb_cred_unlock_read();

_exit:
    LeaveCriticalSection(&(dest->cs));
    LeaveCriticalSection(&(src->cs));

    return code;
}
예제 #9
0
파일: krb5common.c 프로젝트: aosm/Kerberos
int 
khm_krb5_initialize(khm_handle ident, 
                    krb5_context *ctx, 
                    krb5_ccache *cache)
{
#ifdef NO_KRB5
    return(0);
#else

    LPCSTR          functionName = NULL;
    int             freeContextFlag = 0;
    krb5_error_code	rc = 0;
    krb5_flags          flags = 0;

    if (pkrb5_init_context == NULL)
        return 1;

    if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx))) {
        functionName = "krb5_init_context()";
        freeContextFlag = 0;
        goto on_error;
    }

    if(*cache == 0) {
        wchar_t wccname[MAX_PATH];
        khm_size cbwccname;

        if(ident != NULL) {
            cbwccname = sizeof(wccname);
            do {
                char ccname[256];

                if(KHM_FAILED(kcdb_identity_get_attrib(ident, L"Krb5CCName",
                                                       NULL, wccname,
                                                       &cbwccname))) {
                    cbwccname = sizeof(wccname);
                    if (KHM_FAILED
                        (khm_krb5_find_ccache_for_identity(ident,
                                                           ctx,
                                                           wccname,
                                                           &cbwccname))) {
#ifdef DEBUG_LIKE_A_MADMAN
                        assert(FALSE);
#endif
                        break;
                    }
                }

                if(UnicodeStrToAnsi(ccname, sizeof(ccname), wccname) == 0)
                    break;

                if((*pkrb5_cc_resolve)(*ctx, ccname, cache)) {
                    functionName = "krb5_cc_resolve()";
                    freeContextFlag = 1;
                    goto on_error;
                }
            } while(FALSE);
        }

#ifndef FAILOVER_TO_DEFAULT_CCACHE
	rc = 1;
#endif
        if (*cache == 0
#ifdef FAILOVER_TO_DEFAULT_CCACHE
            && (rc = (*pkrb5_cc_default)(*ctx, cache))
#endif
            ) {
            functionName = "krb5_cc_default()";
            freeContextFlag = 1;
            goto on_error;
        }
    }

#ifdef KRB5_TC_NOTICKET
    flags = KRB5_TC_NOTICKET;
#endif

    if ((rc = (*pkrb5_cc_set_flags)(*ctx, *cache, flags)))
    {
        if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
            khm_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx, 
            cache);
        else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) {
            if (*cache != NULL) {
                (*pkrb5_cc_close)(*ctx, *cache);
                *cache = NULL;
            }
        }
        return rc;
    }
    return 0;

on_error:
    return khm_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
#endif //!NO_KRB5
}
예제 #10
0
void
khm_cred_addr_change(void) {
    khm_handle csp_cw = NULL;
    khm_int32 check_net = 0;

    wchar_t * ids = NULL;
    wchar_t * t;
    khm_size cb;
    khm_size n_idents;

    FILETIME ft_now;
    FILETIME ft_exp;
    FILETIME ft_issue;

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
                                     0, &csp_cw))) {
        khc_read_int32(csp_cw, L"AutoDetectNet", &check_net);

        khc_close_space(csp_cw);
    }

    if (!check_net)
        return;

    while(TRUE) {
        if (ids)
            PFREE(ids);
        ids = NULL;

        if (kcdb_identity_enum(KCDB_IDENT_FLAG_VALID |
                               KCDB_IDENT_FLAG_RENEWABLE,
                               KCDB_IDENT_FLAG_VALID |
                               KCDB_IDENT_FLAG_RENEWABLE,
                               NULL,
                               &cb,
                               &n_idents) != KHM_ERROR_TOO_LONG)
            break;

        ids = PMALLOC(cb);

        if (KHM_SUCCEEDED
            (kcdb_identity_enum(KCDB_IDENT_FLAG_VALID |
                                KCDB_IDENT_FLAG_RENEWABLE,
                                KCDB_IDENT_FLAG_VALID |
                                KCDB_IDENT_FLAG_RENEWABLE,
                                ids,
                                &cb,
                                &n_idents)))
            break;
    }

    if (!ids)
        return;

    GetSystemTimeAsFileTime(&ft_now);

    for (t=ids; t && *t; t = multi_string_next(t)) {
        khm_handle ident;


        if (KHM_FAILED
            (kcdb_identity_create(t, 0, &ident)))
            continue;

        cb = sizeof(ft_issue);

        if (KHM_SUCCEEDED
            (kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE, NULL,
                                    &ft_issue, &cb)) &&

            (cb = sizeof(ft_exp)) &&
            KHM_SUCCEEDED
            (kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE, NULL,
                                    &ft_exp, &cb)) &&

            CompareFileTime(&ft_now, &ft_exp) < 0) {

            khm_int64 i_issue;
            khm_int64 i_exp;
            khm_int64 i_now;

            i_issue = FtToInt(&ft_issue);
            i_exp = FtToInt(&ft_exp);
            i_now = FtToInt(&ft_now);

            if (i_now > (i_issue + i_exp) / 2) {

                khm_cred_renew_identity(ident);

            }
        }

        kcdb_identity_release(ident);
    }
}
예제 #11
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

    /* This is the first message that will be received by a
       plugin.  We use it to perform initialization operations
       such as registering any credential types, data types and
       attributes. */
    case KMSG_SYSTEM_INIT:
    {
        kcdb_credtype ct;
        wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
        wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
        khui_config_node cnode;
        khui_config_node_reg creg;

        /* First and foremost, we need to register a credential
           type. */
        ZeroMemory(&ct, sizeof(ct));
        ct.id = KCDB_CREDTYPE_AUTO;
        ct.name = MYCREDTYPE_NAMEW;

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CT_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));

        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CT_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        ct.icon = NULL;     /* We skip the icon for now, but you
                               can assign a handle to an icon
                               here.  The icon will be used to
                               represent the credentials type.*/

        kmq_create_subscription(plugin_msg_proc, &ct.sub);

        ct.is_equal = cred_is_equal;

        rv = kcdb_credtype_register(&ct, &credtype_id);

        /* We create a global credential set that we use in the
           plug-in thread.  This alleviates the need to create one
           everytime we need one. Keep in mind that this should
           only be used in the plug-in thread and should not be
           touched from the UI thread or any other thread. */
        kcdb_credset_create(&g_credset);

        /* TODO: Perform additional initialization operations. */

        /* TODO: Also list out the credentials of this type that
           already exist. */

        /* Now we register our configuration panels. */


        /* This configuration panel is the one that controls
           general options.  We leave the identity specific and
           identity defaults for other configuration panels. */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';

        LoadString(hResModule, IDS_CFG_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));

        long_desc[0] = L'\0';

        LoadString(hResModule, IDS_CFG_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_MAIN;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
        creg.dlg_proc = config_dlgproc;
        creg.flags = 0;

        khui_cfg_register(NULL, &creg);

        /* Now we do the identity specific and identity default
           configuration panels. "KhmIdentities" is a predefined
           configuration node under which all the identity spcific
           configuration is managed. */

        if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
            /* this should always work */
            assert(FALSE);
            rv = KHM_ERROR_NOT_FOUND;
            break;
        }

        /* First the tab panel for defaults for all identities */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));
        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_ALL_ID;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
        creg.dlg_proc = config_ids_dlgproc;
        creg.flags = KHUI_CNFLAG_SUBPANEL;

        khui_cfg_register(cnode, &creg);

        /* Now the panel for per identity configuration */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));
        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_PER_ID;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
        creg.dlg_proc = config_id_dlgproc;
        creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

        khui_cfg_register(cnode, &creg);

        khui_cfg_release(cnode);

        /* get IdentProvider handle to which this plugin belongs
           it is possible to use kcdb_identity_create_ex() function with
           proper h_idprov */
        if (KHM_FAILED(kcdb_identpro_find(IDPROV_NAMEW, &h_idprov))) {
            return KHM_ERROR_UNKNOWN;
        }
    }
    break;

    /* This is the last message that will be received by the
       plugin. */
    case KMSG_SYSTEM_EXIT:
    {
        khui_config_node cnode;
        khui_config_node cn_idents;

        /* It should not be assumed that initialization of the
           plugin went well at this point since we receive a
           KMSG_SYSTEM_EXIT even if the initialization failed. */

        if (credtype_id != KCDB_CREDTYPE_INVALID) {
            kcdb_credtype_unregister(credtype_id);
            credtype_id = KCDB_CREDTYPE_INVALID;
        }

        if (g_credset) {
            kcdb_credset_delete(g_credset);
            g_credset = NULL;
        }

        /* Now unregister any configuration nodes we registered. */

        if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
            khui_cfg_remove(cnode);
            khui_cfg_release(cnode);
        }

        if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
            if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                            CONFIGNODE_ALL_ID,
                                            &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                            CONFIGNODE_PER_ID,
                                            &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            khui_cfg_release(cn_idents);
        }

        /* TODO: Perform additional uninitialization
           operations. */

        kcdb_identpro_release(h_idprov);
    }
    break;
    }

    return rv;
}
예제 #12
0
KHMEXP khm_int32 KHMAPI
kcdb_identpro_set_default_identity(khm_handle videntity, khm_boolean ask_idpro)
{
    khm_handle sub = NULL;
    khm_int32 rv = KHM_ERROR_SUCCESS;
    kcdb_identpro_i * p;

    if(!kcdb_is_identity(videntity))
        return KHM_ERROR_INVALID_PARAM;

    p = identpro_get_provider_for_identity(videntity);

    EnterCriticalSection(&cs_identpro);
    if (!kcdb_is_active_identpro(p)) {
        rv = KHM_ERROR_INVALID_PARAM;
    } else {
        if (kcdb_identity_is_equal(videntity, p->default_id))
            rv = KHM_ERROR_DUPLICATE;
    }
    LeaveCriticalSection(&cs_identpro);

    if (KHM_FAILED(rv)) {
        return (rv == KHM_ERROR_DUPLICATE)? KHM_ERROR_SUCCESS : rv;
    }

    if (ask_idpro) {
        sub = identpro_get_sub_for_identity(videntity);

        if(sub != NULL) {
            rv = kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_SET_DEFAULT,
                                  TRUE, (void *) videntity);
        } else {
#ifdef DEBUG
            assert(FALSE);
#endif
            rv = KHM_ERROR_NO_PROVIDER;
        }
    }

    if (KHM_SUCCEEDED(rv)) {
        khm_handle h_old_id = NULL;
        int new_default = FALSE;
        kcdb_identity * id;

        EnterCriticalSection(&cs_identpro);
        if (!kcdb_identity_is_equal(videntity, p->default_id)) {
            h_old_id = p->default_id;
            p->default_id = videntity;
            new_default = TRUE;
        }
        LeaveCriticalSection(&cs_identpro);

        EnterCriticalSection(&cs_ident);
        if (new_default)
            kcdb_identity_hold(videntity);
        id = (kcdb_identity *) videntity;
        id->flags |= KCDB_IDENT_FLAG_DEFAULT;

        if (h_old_id) {
            id = (kcdb_identity *) h_old_id;
            id->flags &= ~KCDB_IDENT_FLAG_DEFAULT;
            kcdb_identity_release(h_old_id);
        }
        LeaveCriticalSection(&cs_ident);

        if (new_default) {
            kcdb_identity_hold(videntity);
            kcdbint_ident_post_message(KCDB_OP_NEW_DEFAULT, (kcdb_identity *) videntity);
        }
    }

    return rv;
}
예제 #13
0
KHMEXP khm_int32 KHMAPI
kcdb_identity_set_provider(khm_handle sub)
{
    kmm_plugin plugin = NULL;
    kcdb_identpro_i * p;
    khm_int32 rv = KHM_ERROR_SUCCESS;

    plugin = kmm_this_plugin();
    if (plugin == NULL) {
#ifdef DEBUG
        assert(FALSE);
#endif
        return KHM_ERROR_INVALID_OPERATION;
    }

    p = identpro_find_by_plugin(plugin);
    if (p != NULL && sub != NULL) {
        rv = KHM_ERROR_DUPLICATE;
#ifdef DEBUG
        assert(FALSE);
#endif
        goto _exit;
    }

#ifdef DEBUG
    assert(sub != NULL || p != NULL);
#endif

    if (p == NULL)
        p = identpro_create_with_plugin(plugin, sub);

    if (p == NULL) {
        rv = KHM_ERROR_UNKNOWN;
        goto _exit;
    }

    if (sub) {
        rv = kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_INIT, 0, 0);

        if (KHM_FAILED(rv)) {
            kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_EXIT, 0, 0);
            identpro_mark_for_deletion(p);
        } else {
	    EnterCriticalSection(&cs_identpro);
	    p->flags |= KCDB_IDENTPRO_FLAG_READY;
	    LeaveCriticalSection(&cs_identpro);
	}
    } else {
        EnterCriticalSection(&cs_identpro);
        sub = p->sub;
        LeaveCriticalSection(&cs_identpro);
        kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_EXIT, 0, 0);
        identpro_mark_for_deletion(p);
    }

 _exit:
    if (p)
        identpro_release(p);

    if (plugin)
        kmm_release_plugin(plugin);

    return rv;
}
예제 #14
0
int main(int argc, char ** argv)
{
    keystore_t * ks = NULL;
    int fd = -1;
    long len;
    void * buffer = NULL;
    int read_len;
    khm_int32 rv;

    __try {
        if (argc != 2) {
            usage(argv[0]);
            return 0;
        }

        fprintf(stderr, "Trying to open file %s\n", argv[1]);

        _sopen_s(&fd, argv[1], _O_RDONLY | _O_BINARY | _O_SEQUENTIAL, _SH_DENYNO, _S_IREAD);

        if (fd == -1) {
            perror("_open");
            return 1;
        }

        len = _lseek(fd, 0, SEEK_END);
        if (len == -1) {
            perror("_lseek");
            return 1;
        }

        _lseek(fd, 0, SEEK_SET);

        buffer = malloc(len);

        read_len = _read(fd, buffer, len);

        if (read_len == -1) {
            perror("_read");
            return 1;
        }

        if (read_len != len) {
            fprintf(stderr, "Expected read len %ld.  Actual len %d\n", len, read_len);
            return 1;
        }

        if (KHM_FAILED(rv = ks_keystore_unserialize(buffer, len, &ks))) {
            fprintf(stderr, "ks_keystore_unserialize() == %d\n", rv);
            return 1;
        }

        dump_keystore(ks);

    } __finally {
        if (fd != -1)
            _close(fd);

        if (buffer != NULL)
            free(buffer);

        if (ks != NULL)
            ks_keystore_release(ks);
    }

    return 0;
}
예제 #15
0
void khm_cred_renew_all_identities(void)
{
    khm_size count;
    khm_size cb = 0;
    khm_size n_idents = 0;
    khm_int32 rv;
    wchar_t * ident_names = NULL;
    wchar_t * this_ident;

    kcdb_credset_get_size(NULL, &count);

    /* if there are no credentials, we just skip over the renew
       action. */

    if (count == 0)
        return;

    ident_names = NULL;

    while (TRUE) {
        if (ident_names) {
            PFREE(ident_names);
            ident_names = NULL;
        }

        cb = 0;
        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0,
                                NULL,
                                &cb, &n_idents);

        if (n_idents == 0 || rv != KHM_ERROR_TOO_LONG ||
            cb == 0)
            break;

        ident_names = PMALLOC(cb);
        ident_names[0] = L'\0';

        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0,
                                ident_names,
                                &cb, &n_idents);

        if (KHM_SUCCEEDED(rv))
            break;
    }

    if (ident_names) {
        for (this_ident = ident_names;
             this_ident && *this_ident;
             this_ident = multi_string_next(this_ident)) {
            khm_handle ident;

            if (KHM_FAILED(kcdb_identity_create(this_ident, 0,
                                                &ident)))
                continue;

            khm_cred_renew_identity(ident);

            kcdb_identity_release(ident);
        }

        PFREE(ident_names);
        ident_names = NULL;
    }
}
예제 #16
0
파일: kmm_reg.c 프로젝트: Brainiarc7/pbis
KHMEXP khm_int32   KHMAPI
kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags)
{
    khm_int32 rv = KHM_ERROR_SUCCESS;
    khm_handle csp_plugin = NULL;
    khm_handle csp_module = NULL;
    size_t cch;

    /* avoid accidently creating the module key if it doesn't exist */
    config_flags &= ~KHM_FLAG_CREATE;

    if((plugin == NULL) ||
       (plugin->dependencies &&
        KHM_FAILED(multi_string_length_cch(plugin->dependencies,
                                           KMM_MAXCCH_DEPS, &cch))) ||
       FAILED(StringCchLength(plugin->module, KMM_MAXCCH_NAME, &cch)) ||
       (plugin->description &&
        FAILED(StringCchLength(plugin->description,
                               KMM_MAXCCH_DESC, &cch))) ||
       FAILED(StringCchLength(plugin->name, KMM_MAXCCH_NAME, &cch)))
    {
        return KHM_ERROR_INVALID_PARAM;
    }

    /* note that we are retaining the length of the plugin name in
       chars in cch */
    cch ++;

#define CKRV if(KHM_FAILED(rv)) goto _exit

    rv = kmm_get_plugin_config(plugin->name,
                               config_flags | KHM_FLAG_CREATE, &csp_plugin);
    CKRV;

    /* should fail if the module key doesn't exist */
    rv = kmm_get_module_config(plugin->module, config_flags, &csp_module);
    CKRV;

    /*TODO: Make sure that the module registration is in the same
      config store as the one in which the plugin is going to be
      registered */

    rv = khc_write_string(csp_plugin, L"Module", plugin->module);
    CKRV;
    if(plugin->description) {
        rv = khc_write_string(csp_plugin, L"Description", plugin->description);
        CKRV;
    }

    if(plugin->dependencies) {
        rv = khc_write_multi_string(csp_plugin, L"Dependencies",
                                    plugin->dependencies);
        CKRV;
    }

    rv = khc_write_int32(csp_plugin, L"Type", plugin->type);
    CKRV;
    rv = khc_write_int32(csp_plugin, L"Disabled",
                         !!(plugin->flags & KMM_PLUGIN_FLAG_DISABLED));
    CKRV;

    {
        khm_size cb = 0;
        wchar_t * pl = NULL;
        size_t scb = 0;

        rv = khc_read_multi_string(csp_module, L"PluginList", NULL, &cb);
        if(rv != KHM_ERROR_TOO_LONG) {
            if (rv == KHM_ERROR_NOT_FOUND) {

                scb = cb = (cch + 1) * sizeof(wchar_t);
                pl = PMALLOC(cb);
                multi_string_init(pl, cb);
                rv = KHM_ERROR_SUCCESS;

                goto add_plugin_to_list;

            } else {
                goto _exit;
            }
        }

        cb += cch * sizeof(wchar_t);
        scb = cb;

        pl = PMALLOC(cb);

        rv = khc_read_multi_string(csp_module, L"PluginList", pl, &cb);
        if(KHM_FAILED(rv)) {
            if(pl)
                PFREE(pl);
            goto _exit;
        }

    add_plugin_to_list:

        if(!multi_string_find(pl, plugin->name, 0)) {
            multi_string_append(pl, &scb, plugin->name);
            rv = khc_write_multi_string(csp_module, L"PluginList", pl);
        }

        PFREE(pl);
        CKRV;
    }

#undef CKRV

_exit:
    if(csp_plugin)
        khc_close_space(csp_plugin);
    if(csp_module)
        khc_close_space(csp_module);

    return rv;
}
예제 #17
0
void pw_update_property_data(HWND hw, pw_data * d)
{
    HWND hwnd_lv;
    khm_int32 * attrs = NULL;

    hwnd_lv = d->hwnd_lv;

    if(hwnd_lv == NULL)
        return;

    ListView_DeleteAllItems(hwnd_lv);

    if(d->record != NULL) {
        wchar_t * buffer;
        khm_size attr_count;
        khm_size i;
        khm_size cb_buf;
        khm_size t;
        LVITEM lvi;
        int idx;

        if(KHM_FAILED(kcdb_attrib_get_count(
            KCDB_ATTR_FLAG_VOLATILE |
            KCDB_ATTR_FLAG_HIDDEN,
            0,
            &attr_count)))
            return;

        attrs = PMALLOC(sizeof(khm_int32) * attr_count);
        assert(attrs != NULL);

        kcdb_attrib_get_ids(
            KCDB_ATTR_FLAG_VOLATILE |
            KCDB_ATTR_FLAG_HIDDEN,
            0,
            attrs,
            &attr_count);

        cb_buf = sizeof(wchar_t) * 2048;
        buffer = PMALLOC(cb_buf);
        assert(buffer != NULL);

        for(i=0; i<attr_count; i++) {
            if(KHM_FAILED(kcdb_buf_get_attr(d->record, attrs[i], NULL, NULL, NULL)))
                continue;

            ZeroMemory(&lvi, sizeof(lvi));
            lvi.mask = LVIF_TEXT | LVIF_PARAM;
            lvi.iItem = (int) i;
            lvi.iSubItem = 0;
            lvi.pszText = buffer;
            lvi.lParam = (LPARAM) attrs[i];

            t = cb_buf;
            kcdb_attrib_describe(attrs[i], buffer, &t, KCDB_TS_SHORT);

            idx = ListView_InsertItem(hwnd_lv, &lvi);

            ZeroMemory(&lvi, sizeof(lvi));
            lvi.mask = LVIF_TEXT;
            lvi.iItem = idx;
            lvi.iSubItem = 1;
            lvi.pszText = buffer;

            t = cb_buf;
            kcdb_buf_get_attr_string(d->record, attrs[i], buffer, &t, 0);

            ListView_SetItem(hwnd_lv, &lvi);
        }

        PFREE(attrs);
        PFREE(buffer);
    }
}
예제 #18
0
/* Returns true if we find cached prompts.
   Called with kt->cs held.
 */
static khm_boolean
cached_kinit_prompter(k5_kinit_task * kt) {
    khm_boolean rv = FALSE;
    khm_handle csp_idconfig = NULL;
    khm_handle csp_k5config = NULL;
    khm_handle csp_prcache = NULL;
    khm_size cb;
    khm_size n_cur_prompts;
    khm_int32 n_prompts;
    khm_int32 i;
    khm_int64 iexpiry;
    FILETIME expiry;

    assert(kt->nc);

    if (KHM_FAILED(kcdb_identity_get_config(kt->identity, 0, &csp_idconfig)) ||

        KHM_FAILED(khc_open_space(csp_idconfig, CSNAME_KRB5CRED,
                                  0, &csp_k5config)) ||

        KHM_FAILED(khc_open_space(csp_k5config, CSNAME_PROMPTCACHE,
                                  0, &csp_prcache)) ||

        KHM_FAILED(khc_read_int32(csp_prcache, L"PromptCount",
                                  &n_prompts)) ||
        n_prompts == 0)

        goto _cleanup;

    if (KHM_SUCCEEDED(khc_read_int64(csp_prcache, L"ExpiresOn", &iexpiry))) {
        FILETIME current;

        /* has the cache expired? */
        expiry = IntToFt(iexpiry);
        GetSystemTimeAsFileTime(&current);

        if (CompareFileTime(&expiry, &current) < 0)
            /* already expired */
            goto _cleanup;
    } else {
        /* if there is no value for ExpiresOn, we assume the prompts
           have already expired. */
        goto _cleanup;
    }

    /* we found a prompt cache.  We take this to imply that the
       principal is valid. */
    kt->is_valid_principal = TRUE;

    /* check if there are any prompts currently showing.  If there are
       we check if they are the same as the ones we are going to show.
       In which case we just reuse the exisitng prompts */
    if (KHM_FAILED(khui_cw_get_prompt_count(kt->nc, &n_cur_prompts)) ||
        n_prompts != (khm_int32) n_cur_prompts)
        goto _show_new_prompts;

    for(i = 0; i < n_prompts; i++) {
        wchar_t wsname[8];
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khm_handle csp_p = NULL;
        khm_int32 p_type;
        khm_int32 p_flags;
        khui_new_creds_prompt * p;

        if (KHM_FAILED(khui_cw_get_prompt(kt->nc, i, &p)))
            break;

        StringCbPrintf(wsname, sizeof(wsname), L"%d", i);

        if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
            break;

        cb = sizeof(wprompt);
        if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
                                       wprompt, &cb))) {
            khc_close_space(csp_p);
            break;
        }

        if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
            p_type = 0;

        if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
            p_flags = 0;

        if (                    /* if we received a prompt string,
                                   then it should be the same as the
                                   one that is displayed */
            (wprompt[0] &&
             (p->prompt == NULL ||
              wcscmp(wprompt, p->prompt))) ||

                                /* if we didn't receive one, then
                                   there shouldn't be one displayed.
                                   This case really shouldn't happen
                                   in reality, but we check anyway. */
            (!wprompt[0] &&
             p->prompt != NULL) ||

                                /* the type should match */
            (p_type != p->type) ||

                                /* if this prompt should be hidden,
                                   then it must also be so */
            (p_flags != p->flags)
            ) {

            khc_close_space(csp_p);
            break;

        }


        khc_close_space(csp_p);
    }

    if (i == n_prompts) {
        /* We are already showing the right set of prompts. */
        rv = TRUE;
        goto _cleanup;
    }

 _show_new_prompts:

    khui_cw_clear_prompts(kt->nc);

    {
        wchar_t wbanner[KHUI_MAXCCH_BANNER];
        wchar_t wpname[KHUI_MAXCCH_PNAME];

        cb = sizeof(wbanner);
        if (KHM_FAILED(khc_read_string(csp_prcache, L"Banner",
                                      wbanner, &cb)))
            wbanner[0] = 0;

        cb = sizeof(wpname);
        if (KHM_FAILED(khc_read_string(csp_prcache, L"Name",
                                       wpname, &cb)))
            wpname[0] = 0;

        if (wpname[0] == L'\0')
            LoadString(hResModule, IDS_PNAME_PW, wpname, ARRAYLENGTH(wpname));

        khui_cw_begin_custom_prompts(kt->nc,
                                     n_prompts,
                                     (wbanner[0]? wbanner: NULL),
                                     (wpname[0]? wpname: NULL));
    }

    for(i = 0; i < n_prompts; i++) {
        wchar_t wsname[8];
        wchar_t wprompt[KHUI_MAXCCH_PROMPT];
        khm_handle csp_p = NULL;
        khm_int32 p_type;
        khm_int32 p_flags;

        StringCbPrintf(wsname, sizeof(wsname), L"%d", i);

        if (KHM_FAILED(khc_open_space(csp_prcache, wsname, 0, &csp_p)))
            break;

        cb = sizeof(wprompt);
        if (KHM_FAILED(khc_read_string(csp_p, L"Prompt",
                                       wprompt, &cb))) {
            khc_close_space(csp_p);
            break;
        }

        if (KHM_FAILED(khc_read_int32(csp_p, L"Type", &p_type)))
            p_type = 0;

        if (KHM_FAILED(khc_read_int32(csp_p, L"Flags", &p_flags)))
            p_flags = 0;

        khui_cw_add_prompt(kt->nc, p_type, wprompt, NULL, p_flags);

        khc_close_space(csp_p);
    }

    if (i < n_prompts) {
        khui_cw_clear_prompts(kt->nc);
    } else {
        rv = TRUE;
    }

 _cleanup:

    if (csp_prcache)
        khc_close_space(csp_prcache);

    if (csp_k5config)
        khc_close_space(csp_k5config);

    if (csp_idconfig)
        khc_close_space(csp_idconfig);

    return rv;
}
예제 #19
0
khm_int32
krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
                 khm_ui_4 uparam, void * vparam) {

    switch(msg_subtype) {
    case KMSG_CRED_NEW_CREDS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct;
            khm_size cbsize;
            wchar_t wbuf[256];

            nc = (khui_new_creds *) vparam;

            nct = PMALLOC(sizeof(*nct));
#ifdef DEBUG
            assert(nct);
#endif
            ZeroMemory(nct, sizeof(*nct));

            nct->type = credtype_id_krb4;
            nct->ordinal = 3;
            LoadString(hResModule, IDS_NC_K4_SHORT,
                       wbuf, ARRAYLENGTH(wbuf));
            StringCbLength(wbuf, sizeof(wbuf), &cbsize);
            cbsize += sizeof(wchar_t);

            nct->name = PMALLOC(cbsize);
            StringCbCopy(nct->name, cbsize, wbuf);

            nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;

            nct->h_module = hResModule;
            nct->dlg_proc = k4_nc_dlg_proc;
            nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4);

            khui_cw_add_type(nc, nct);
        }
        break;

    case KMSG_CRED_RENEW_CREDS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct;
            khm_size cbsize;
            wchar_t wbuf[256];

            nc = (khui_new_creds *) vparam;

            if (!nc->ctx.identity)
                break;

            nct = PMALLOC(sizeof(*nct));
#ifdef DEBUG
            assert(nct);
#endif

            ZeroMemory(nct, sizeof(*nct));

            nct->type = credtype_id_krb4;
            nct->ordinal = 3;
            LoadString(hResModule, IDS_NC_K4_SHORT,
                       wbuf, ARRAYLENGTH(wbuf));
            StringCbLength(wbuf, sizeof(wbuf), &cbsize);
            cbsize += sizeof(wchar_t);

            nct->name = PMALLOC(cbsize);
            StringCbCopy(nct->name, cbsize, wbuf);

            nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;

            khui_cw_add_type(nc, nct);
        }
        break;

    case KMSG_CRED_DIALOG_SETUP:
        break;

    case KMSG_CRED_PROCESS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct = NULL;
            khm_handle ident = NULL;
            k4_dlg_data * d = NULL;
            long code = 0;
            wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
            khm_size cb;

            nc = (khui_new_creds *) vparam;
            if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
                break;

            if (nc->subtype == KMSG_CRED_NEW_CREDS ||
                nc->subtype == KMSG_CRED_RENEW_CREDS) {
                khm_int32 method;

                if (nc->subtype == KMSG_CRED_NEW_CREDS) {

                    d = (k4_dlg_data *) nct->aux;
                    if (!d ||
                        nc->n_identities == 0 ||
                        nc->identities[0] == NULL ||
                        nc->result != KHUI_NC_RESULT_PROCESS) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);
                        break;
                    }

                    if (!d->k4_enabled) {
                        k4_write_identity_data(d);
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);
                        break;
                    }

                    method = d->method;
                    ident = nc->identities[0];

                    cb = sizeof(idname);
                    kcdb_identity_get_name(ident, idname, &cb);
                    _begin_task(0);
                    _report_mr2(KHERR_NONE, MSG_K4_NEW_CREDS,
                                _cstr(ident), _int32(method));
                    _resolve();
                    _describe();

                } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                    if ((nc->ctx.scope == KHUI_SCOPE_IDENT &&
                         nc->ctx.identity != NULL) ||

                        (nc->ctx.scope == KHUI_SCOPE_CREDTYPE &&
                         nc->ctx.cred_type == credtype_id_krb4 &&
                         nc->ctx.identity != NULL) ||

                        (nc->ctx.scope == KHUI_SCOPE_CRED &&
                         nc->ctx.cred_type == credtype_id_krb4 &&
                         nc->ctx.identity != NULL &&
                         nc->ctx.cred != NULL)) {

                        ident = nc->ctx.identity;

                        if (!k4_should_identity_get_k4(ident)) {

                            _reportf(L"Kerberos 4 is not enabled for this identity.  Skipping");

                            khui_cw_set_response(nc, credtype_id_krb4,
                                                 KHUI_NC_RESPONSE_FAILED |
                                                 KHUI_NC_RESPONSE_EXIT);
                            break;
                        }

                    } else {

                        _reportf(L"Kerberos 4 is not within renewal scope. Skipping");

                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_FAILED |
                                             KHUI_NC_RESPONSE_EXIT);
                        break;
                    }

                    method = K4_METHOD_K524; /* only k524 is supported
                                                for renewals */

                    _begin_task(0);
                    cb = sizeof(idname);
                    kcdb_identity_get_name(ident, idname, &cb);
                    _report_mr2(KHERR_NONE, MSG_K4_RENEW_CREDS,
                                _cstr(ident), _int32(method));
                    _resolve();
                    _describe();
                } else {
                    assert(FALSE);
                    break;
                }

                if ((method == K4_METHOD_AUTO ||
                     method == K4_METHOD_K524) &&
                    khui_cw_type_succeeded(nc, credtype_id_krb5)) {

                    khm_handle tgt;
                    FILETIME ft_prev;
                    FILETIME ft_new;
                    khm_size cb;

                    _report_mr0(KHERR_INFO, MSG_K4_TRY_K524);

                    tgt = khm_krb4_find_tgt(NULL, ident);
                    if (tgt) {
                        cb = sizeof(ft_prev);
                        if (KHM_FAILED(kcdb_cred_get_attr(tgt,
                                                          KCDB_ATTR_EXPIRE,
                                                          NULL,
                                                          &ft_prev,
                                                          &cb)))
                            ZeroMemory(&ft_prev, sizeof(ft_prev));
                        kcdb_cred_release(tgt);
                    }

                    code = khm_convert524(ident);

                    _reportf(L"khm_convert524 returns code %d", code);

                    if (code == 0) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);

                        if (nc->subtype == KMSG_CRED_NEW_CREDS) {
                            assert(d != NULL);

                            k4_write_identity_data(d);

                        } else if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                                   (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
                                    nc->ctx.scope == KHUI_SCOPE_CRED)) {

                            khm_krb4_list_tickets();

                            tgt = khm_krb4_find_tgt(NULL, ident);

                            if (tgt) {
                                cb = sizeof(ft_new);
                                ZeroMemory(&ft_new, sizeof(ft_new));

                                kcdb_cred_get_attr(tgt,
                                                   KCDB_ATTR_EXPIRE,
                                                   NULL,
                                                   &ft_new,
                                                   &cb);

                                kcdb_cred_release(tgt);
                            }

                            if (!tgt ||
                                CompareFileTime(&ft_new,
                                                &ft_prev) <= 0) {
                                /* The new TGT wasn't much of an
                                   improvement over what we already
                                   had.  We should go out and try to
                                   renew the identity now. */

                                khui_action_context ctx;

                                _reportf(L"Renewal of Krb4 creds failed to get a longer TGT.  Triggering identity renewal");

                                khui_context_create(&ctx,
                                                    KHUI_SCOPE_IDENT,
                                                    nc->ctx.identity,
                                                    KCDB_CREDTYPE_INVALID,
                                                    NULL);
                                khui_action_trigger(KHUI_ACTION_RENEW_CRED,
                                                    &ctx);

                                khui_context_release(&ctx);
                            }
                        }

                        _end_task();
                        break;

                    } else if (method == K4_METHOD_K524) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_FAILED |
                                             KHUI_NC_RESPONSE_EXIT);

			if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
			    (nc->ctx.scope == KHUI_SCOPE_CREDTYPE ||
			     nc->ctx.scope == KHUI_SCOPE_CRED)) {
			    /* We were trying to get a new Krb4 TGT
			       for this identity.  Sometimes this
			       fails because of restrictions placed on
			       K524d regarding the lifetime of the
			       issued K4 TGT.  In this case, we
			       trigger a renewal of the identity in
			       the hope that the new K5 TGT will allow
			       us to successfully get a new K4 TGT
			       next time over using the new K5 TGT. */

			    khui_action_context ctx;

                            _reportf(L"Renewal of Krb4 creds failed using k524.  Triggerring identity renewal.");

			    khui_context_create(&ctx,
						KHUI_SCOPE_IDENT,
						nc->ctx.identity,
						KCDB_CREDTYPE_INVALID,
						NULL);

			    khui_action_trigger(KHUI_ACTION_RENEW_CRED,
						&ctx);

			    khui_context_release(&ctx);
			}

                        _end_task();
                        break;

                    }
                }

                /* only supported for new credentials */
                if (method == K4_METHOD_AUTO ||
                    method == K4_METHOD_PASSWORD) {

                    khm_size n_prompts = 0;
                    khm_size idx;
                    khm_size cb;
                    wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE];
                    char pwd[KHUI_MAXCCH_PROMPT_VALUE];
                    wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
                    char idname[KCDB_IDENT_MAXCCH_NAME];

                    char * aname = NULL;
                    char * inst = NULL;
                    char * realm = NULL;

                    assert(nc->subtype == KMSG_CRED_NEW_CREDS);

                    _report_mr0(KHERR_INFO, MSG_K4_TRY_PASSWORD);

                    code = TRUE; /* just has to be non-zero */

                    khui_cw_get_prompt_count(nc, &n_prompts);

                    if (n_prompts == 0)
                        goto _skip_pwd;

                    for (idx = 0; idx < n_prompts; idx++) {
                        khui_new_creds_prompt * p;

                        if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p)))
                            continue;

                        if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD)
                            break;
                    }

                    if (idx >= n_prompts) {
                        _reportf(L"Password prompt not found");
                        goto _skip_pwd;
                    }

                    khui_cw_sync_prompt_values(nc);

                    cb = sizeof(wpwd);
                    if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx,
                                                            wpwd,
                                                            &cb))) {
                        _reportf(L"Failed to obtain password value");
                        goto _skip_pwd;
                    }

                    UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);

                    cb = sizeof(widname);
                    kcdb_identity_get_name(ident,
                                           widname,
                                           &cb);

                    UnicodeStrToAnsi(idname, sizeof(idname), widname);

                    {
                        char * atsign;

                        atsign = strchr(idname, '@');
                        if (atsign == NULL) {
                            _reportf(L"Identity name does not contain an '@'");
                            goto _skip_pwd;
                        }

                        *atsign++ = 0;

                        realm = atsign;
                    }

                    {
                        char * slash;

                        slash = strchr(idname, '/');
                        if (slash != NULL) {
                            *slash++ = 0;
                            inst = slash;
                        } else {
                            inst = "";
                        }
                    }

                    aname = idname;

                    code = khm_krb4_kinit(aname, inst, realm,
                                          (long) d->lifetime, pwd);

                    _reportf(L"khm_krb4_kinit returns code %d", code);

                _skip_pwd:

                    if (code) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_EXIT |
                                             KHUI_NC_RESPONSE_FAILED);

                    } else {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_EXIT |
                                             KHUI_NC_RESPONSE_SUCCESS);

                        if (nc->subtype == KMSG_CRED_NEW_CREDS) {

                            assert(d != NULL);
                            k4_write_identity_data(d);

                        }
                    }
                }

                _end_task();
            }
        }
        break;

    case KMSG_CRED_END:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct = NULL;

            nc = (khui_new_creds *) vparam;
            if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
                break;

            khui_cw_del_type(nc, credtype_id_krb4);

            if (nct->name)
                PFREE(nct->name);

            if (nct->credtext)
                PFREE(nct->credtext);

            PFREE(nct);
        }
        break;
    }

    return KHM_ERROR_SUCCESS;
}
예제 #20
0
khm_int32
kmmint_read_module_info(kmm_module_i * m) {
    /* the only fields we can count on at this point are m->name and
       m->path */
    DWORD t;
    size_t cb;
    WORD lang;
    khm_int32 rv = KHM_ERROR_SUCCESS;
    struct lang_code *languages;
    int n_languages;
    int i;
    wchar_t resname[256];       /* the resource names are a lot shorter */
    wchar_t * r;
    VS_FIXEDFILEINFO *vff;
    UINT c;

    assert(m->name);
    assert(m->path);

    t = TRUE;
    cb = GetFileVersionInfoSize(m->path,
                                &t);
    /* if successful, cb gets the size in bytes of the version info
       structure and sets t to zero */
    if (t) {
        return KHM_ERROR_NOT_FOUND;
    } else if (cb == 0) {
        _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path));
        return KHM_ERROR_INVALID_PARAM;
    }

    if (m->version_info) {
        PFREE(m->version_info);
        m->version_info = NULL;
    }

    m->version_info = PMALLOC(cb);
#ifdef DEBUG
    assert(m->version_info);
#endif

    if(!GetFileVersionInfo(m->path,
                           t, (DWORD) cb, m->version_info)) {
        rv = KHM_ERROR_NOT_FOUND;
        _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path));
        _location(L"GetFileVersionInfo");
        goto _cleanup;
    }

    if(!VerQueryValue(m->version_info,
                     L"\\VarFileInfo\\Translation",
                     (LPVOID*) &languages,
                     &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_NO_TRANS, _dupstr(m->path));
        _location(L"VerQueryValue");
        goto _cleanup;
    }

    n_languages = (int) (c / sizeof(*languages));

    /* Try searching for the user's default language first */
    lang = GetUserDefaultLangID();
    for (i = 0; i < n_languages; i++) {
        if(languages[i].language == lang)
            break;
    }

    /* If not, try the system default */
    if (i >= n_languages) {
        lang = GetSystemDefaultLangID();
        for (i=0; i<n_languages; i++)
            if (languages[i].language == lang)
                break;
    }

    /* Then try EN_US */
    if (i >= n_languages) {
        lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
        for (i=0; i<n_languages; i++)
            if (languages[i].language == lang)
                break;
    }

    /* Language neutral? */
    if (i >= n_languages) {
        lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
        for (i=0; i<n_languages; i++)
            if (languages[i].language == lang)
                break;
    }

    /* Just use the first one? */
    if (i >= n_languages) {
        i = 0;
    }

    if (i >= n_languages) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr0(KHERR_WARNING, MSG_RMI_NO_LOCAL);
        goto _cleanup;
    }

    /* check module name */
    StringCbPrintf(resname, sizeof(resname),
                   L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_MODULE),
                   languages[i].language,
                   languages[i].codepage);

    if (!VerQueryValue(m->version_info,
                       resname, (LPVOID *) &r, &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, 
                    _cstr(TEXT(NIMV_MODULE)));
        goto _cleanup;
    }

    if (c > KMM_MAXCB_NAME ||
        FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG,
                    _cstr(TEXT(NIMV_MODULE)));
        goto _cleanup;
    }

    if (wcscmp(r, m->name)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr2(KHERR_WARNING, MSG_RMI_MOD_MISMATCH,
                    _dupstr(r), _dupstr(m->name));
        goto _cleanup;
    }

    /* check API version */
    StringCbPrintf(resname, sizeof(resname),
                   L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_APIVER),
                   languages[i].language,
                   languages[i].codepage);

    if (!VerQueryValue(m->version_info,
                       resname, (LPVOID *) &r, &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, 
                    _cstr(TEXT(NIMV_APIVER)));
        goto _cleanup;
    }

    if (c > KMM_MAXCB_NAME ||
        FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG,
                    _cstr(TEXT(NIMV_APIVER)));
        goto _cleanup;
    }

    t = wcstol(r, NULL, 10);

    rv = kmmint_check_api_version(t);

    if (KHM_FAILED(rv)) {
        _report_mr2(KHERR_WARNING, MSG_RMI_API_MISMATCH,
                    _int32(t), _int32(KH_VERSION_API));
        goto _cleanup;
    }

    /* Looks good.  Now load the description, copyright, support URI
       and file versions */
    if (m->description) {
        PFREE(m->description);
        m->description = NULL;
    }

    StringCbPrintf(resname, sizeof(resname),
                   L"\\StringFileInfo\\%04x%04x\\FileDescription",
                   languages[i].language,
                   languages[i].codepage);

    if (!VerQueryValue(m->version_info,
                       resname, (LPVOID *) &r, &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, 
                    _cstr(L"FileDescription"));
        goto _cleanup;
    }

    if (c > KMM_MAXCB_DESC ||
        FAILED(StringCbLength(r, KMM_MAXCB_DESC, &cb))) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG,
                    _cstr(L"FileDescription"));
        goto _cleanup;
    }

    cb += sizeof(wchar_t);

    m->description = PMALLOC(cb);
#ifdef DEBUG
    assert(m->description);
#endif
    StringCbCopy(m->description, cb, r);

    /* on to the support URI */
    if (m->support) {
        PFREE(m->support);
        m->support = NULL;
    }

    StringCbPrintf(resname, sizeof(resname),
                   L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_SUPPORT),
                   languages[i].language,
                   languages[i].codepage);

    if (!VerQueryValue(m->version_info,
                       resname, (LPVOID *) &r, &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING,
                    _cstr(TEXT(NIMV_SUPPORT)));
        goto _cleanup;
    }

    if (c > KMM_MAXCB_SUPPORT ||
        FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG,
                    _cstr(TEXT(NIMV_SUPPORT)));
        goto _cleanup;
    }

    cb += sizeof(wchar_t);

    m->support = PMALLOC(cb);
#ifdef DEBUG
    assert(m->support);
#endif
    StringCbCopy(m->support, cb, r);

    /* the vendor/copyright */
    if (m->vendor) {
        PFREE(m->vendor);
        m->vendor = NULL;
    }

    StringCbPrintf(resname, sizeof(resname),
                   L"\\StringFileInfo\\%04x%04x\\LegalCopyright",
                   languages[i].language,
                   languages[i].codepage);

    if (!VerQueryValue(m->version_info,
                       resname, (LPVOID *) &r, &c)) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, 
                    _cstr(L"LegalCopyright"));
        goto _cleanup;
    }

    if (c > KMM_MAXCB_SUPPORT ||
        FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) {
        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG,
                    _cstr(L"LegalCopyright"));
        goto _cleanup;
    }

    cb += sizeof(wchar_t);

    m->vendor = PMALLOC(cb);
#ifdef DEBUG
    assert(m->vendor);
#endif
    StringCbCopy(m->vendor, cb, r);

    if (!VerQueryValue(m->version_info,
                       L"\\",
                       (LPVOID *) &vff, &c) ||
        c != sizeof(*vff)) {

        rv = KHM_ERROR_INVALID_PARAM;
        _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, 
                    _cstr(L"Fixed Version Info"));
        goto _cleanup;
    }

    m->file_version.major = HIWORD(vff->dwFileVersionMS);
    m->file_version.minor = LOWORD(vff->dwFileVersionMS);
    m->file_version.patch = HIWORD(vff->dwFileVersionLS);
    m->file_version.aux   = LOWORD(vff->dwFileVersionLS);

    m->prod_version.major = HIWORD(vff->dwProductVersionMS);
    m->prod_version.minor = LOWORD(vff->dwProductVersionMS);
    m->prod_version.patch = HIWORD(vff->dwProductVersionLS);
    m->prod_version.aux   = LOWORD(vff->dwProductVersionLS);

    rv = KHM_ERROR_SUCCESS;

 _cleanup:
    if (KHM_FAILED(rv)) {
        if (m->version_info) {
            PFREE(m->version_info);
            m->version_info = NULL;
        }
    }

    return rv;
}
예제 #21
0
INT_PTR CALLBACK
khm_cfg_plugins_proc(HWND hwnd,
                     UINT uMsg,
                     WPARAM wParam,
                     LPARAM lParam) {

    plugin_dlg_data * d;

    switch(uMsg) {
    case WM_INITDIALOG:
        {
            kmm_plugin p;
            kmm_plugin pn;
            kmm_module m;
            khm_size i;
            LVCOLUMN lvc;
            RECT r;
            HWND hw;
            wchar_t buf[256];
            HIMAGELIST h_ilist;
            HICON h_icon;

            d = PMALLOC(sizeof(*d));
#ifdef DEBUG
            assert(d);
#endif
            ZeroMemory(d, sizeof(*d));
#pragma warning(push)
#pragma warning(disable: 4244)
            SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
#pragma warning(pop)

            p = NULL;
            i = 0;
            do {
                if (KHM_FAILED(kmm_get_next_plugin(p, &pn)))
                    break;

                if (p)
                    kmm_release_plugin(p);
                p = pn;

#ifdef DEBUG
                assert(d->info[i] == NULL);
#endif
                d->info[i] = PMALLOC(sizeof(*(d->info[i])));
#ifdef DEBUG
                assert(d->info[i]);
#endif
                ZeroMemory(&d->info[i]->plugin,
                           sizeof(d->info[i]->plugin));

                if (KHM_FAILED(kmm_get_plugin_info_i(p, &d->info[i]->plugin))) {
                    PFREE(d->info[i]);
                    d->info[i] = NULL;
                    break;
                }

                ZeroMemory(&d->info[i]->module,
                           sizeof(d->info[i]->module));

                if (KHM_SUCCEEDED(kmm_load_module(d->info[i]->plugin.reg.module,
                                                  KMM_LM_FLAG_NOLOAD,
                                                  &m))) {
                    kmm_get_module_info_i(m, &d->info[i]->module);
                    kmm_release_module(m);
                }

                i ++;

                if (i == MAX_PLUGINS)
                    break;
            } while(p);

            if (p)
                kmm_release_plugin(p);

            d->n_info = i;

            /* now populate the list view */
            hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS);
#ifdef DEBUG
            assert(hw);
#endif

            h_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
                                       GetSystemMetrics(SM_CYSMICON),
                                       ILC_COLOR8,
                                       4, 4);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN_DIS),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN_ERR),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            ListView_SetImageList(hw, h_ilist, LVSIL_STATE);

            ZeroMemory(&lvc, sizeof(lvc));

            lvc.mask = LVCF_TEXT | LVCF_WIDTH;
            GetWindowRect(hw, &r);
            lvc.cx = ((r.right - r.left) * 95) / 100;
            lvc.pszText = buf;

            LoadString(khm_hInstance, IDS_CFG_PI_COL_PLUGINS,
                       buf, ARRAYLENGTH(buf));

            ListView_InsertColumn(hw, 0, &lvc);

            for(i=0; i<d->n_info; i++) {
                LVITEM lvi;

                ZeroMemory(&lvi, sizeof(lvi));

                lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
                lvi.lParam = (LPARAM) d->info[i];
                lvi.pszText = d->info[i]->plugin.reg.name;

                if (d->info[i]->plugin.flags & KMM_PLUGIN_FLAG_DISABLED) {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_DISABLED);
                } else if (d->info[i]->plugin.state < 0) {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_ERROR);
                } else {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_NORMAL);
                }

                ListView_InsertItem(hw, &lvi);
            }

            d->plugin_ico =
                (HICON) LoadImage(khm_hInstance,
                                  MAKEINTRESOURCE(IDI_CFG_PLUGIN),
                                  IMAGE_ICON,
                                  GetSystemMetrics(SM_CXICON),
                                  GetSystemMetrics(SM_CYICON),
                                  LR_DEFAULTCOLOR);
        }
        return FALSE;

    case WM_NOTIFY:
        {
            LPNMHDR lpnm;
            HWND hw;

            d = (plugin_dlg_data *) (LONG_PTR) 
                GetWindowLongPtr(hwnd, DWLP_USER);
            if (d == NULL)
                return FALSE;

            if (wParam == IDC_CFG_PLUGINS &&
                (lpnm = (LPNMHDR) lParam) &&
                lpnm->code == LVN_ITEMCHANGED) {

                LVITEM lvi;

                hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS);
#ifdef DEBUG
                assert(hw);
#endif
                if (ListView_GetSelectedCount(hw) != 1) {
                    SetDlgItemText(hwnd, IDC_CFG_DESC, L"");
                    SetDlgItemText(hwnd, IDC_CFG_STATE, L"");
                    SetDlgItemText(hwnd, IDC_CFG_MODULE, L"");
                    SetDlgItemText(hwnd, IDC_CFG_VENDOR, L"");
                    SetDlgItemText(hwnd, IDC_CFG_VERSION, L"");
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_ENABLE), FALSE);
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_DISABLE), FALSE);
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_UNREGISTER), FALSE);
                    SendDlgItemMessage(hwnd, IDC_CFG_DEPS, 
                                       LB_RESETCONTENT, 0, 0);
                    SendDlgItemMessage(hwnd, IDC_CFG_ICON, STM_SETICON,
                                       (WPARAM) d->plugin_ico, 0);
                    d->selected = NULL;
                } else {
                    int idx;
                    plugin_data * info;

                    idx = ListView_GetNextItem(hw, -1, LVNI_SELECTED);
#ifdef DEBUG
                    assert(idx != -1);
#endif
                    ZeroMemory(&lvi, sizeof(lvi));
                    lvi.iItem = idx;
                    lvi.iSubItem = 0;
                    lvi.mask = LVIF_PARAM;

                    ListView_GetItem(hw, &lvi);
#ifdef DEBUG
                    assert(lvi.lParam != 0);
#endif
                    info = (plugin_data *) lvi.lParam;

                    update_dialog_fields(hwnd, d, info);
                }
            }
        }
        return TRUE;

    case WM_COMMAND:
        {

            d = (plugin_dlg_data *) (LONG_PTR)
                GetWindowLongPtr(hwnd, DWLP_USER);
            if (d == NULL)
                return FALSE;

            switch (wParam) {
            case MAKEWPARAM(IDC_CFG_ENABLE, BN_CLICKED):
                if (d->selected != NULL) {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    kmm_plugin p;

                    khui_alert_create_empty(&alert);

                    LoadString(khm_hInstance, IDS_CFG_P_ENBCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_ENBCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_message(alert, buf);

                    khui_alert_set_severity(alert, KHERR_INFO);

                    khui_alert_show_modal(alert);

                    kmm_enable_plugin(d->selected->plugin.h_plugin, TRUE);

                    khui_alert_release(alert);

                    p = d->selected->plugin.h_plugin;
                    kmm_hold_plugin(p);
                    kmm_release_plugin_info_i(&d->selected->plugin);
                    kmm_get_plugin_info_i(p, &d->selected->plugin);
                    kmm_release_plugin(p);

                    update_dialog_fields(hwnd, d, d->selected);
                }
                break;

            case MAKEWPARAM(IDC_CFG_DISABLE, BN_CLICKED):
                if (d->selected != NULL) {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    wchar_t depends[KHUI_MAXCCH_MESSAGE];
                    khm_size i;
                    kmm_plugin p;

                    khui_alert_create_empty(&alert);
#ifdef DEBUG
                    assert(alert);
#endif
                    if (alert == NULL)
                        break;

                    LoadString(khm_hInstance, IDS_CFG_P_DELCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_DELCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_message(alert, buf);

                    depends[0] = L'\0';

                    for (i=0; i<d->n_info; i++) {
                        wchar_t * t;

                        t = d->info[i]->plugin.reg.dependencies;

                        while(t) {
                            if (!wcscmp(t, d->selected->plugin.reg.name)) {
                                if (depends[0])
                                    StringCbCat(depends, sizeof(depends), L", ");
                                StringCbCat(depends, sizeof(depends),
                                            d->info[i]->plugin.reg.name);
                                break;
                            }
                            t = multi_string_next(t);
                        }
                    }

                    if (depends[0]) {
                        LoadString(khm_hInstance, IDS_CFG_P_DELCNFS,
                                   fmt, ARRAYLENGTH(fmt));
                        StringCbPrintf(buf, sizeof(buf), fmt, depends);
                        khui_alert_set_suggestion(alert, buf);
                    } else {
                        LoadString(khm_hInstance, IDS_CFG_P_DELNDEP,
                                   buf, ARRAYLENGTH(buf));
                        khui_alert_set_suggestion(alert, buf);
                    }

                    khui_alert_add_command(alert, KHUI_PACTION_YES);
                    khui_alert_add_command(alert, KHUI_PACTION_NO);

                    khui_alert_set_severity(alert, KHERR_WARNING);

                    if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) &&
                        alert->response == KHUI_PACTION_YES) {
                        kmm_enable_plugin(d->selected->plugin.h_plugin, FALSE);
                    }

                    khui_alert_release(alert);

                    p = d->selected->plugin.h_plugin;
                    kmm_hold_plugin(p);
                    kmm_release_plugin_info_i(&d->selected->plugin);
                    kmm_get_plugin_info_i(p, &d->selected->plugin);
                    kmm_release_plugin(p);

                    update_dialog_fields(hwnd, d, d->selected);
                }
                break;

            case MAKEWPARAM(IDC_CFG_UNREGISTER, BN_CLICKED):
                {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    wchar_t plist[KHUI_MAXCCH_MESSAGE];
                    khm_size i;

                    if (d->selected == NULL) {
#ifdef DEBUG
                        assert(FALSE);
#endif
                        break;
                    }

                    khui_alert_create_empty(&alert);

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt,
                                   d->selected->plugin.reg.name);

                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt,
                                   d->selected->plugin.reg.name);

                    khui_alert_set_message(alert, buf);

                    plist[0] = L'\0';
                    for (i=0; i < d->n_info; i++) {
                        if (!wcscmp(d->info[i]->module.reg.name,
                                    d->selected->module.reg.name)) {
                            if (plist[0])
                                StringCbCat(plist, sizeof(plist), L", ");
                            StringCbCat(plist, sizeof(plist),
                                        d->info[i]->plugin.reg.name);
                        }
                    }

#ifdef DEBUG
                    /* there should have been at least one plugin */
                    assert(plist[0]);
#endif

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFS,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, plist);
                    khui_alert_set_suggestion(alert, buf);

                    khui_alert_add_command(alert, KHUI_PACTION_YES);
                    khui_alert_add_command(alert, KHUI_PACTION_NO);

                    khui_alert_set_severity(alert, KHERR_WARNING);

                    if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) &&
                        alert->response == KHUI_PACTION_YES) {
                        kmm_unregister_module(d->selected->module.reg.name, 0);

                        update_dialog_fields(hwnd, d, d->selected);
                    }
                }
                break;

            case MAKEWPARAM(IDC_CFG_REGISTER, BN_CLICKED):
                {
                    
                }
                break;
            }
        }
        return TRUE;

    case WM_DESTROY:
        {
            khm_size i;

            d = (plugin_dlg_data *) (LONG_PTR) 
                GetWindowLongPtr(hwnd, DWLP_USER);
#ifdef DEBUG
            assert(d);
#endif
            if (d == NULL)
                return TRUE;

            for (i=0; i<d->n_info; i++) {
#ifdef DEBUG
                assert(d->info[i]);
#endif
                kmm_release_plugin_info_i(&d->info[i]->plugin);
                kmm_release_module_info_i(&d->info[i]->module);
                PFREE(d->info[i]);
            }

            PFREE(d);
            SetWindowLongPtr(hwnd, DWLP_USER, 0);

            khm_set_dialog_result(hwnd, 0);
        }
        return TRUE;
    }
    return FALSE;
}
예제 #22
0
static void
read_params_ident(ident_data * d) {
    khm_handle csp_ident;
    khm_handle csp_cw;
    khm_int32 t;

    if (KHM_FAILED(kcdb_identity_get_config(d->ident,
                                            KHM_PERM_READ,
                                            &csp_ident))) {
        csp_ident = NULL;
    }

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_READ,
                                     &csp_cw))) {
        if (csp_ident) {
            khc_shadow_space(csp_ident,
                             csp_cw);
            khc_close_space(csp_cw);
        } else {
            csp_ident = csp_cw;
        }
        csp_cw = NULL;
    } else {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.monitor = TRUE;
        d->saved.auto_renew = TRUE;
        d->saved.sticky = FALSE;
        d->work = d->saved;

        if (csp_ident)
            khc_close_space(csp_ident);

        return;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"Monitor", &t))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.monitor = TRUE;
    } else {
        d->saved.monitor = !!t;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"AllowAutoRenew", &t))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        d->saved.auto_renew = TRUE;
    } else {
        d->saved.auto_renew = !!t;
    }

    if (KHM_FAILED(khc_read_int32(csp_ident, L"Sticky", &t))) {
        d->saved.sticky = FALSE;
    } else {
        d->saved.sticky = !!t;
    }

    khc_close_space(csp_ident);

    d->work = d->saved;
    d->applied = FALSE;
}
예제 #23
0
/*! \internal
  \brief Manages a plugin message thread.

  Each plugin gets its own plugin thread which is used to dispatch
  messages to the plugin.  This acts as the thread function for the
  plugin thread.*/
DWORD WINAPI kmmint_plugin_broker(LPVOID lpParameter)
{
    DWORD rv = 0;
    kmm_plugin_i * p = (kmm_plugin_i *) lpParameter;

    PDESCTHREAD(p->p.name, L"KMM");

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_PB_START, _cstr(p->p.name));
    _describe();

    TlsSetValue(tls_kmm, (LPVOID) p);

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    p->tid_thread = GetCurrentThreadId();

    if (IsBadCodePtr(p->p.msg_proc)) {
        _report_mr0(KHERR_WARNING, MSG_PB_INVALID_CODE_PTR);
        rv = KHM_ERROR_INVALID_PARAM;
    } else {
        rv = (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_INIT, 
                              0, (void *) &(p->p));
        _report_mr1(KHERR_INFO, MSG_PB_INIT_RV, _int32(rv));
    }

    /* if it fails to initialize, we exit the plugin */
    if(KHM_FAILED(rv)) {

        kherr_report(KHERR_ERROR,
                     (wchar_t *) MSG_PB_INIT_FAIL_S,
                     (wchar_t *) KHERR_FACILITY,
                     NULL,
                     (wchar_t *) MSG_PB_INIT_FAIL,
                     (wchar_t *) MSG_PB_INIT_FAIL_G,
                     KHERR_FACILITY_ID,
                     KHERR_SUGGEST_NONE,
                     _cstr(p->p.name),
                     _cstr(p->p.description),
                     _cstr(p->module->path),
                     _cstr(p->module->support),
                     KHERR_RF_MSG_SHORT_DESC |
                     KHERR_RF_MSG_LONG_DESC |
                     KHERR_RF_MSG_SUGGEST
#ifdef _WIN32
                     ,KHERR_HMODULE
#endif
                     );
        _resolve();

        /* exit the plugin first.  Otherwise it may not uninitialize correctly */
        (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p));

        kmmint_remove_from_plugin_queue(p);
        rv = 1;
        _end_task();

        p->state = KMM_PLUGIN_STATE_FAIL_INIT;
        goto _exit;
    }

    /* subscribe to default message classes by plugin type */
    if(p->p.type == KHM_PITYPE_CRED) {
        kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_subscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_subscribe(KMSG_CRED, p->p.msg_proc);
    } else if(p->p.type == KHM_PITYPE_IDENT) {
        khm_handle h = NULL;

        kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_subscribe(KMSG_KCDB, p->p.msg_proc);

        kmq_create_subscription(p->p.msg_proc, &h);
        kcdb_identity_set_provider(h);
        /* kcdb deletes the subscription when it's done with it */
    } else if(p->p.type == KHM_PITYPE_CONFIG) {
        /*TODO: subscribe to configuration provider messages here */
    }

    p->state = KMM_PLUGIN_STATE_RUNNING;

    _report_mr0(KHERR_INFO, MSG_PB_INIT_DONE);

    _end_task();

    /* if there were any plugins that were waiting for this one to
       start, we should start them too */
    EnterCriticalSection(&cs_kmm);
    do {
        kmm_plugin_i * pd;
        int i;

        for(i=0; i < p->n_dependants; i++) {
            pd = p->dependants[i];

            pd->n_unresolved--;

            if(pd->n_unresolved == 0) {
                kmmint_add_to_plugin_queue(pd);
                kmm_hold_plugin(kmm_handle_from_plugin(pd));
                kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_INIT_PLUGIN, (void *) pd);
            }
        }
    } while(FALSE);
    LeaveCriticalSection(&cs_kmm);

    kmmint_remove_from_plugin_queue(p);

    /* main message loop */
    while(KHM_SUCCEEDED(kmq_dispatch(INFINITE)));

    /* unsubscribe from default message classes by plugin type */
    if(p->p.type == KHM_PITYPE_CRED) {
        kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc);
        kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_unsubscribe(KMSG_CRED, p->p.msg_proc);
    } else if (p->p.type == KHM_PITYPE_IDENT) {
        kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc);
        kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc);
        kcdb_identity_set_provider(NULL);
    } else if(p->p.type == KHM_PITYPE_CONFIG) {
        /*TODO: unsubscribe from configuration provider messages here */
    }

    p->p.msg_proc(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p));

 _exit:
    if (p->state >= 0)
        p->state = KMM_PLUGIN_STATE_EXITED;

    /* the following call will automatically release the plugin */
    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, 
                     KMM_REG_EXIT_PLUGIN, (void *) p);

    TlsSetValue(tls_kmm, (LPVOID) 0);

    ExitThread(rv);

    /* not reached */
    return rv;
}
예제 #24
0
static void
add_subpanels(HWND hwnd, 
              khui_config_node ctx_node,
              khui_config_node ref_node) {

    HWND hw_tab;
    HWND hw_target;
    khui_config_node sub;
    khui_config_node_reg reg;
    khui_config_init_data idata;
    int idx;

    hw_tab = GetDlgItem(hwnd, IDC_CFG_TAB);
    hw_target = GetDlgItem(hwnd, IDC_CFG_TARGET);
#ifdef DEBUG
    assert(hw_tab);
    assert(hw_target);
#endif

    if (KHM_FAILED(khui_cfg_get_first_subpanel(ref_node, &sub))) {
#ifdef DEBUG
        assert(FALSE);
#endif
        return;
    }

    idx = 0;
    while(sub) {
        HWND hwnd_panel;
        TCITEM tci;
        int iid;

        khui_cfg_get_reg(sub, &reg);

        if ((ctx_node == ref_node && (reg.flags & KHUI_CNFLAG_PLURAL)) ||
            (ctx_node != ref_node && !(reg.flags & KHUI_CNFLAG_PLURAL)))
            goto _next_node;

        idata.ctx_node = ctx_node;
        idata.this_node = sub;
        idata.ref_node = ref_node;

        hwnd_panel = CreateDialogParam(reg.h_module,
                                       reg.dlg_template,
                                       hwnd,
                                       reg.dlg_proc,
                                       (LPARAM) &idata);

#ifdef DEBUG
        assert(hwnd_panel);
#endif

        ShowWindow(hwnd_panel, SW_HIDE);

        ZeroMemory(&tci, sizeof(tci));

        tci.mask = TCIF_PARAM | TCIF_TEXT;
        tci.lParam = (LPARAM) sub;
        tci.pszText = (LPWSTR) reg.short_desc;

        iid = TabCtrl_InsertItem(hw_tab, 0, &tci);
        idx++;

        if (reg.flags & KHUI_CNFLAG_PLURAL) {
            khui_cfg_set_param_inst(sub, ctx_node, iid);
            khui_cfg_set_hwnd_inst(sub, ctx_node, hwnd_panel);
        } else {
            khui_cfg_set_param(sub, iid);
            khui_cfg_set_hwnd(sub, hwnd_panel);
        }

    _next_node:

        khui_cfg_get_next_release(&sub);
    }

    TabCtrl_SetCurSel(hw_tab, 0);
}
예제 #25
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

        /* This is the first message that will be received by a
           plugin.  We use it to perform initialization operations
           such as registering any credential types, data types and
           attributes. */
    case KMSG_SYSTEM_INIT:
        {
            kcdb_credtype ct;
            wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
            wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
            khui_config_node cnode;
            khui_config_node_reg creg;
            kcdb_attrib attr;
            khm_handle csp_plugin = NULL;
            khm_handle csp_plugins = NULL;

#ifdef BUILD_KRBCOMPAT
            /* If we don't have a Kerberos backend, then we can't
             * function. */
            if (!DelayLoadHeimdal()) {
		_reportf("Can't initialize a Kerberos backend.  LastError=%d", GetLastError());
                return KHM_ERROR_NOT_FOUND;
            }
#endif

#if KH_VERSION_API < 12

            do {
                khm_version libver;
                khm_ui_4 apiver;

                khm_get_lib_version(&libver, &apiver);

                if (apiver < 7)
                    break;

                hm_netidmgr = LoadLibrary(NIMDLLNAME);

                if (hm_netidmgr == NULL)
                    break;

#if KH_VERSION_API < 7
                pkhui_action_lock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_lock);
                pkhui_action_unlock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_unlock);
                pkhui_refresh_actions = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_refresh_actions);
                pkhui_request_UI_callback = (khm_int32 (KHMAPI *)(khm_ui_callback, void *))
                    GetProcAddress(hm_netidmgr, API_khui_request_UI_callback);
#endif
                pkhui_cw_get_primary_id = (khm_int32 (KHMAPI *)(khui_new_creds *, khm_handle *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_primary_id);
                pkhui_cw_get_result = (khm_int32 (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_result);
                pkhui_cw_get_subtype = (khui_nc_subtype (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_subtype);
                pkhui_cw_get_ctx = (khui_action_context * (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_ctx);
                pkcdb_get_resource = (khm_int32 (KHMAPI *)(khm_handle, kcdb_resource_id,
                                                           khm_int32, khm_int32 *,
                                                           void *, void *, khm_size *))
                    GetProcAddress(hm_netidmgr, API_kcdb_get_resource);
            } while (FALSE);

            if (pkhui_cw_get_primary_id == NULL)
              pkhui_cw_get_primary_id = int_khui_cw_get_primary_id;

            if (pkhui_cw_get_result == NULL)
                pkhui_cw_get_result = int_khui_cw_get_result;

            if (pkhui_cw_get_subtype == NULL)
                pkhui_cw_get_subtype = int_khui_cw_get_subtype;

            if (pkhui_cw_get_ctx == NULL)
                pkhui_cw_get_ctx = int_khui_cw_get_ctx;

            if (pkcdb_get_resource == NULL)
                pkcdb_get_resource = int_kcdb_get_resource;
#endif

            /* Add the icon now.  On NIM v2.x, doing so after tokens
               were reported may result in a deadlock as we try to
               switch to the UI thread and the UI thread is blocked on
               a resource request to this plug-in. */
            kca_icon_set_state(NULL);

            /* First and foremost, we need to register a credential
               type. */
            ZeroMemory(&ct, sizeof(ct));
            ct.id = KCDB_CREDTYPE_AUTO;
            ct.name = MYCREDTYPE_NAMEW;
            ct.short_desc = short_desc;
            ct.long_desc = long_desc;

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            ct.icon = NULL;     /* We skip the icon for now, but you
                                   can assign a handle to an icon
                                   here.  The icon will be used to
                                   represent the credentials type.*/

            kmq_create_subscription(plugin_msg_proc, &ct.sub);

            ct.is_equal = cred_is_equal;

            rv = kcdb_credtype_register(&ct, &credtype_id);

            /* We create a global credential set that we use in the
               plug-in thread.  This alleviates the need to create one
               everytime we need one. Keep in mind that this should
               only be used in the plug-in thread and should not be
               touched from the UI thread or any other thread. */
            kcdb_credset_create(&g_credset);

            /* TODO: Perform additional initialization operations. */

            /* Register our attributes */

            ZeroMemory(&attr, sizeof(attr));

            attr.name = ATTRNAME_KCA_AUTHREALM;
            attr.id = KCDB_ATTR_INVALID;
            attr.alt_id = KCDB_ATTR_INVALID;
            attr.flags = 0;
            attr.type = KCDB_TYPE_STRING;
            attr.short_desc = short_desc;
            attr.long_desc = long_desc;
            attr.compute_cb = NULL;
            attr.compute_min_cbsize = 0;
            attr.compute_max_cbsize = 0;

            LoadString(hResModule, IDS_ATTR_REALM_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_REALM_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_auth_realm);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_EMAIL;

            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_email);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_DISPLAY;

            LoadString(hResModule, IDS_ATTR_SUBJECT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_DISPLAY;

            LoadString(hResModule, IDS_ATTR_ISSUER_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_ISSUER_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_NAME;
            attr.flags = KCDB_ATTR_FLAG_HIDDEN;
            attr.type = KCDB_TYPE_DATA;
            attr.short_desc = NULL;
            attr.long_desc = NULL;

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_name);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SERIAL;

            rv = kcdb_attrib_register(&attr, &attr_id_serial_number);
            if (KHM_FAILED(rv))
                break;

            /* List the credentials that are already here */
            kca_list_creds();

            /* Now we register our configuration panels. */

#ifdef GENERAL_CONFIG_PANEL
            /* This configuration panel is the one that controls
               general options.  We leave the identity specific and
               identity defaults for other configuration panels. */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_MAIN;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
            creg.dlg_proc = config_dlgproc;
            creg.flags = 0;

            khui_cfg_register(NULL, &creg);
#endif

            /* Now we do the identity specific and identity default
               configuration panels. "KhmIdentities" is a predefined
               configuration node under which all the identity spcific
               configuration is managed. */

            if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
                /* this should always work */
                assert(FALSE);
                rv = KHM_ERROR_NOT_FOUND;
                break;
            }

            /* First the tab panel for defaults for all identities */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_ALL_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
            creg.dlg_proc = config_ids_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL;

            khui_cfg_register(cnode, &creg);

            /* Now the panel for per identity configuration */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_PER_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
            creg.dlg_proc = config_id_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

            khui_cfg_register(cnode, &creg);

            khui_cfg_release(cnode);

            /* load the schema */
            if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
                khc_load_schema(csp_plugins, plugin_schema);
                khc_close_space(csp_plugins);
            }

            /* open the plug-in and parameter configuration spaces */
            if (KHM_SUCCEEDED(kmm_get_plugin_config(MYPLUGIN_NAMEW,
                                                    KHM_FLAG_CREATE,
                                                    &csp_plugin))) {
                khc_open_space(csp_plugin, L"Parameters", KHM_FLAG_CREATE,
                               &csp_params);

                khc_close_space(csp_plugin);
            }

            /* try to install the kpkcs11 plugin now */
            install_kpkcs11_plugin();

            /* register the "KCA Help" menu item, so that we can add
               the plug-in menu item to the Help menu. */
            {
                khm_handle h_sub = NULL;

#if KH_VERSION_API < 7

                if (pkhui_action_lock == NULL ||
                    pkhui_action_unlock == NULL ||
                    pkhui_refresh_actions == NULL ||
                    pkhui_request_UI_callback == NULL)

                    goto no_custom_help;

#endif

                kmq_create_subscription(plugin_msg_proc, &h_sub);

                LoadString(hResModule, IDS_ACTION_KCA_HELP,
                           short_desc, ARRAYLENGTH(short_desc));
                LoadString(hResModule, IDS_ACTION_KCA_HELP_TT,
                           long_desc, ARRAYLENGTH(long_desc));

                action_id_kca_help = khui_action_create(NULL,
                                                        short_desc,
                                                        long_desc,
                                                        NULL,
                                                        KHUI_ACTIONTYPE_TRIGGER,
                                                        h_sub);

                if (action_id_kca_help != 0) {
                    khm_size s;
                    khm_size i;
                    khui_menu_def * help_menu;
                    khm_boolean refresh = FALSE;

                    khui_action_lock();

                    help_menu = khui_find_menu(KHUI_MENU_HELP);
                    if (help_menu) {
                        s = khui_menu_get_size(help_menu);

                        for (i=0; i < s; i++) {
                            khui_action_ref * aref;

                            aref = khui_menu_get_action(help_menu, i);

                            if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                                aref->action == KHUI_ACTION_HELP_INDEX) {

                                khui_menu_insert_action(help_menu,
                                                        i + 1,
                                                        action_id_kca_help,
                                                        0);
                                refresh = TRUE;
                                break;
                            }
                        }
                    }

                    khui_action_unlock();

                    if (refresh)
                        khui_refresh_actions();
                }

#if KH_VERSION_API < 7
            no_custom_help:
                ;
#endif
            }
        }
        break;

        /* This is the last message that will be received by the
           plugin. */
    case KMSG_SYSTEM_EXIT:
        {
            khui_config_node cnode;
            khui_config_node cn_idents;
            khm_int32 attr_id;

            kca_remove_icon();

            /* It should not be assumed that initialization of the
               plugin went well at this point since we receive a
               KMSG_SYSTEM_EXIT even if the initialization failed. */

            /* Try to remove the KCA plug-in action from Help menu if
               it was successfully registered.  Also, delete the
               action. */
            if (action_id_kca_help != 0) {

                khui_menu_def * help_menu;
                khm_boolean menu_changed = FALSE;

                khui_action_lock();

                help_menu = khui_find_menu(KHUI_MENU_HELP);
                if (help_menu) {
                    khm_size s;
                    khm_size i;

                    s = khui_menu_get_size(help_menu);
                    for (i=0; i < s; i++) {
                        khui_action_ref * aref = khui_menu_get_action(help_menu, i);

                        if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                            aref->action == action_id_kca_help) {

                            khui_menu_remove_action(help_menu, i);
                            menu_changed = TRUE;
                            break;

                        }
                    }
                }

                khui_action_delete(action_id_kca_help);

                khui_action_unlock();

                if (menu_changed)
                    khui_refresh_actions();

                action_id_kca_help = 0;
            }

            if (credtype_id != KCDB_CREDTYPE_INVALID) {
                kcdb_credtype_unregister(credtype_id);
                credtype_id = KCDB_CREDTYPE_INVALID;
            }

            if (g_credset) {
                kcdb_credset_delete(g_credset);
                g_credset = NULL;
            }

            /* Now unregister any configuration nodes we registered. */

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_ALL_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_PER_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                khui_cfg_release(cn_idents);
            }

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_KCA_AUTHREALM,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_EMAIL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_NAME,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SERIAL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (csp_params) {
                khc_close_space(csp_params);
                csp_params = NULL;
            }

#if KH_VERSION_API < 12
            if (hm_netidmgr)
                FreeLibrary(hm_netidmgr);

            pkhui_cw_get_primary_id = NULL;
#endif

#if KH_VERSION_API < 7
            pkhui_action_lock = NULL;
            pkhui_action_unlock = NULL;
            pkhui_refresh_actions = NULL;
            pkhui_request_UI_callback = NULL;
#endif

            /* TODO: Perform additional uninitialization
               operations. */
        }
        break;
    }

    return rv;
}