Example #1
0
void kmqint_init(void) {
    khm_handle hconfig = NULL;

    queues = NULL;

    InitializeCriticalSection(&cs_kmq_global);
    InitializeCriticalSection(&cs_kmq_msg);
    InitializeCriticalSection(&cs_kmq_msg_ref);

    EnterCriticalSection(&cs_kmq_global);
    khc_load_schema(NULL, schema_kmqconfig);
    khc_open_space(NULL, KMQ_CONF_SPACE_NAME, KHM_PERM_READ, &hconfig);
    if(hconfig) {
        khm_int32 t = 0;

        khc_read_int32(hconfig, KMQ_CONF_QUEUE_DEAD_TIMEOUT_NAME, &t);
        kmq_queue_dead_timeout = t;

        khc_read_int32(hconfig, KMQ_CONF_CALL_DEAD_TIMEOUT_NAME, &t);
        kmq_call_dead_timeout = t;

        khc_close_space(hconfig);
    }
    kmqint_init_msg_types();
    LeaveCriticalSection(&cs_kmq_global);

    kmq_tls_queue = TlsAlloc();
}
Example #2
0
void k4_read_identity_data(k4_dlg_data * d) {
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;
    khm_handle identity = NULL;

    khm_int32 idflags = 0;
    khm_int32 t;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)))
        d->k4_enabled = !!t;
    else
        d->k4_enabled = TRUE;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4Method", &t)))
        d->method = t;
    else
        d->method = K4_METHOD_AUTO;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"DefaultLifetime", &t)))
        d->lifetime = t;
    else
        d->lifetime = 10 * 60 * 60; /* 10 hours */

    if (KHM_SUCCEEDED(khui_cw_get_primary_id(d->nc, &identity))) {

        if (KHM_SUCCEEDED(kcdb_identity_get_config(identity, 0,
                                                   &csp_ident))) {

            khc_open_space(csp_ident, CSNAME_KRB4CRED, 0, &csp_k4);

            if (csp_k4) {
                if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t)))
                    d->k4_enabled = !!t;
                if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4Method", &t)))
                    d->method = t;
                khc_close_space(csp_k4);
            }

            khc_close_space(csp_ident);
        }

        if (d->k4_enabled) {
            d->k4_enabled = k4_should_identity_get_k4(identity);
        }
    } else {
        d->k4_enabled = FALSE;
    }

    if (d->method < 0 || d->method > K4_METHOD_K524)
        d->method = K4_METHOD_AUTO;

    if (identity)
        kcdb_identity_release(identity);
}
Example #3
0
KHMEXP khm_int32   KHMAPI
kmm_get_plugin_info_i(kmm_plugin p, kmm_plugin_info * info) {
    khm_int32 rv = KHM_ERROR_SUCCESS;
    kmm_plugin_i * pi;
    khm_handle csp_plugin;

    if (!info)
        return KHM_ERROR_INVALID_PARAM;

    EnterCriticalSection(&cs_kmm);
    if (!kmm_is_plugin(p)) {
        rv = KHM_ERROR_INVALID_PARAM;
        goto _cleanup;
    }

    pi = kmm_plugin_from_handle(p);

    ZeroMemory(info, sizeof(*info));

    info->reg = pi->p;
    info->reg.msg_proc = NULL;

    if (KHM_FAILED(kmm_get_plugin_config(pi->p.name, KHM_PERM_READ,
                                         &csp_plugin))) {
        info->failure_count = 0;
        *((khm_int64 *)&info->failure_time) = 0;
        info->failure_reason = 0;
    } else {
        if (KHM_FAILED(khc_read_int32(csp_plugin, L"FailureCount",
                                      &info->failure_count)))
            info->failure_count = 0;
        if (KHM_FAILED(khc_read_int64(csp_plugin, L"FailureTime",
                                      (khm_int64 *) &info->failure_time)))
            *((khm_int64 *) &info->failure_time) = 0;
        if (KHM_FAILED(khc_read_int32(csp_plugin, L"FailureReason",
                                      &info->failure_reason)))
            info->failure_reason = 0;

        khc_close_space(csp_plugin);
    }

    info->state = pi->state;

    kmm_hold_plugin(p);
    info->h_plugin = p;

    info->flags = (pi->flags & KMM_PLUGIN_FLAG_DISABLED);

 _cleanup:
    LeaveCriticalSection(&cs_kmm);

    return rv;
}
void
k4_id_read_params(k4_id_data * d) {
    khm_handle ident = NULL;
    khm_handle csp_ident = NULL;
    khm_handle csp_idk4 = NULL;
    khm_int32 flags = 0;
    khm_int32 t;

    khc_read_int32(csp_params, L"Krb4NewCreds", &d->gettix);

    ident = khui_cfg_get_data(d->cfg.ctx_node);

    if (ident == NULL) {
        d->gettix = 0;
        goto done;
    }

    kcdb_identity_get_flags(ident, &flags);

    if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) {
        d->gettix = 0;
        goto done;
    }

    d->is_default_ident = TRUE;

    if (d->gettix == 0)
        goto done;

    if (KHM_FAILED(kcdb_identity_get_config(ident, 0, &csp_ident)))
        goto done;

    if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED,
                                  0, &csp_idk4)))
        goto close_config;

    if (KHM_SUCCEEDED(khc_read_int32(csp_idk4, L"Krb4NewCreds", &t)) &&
        !t)
        d->gettix = 1;

 close_config:
    if (csp_ident)
        khc_close_space(csp_ident);

    if (csp_idk4)
        khc_close_space(csp_idk4);

 done:
    if (ident)
        kcdb_identity_release(ident);

    return;
}
Example #5
0
khm_boolean k4_should_identity_get_k4(khm_handle ident) {
    khm_int32 idflags = 0;
    khm_int32 t = TRUE;
    khm_handle csp_ident = NULL;
    khm_handle csp_k4 = NULL;
    khm_boolean get_k4 = TRUE;
    khm_boolean id_spec = FALSE;

    if (KHM_FAILED(kcdb_identity_get_flags(ident, &idflags)))
        return FALSE;

    if (!(idflags & KCDB_IDENT_FLAG_DEFAULT)) {
        /* we only support k4 for one identity, and that is the
           default identity.  If we are trying to get tickets for a
           non-default identity, then we start off as disabled unless
           there is no default identity. */

        khm_handle defident = NULL;

        if (KHM_SUCCEEDED(kcdb_identity_get_default(&defident))) {
            kcdb_identity_release(defident);

            return FALSE;
        }
    }

    if (KHM_SUCCEEDED(kcdb_identity_get_config(ident, 0, &csp_ident))) {
        if (KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB4CRED, 0,
                                         &csp_k4))) {
            khm_int32 t = 0;

            if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t))) {
                get_k4 = !!t;
                id_spec = TRUE;
            }

            khc_close_space(csp_k4);
        }
        khc_close_space(csp_ident);
    }

    /* if there was a value specified for the identity, then that
       takes precedence. */
    if (id_spec || !get_k4)
        return get_k4;

    if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t)) &&
        !t)
        return FALSE;

    return TRUE;
}
Example #6
0
void
khm_cred_begin_startup_actions(void) {
    khm_handle csp_cw;

    if (khm_startup.seen)
        return;

    if (!khm_startup.remote &&
        KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw))) {

        khm_int32 t = 0;

        khc_read_int32(csp_cw, L"Autoinit", &t);
        if (t)
            khm_startup.autoinit = TRUE;

        t = 0;
        khc_read_int32(csp_cw, L"AutoImport", &t);
        if (t)
            khm_startup.import = TRUE;

        khc_close_space(csp_cw);

    }

    /* if this is a remote request, and no specific options were
       specified other than --renew, then we perform the default
       action, as if the user clicked on the tray icon. */
    if (khm_startup.remote &&
        !khm_startup.exit &&
        !khm_startup.destroy &&
        !khm_startup.autoinit &&
        !khm_startup.init &&
        !khm_startup.remote_exit &&
        !khm_startup.import &&
        !khm_startup.display) {

        khm_int32 def_action = khm_get_default_notifier_action();

        if (def_action > 0) {
            khui_action_trigger(def_action, NULL);
        }
    }

    khm_startup.seen = TRUE;
    khm_startup.processing = TRUE;

    khm_cred_process_startup_actions();
}
Example #7
0
void k5_read_file_cc_data(k5_ccc_data * d) {
    khm_int32 t;
    wchar_t * fclist = NULL;
    wchar_t * fc;
    khm_size cb;

#ifdef DEBUG
    assert(csp_params);
#endif

    d->inc_api = TRUE;
    t = TRUE;
    khc_read_int32(csp_params, L"MsLsaList", &t);
    d->inc_mslsa = t;

    if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
        != KHM_ERROR_TOO_LONG ||
        cb <= sizeof(wchar_t) * 2) {

        k5_flush_file_ccs(d);
    } else {
        fclist = PMALLOC(cb);
#ifdef DEBUG
        assert(fclist);
#endif
        khc_read_multi_string(csp_params, L"FileCCList", fclist, &cb);

        for(fc = fclist; fc && *fc; fc = multi_string_next(fc)) {
            k5_add_file_cc(d, fc);
        }

        PFREE(fclist);
    }
}
Example #8
0
void
khm_hide_main_window(void) {
    khm_handle csp_notices = NULL;
    khm_int32 show_warning = FALSE;

    if (khm_nCmdShow != SW_MINIMIZE &&
        KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow\\Notices",
                                     KHM_PERM_WRITE, &csp_notices)) &&
        KHM_SUCCEEDED(khc_read_int32(csp_notices, L"MinimizeWarning",
                                     &show_warning)) &&
        show_warning != 0) {

        khui_alert * alert;
        wchar_t title[KHUI_MAXCCH_TITLE];
        wchar_t msg[KHUI_MAXCCH_MESSAGE];

        LoadString(khm_hInstance, IDS_WARN_WM_TITLE,
                   title, ARRAYLENGTH(title));
        LoadString(khm_hInstance, IDS_WARN_WM_MSG,
                   msg, ARRAYLENGTH(msg));

        khui_alert_create_simple(title, msg, KHERR_INFO, &alert);
        khui_alert_set_flags(alert, KHUI_ALERT_FLAG_REQUEST_BALLOON,
                             KHUI_ALERT_FLAG_REQUEST_BALLOON);

        khui_alert_show(alert);

        khc_write_int32(csp_notices, L"MinimizeWarning", 0);
    }

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

    ShowWindow(khm_hwnd_main, SW_HIDE);
}
Example #9
0
void
khm_close_main_window(void) {
    khm_handle csp_cw;
    BOOL keep_running = FALSE;

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
                                     KHM_PERM_READ, &csp_cw))) {
        khm_int32 t;

        if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"KeepRunning",
                                         &t))) {
            keep_running = t;
        } else {
#ifdef DEBUG
            assert(FALSE);
#endif
        }

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

    if (keep_running)
        khm_hide_main_window();
    else
        DestroyWindow(khm_hwnd_main);
}
Example #10
0
static LRESULT CALLBACK
notifier_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == TOKEN_MESSAGE_ID) {
        switch (lParam) {
        case NIN_SELECT:
        case NIN_KEYSELECT:

            {
                NOTIFYICONDATA idata;
                khm_int32 cmd = KHUI_ACTION_OPEN_APP;

                khc_read_int32(NULL, L"CredWindow\\NotificationAction", &cmd);

                khui_action_trigger(cmd, NULL);

                ZeroMemory(&idata, sizeof(idata));

                Shell_NotifyIcon(NIM_SETFOCUS, &idata);
            }
            return 0;

        case WM_CONTEXTMENU:
            handle_context_menu();
            return TRUE;

        default:
            return 0;
        }
    }
    else if (uMsg == WM_COMMAND) {
        switch (LOWORD(wParam)) {
        case ID_DEFAULT:
            {
                khm_int32 cmd;

                cmd = get_default_notifier_action();

                khui_action_trigger(cmd, NULL);
            }
            return TRUE;

        case ID_SHOWHELP:
            {
                wchar_t helploc[MAX_PATH + MAX_PATH];

                get_help_file(helploc, sizeof(helploc));

                StringCbCat(helploc, sizeof(helploc), L"::index.html");

                HtmlHelp(notifier_window, helploc, HH_DISPLAY_TOPIC, 0);
            }
            return TRUE;
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
Example #11
0
static khm_int32
get_default_notifier_action(void)
{
    khm_int32 cmd = KHUI_ACTION_OPEN_APP;

    khc_read_int32(NULL, L"CredWindow\\NotificationAction", &cmd);

    return cmd;
}
Example #12
0
static void
k4_ids_read_params(k4_ids_data * d) {
    khm_int32 t;
#ifdef DEBUG
    assert(csp_params);
#endif

    t = 1;
    khc_read_int32(csp_params, L"Krb4NewCreds", &t);
    d->get_tix = !!t;
}
Example #13
0
void
khm_create_main_window(void) {
    wchar_t buf[1024];
    khm_handle csp_cw = NULL;
    RECT r;

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

    khm_hwnd_null =
        CreateWindow(MAKEINTATOM(khm_null_window_class),
                     buf,
                     0,         /* Style */
                     0, 0,      /* x, y */
                     100, 100,  /* width, height */
                     NULL,      /* parent */
                     NULL,      /* menu */
                     NULL,      /* HINSTANCE */
                     0);        /* lparam */

    if (!khm_hwnd_null)
        return;

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
                                     KHM_PERM_READ,
                                     &csp_cw))) {
        khm_int32 t;

        if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultWindowMode", &t))) {
            khm_set_main_window_mode(t);
        }

        khc_close_space(csp_cw);
    }

    khm_get_main_window_rect(&r);

    khm_hwnd_main =
        CreateWindowEx(WS_EX_OVERLAPPEDWINDOW | WS_EX_APPWINDOW,
                       MAKEINTATOM(khm_main_window_class),
                       buf,
                       WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
                       WS_CLIPSIBLINGS,
                       r.left, r.top,
                       r.right - r.left,
                       r.bottom - r.top,
                       khm_hwnd_null,
                       NULL,
                       NULL,
                       NULL);

    khui_set_main_window(khm_hwnd_main);
}
Example #14
0
/* Identity Selector control factory

   Runs in UI thread */
