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); }
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(); }
void k4_write_identity_data(k4_dlg_data * d) { khm_handle csp_ident = NULL; khm_handle csp_k4 = NULL; khm_handle identity = NULL; if (KHM_SUCCEEDED(khui_cw_get_primary_id(d->nc, &identity)) && KHM_SUCCEEDED(kcdb_identity_get_config(identity, KHM_FLAG_CREATE, &csp_ident))) { khc_open_space(csp_ident, CSNAME_KRB4CRED, KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD, &csp_k4); if (csp_k4) { khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled); khc_write_int32(csp_k4, L"Krb4Method", d->method); khc_close_space(csp_k4); } khc_close_space(csp_ident); } if (identity) kcdb_identity_release(identity); }
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); }
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); } }
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); }
KHMEXP khm_int32 KHMAPI kmm_get_modules_config(khm_int32 flags, khm_handle * result) { khm_handle croot; khm_handle kmm_all_modules; khm_int32 rv; rv = khc_open_space(NULL, KMM_CSNAME_ROOT, flags, &croot); if(KHM_FAILED(rv)) return rv; rv = khc_open_space(croot, KMM_CSNAME_MODULES, flags, &kmm_all_modules); khc_close_space(croot); if(KHM_SUCCEEDED(rv)) *result = kmm_all_modules; else *result = NULL; 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; }
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); }
KHMEXP khm_int32 KHMAPI kmm_get_plugins_config(khm_int32 flags, khm_handle * result) { khm_handle csp_root; khm_handle csp_plugins; khm_int32 rv; rv = khc_open_space(KHM_INVALID_HANDLE, KMM_CSNAME_ROOT, flags, &csp_root); if(KHM_FAILED(rv)) return rv; rv = khc_open_space(csp_root, KMM_CSNAME_PLUGINS, flags, &csp_plugins); khc_close_space(csp_root); if(KHM_SUCCEEDED(rv)) *result = csp_plugins; else *result = NULL; return rv; }
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; }
/* called with cs_identpro held */ static void identpro_check_and_set_default_provider(void) { wchar_t * p_order = NULL; khm_size cb; khm_handle csp_kcdb = NULL; khm_int32 rv; kcdb_identpro_i * p = NULL; wchar_t * e; if (KHM_SUCCEEDED(khc_open_space(NULL, L"KCDB", KHM_PERM_READ, &csp_kcdb))) { rv = khc_read_multi_string(csp_kcdb, L"IdentityProviderOrder", NULL, &cb); if (rv == KHM_ERROR_TOO_LONG && cb > sizeof(wchar_t) * 2) { p_order = PMALLOC(cb); rv = khc_read_multi_string(csp_kcdb, L"IdentityProviderOrder", p_order, &cb); if (KHM_FAILED(rv)) { PFREE(p_order); p_order = NULL; } } khc_close_space(csp_kcdb); csp_kcdb = NULL; } for (e = p_order; e && e[0]; e = multi_string_next(e)) { p = identpro_find_by_name(e); if (p) break; } if (p != NULL) { if (DEFAULT_PROVIDER != p) { QDEL(&id_providers, p); QPUSH(&id_providers, p); #ifdef DEBUG assert(DEFAULT_PROVIDER == p); #endif kcdbint_identpro_post_message(KCDB_OP_NEW_DEFAULT, DEFAULT_PROVIDER); } } if (p) identpro_release(p); if (p_order) PFREE(p_order); }
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(); }
void khm_set_main_window_mode(int mode) { RECT r; khm_handle csp_cw; if (mode == khm_main_wnd_mode) return; khui_check_action(KHUI_ACTION_LAYOUT_MINI, ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE)); khui_enable_action(KHUI_MENU_LAYOUT, ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE)); khui_enable_action(KHUI_MENU_COLUMNS, ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE)); khui_refresh_actions(); /* * set the window position before the global khm_main_wnd_mode * is updated. otherwise, the windows position for the wrong * mode will be set. Do not set the window position if the * main application window has not yet been created. */ if (khm_hwnd_main) main_wnd_save_sizepos(); khm_main_wnd_mode = mode; if (khm_hwnd_main) { khm_get_main_window_rect(&r); SetWindowPos(khm_hwnd_main, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); } if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_WRITE, &csp_cw))) { khc_write_int32(csp_cw, L"DefaultWindowMode", mode); khc_close_space(csp_cw); } khm_cred_refresh(); }
/* 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); }
khm_boolean k4_id_write_params(HWND hwnd, k4_id_data * d) { khm_handle ident = NULL; khm_int32 flags = 0; khm_handle csp_ident = NULL; khm_handle csp_idk4 = NULL; khm_int32 gettix = 0; khm_boolean applied = FALSE; ident = khui_cfg_get_data(d->cfg.ctx_node); if (ident == NULL) return FALSE; kcdb_identity_get_flags(ident, &flags); if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) goto done_apply; if (IsDlgButtonChecked(hwnd, IDC_CFG_GETTIX) == BST_CHECKED) gettix = TRUE; if (KHM_FAILED(kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &csp_ident))) goto done_apply; if (KHM_FAILED(khc_open_space(csp_ident, CSNAME_KRB4CRED, KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD, &csp_idk4))) goto done_apply; khc_write_int32(csp_idk4, L"Krb4NewCreds", gettix); applied = TRUE; done_apply: if (ident) kcdb_identity_release(ident); if (csp_ident) khc_close_space(csp_ident); if (csp_idk4) khc_close_space(csp_idk4); return applied; }
KHMEXP khm_int32 KHMAPI kmm_get_module_config(wchar_t * module, khm_int32 flags, khm_handle * result) { khm_handle csmodules; khm_handle csmodule; khm_int32 rv; if(!module || wcschr(module, L'/') || wcschr(module, L'\\')) return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kmm_get_modules_config(flags, &csmodules))) return KHM_ERROR_UNKNOWN; rv = khc_open_space(csmodules, module, flags, &csmodule); *result = csmodule; khc_close_space(csmodules); return rv; }
KHMEXP khm_int32 KHMAPI kmm_get_plugin_config(wchar_t * plugin, khm_int32 flags, khm_handle * result) { khm_handle csplugins; khm_handle csplugin; khm_int32 rv; if(!plugin || wcschr(plugin, L'/') || wcschr(plugin, L'\\')) return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kmm_get_plugins_config(flags, &csplugins))) return KHM_ERROR_UNKNOWN; rv = khc_open_space(csplugins, plugin, flags, &csplugin); *result = csplugin; khc_close_space(csplugins); return rv; }
static void write_params_idents(void) { khm_handle csp_cw = NULL; if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_FLAG_CREATE, &csp_cw))) { if (cfg_idents.work.monitor != cfg_idents.saved.monitor) { khc_write_int32(csp_cw, L"DefaultMonitor", !!cfg_idents.work.monitor); cfg_idents.work.monitor = cfg_idents.saved.monitor; cfg_idents.applied = TRUE; } if (cfg_idents.work.auto_renew != cfg_idents.saved.auto_renew) { khc_write_int32(csp_cw, L"DefaultAllowAutoRenew", !!cfg_idents.work.auto_renew); cfg_idents.work.auto_renew = cfg_idents.saved.auto_renew; cfg_idents.applied = TRUE; } if (cfg_idents.work.sticky != cfg_idents.saved.sticky) { khc_write_int32(csp_cw, L"DefaultSticky", !!cfg_idents.work.sticky); cfg_idents.work.sticky = cfg_idents.saved.sticky; cfg_idents.applied = TRUE; } khc_close_space(csp_cw); csp_cw = NULL; } #if 0 for (i=0; i < (int)cfg_idents.n_idents; i++) { write_params_ident(&cfg_idents.idents[i]); } #endif if (cfg_idents.hwnd) PostMessage(cfg_idents.hwnd, KHUI_WM_CFG_NOTIFY, MAKEWPARAM(0, WMCFG_UPDATE_STATE), 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); }
void k4_write_identity_data(k4_dlg_data * d) { khm_handle csp_ident = NULL; khm_handle csp_k4 = NULL; if (d->nc->n_identities > 0 && d->nc->identities[0] && KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0], KHM_FLAG_CREATE, &csp_ident))) { khc_open_space(csp_ident, CSNAME_KRB4CRED, KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD, &csp_k4); if (csp_k4) { khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled); khc_write_int32(csp_k4, L"Krb4Method", d->method); khc_close_space(csp_k4); } khc_close_space(csp_ident); } }
/* 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; }
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; }
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; }
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); } }
/* called by the NetIDMgr module manager */ KHMEXP_EXP khm_int32 KHMAPI init_module(kmm_module h_module) { khm_int32 rv = KHM_ERROR_SUCCESS; kmm_plugin_reg pi; wchar_t buf[256]; h_khModule = h_module; rv = kmm_set_locale_info(h_module, locales, n_locales); if(KHM_SUCCEEDED(rv)) { hResModule = kmm_get_resource_hmodule(h_module); } else goto _exit; k5_commctl_version = khm_get_commctl_version(NULL); /* register the plugin */ ZeroMemory(&pi, sizeof(pi)); pi.name = KRB5_PLUGIN_NAME; pi.type = KHM_PITYPE_CRED; pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE); pi.flags = 0; pi.msg_proc = k5_msg_callback; pi.description = buf; pi.dependencies = NULL; LoadString(hResModule, IDS_PLUGIN_DESC, buf, ARRAYLENGTH(buf)); kmm_provide_plugin(h_module, &pi); ZeroMemory(&pi, sizeof(pi)); pi.name = KRB5_IDENTPRO_NAME; pi.type = KHM_PITYPE_IDENT; pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE); pi.flags = 0; pi.msg_proc = k5_ident_callback; pi.description = buf; pi.dependencies = KRB5_PLUGIN_NAME L"\0"; LoadString(hResModule, IDS_IDENTPRO_DESC, buf, ARRAYLENGTH(buf)); kmm_provide_plugin(h_module, &pi); if(KHM_FAILED(rv = init_imports())) goto _exit; if(KHM_FAILED(rv = init_error_funcs())) goto _exit; /* Register common data types */ if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, &type_id_enctype))) { kcdb_type type; kcdb_type *t32; kcdb_type_get_info(KCDB_TYPE_INT32, &t32); type.id = KCDB_TYPE_INVALID; type.name = TYPENAME_ENCTYPE; type.flags = KCDB_TYPE_FLAG_CB_FIXED; type.cb_max = t32->cb_max; type.cb_min = t32->cb_min; type.isValid = t32->isValid; type.comp = t32->comp; type.dup = t32->dup; type.toString = enctype_toString; rv = kcdb_type_register(&type, &type_id_enctype); kcdb_type_release_info(t32); if(KHM_FAILED(rv)) goto _exit; type_regd_enctype = TRUE; } if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, &type_id_addr_list))) { kcdb_type type; kcdb_type *tdata; kcdb_type_get_info(KCDB_TYPE_DATA, &tdata); type.id = KCDB_TYPE_INVALID; type.name = TYPENAME_ADDR_LIST; type.flags = KCDB_TYPE_FLAG_CB_MIN; type.cb_min = 0; type.cb_max = 0; type.isValid = tdata->isValid; type.comp = addr_list_comp; type.dup = tdata->dup; type.toString = addr_list_toString; rv = kcdb_type_register(&type, &type_id_addr_list); kcdb_type_release_info(tdata); if(KHM_FAILED(rv)) goto _exit; type_regd_addr_list = TRUE; } if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, &type_id_krb5_flags))) { kcdb_type type; kcdb_type *t32; kcdb_type_get_info(KCDB_TYPE_INT32, &t32); type.id = KCDB_TYPE_INVALID; type.name = TYPENAME_KRB5_FLAGS; type.flags = KCDB_TYPE_FLAG_CB_FIXED; type.cb_max = t32->cb_max; type.cb_min = t32->cb_min; type.isValid = t32->isValid; type.comp = t32->comp; type.dup = t32->dup; type.toString = krb5flags_toString; rv = kcdb_type_register(&type, &type_id_krb5_flags); kcdb_type_release_info(t32); if(KHM_FAILED(rv)) goto _exit; type_regd_krb5_flags = TRUE; } if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KVNO, &type_id_kvno))) { kcdb_type type; kcdb_type *t32; kcdb_type_get_info(KCDB_TYPE_INT32, &t32); type.id = KCDB_TYPE_INVALID; type.name = TYPENAME_KVNO; type.flags = KCDB_TYPE_FLAG_CB_FIXED; type.cb_max = t32->cb_max; type.cb_min = t32->cb_min; type.isValid = t32->isValid; type.comp = t32->comp; type.dup = t32->dup; type.toString = kvno_toString; rv = kcdb_type_register(&type, &type_id_kvno); kcdb_type_release_info(t32); if (KHM_FAILED(rv)) goto _exit; type_regd_kvno = TRUE; } /* Register common attributes */ if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, &attr_id_key_enctype))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC]; /* although we are loading a long descriptoin, it still fits in the short descriptoin buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_KEY_ENCTYPE; attrib.id = KCDB_ATTR_INVALID; attrib.type = type_id_enctype; attrib.flags = KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_KEY_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); LoadString(hResModule, IDS_KEY_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf)); attrib.short_desc = sbuf; attrib.long_desc = lbuf; rv = kcdb_attrib_register(&attrib, &attr_id_key_enctype); if(KHM_FAILED(rv)) goto _exit; attr_regd_key_enctype = TRUE; } if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, &attr_id_tkt_enctype))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC]; /* although we are loading a long descriptoin, it still fits in the short descriptoin buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_TKT_ENCTYPE; attrib.id = KCDB_ATTR_INVALID; attrib.type = type_id_enctype; attrib.flags = KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_TKT_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); LoadString(hResModule, IDS_TKT_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf)); attrib.short_desc = sbuf; attrib.long_desc = lbuf; rv = kcdb_attrib_register(&attrib, &attr_id_tkt_enctype); if(KHM_FAILED(rv)) goto _exit; attr_regd_tkt_enctype = TRUE; } if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, &attr_id_addr_list))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC]; /* although we are loading a long descriptoin, it still fits in the short descriptoin buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_ADDR_LIST; attrib.id = KCDB_ATTR_INVALID; attrib.type = type_id_addr_list; attrib.flags = KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_ADDR_LIST_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); LoadString(hResModule, IDS_ADDR_LIST_LONG_DESC, lbuf, ARRAYLENGTH(lbuf)); attrib.short_desc = sbuf; attrib.long_desc = lbuf; rv = kcdb_attrib_register(&attrib, &attr_id_addr_list); if(KHM_FAILED(rv)) goto _exit; attr_regd_addr_list = TRUE; } if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, &attr_id_krb5_flags))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; /* although we are loading a long descriptoin, it still fits in the short descriptoin buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_KRB5_FLAGS; attrib.id = KCDB_ATTR_INVALID; attrib.type = type_id_krb5_flags; attrib.flags = KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_KRB5_FLAGS_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); attrib.short_desc = sbuf; attrib.long_desc = NULL; rv = kcdb_attrib_register(&attrib, &attr_id_krb5_flags); if(KHM_FAILED(rv)) goto _exit; attr_regd_krb5_flags = TRUE; } if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_CCNAME, &attr_id_krb5_ccname))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC]; /* although we are loading a long descriptoin, it still fits in the short descriptoin buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_KRB5_CCNAME; attrib.id = KCDB_ATTR_INVALID; attrib.type = KCDB_TYPE_STRING; attrib.flags = KCDB_ATTR_FLAG_PROPERTY | KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_KRB5_CCNAME_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); LoadString(hResModule, IDS_KRB5_CCNAME_LONG_DESC, lbuf, ARRAYLENGTH(lbuf)); attrib.short_desc = sbuf; attrib.long_desc = lbuf; rv = kcdb_attrib_register(&attrib, &attr_id_krb5_ccname); if(KHM_FAILED(rv)) goto _exit; attr_regd_krb5_ccname = TRUE; } if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KVNO, &attr_id_kvno))) { kcdb_attrib attrib; wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC]; wchar_t lbuf[KCDB_MAXCCH_LONG_DESC]; /* although we are loading a long description, it still fits in the short description buffer */ ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_KVNO; attrib.id = KCDB_ATTR_INVALID; attrib.type = type_id_kvno; attrib.flags = KCDB_ATTR_FLAG_TRANSIENT; LoadString(hResModule, IDS_KVNO_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf)); LoadString(hResModule, IDS_KVNO_LONG_DESC, lbuf, ARRAYLENGTH(lbuf)); attrib.short_desc = sbuf; attrib.long_desc = lbuf; rv = kcdb_attrib_register(&attrib, &attr_id_kvno); if (KHM_FAILED(rv)) goto _exit; attr_regd_kvno = TRUE; } if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_IDFLAGS, &attr_id_krb5_idflags))) { kcdb_attrib attrib; ZeroMemory(&attrib, sizeof(attrib)); attrib.name = ATTRNAME_KRB5_IDFLAGS; attrib.id = KCDB_ATTR_INVALID; attrib.type = KCDB_TYPE_INT32; attrib.flags = KCDB_ATTR_FLAG_PROPERTY | KCDB_ATTR_FLAG_HIDDEN; /* we don't bother localizing these strings since the attribute is hidden. The user will not see these descriptions anyway. */ attrib.short_desc = L"Krb5 ID flags"; attrib.long_desc = L"Kerberos 5 Identity Flags"; rv = kcdb_attrib_register(&attrib, &attr_id_krb5_idflags); if (KHM_FAILED(rv)) goto _exit; attr_regd_krb5_idflags = TRUE; } rv = kmm_get_plugins_config(0, &csp_plugins); if(KHM_FAILED(rv)) goto _exit; rv = khc_load_schema(csp_plugins, schema_krbconfig); if(KHM_FAILED(rv)) goto _exit; rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, 0, &csp_krbcred); if(KHM_FAILED(rv)) goto _exit; rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params); if(KHM_FAILED(rv)) goto _exit; _exit: return rv; }
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); }
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; }
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(¤t); #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(¤t, &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; }
/* 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(¤t); if (CompareFileTime(&expiry, ¤t) < 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; }