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); }
KHMEXP khm_int32 KHMAPI kmm_enable_plugin(kmm_plugin p, khm_boolean enable) { kmm_plugin_i * pi; khm_int32 rv = KHM_ERROR_NOT_FOUND; /* default to error */ khm_handle csp_plugin = NULL; EnterCriticalSection(&cs_kmm); if (!kmm_is_plugin(p)) { rv = KHM_ERROR_INVALID_PARAM; goto _cleanup; } pi = kmm_plugin_from_handle(p); if (KHM_FAILED(rv = kmm_get_plugin_config(pi->p.name, 0, &csp_plugin))) { goto _cleanup; } if (KHM_FAILED(rv = khc_write_int32(csp_plugin, L"Disabled", !enable))) { goto _cleanup; } rv = KHM_ERROR_SUCCESS; _cleanup: LeaveCriticalSection(&cs_kmm); if (csp_plugin) khc_close_space(csp_plugin); return rv; }
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); }
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); } }
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); }
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); } }
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(); }
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_register_module(kmm_module_reg * module, khm_int32 config_flags) { khm_int32 rv = KHM_ERROR_SUCCESS; khm_handle csp_module = NULL; size_t cch; int i; if((module == NULL) || FAILED(StringCchLength(module->name, KMM_MAXCCH_NAME, &cch)) || (module->description && FAILED(StringCchLength(module->description, KMM_MAXCCH_DESC, &cch))) || FAILED(StringCchLength(module->path, MAX_PATH, &cch)) || (module->n_plugins > 0 && module->plugin_reg_info == NULL)) { return KHM_ERROR_INVALID_PARAM; } #define CKRV if(KHM_FAILED(rv)) goto _exit rv = kmm_get_module_config(module->name, config_flags | KHM_FLAG_CREATE, &csp_module); CKRV; rv = khc_write_string(csp_module, L"ImagePath", module->path); CKRV; rv = khc_write_int32(csp_module, L"Disabled", 0); CKRV; /* FileVersion and ProductVersion will be set when the module is loaded for the first time */ for(i=0; i<module->n_plugins; i++) { rv = kmm_register_plugin(&(module->plugin_reg_info[i]), config_flags); CKRV; } #undef CKRV _exit: if(csp_module) khc_close_space(csp_module); return rv; }
static void k4_ids_write_params(HWND hw, k4_ids_data * d) { khm_int32 nv; khm_boolean applied = FALSE; if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED) nv = TRUE; else nv = FALSE; if (!!nv != !!d->get_tix) { d->get_tix = !!nv; khc_write_int32(csp_params, L"Krb4NewCreds", d->get_tix); applied = TRUE; } khui_cfg_set_flags_inst(&d->cfg, (applied)?KHUI_CNFLAG_APPLIED:0, KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); }
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"); } }
/*! \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(); }
static void k5_id_write_params(HWND hw, k5_id_dlg_data * d) { khm_handle csp_ident = NULL; wchar_t ccache[KRB5_MAXCCH_CCNAME]; khm_size cb; khm_int32 rv; khm_boolean b; khm_boolean applied = FALSE; DWORD dwaddress = 0; if (!k5_id_is_mod(hw, d)) return; rv = khm_krb5_get_identity_config(d->ident, KHM_FLAG_CREATE | KCONF_FLAG_WRITEIFMOD, &csp_ident); if (KHM_FAILED(rv)) return; if (d->life != d->tc_life.current) { d->life = d->tc_life.current; khc_write_int32(csp_ident, L"DefaultLifetime", (khm_int32) d->life); applied = TRUE; } if (d->renew_life != d->tc_renew.current) { d->renew_life = d->tc_renew.current; khc_write_int32(csp_ident, L"DefaultRenewLifetime", (khm_int32) d->renew_life); applied = TRUE; } b = (IsDlgButtonChecked(hw, IDC_CFG_RENEW) == BST_CHECKED); if (b != d->renewable) { d->renewable = b; khc_write_int32(csp_ident, L"Renewable", (khm_int32) b); applied = TRUE; } b = (IsDlgButtonChecked(hw, IDC_CFG_FORWARD) == BST_CHECKED); if (b != d->forwardable) { d->forwardable = b; khc_write_int32(csp_ident, L"Forwardable", (khm_int32) b); applied = TRUE; } b = (IsDlgButtonChecked(hw, IDC_CFG_PROXY) == BST_CHECKED); if (b != d->proxiable) { d->proxiable = b; khc_write_int32(csp_ident, L"Proxiable", (khm_int32) b); applied = TRUE; } b = (IsDlgButtonChecked(hw, IDC_CFG_ADDRESSLESS) == BST_CHECKED); if (b != d->addressless) { d->addressless = b; khc_write_int32(csp_ident, L"Addressless", (khm_int32) b); applied = TRUE; } SendDlgItemMessage(hw, IDC_CFG_PUBLICIP, IPM_GETADDRESS, 0, (LPARAM) &dwaddress); if (dwaddress != d->public_ip) { d->public_ip = dwaddress; khc_write_int32(csp_ident, L"PublicIP", (khm_int32) dwaddress); applied = TRUE; } GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache)); if (SUCCEEDED(StringCbLength(ccache, sizeof(ccache), &cb)) && cb > sizeof(wchar_t)) { khm_krb5_canon_cc_name(ccache, sizeof(ccache)); if (wcscmp(ccache, d->ccache)) { khc_write_string(csp_ident, L"DefaultCCName", ccache); StringCbCopy(d->ccache, sizeof(d->ccache), ccache); SetDlgItemText(hw, IDC_CFG_CCACHE, ccache); applied = TRUE; } } else { khc_remove_value(csp_ident, L"DefaultCCName", KCONF_FLAG_USER); d->ccache[0] = L'\0'; applied = TRUE; } if (csp_ident) khc_close_space(csp_ident); khui_cfg_set_flags_inst(&d->cfg, (applied ? KHUI_CNFLAG_APPLIED : 0), KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); }
/* dialog box procedure for the "Add new identity" dialog */ INT_PTR CALLBACK khm_cfg_add_ident_proc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) { add_ident_data * d; switch(umsg) { case WM_INITDIALOG: /* we create a new credentials blob and pull in the identity selectors from the identity provider. */ d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); khui_cw_create_cred_blob(&d->nc); #ifdef DEBUG assert(d->nc != NULL); #endif if (d->nc == NULL) { PFREE(d); break; } if (KHM_FAILED(kcdb_identpro_get_ui_cb(&d->nc->ident_cb))) { /* this should have worked. The only reason it would fail is if there is no identity provider or if the identity provider does not support providing idnetity selectors. */ khui_cw_destroy_cred_blob(d->nc); PFREE(d); break; } #pragma warning(push) #pragma warning(disable: 4244) SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); #pragma warning(pop) /* get metrics for dynamic controls */ get_ctrl_row_metrics(&d->dim_small, GetDlgItem(hwnd, IDC_SM_LBL), GetDlgItem(hwnd, IDC_SM_CTL)); get_ctrl_row_metrics(&d->dim_medium, GetDlgItem(hwnd, IDC_MED_LBL), GetDlgItem(hwnd, IDC_MED_CTL)); get_ctrl_row_metrics(&d->dim_large, GetDlgItem(hwnd, IDC_LG_LBL), GetDlgItem(hwnd, IDC_LG_CTL)); { RECT rlbl; RECT rctl; RECT rwnd; GetWindowRect(GetDlgItem(hwnd, IDC_SM_LBL), &rlbl); GetWindowRect(GetDlgItem(hwnd, IDC_SM_CTL), &rctl); GetWindowRect(hwnd, &rwnd); OffsetRect(&rlbl, -rwnd.left, -rwnd.top); OffsetRect(&rctl, -rwnd.left, -rwnd.top); d->current_x = rlbl.left; d->current_y = rctl.top - GetSystemMetrics(SM_CYCAPTION); GetWindowRect(GetDlgItem(hwnd, IDC_MED_CTL), &rlbl); OffsetRect(&rlbl, -rwnd.left, -rwnd.top); d->row_gap = rlbl.top - rctl.bottom; } d->nc->hwnd = hwnd; /* now call the UI callback and make it create the controls. */ d->nc->ident_cb(d->nc, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) hwnd); break; case WM_DESTROY: d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) break; d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0); khui_cw_destroy_cred_blob(d->nc); PFREE(d); break; case KHUI_WM_NC_NOTIFY: d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); switch(HIWORD(wParam)) { case WMNC_ADD_CONTROL_ROW: { khui_control_row * row; RECT r_lbl, r_inp, r_enc; struct ctrl_row_dimensions * dim; HFONT hf; row = (khui_control_row *) lParam; #ifdef DEBUG assert(row->label); assert(row->input); assert(d); #endif if (row->size == KHUI_CTRLSIZE_SMALL) { dim = &d->dim_small; } else if (row->size == KHUI_CTRLSIZE_HALF) { dim = &d->dim_medium; } else { dim = &d->dim_large; #ifdef DEBUG assert(row->size == KHUI_CTRLSIZE_FULL); #endif } CopyRect(&r_enc, &dim->enclosure); CopyRect(&r_lbl, &dim->label); CopyRect(&r_inp, &dim->control); OffsetRect(&r_enc, d->current_x, d->current_y); OffsetRect(&r_lbl, r_enc.left, r_enc.top); OffsetRect(&r_inp, r_enc.left, r_enc.top); d->current_y += r_enc.bottom - r_enc.top; hf = (HFONT) SendDlgItemMessage(hwnd, IDOK, WM_GETFONT, 0, 0); if (row->label) { SetWindowPos(row->label, ((d->hwnd_last_ctrl != NULL)? d->hwnd_last_ctrl : HWND_TOP), r_lbl.left, r_lbl.top, r_lbl.right - r_lbl.left, r_lbl.bottom - r_lbl.top, SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (hf) SendMessage(row->label, WM_SETFONT, (WPARAM) hf, TRUE); d->hwnd_last_ctrl = row->label; } if (row->input) { SetWindowPos(row->input, ((d->hwnd_last_ctrl != NULL)? d->hwnd_last_ctrl : HWND_TOP), r_inp.left, r_inp.top, r_inp.right - r_inp.left, r_inp.bottom - r_inp.top, SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (hf) SendMessage(row->input, WM_SETFONT, (WPARAM) hf, TRUE); d->hwnd_last_ctrl = row->input; } } break; case WMNC_IDENTITY_CHANGE: break; } return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK) { wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; wchar_t err_msg[1024]; khm_handle ident = NULL; khm_handle csp_ident = NULL; khm_size cb; khm_int32 rv = KHM_ERROR_SUCCESS; d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (!d || !d->nc) break; /* check if there was an identity selected */ if (d->nc->n_identities == 0 || d->nc->identities[0] == NULL) { StringCbCopy(idname, sizeof(idname), L""); LoadString(khm_hInstance, IDS_CFG_IDNAME_NON, err_msg, ARRAYLENGTH(err_msg)); goto show_failure; } ident = d->nc->identities[0]; kcdb_identity_hold(ident); cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); /* now we have to create the identity configuration. */ if (KHM_FAILED(rv = kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &csp_ident))) { wchar_t fmt[256]; LoadString(khm_hInstance, IDS_CFG_IDNAME_CCC, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(err_msg, sizeof(err_msg), fmt, rv); kcdb_identity_release(ident); goto show_failure; } /* create a value so that the configuration space will actually be created in the registry. We don't want this new identity to be sticky. */ khc_write_int32(csp_ident, L"Sticky", 0); khm_refresh_config(); kcdb_identity_release(ident); khc_close_space(csp_ident); EndDialog(hwnd, 0); break; show_failure: { wchar_t title[512]; wchar_t fmt[256]; if (!err_msg[0]) break; LoadString(khm_hInstance, IDS_CFG_IDNAME_PRB, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(title, sizeof(title), fmt, idname); MessageBox(hwnd, err_msg, title, MB_OK | MB_ICONSTOP); /* don't end the dialog yet */ break; } break; } else if (LOWORD(wParam) == IDCANCEL) { EndDialog(hwnd, 1); } else { d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d && d->nc && d->nc->ident_cb) { return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, umsg, wParam, lParam); } } break; } return FALSE; }
KHMEXP khm_int32 KHMAPI kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags) { khm_int32 rv = KHM_ERROR_SUCCESS; khm_handle csp_plugin = NULL; khm_handle csp_module = NULL; size_t cch; /* avoid accidently creating the module key if it doesn't exist */ config_flags &= ~KHM_FLAG_CREATE; if((plugin == NULL) || (plugin->dependencies && KHM_FAILED(multi_string_length_cch(plugin->dependencies, KMM_MAXCCH_DEPS, &cch))) || FAILED(StringCchLength(plugin->module, KMM_MAXCCH_NAME, &cch)) || (plugin->description && FAILED(StringCchLength(plugin->description, KMM_MAXCCH_DESC, &cch))) || FAILED(StringCchLength(plugin->name, KMM_MAXCCH_NAME, &cch))) { return KHM_ERROR_INVALID_PARAM; } /* note that we are retaining the length of the plugin name in chars in cch */ cch ++; #define CKRV if(KHM_FAILED(rv)) goto _exit rv = kmm_get_plugin_config(plugin->name, config_flags | KHM_FLAG_CREATE, &csp_plugin); CKRV; /* should fail if the module key doesn't exist */ rv = kmm_get_module_config(plugin->module, config_flags, &csp_module); CKRV; /*TODO: Make sure that the module registration is in the same config store as the one in which the plugin is going to be registered */ rv = khc_write_string(csp_plugin, L"Module", plugin->module); CKRV; if(plugin->description) { rv = khc_write_string(csp_plugin, L"Description", plugin->description); CKRV; } if(plugin->dependencies) { rv = khc_write_multi_string(csp_plugin, L"Dependencies", plugin->dependencies); CKRV; } rv = khc_write_int32(csp_plugin, L"Type", plugin->type); CKRV; rv = khc_write_int32(csp_plugin, L"Disabled", !!(plugin->flags & KMM_PLUGIN_FLAG_DISABLED)); CKRV; { khm_size cb = 0; wchar_t * pl = NULL; size_t scb = 0; rv = khc_read_multi_string(csp_module, L"PluginList", NULL, &cb); if(rv != KHM_ERROR_TOO_LONG) { if (rv == KHM_ERROR_NOT_FOUND) { scb = cb = (cch + 1) * sizeof(wchar_t); pl = PMALLOC(cb); multi_string_init(pl, cb); rv = KHM_ERROR_SUCCESS; goto add_plugin_to_list; } else { goto _exit; } } cb += cch * sizeof(wchar_t); scb = cb; pl = PMALLOC(cb); rv = khc_read_multi_string(csp_module, L"PluginList", pl, &cb); if(KHM_FAILED(rv)) { if(pl) PFREE(pl); goto _exit; } add_plugin_to_list: if(!multi_string_find(pl, plugin->name, 0)) { multi_string_append(pl, &scb, plugin->name); rv = khc_write_multi_string(csp_module, L"PluginList", pl); } PFREE(pl); CKRV; } #undef CKRV _exit: if(csp_plugin) khc_close_space(csp_plugin); if(csp_module) khc_close_space(csp_module); return rv; }
static void write_params_ident(ident_data * d) { khm_handle csp_ident; if (d->saved.monitor == d->work.monitor && d->saved.auto_renew == d->work.auto_renew && d->saved.sticky == d->work.sticky && !d->removed) return; if (KHM_FAILED(kcdb_identity_get_config(d->ident, KHM_PERM_WRITE, &csp_ident))) { #ifdef DEBUG assert(FALSE); #endif return; } if (d->removed) { khm_handle h = NULL; khm_int32 flags = 0; khc_remove_space(csp_ident); /* calling kcdb_identity_get_config() will update the KCDB_IDENT_FLAG_CONFIG flag for the identity to reflect the fact that it nolonger has a configuration. */ kcdb_identity_get_config(d->ident, 0, &h); if (h) { /* what the ? */ #ifdef DEBUG assert(FALSE); #endif khc_close_space(h); } #ifdef DEBUG kcdb_identity_get_flags(d->ident, &flags); assert(!(flags & KCDB_IDENT_FLAG_CONFIG)); #endif } else { if (d->saved.monitor != d->work.monitor) khc_write_int32(csp_ident, L"Monitor", !!d->work.monitor); if (d->saved.auto_renew != d->work.auto_renew) khc_write_int32(csp_ident, L"AllowAutoRenew", !!d->work.auto_renew); if (d->saved.sticky != d->work.sticky) { kcdb_identity_set_flags(d->ident, (d->work.sticky)?KCDB_IDENT_FLAG_STICKY:0, KCDB_IDENT_FLAG_STICKY); } } khc_close_space(csp_ident); d->saved = d->work; d->applied = TRUE; if (d->hwnd) PostMessage(d->hwnd, KHUI_WM_CFG_NOTIFY, MAKEWPARAM(0, WMCFG_UPDATE_STATE), 0); khm_refresh_config(); }
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; }