khm_int32 KHMAPI
idsel_factory(HWND hwnd_parent, khui_identity_selector * u) {

    if (hwnd_parent) {
        HWND hw_dlg;
        wchar_t display_name[KHUI_MAXCCH_NAME] = L"";
        khm_handle csp_p = NULL;
        khm_int32 allow_create = 0;

        if (KHM_FAILED(kmm_get_plugin_config(IDPROV_NAMEW, 0, &csp_p)) ||
            KHM_FAILED(khc_read_int32(csp_p, L"AllowMultipleKeystores", &allow_create)) ||
            allow_create == 0) {
            if (csp_p)
                khc_close_space(csp_p);
            return KHM_ERROR_INVALID_OPERATION;
        }

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

        hw_dlg = CreateDialog(hResModule, MAKEINTRESOURCE(IDD_IDSPEC),
                              hwnd_parent, idspec_dlg_proc);

        assert(hw_dlg);

        u->hwnd_selector = hw_dlg;

        LoadString(hResModule, IDS_ID_INSTANCE, display_name, ARRAYLENGTH(display_name));
        u->display_name = PWCSDUP(display_name);

        u->icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_IDENTITY),
                            IMAGE_ICON, 0, 0,
                            LR_DEFAULTSIZE | LR_DEFAULTCOLOR);

        return (hw_dlg ? KHM_ERROR_SUCCESS : KHM_ERROR_UNKNOWN);

    } else {

        if (u->display_name) {
            PFREE(u->display_name);
            u->display_name = NULL;
        }

        if (u->icon) {
            DestroyIcon(u->icon);
            u->icon = NULL;
        }

        return KHM_ERROR_SUCCESS;
    }
}
Example #15
0
/* perform shutdown operations */
static void
khm_pre_shutdown(void) {
    khm_handle csp_cw = NULL;
    khm_handle credset = NULL;
    khm_int32 t;
    khm_size s;

    /* Check if we should destroy all credentials on exit... */

    if (KHM_FAILED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw)))
        return;

    if (KHM_FAILED(khc_read_int32(csp_cw, L"DestroyCredsOnExit", &t)) ||
        !t)
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_create(&credset)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_extract(credset, NULL, NULL,
                                        KCDB_TYPE_INVALID)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_get_size(credset, &s)) ||
        s == 0)
        goto _cleanup;

    kcdb_credset_apply(credset, mw_select_cred, NULL);

    khui_context_set(KHUI_SCOPE_GROUP,
                     NULL,
                     KCDB_CREDTYPE_INVALID,
                     NULL,
                     NULL,
                     0,
                     credset);

    khm_cred_destroy_creds(TRUE, TRUE);

 _cleanup:

    if (credset)
        kcdb_credset_delete(credset);

    if (csp_cw)
        khc_close_space(csp_cw);
}
Example #16
0
static void
main_wnd_save_sizepos() {
    RECT r;
    khm_handle csp_cw;
    khm_handle csp_mw;
    const wchar_t * wconfig;

    KillTimer(khm_hwnd_main, MW_RESIZE_TIMER);

    if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
        wconfig = L"Windows\\MainMini";
    else
        wconfig = L"Windows\\Main";

    GetWindowRect(khm_hwnd_main, &r);

    if (KHM_SUCCEEDED(khc_open_space(NULL,
                                     L"CredWindow",
                                     KHM_PERM_WRITE,
                                     &csp_cw))) {
        if (KHM_SUCCEEDED(khc_open_space(csp_cw,
                                        wconfig,
                                        KHM_PERM_WRITE,
                                        &csp_mw))) {
            khm_int32 t;

            khc_write_int32(csp_mw, L"XPos", r.left);
            khc_write_int32(csp_mw, L"YPos", r.top);
            khc_write_int32(csp_mw, L"Width", r.right - r.left);
            khc_write_int32(csp_mw, L"Height", r.bottom - r.top);

            if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)) &&
                t != KHM_DOCK_NONE) {
                khc_write_int32(csp_mw, L"Dock", KHM_DOCK_AUTO);
            }

            khc_close_space(csp_mw);
        }

        khc_close_space(csp_cw);
    }
}
Example #17
0
void k5_write_file_cc_data(k5_ccc_data * d) {
    wchar_t * ms;
    khm_size cb;
    khm_size cbt;
    khm_int32 t;
    khm_size i;

#ifdef DEBUG
    assert(csp_params);
#endif
    if (KHM_FAILED(khc_read_int32(csp_params, L"MsLsaList", &t)) ||
        !!t != !!d->inc_mslsa) {
        khc_write_int32(csp_params, L"MsLsaList", !!d->inc_mslsa);
    }

    if (d->n_file_ccs > 0) {
        cb = d->n_file_ccs * MAX_PATH * sizeof(wchar_t);
        ms = PMALLOC(cb);
#ifdef DEBUG
        assert(ms);
#endif
        multi_string_init(ms, cb);

        for(i=0; i<d->n_file_ccs; i++) {
            cbt = cb;
            multi_string_append(ms, &cbt, d->file_ccs[i].path);
        }

        khc_write_multi_string(csp_params, L"FileCCList", ms);

        PFREE(ms);
    } else {
        if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
            != KHM_ERROR_TOO_LONG ||
            cb != sizeof(wchar_t) * 2)

            khc_write_multi_string(csp_params, L"FileCCList", L"\0\0");
    }
}
Example #18
0
BOOL 
khm_cred_begin_dialog(void) {
    BOOL rv;

    dialog_sync_init();

    EnterCriticalSection(&cs_dialog);

    if (in_dialog) {
        rv = FALSE;

        /* if a dialog is being displayed and we got a another request
           to show one, we bring the existing one to the
           foreground. */
        if (dialog_nc && dialog_nc->hwnd) {
            khm_int32 t = 0;

            if (KHM_SUCCEEDED(khc_read_int32(NULL,
                                             L"CredWindow\\Windows\\NewCred\\ForceToTop",
                                             &t)) &&
                t != 0) {

                khm_activate_main_window();

                SetWindowPos(dialog_nc->hwnd, HWND_TOP, 0, 0, 0, 0,
                             (SWP_NOMOVE | SWP_NOSIZE));
            }
        }

    } else {
        rv = TRUE;
        in_dialog = TRUE;
        ResetEvent(in_dialog_evt);
    }

    LeaveCriticalSection(&cs_dialog);
    return rv;
}
Example #19
0
static void
mw_restart_refresh_timer(HWND hwnd) {
    khm_handle csp_cw;
    khm_int32 timeout;

    KillTimer(hwnd, MW_REFRESH_TIMER);
    if (KHM_SUCCEEDED(khc_open_space(NULL,
                                     L"CredWindow",
                                     KHM_PERM_READ,
                                     &csp_cw))) {
        if (KHM_FAILED(khc_read_int32(csp_cw,
                                      L"RefreshTimeout",
                                      &timeout)))
            timeout = MW_REFRESH_TIMEOUT;
        khc_close_space(csp_cw);
    } else {
        timeout = MW_REFRESH_TIMEOUT;
    }

    timeout *= 1000;            /* convert to milliseconds */

    SetTimer(hwnd, MW_REFRESH_TIMER, timeout, NULL);
}
Example #20
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();
}
Example #21
0
static void
k5_id_read_params(k5_id_dlg_data * d) {

    khm_size cb;
    khm_int32 rv;
    khm_int32 t;
    khm_handle csp_ident = NULL;

    d->ident = khui_cfg_get_data(d->cfg.ctx_node);
    assert(d->ident != NULL);

    khm_krb5_get_identity_config(d->ident, 0, &csp_ident);

    rv = khc_read_int32(csp_ident, L"DefaultLifetime",  &t);
    if (KHM_SUCCEEDED(rv))
        d->life = t;
    else
        d->life = 36000;

    rv = khc_read_int32(csp_ident, L"DefaultRenewLifetime", &t);
    if (KHM_SUCCEEDED(rv))
        d->renew_life = t;
    else
        d->renew_life = 604800;

    rv = khc_read_int32(csp_ident, L"Renewable", &t);
    if (KHM_SUCCEEDED(rv))
        d->renewable = !!t;
    else
        d->renewable = TRUE;

    rv = khc_read_int32(csp_ident, L"Forwardable", &t);
    if (KHM_SUCCEEDED(rv))
        d->forwardable = !!t;
    else
        d->forwardable = FALSE;

    rv = khc_read_int32(csp_ident, L"Proxiable", &t);
    if (KHM_SUCCEEDED(rv))
        d->proxiable = !!t;
    else
        d->proxiable = FALSE;

    rv = khc_read_int32(csp_ident, L"Addressless", &t);
    if (KHM_SUCCEEDED(rv))
        d->addressless = !!t;
    else
        d->addressless = TRUE;

    rv = khc_read_int32(csp_ident, L"PublicIP", &t);
    if (KHM_SUCCEEDED(rv))
        d->public_ip = (khm_ui_4) t;
    else
        d->public_ip = 0;

    cb = sizeof(d->ccache);
    rv = khm_krb5_get_identity_default_ccache(d->ident, d->ccache, &cb);

#ifdef DEBUG
    assert(KHM_SUCCEEDED(rv));
#endif

    khui_tracker_initialize(&d->tc_life);
    d->tc_life.current = (khm_int32) d->life;
    d->tc_life.min = 0;
    d->tc_life.max = 3600 * 24 * 7;

    khui_tracker_initialize(&d->tc_renew);
    d->tc_renew.current = (khm_int32) d->renew_life;
    d->tc_renew.min = 0;
    d->tc_renew.max = 3600 * 24 * 30;

    if (csp_ident)
        khc_close_space(csp_ident);
}
Example #22
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);
    }
}
Example #23
0
static void
init_idents_data(void) {
    khm_int32 rv;
    wchar_t * t;
    wchar_t * widnames = NULL;
    khm_size cb;
    int n_tries = 0;
    int i;
    khm_handle csp_cw = NULL;

    if (cfg_idents.valid)
        return;

#ifdef DEBUG
    assert(cfg_idents.idents == NULL);
    assert(cfg_idents.n_idents == 0);
    assert(cfg_idents.nc_idents == 0);
#endif

    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw))) {
        khm_int32 t;

        if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultMonitor", &t)))
            cfg_idents.saved.monitor = !!t;
        else
            cfg_idents.saved.monitor = TRUE;

        if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultAllowAutoRenew", &t)))
            cfg_idents.saved.auto_renew = !!t;
        else
            cfg_idents.saved.auto_renew = TRUE;

        if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultSticky", &t)))
            cfg_idents.saved.sticky = !!t;
        else
            cfg_idents.saved.sticky = FALSE;

        khc_close_space(csp_cw);
        csp_cw = NULL;

    } else {

        cfg_idents.saved.monitor = TRUE;
        cfg_idents.saved.auto_renew = TRUE;
        cfg_idents.saved.sticky = FALSE;

    }

    cfg_idents.work = cfg_idents.saved;
    cfg_idents.applied = FALSE;

    do {
        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
                                KCDB_IDENT_FLAG_CONFIG,
                                NULL,
                                &cb,
                                &cfg_idents.n_idents);

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

        if (widnames)
            PFREE(widnames);
        widnames = PMALLOC(cb);
#ifdef DEBUG
        assert(widnames);
#endif

        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_CONFIG,
                                KCDB_IDENT_FLAG_CONFIG,
                                widnames,
                                &cb,
                                &cfg_idents.n_idents);
        n_tries++;
    } while(KHM_FAILED(rv) &&
            n_tries < 5);

    if (KHM_FAILED(rv) ||
        cfg_idents.n_idents == 0) {
        cfg_idents.n_idents = 0;
        goto _cleanup;
    }

    cfg_idents.idents = PMALLOC(sizeof(*cfg_idents.idents) * 
                               cfg_idents.n_idents);
#ifdef DEBUG
    assert(cfg_idents.idents);
#endif
    ZeroMemory(cfg_idents.idents, 
               sizeof(*cfg_idents.idents) * cfg_idents.n_idents);
    cfg_idents.nc_idents = cfg_idents.n_idents;

    i = 0;
    for (t = widnames; t && *t; t = multi_string_next(t)) {
        khm_handle ident;

        if (KHM_FAILED(kcdb_identity_create(t, 0, &ident))) {
            cfg_idents.n_idents--;
            continue;
        }

        StringCbLength(t, 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, t);

        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]);

        i++;
        /* leave identity held */
    }

 _cleanup:

    cfg_idents.valid = TRUE;

    if (widnames)
        PFREE(widnames);
}
Example #24
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;
}
Example #25
0
void
khm_get_main_window_rect(RECT * pr) {
    khm_handle csp_mw = NULL;
    int x,y,width,height,dock;
    RECT r;
    const wchar_t * wconfig;

    x = CW_USEDEFAULT;
    y = CW_USEDEFAULT;
    width = CW_USEDEFAULT;
    height = CW_USEDEFAULT;
    dock = KHM_DOCK_NONE;

    if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
        wconfig = L"CredWindow\\Windows\\MainMini";
    else
        wconfig = L"CredWindow\\Windows\\Main";

    if (KHM_SUCCEEDED(khc_open_space(NULL,
                                     wconfig,
                                     KHM_PERM_READ,
                                     &csp_mw))) {
        khm_int32 t;

        if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"XPos", &t)))
            x = t;
        if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"YPos", &t)))
            y = t;
        if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Width", &t)))
            width = t;
        if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Height", &t)))
            height = t;
        if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)))
            dock = t;

        khc_close_space(csp_mw);
    }

    /* If there were no default values, we default to using 1/4 of the
       work area centered on the primary monitor.  If there were any
       docking hints, then the next call to
       khm_adjust_window_dimensions_for_display() will reposition the
       window. */
    if (width == CW_USEDEFAULT || x == CW_USEDEFAULT) {
        RECT wr;

        SetRectEmpty(&wr);
        SystemParametersInfo(SPI_GETWORKAREA, 0, &wr, 0);

        if (width == CW_USEDEFAULT) {
            width = (wr.right - wr.left) / 2;
            height = (wr.bottom - wr.top) / 2;
        }

        if (x == CW_USEDEFAULT) {
            x = (wr.left + wr.right) / 2 - width / 2;
            y = (wr.top + wr.bottom) / 2 - height / 2;
        }
    }

    /* The saved dimensions might not actually be visible if the user
       has changed the resolution of the display or if it's a multiple
       monitor system where the monitor on which the Network Identity
       Manager window was on previously is no longer connected.  We
       have to check for that and adjust the dimensions if needed. */
    SetRect(&r, x, y, x + width, y + height);
    khm_adjust_window_dimensions_for_display(&r, dock);

    *pr = r;
}
Example #26
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
}
Example #27
0
/* process KMSG_SYSTEM messages */
khm_int32 KHMAPI
afs_msg_system(khm_int32 msg_subtype,
               khm_ui_4 uparam,
               void * vparam)
{
    khm_int32 rv = KHM_ERROR_UNKNOWN;

    switch(msg_subtype) {
    case KMSG_SYSTEM_INIT:

        /* If we are building against an older SDK, we should try to
           load newer APIs if it's available at run-time. */
#if KH_VERSION_API < 7
        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;

            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);

        } while (FALSE);
#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. */
        afs_icon_set_state(AFSICON_SERVICE_STOPPED, NULL);

        /* Perform critical registrations and data structure
           initalization */
        {
            kcdb_credtype ct;
            wchar_t buf[KCDB_MAXCCH_LONG_DESC];
            size_t cbsize;
            kcdb_attrib att;
            khm_handle csp_afscred = NULL;
            khm_int32 disable_afscreds = FALSE;

            ZeroMemory(&ct, sizeof(ct));
            /* first of all, register the AFS token credential type */
            ct.id = KCDB_CREDTYPE_AUTO;
            ct.name = AFS_CREDTYPE_NAME;

            if(LoadString(hResModule,
                          IDS_AFS_SHORT_DESC,
                          buf,
                          ARRAYLENGTH(buf)) != 0) {
                StringCbLength(buf, sizeof(buf), &cbsize);
                cbsize += sizeof(wchar_t);
                ct.short_desc = PMALLOC(cbsize);
                StringCbCopy(ct.short_desc, cbsize, buf);
            } else
                ct.short_desc = NULL;

            if(LoadString(hResModule,
                          IDS_AFS_LONG_DESC,
                          buf,
                          ARRAYLENGTH(buf)) != 0) {
                StringCbLength(buf, sizeof(buf), &cbsize);
                cbsize += sizeof(wchar_t);
                ct.long_desc = PMALLOC(cbsize);
                StringCbCopy(ct.long_desc, cbsize, buf);
            } else
                ct.long_desc = NULL;

            ct.icon = LoadImage(hResModule,
                                MAKEINTRESOURCE(IDI_AFSTOKEN),
                                IMAGE_ICON,
                                0, 0, LR_DEFAULTSIZE);

            kmq_create_subscription(afs_plugin_cb, &afs_sub);
            ct.sub = afs_sub;

            kcdb_credtype_register(&ct, &afs_credtype_id);

            /* register the attribute types */
            {
                kcdb_type type;

                ZeroMemory(&type, sizeof(type));
                type.comp = afs_type_principal_comp;
                type.dup = afs_type_principal_dup;
                type.isValid = afs_type_principal_isValid;
                type.toString = afs_type_principal_toString;
                type.name = AFS_TYPENAME_PRINCIPAL;
                type.id = KCDB_TYPE_INVALID;
                type.cb_max = sizeof(struct ktc_principal);
                type.cb_min = sizeof(struct ktc_principal);
                type.flags = KCDB_TYPE_FLAG_CB_FIXED;

                if(KHM_FAILED(kcdb_type_register(&type,
                                                 &afs_type_principal)))
                    goto _exit_init;
            }

            {
                kcdb_type type;
                kcdb_type *ti32 = NULL;

                kcdb_type_get_info(KCDB_TYPE_INT32, &ti32);

                ZeroMemory(&type, sizeof(type));
                type.comp = ti32->comp;
                type.dup = ti32->dup;
                type.isValid = ti32->isValid;
                type.toString = afs_type_method_toString;
                type.name = AFS_TYPENAME_METHOD;
                type.id = KCDB_TYPE_INVALID;
                type.cb_max = sizeof(khm_int32);
                type.cb_min = sizeof(khm_int32);
                type.flags = KCDB_TYPE_FLAG_CB_FIXED;

                if(KHM_FAILED(kcdb_type_register(&type,
                                                 &afs_type_method))) {
                    kcdb_type_release_info(ti32);
                    goto _exit_init;
                }

                kcdb_type_release_info(ti32);
            }

            /* now register the attributes */
            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = KCDB_TYPE_STRING;
                att.name = AFS_ATTRNAME_CELL;
                LoadString(hResModule,
                           IDS_ATTR_CELL_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_cell)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = KCDB_TYPE_STRING;
                att.name = AFS_ATTRNAME_REALM;
                LoadString(hResModule,
                           IDS_ATTR_REALM_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_realm)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_method;
                att.name = AFS_ATTRNAME_METHOD;
                LoadString(hResModule,
                           IDS_ATTR_METHOD_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_method)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_principal;
                att.name = AFS_ATTRNAME_CLIENT_PRINC;
                LoadString(hResModule,
                           IDS_ATTR_CLIENT_PRINC_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_client_princ)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_principal;
                att.name = AFS_ATTRNAME_SERVER_PRINC;
                LoadString(hResModule,
                           IDS_ATTR_SERVER_PRINC_SHORT_DESC,
                           short_desc, ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_server_princ)))
                    goto _exit_init;
            }

            /* afs_credset is our stock credentials set that we
               use for all our credset needs (instead of creating
               a new one every time) */

            if(KHM_FAILED(rv = kcdb_credset_create(&afs_credset)))
                goto _exit_init;

            if(KHM_FAILED(rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME,
                                                    &krb5_credtype_id)))
                goto _exit_init;

            /* register the configuration nodes */
            {
                khui_config_node node_ident;
                khui_config_node_reg reg;
                wchar_t wshort_desc[KHUI_MAXCCH_SHORT_DESC];
                wchar_t wlong_desc[KHUI_MAXCCH_LONG_DESC];

                if (KHM_FAILED(rv = khui_cfg_open(NULL,
                                                  L"KhmIdentities",
                                                  &node_ident)))
                    goto _exit_init;

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_MAIN;
                reg.short_desc = wshort_desc;
                reg.long_desc = wlong_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_AFS);
                reg.dlg_proc = afs_cfg_main_proc;
                reg.flags = 0;
                LoadString(hResModule, IDS_CFG_MAIN_LONG,
                           wlong_desc, ARRAYLENGTH(wlong_desc));
                LoadString(hResModule, IDS_CFG_MAIN_SHORT,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(NULL, &reg);

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_IDS;
                reg.short_desc = wshort_desc;
                reg.long_desc = wshort_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_TAB);
                reg.dlg_proc = afs_cfg_ids_proc;
                reg.flags = KHUI_CNFLAG_SUBPANEL;
                LoadString(hResModule, IDS_CFG_IDS_TAB,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(node_ident, &reg);

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_ID;
                reg.short_desc = wshort_desc;
                reg.long_desc = wshort_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_TAB);
                reg.dlg_proc = afs_cfg_id_proc;
                reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL;
                LoadString(hResModule, IDS_CFG_ID_TAB,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(node_ident, &reg);
            }

            /* and register the AFS message type */
            rv = kmq_register_type(AFS_MSG_TYPENAME, &afs_msg_type_id);

            if (KHM_SUCCEEDED(rv))
                kmq_subscribe(afs_msg_type_id, afs_plugin_cb);

            /* if the configuration is set to disable afscreds.exe,
               then we look for the shortcut and remove it if
               found. */
            if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME,
                                                    0,
                                                    &csp_afscred))) {
                wchar_t wpath[MAX_PATH];

                khc_read_int32(csp_afscred, L"Disableafscreds",
                               &disable_afscreds);

                if (disable_afscreds &&
                    afs_cfg_get_afscreds_shortcut(wpath)) {

                    DeleteFile(wpath);

                }

                khc_close_space(csp_afscred);
            }

            /* try to register the "AFS Help" menu item, if
               possible */
            {
                khm_handle h_sub = NULL;
                wchar_t short_desc[KHUI_MAXCCH_SHORT_DESC];
                wchar_t long_desc[KHUI_MAXCCH_LONG_DESC];

#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(afs_plugin_cb, &h_sub);

                LoadString(hResModule, IDS_ACTION_AFS_HELP,
                           short_desc, ARRAYLENGTH(short_desc));
                LoadString(hResModule, IDS_ACTION_AFS_HELP_TT,
                           long_desc, ARRAYLENGTH(long_desc));

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

                if (action_id_afs_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_afs_help,
                                                        0);
                                refresh = TRUE;
                                break;
                            }
                        }
                    }

                    khui_action_unlock();

                    if (refresh)
                        khui_refresh_actions();
                }

#if KH_VERSION_API < 7
            no_custom_help:
                ;
#endif
            }

        _exit_init:
            if(ct.short_desc)
                PFREE(ct.short_desc);
            if(ct.long_desc)
                PFREE(ct.long_desc);
        }
        /* now that the critical stuff is done, we move on to the
           non-critical stuff */
        if(KHM_SUCCEEDED(rv)) {
            initialized = TRUE;

            /* obtain existing tokens */
            afs_list_tokens();
        }

        /* define this so that if there are no TGT's, we don't
           deadlock trying to open a new creds dialog from within the
           new creds dialog. */
        SetEnvironmentVariable(L"KERBEROSLOGIN_NEVER_PROMPT", L"1");

        break;
        /* end of KMSG_SYSTEM_INIT */

    case KMSG_SYSTEM_EXIT:

        afs_remove_icon();

        /* Try to remove the AFS plug-in action from Help menu if it
           was successfully registered.  Also, delete the action. */
        if (action_id_afs_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_afs_help) {

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

            khui_action_delete(action_id_afs_help);

            khui_action_unlock();

            if (menu_changed)
                khui_refresh_actions();

            action_id_afs_help = 0;
        }

        if (afs_msg_type_id != -1) {
            kmq_unsubscribe(afs_msg_type_id, afs_plugin_cb);
            kmq_unregister_type(afs_msg_type_id);
        }
        if(afs_credtype_id >= 0) {
            kcdb_credtype_unregister(afs_credtype_id);
        }
#if 0
        if(afs_attr_client >= 0) {
            kcdb_attrib_unregister(afs_attr_client);
        }
#endif
        if(afs_attr_cell >= 0) {
            kcdb_attrib_unregister(afs_attr_cell);
        }
        if(afs_attr_realm >= 0) {
            kcdb_attrib_unregister(afs_attr_realm);
        }
        if(afs_attr_method >= 0) {
            kcdb_attrib_unregister(afs_attr_method);
        }
        if(afs_attr_client_princ >= 0) {
            kcdb_attrib_unregister(afs_attr_client_princ);
        }
        if(afs_attr_server_princ >= 0) {
            kcdb_attrib_unregister(afs_attr_server_princ);
        }
        if(afs_type_principal >= 0) {
            kcdb_type_unregister(afs_type_principal);
        }
        if(afs_type_method >= 0) {
            kcdb_type_unregister(afs_type_method);
        }
        initialized = FALSE;
        if(afs_credset)
            kcdb_credset_delete(afs_credset);

        /* afs_sub doesn't need to be deleted.  That is taken care
           of when unregistering the afs cred type */
        afs_sub = NULL;

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

        pkhui_action_lock = NULL;
        pkhui_action_unlock = NULL;
        pkhui_refresh_actions = NULL;
        pkhui_request_UI_callback = NULL;
#endif

        rv = KHM_ERROR_SUCCESS;
        break;
        /* end of KMSG_SYSTEM_EXIT */
    }
    return rv;
}
Example #28
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;
}
Example #29
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;
}
Example #30
0
khm_int32 KHMAPI
khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
                                  void * buffer, khm_size * pcbbuf)
{
    krb5_context        ctx = 0;
    krb5_ccache         cache = 0;
    krb5_error_code     code;
    apiCB *             cc_ctx = 0;
    struct _infoNC **   pNCi = NULL;
    int                 i;
    khm_int32           t;
    wchar_t *           ms = NULL;
    khm_size            cb;
    krb5_timestamp      expiration = 0;
    krb5_timestamp      best_match_expiration = 0;
    char                best_match_ccname[256] = "";
    khm_handle          csp_params = NULL;
    khm_handle          csp_plugins = NULL;

    if (!buffer || !pcbbuf)
    return KHM_ERROR_GENERAL;

    ctx = *pctx;

    if (!pcc_initialize ||
        !pcc_get_NC_info ||
        !pcc_free_NC_info ||
        !pcc_shutdown)
        goto _skip_cc_iter;

    code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
    if (code)
        goto _exit;

    code = pcc_get_NC_info(cc_ctx, &pNCi);

    if (code) 
        goto _exit;

    for(i=0; pNCi[i]; i++) {
        if (pNCi[i]->vers != CC_CRED_V5)
            continue;

        code = (*pkrb5_cc_resolve)(ctx, pNCi[i]->name, &cache);
        if (code)
            continue;

        /* need a function to check the cache for the identity
         * and determine if it has valid tickets.  If it has 
         * the right identity and valid tickets, store the 
         * expiration time and the cache name.  If it has the
         * right identity but no valid tickets, store the ccache
         * name and an expiration time of zero.  if it does not
         * have the right identity don't save the name.
         * 
         * Keep searching to find the best cache available.
         */

        if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                           ident, 
                                                           &expiration))) {
            if ( expiration > best_match_expiration ) {
                best_match_expiration = expiration;
                StringCbCopyA(best_match_ccname, 
                              sizeof(best_match_ccname),
                              "API:");
                StringCbCatA(best_match_ccname,
                             sizeof(best_match_ccname),
                             pNCi[i]->name);
                expiration = 0;
            }
        }

        if(ctx != NULL && cache != NULL)
            (*pkrb5_cc_close)(ctx, cache);
        cache = 0;
    }

 _skip_cc_iter:

    if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
        khc_open_space(csp_plugins, L"Krb5Cred\\Parameters",  0, &csp_params);
        khc_close_space(csp_plugins);
        csp_plugins = NULL;
    }

#ifdef DEBUG
    if (csp_params == NULL) {
        assert(FALSE);
    }
#endif

    if (csp_params &&
        KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
        code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
        if (code == 0 && cache) {
            if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                               ident, 
                                                               &expiration))) {
                if ( expiration > best_match_expiration ) {
                    best_match_expiration = expiration;
                    StringCbCopyA(best_match_ccname, sizeof(best_match_ccname),
                                  "MSLSA:");
                    expiration = 0;
                }
            }
        }

        if (ctx != NULL && cache != NULL)
            (*pkrb5_cc_close)(ctx, cache);

        cache = 0;
    }

    if (csp_params &&
        khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
        == KHM_ERROR_TOO_LONG &&
        cb > sizeof(wchar_t) * 2) {

        wchar_t * t;
        char ccname[MAX_PATH + 6];

        ms = PMALLOC(cb);

#ifdef DEBUG
        assert(ms);
#endif

        khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
        for(t = ms; t && *t; t = multi_string_next(t)) {
            StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
                             "FILE:%S", t);

            code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
            if (code)
                continue;

            if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                               ident, 
                                                               &expiration))) {
                if ( expiration > best_match_expiration ) {
                    best_match_expiration = expiration;
                    StringCbCopyA(best_match_ccname,
                                  sizeof(best_match_ccname),
                                  ccname);
                    expiration = 0;
                }
            }

            if (ctx != NULL && cache != NULL)
                (*pkrb5_cc_close)(ctx, cache);
            cache = 0;
        }

        PFREE(ms);
    }
 _exit:
    if (csp_params)
        khc_close_space(csp_params);

    if (pNCi)
        (*pcc_free_NC_info)(cc_ctx, &pNCi);

    if (cc_ctx)
        (*pcc_shutdown)(&cc_ctx);

    if (best_match_ccname[0]) {
        
        if (*pcbbuf = AnsiStrToUnicode((wchar_t *)buffer, 
                                       *pcbbuf,
                                       best_match_ccname)) {

            *pcbbuf = (*pcbbuf + 1) * sizeof(wchar_t);

            return KHM_ERROR_SUCCESS;
        }

    }

    return KHM_ERROR_GENERAL;
}