void k5_read_file_cc_data(k5_ccc_data * d) { khm_int32 t; wchar_t * fclist = NULL; wchar_t * fc; khm_size cb; #ifdef DEBUG assert(csp_params); #endif d->inc_api = TRUE; t = TRUE; khc_read_int32(csp_params, L"MsLsaList", &t); d->inc_mslsa = t; if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb) != KHM_ERROR_TOO_LONG || cb <= sizeof(wchar_t) * 2) { k5_flush_file_ccs(d); } else { fclist = PMALLOC(cb); #ifdef DEBUG assert(fclist); #endif khc_read_multi_string(csp_params, L"FileCCList", fclist, &cb); for(fc = fclist; fc && *fc; fc = multi_string_next(fc)) { k5_add_file_cc(d, fc); } PFREE(fclist); } }
/* 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); }
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); }
INT_PTR CALLBACK k5_ccconfig_dlgproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { k5_ccc_dlg_data * d; switch(uMsg) { case WM_INITDIALOG: d = PMALLOC(sizeof(*d)); #ifdef DEBUG assert(d); #endif ZeroMemory(d, sizeof(*d)); k5_read_file_cc_data(&d->save); k5_copy_file_cc_data(&d->work, &d->save); d->node = (khui_config_node) lParam; #pragma warning(push) #pragma warning(disable: 4244) SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); #pragma warning(pop) { LVCOLUMN lvc; HWND lv; wchar_t buf[256]; RECT r; lv = GetDlgItem(hwnd, IDC_CFG_FCLIST); #ifdef DEBUG assert(lv); #endif ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_TEXT | LVCF_WIDTH; LoadString(hResModule, IDS_CFG_FCTITLE, buf, ARRAYLENGTH(buf)); GetWindowRect(lv, &r); lvc.pszText = buf; lvc.cx = (r.right - r.left) * 9 / 10; ListView_InsertColumn(lv, 0, &lvc); } SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SETLIMITTEXT, MAX_PATH - 1, 0); k5_ccc_update_ui(hwnd, d); break; case WM_COMMAND: d = (k5_ccc_dlg_data *) (DWORD_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) break; switch(wParam) { case MAKEWPARAM(IDC_CFG_ADD, BN_CLICKED): { wchar_t path[MAX_PATH]; wchar_t cpath[MAX_PATH]; khm_size i; GetDlgItemText(hwnd, IDC_CFG_FCNAME, cpath, ARRAYLENGTH(cpath)); PathCanonicalize(path, cpath); if (!*path) return TRUE; /* nothing to add */ for (i=0; i < d->work.n_file_ccs; i++) { if (!_wcsicmp(path, d->work.file_ccs[i].path)) { /* allow the user to correct case, as appropriate */ StringCbCopy(d->work.file_ccs[i].path, sizeof(d->work.file_ccs[i].path), path); k5_ccc_update_ui(hwnd, d); return TRUE; } } /* not there. we need to add. but check a few things first */ if (!PathFileExists(path)) { wchar_t title[64]; wchar_t text[128]; LoadString(hResModule, IDS_CFG_FCN_WARNING, title, ARRAYLENGTH(title)); LoadString(hResModule, IDS_CFG_FCN_W_NOTFOUND, text, ARRAYLENGTH(text)); #if _WIN32_WINNT >= 0x501 if (IS_COMMCTL6()) { EDITBALLOONTIP bt; bt.cbStruct = sizeof(bt); bt.pszTitle = title; bt.pszText = text; bt.ttiIcon = TTI_WARNING; SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SHOWBALLOONTIP, 0, (LPARAM) &bt); } else { #endif MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING); #if _WIN32_WINNT >= 0x501 } #endif } else if (PathIsRelative(path)) { wchar_t title[64]; wchar_t text[128]; LoadString(hResModule, IDS_CFG_FCN_WARNING, title, ARRAYLENGTH(title)); LoadString(hResModule, IDS_CFG_FCN_W_RELATIVE, text, ARRAYLENGTH(text)); #if _WIN32_WINNT >= 0x501 if (IS_COMMCTL6()) { EDITBALLOONTIP bt; bt.cbStruct = sizeof(bt); bt.pszTitle = title; bt.pszText = text; bt.ttiIcon = TTI_WARNING; SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SHOWBALLOONTIP, 0, (LPARAM) &bt); } else { #endif MessageBox(hwnd, text, title, MB_OK | MB_ICONWARNING); #if _WIN32_WINNT >= 0x501 } #endif } k5_add_file_cc(&d->work, path); k5_ccc_update_ui(hwnd, d); } return TRUE; case MAKEWPARAM(IDC_CFG_BROWSE, BN_CLICKED): { OPENFILENAME ofn; wchar_t path[MAX_PATH * 8]; wchar_t title[128]; ZeroMemory(&ofn, sizeof(ofn)); ZeroMemory(path, sizeof(path)); GetDlgItemText(hwnd, IDC_CFG_FCNAME, path, ARRAYLENGTH(path)); /* don't pass in invalid paths */ if (!PathFileExists(path)) *path = 0; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFilter = L"All files\0*.*\0\0"; ofn.nFilterIndex = 1; ofn.lpstrFile = path; ofn.nMaxFile = ARRAYLENGTH(path); ofn.lpstrTitle = title; LoadString(hResModule, IDS_CFG_FCOPENTITLE, title, ARRAYLENGTH(title)); ofn.Flags = OFN_ALLOWMULTISELECT | OFN_DONTADDTORECENT | OFN_FORCESHOWHIDDEN | OFN_EXPLORER; if (GetOpenFileName(&ofn)) { wchar_t * p; wchar_t spath[MAX_PATH]; p = multi_string_next(path); if (p) { /* multi select */ for(;p && *p; p = multi_string_next(p)) { StringCbCopy(spath, sizeof(spath), path); PathAppend(spath, p); k5_add_file_cc(&d->work, spath); } } else { /* single select */ k5_add_file_cc(&d->work, path); } k5_ccc_update_ui(hwnd, d); } } return TRUE; case MAKEWPARAM(IDC_CFG_REMOVE, BN_CLICKED): { khm_size i; int lv_idx; HWND lv; wchar_t buf[MAX_PATH]; lv = GetDlgItem(hwnd, IDC_CFG_FCLIST); #ifdef DEBUG assert(lv); #endif lv_idx = -1; while((lv_idx = ListView_GetNextItem(lv, lv_idx, LVNI_SELECTED)) != -1) { ListView_GetItemText(lv, lv_idx, 0, buf, ARRAYLENGTH(buf)); for (i=0; i < d->work.n_file_ccs; i++) { if (!_wcsicmp(buf, d->work.file_ccs[i].path)) { k5_del_file_cc(&d->work, i); break; } } } k5_ccc_update_ui(hwnd, d); } return TRUE; case MAKEWPARAM(IDC_CFG_INCAPI, BN_CLICKED): case MAKEWPARAM(IDC_CFG_INCMSLSA, BN_CLICKED): k5_ccc_update_data(hwnd, &d->work); k5_ccc_update_ui(hwnd, d); return TRUE; } break; case WM_DESTROY: d = (k5_ccc_dlg_data *) (DWORD_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) break; k5_free_file_ccs(&d->work); k5_free_file_ccs(&d->save); PFREE(d); SetWindowLongPtr(hwnd, DWLP_USER, 0); return TRUE; case KHUI_WM_CFG_NOTIFY: d = (k5_ccc_dlg_data *) (DWORD_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) break; switch(HIWORD(wParam)) { case WMCFG_APPLY: if (k5_ccc_get_mod(d)) { k5_write_file_cc_data(&d->work); k5_copy_file_cc_data(&d->save, &d->work); khui_cfg_set_flags(d->node, KHUI_CNFLAG_APPLIED, KHUI_CNFLAG_APPLIED); k5_ccc_update_ui(hwnd, d); kmq_post_sub_msg(k5_sub, KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); } break; } } return FALSE; }
/*! \internal \brief Initialize a plugin \note If kmmint_init_plugin() is called on a plugin, then kmmint_exit_plugin() \b must be called for the plugin. \note Should only be called from the context of the registrar thread */ void kmmint_init_plugin(kmm_plugin_i * p) { DWORD dummy; khm_handle csp_plugin = NULL; khm_handle csp_plugins = NULL; khm_int32 t; /* the following will be undone in kmmint_exit_plugin() */ kmm_hold_plugin(kmm_handle_from_plugin(p)); EnterCriticalSection(&cs_kmm); if(p->state != KMM_PLUGIN_STATE_REG && p->state != KMM_PLUGIN_STATE_HOLD) { LeaveCriticalSection(&cs_kmm); goto _exit; } _begin_task(0); _report_mr1(KHERR_NONE, MSG_IP_TASK_DESC, _cstr(p->p.name)); _describe(); if(p->state == KMM_PLUGIN_STATE_HOLD) { /* if this plugin was held, then we already had a hold from the initial attempt to start the plugin. Undo the hold we did a few lines earlier. */ kmm_release_plugin(kmm_handle_from_plugin(p)); /* same for the plugin count for the module. */ #ifdef DEBUG assert(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT); #endif p->module->plugin_count--; p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT; } p->state = KMM_PLUGIN_STATE_PREINIT; kmmint_delist_plugin(p); kmmint_list_plugin(p); LeaveCriticalSection(&cs_kmm); if(KHM_FAILED(kmm_get_plugins_config(0, &csp_plugins))) { _report_mr0(KHERR_ERROR, MSG_IP_GET_CONFIG); p->state = KMM_PLUGIN_STATE_FAIL_UNKNOWN; goto _exit; } if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) { if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) { _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED); p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED; goto _exit; } if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) { _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED); p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED; goto _exit; } } if (KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"Disabled", &t)) && t) { p->flags |= KMM_PLUGIN_FLAG_DISABLED; p->state = KMM_PLUGIN_STATE_FAIL_DISABLED; goto _exit; } #if 0 /*TODO: check the failure count and act accordingly */ if(KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"FailureCount", &t)) && (t > 0)) { } #endif EnterCriticalSection(&cs_kmm); p->n_depends = 0; p->n_unresolved = 0; do { wchar_t * deps = NULL; wchar_t * d; khm_size sz = 0; if(khc_read_multi_string(csp_plugin, L"Dependencies", NULL, &sz) != KHM_ERROR_TOO_LONG) break; deps = PMALLOC(sz); if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", deps, &sz))) { if(deps) PFREE(deps); break; } for(d = deps; d && *d; d = multi_string_next(d)) { kmm_plugin_i * pd; int i; pd = kmmint_get_plugin_i(d); if(pd->state == KMM_PLUGIN_STATE_NONE) { /* the dependant was not previously known */ pd->state = KMM_PLUGIN_STATE_PLACEHOLDER; } for(i=0; i < pd->n_dependants; i++) { if(pd->dependants[i] == p) break; } if(i >= pd->n_dependants) { if( pd->n_dependants >= KMM_MAX_DEPENDANTS ) { /*TODO: handle this gracefully */ RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL); } /* released in kmmint_free_plugin() */ kmm_hold_plugin(kmm_handle_from_plugin(p)); pd->dependants[pd->n_dependants] = p; pd->n_dependants++; } p->n_depends++; if(pd->state != KMM_PLUGIN_STATE_RUNNING) { p->n_unresolved++; } } if(p->n_unresolved > 0) { p->state = KMM_PLUGIN_STATE_HOLD; } PFREE(deps); } while(FALSE); #ifdef DEBUG assert(!(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT)); #endif p->flags |= KMM_PLUGIN_FLAG_IN_MODCOUNT; p->module->plugin_count++; LeaveCriticalSection(&cs_kmm); if(p->state == KMM_PLUGIN_STATE_HOLD) { _report_mr1(KHERR_INFO, MSG_IP_HOLD, _dupstr(p->p.name)); goto _exit_post; } kmmint_add_to_plugin_queue(p); p->ht_thread = CreateThread(NULL, 0, kmmint_plugin_broker, (LPVOID) p, CREATE_SUSPENDED, &dummy); p->state = KMM_PLUGIN_STATE_INIT; ResumeThread(p->ht_thread); _exit_post: if(csp_plugin != NULL) khc_close_space(csp_plugin); if(csp_plugins != NULL) khc_close_space(csp_plugins); _report_mr2(KHERR_INFO, MSG_IP_STATE, _dupstr(p->p.name), _int32(p->state)); _end_task(); return; /* jump here if an error condition happens before the plugin broker thread starts and the plugin should be unloaded */ _exit: if(csp_plugin != NULL) khc_close_space(csp_plugin); if(csp_plugins != NULL) khc_close_space(csp_plugins); _report_mr2(KHERR_WARNING, MSG_IP_EXITING, _dupstr(p->p.name), _int32(p->state)); _end_task(); #ifdef ASYNC_PLUGIN_UNLOAD_ON_FAILURE kmm_hold_plugin(kmm_handle_from_plugin(p)); kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p); #else kmmint_exit_plugin(p); #endif }
void update_dialog_fields(HWND hwnd, plugin_dlg_data * d, plugin_data * info) { wchar_t buf[256]; UINT resid; wchar_t * t; khm_handle csp_module = NULL; d->selected = info; if (info->plugin.reg.description) SetDlgItemText(hwnd, IDC_CFG_DESC, info->plugin.reg.description); else { wchar_t fmt[128]; LoadString(khm_hInstance, IDS_CFG_NODESC, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, info->plugin.reg.name); SetDlgItemText(hwnd, IDC_CFG_DESC, buf); } switch(info->plugin.state) { case KMM_PLUGIN_STATE_FAIL_INIT: resid = IDS_PISTATE_FAILINIT; break; case KMM_PLUGIN_STATE_FAIL_UNKNOWN: resid = IDS_PISTATE_FAILUNK; break; case KMM_PLUGIN_STATE_FAIL_MAX_FAILURE: resid = IDS_PISTATE_FAILMAX; break; case KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED: resid = IDS_PISTATE_FAILREG; break; case KMM_PLUGIN_STATE_FAIL_DISABLED: resid = IDS_PISTATE_FAILDIS; break; case KMM_PLUGIN_STATE_FAIL_LOAD: resid = IDS_PISTATE_FAILLOD; break; case KMM_PLUGIN_STATE_NONE: case KMM_PLUGIN_STATE_PLACEHOLDER: resid = IDS_PISTATE_PLACEHOLD; break; case KMM_PLUGIN_STATE_REG: case KMM_PLUGIN_STATE_PREINIT: resid = IDS_PISTATE_REG; break; case KMM_PLUGIN_STATE_HOLD: resid = IDS_PISTATE_HOLD; break; case KMM_PLUGIN_STATE_INIT: resid = IDS_PISTATE_INIT; break; case KMM_PLUGIN_STATE_RUNNING: resid = IDS_PISTATE_RUN; break; case KMM_PLUGIN_STATE_EXITED: resid = IDS_PISTATE_EXIT; break; default: #ifdef DEBUG assert(FALSE); #endif resid = IDS_PISTATE_FAILUNK; } LoadString(khm_hInstance, resid, buf, ARRAYLENGTH(buf)); SetDlgItemText(hwnd, IDC_CFG_STATE, buf); SendDlgItemMessage(hwnd, IDC_CFG_DEPS, LB_RESETCONTENT, 0, 0); for (t = info->plugin.reg.dependencies; t && *t; t = multi_string_next(t)) { SendDlgItemMessage(hwnd, IDC_CFG_DEPS, LB_INSERTSTRING, (WPARAM) -1, (LPARAM) t); } if (info->plugin.reg.module) SetDlgItemText(hwnd, IDC_CFG_MODULE, info->plugin.reg.module); else SetDlgItemText(hwnd, IDC_CFG_MODULE, L""); if (info->module.reg.vendor) SetDlgItemText(hwnd, IDC_CFG_VENDOR, info->module.reg.vendor); else SetDlgItemText(hwnd, IDC_CFG_VENDOR, L""); StringCbPrintf(buf, sizeof(buf), L"%u.%u.%u.%u", (unsigned int) info->module.product_version.major, (unsigned int) info->module.product_version.minor, (unsigned int) info->module.product_version.patch, (unsigned int) info->module.product_version.aux); SetDlgItemText(hwnd, IDC_CFG_VERSION, buf); if (info->plugin.reg.icon) { SendDlgItemMessage(hwnd, IDC_CFG_ICON, STM_SETICON, (WPARAM) info->plugin.reg.icon, 0); } else { SendDlgItemMessage(hwnd, IDC_CFG_ICON, STM_SETICON, (WPARAM) d->plugin_ico, 0); } if (KHM_SUCCEEDED(kmm_get_module_config(info->module.reg.name, 0, &csp_module)) && (khc_value_exists(csp_module, L"ImagePath") & (KCONF_FLAG_MACHINE | KCONF_FLAG_USER))) { EnableWindow(GetDlgItem(hwnd, IDC_CFG_UNREGISTER), TRUE); } else { EnableWindow(GetDlgItem(hwnd, IDC_CFG_UNREGISTER), FALSE); } if (csp_module) khc_close_space(csp_module); if (info->plugin.flags & KMM_PLUGIN_FLAG_DISABLED) { EnableWindow(GetDlgItem(hwnd, IDC_CFG_ENABLE), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_DISABLE), FALSE); } else { EnableWindow(GetDlgItem(hwnd, IDC_CFG_ENABLE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_DISABLE), TRUE); } }
INT_PTR CALLBACK khm_cfg_plugins_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { plugin_dlg_data * d; switch(uMsg) { case WM_INITDIALOG: { kmm_plugin p; kmm_plugin pn; kmm_module m; khm_size i; LVCOLUMN lvc; RECT r; HWND hw; wchar_t buf[256]; HIMAGELIST h_ilist; HICON h_icon; d = PMALLOC(sizeof(*d)); #ifdef DEBUG assert(d); #endif ZeroMemory(d, sizeof(*d)); #pragma warning(push) #pragma warning(disable: 4244) SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); #pragma warning(pop) p = NULL; i = 0; do { if (KHM_FAILED(kmm_get_next_plugin(p, &pn))) break; if (p) kmm_release_plugin(p); p = pn; #ifdef DEBUG assert(d->info[i] == NULL); #endif d->info[i] = PMALLOC(sizeof(*(d->info[i]))); #ifdef DEBUG assert(d->info[i]); #endif ZeroMemory(&d->info[i]->plugin, sizeof(d->info[i]->plugin)); if (KHM_FAILED(kmm_get_plugin_info_i(p, &d->info[i]->plugin))) { PFREE(d->info[i]); d->info[i] = NULL; break; } ZeroMemory(&d->info[i]->module, sizeof(d->info[i]->module)); if (KHM_SUCCEEDED(kmm_load_module(d->info[i]->plugin.reg.module, KMM_LM_FLAG_NOLOAD, &m))) { kmm_get_module_info_i(m, &d->info[i]->module); kmm_release_module(m); } i ++; if (i == MAX_PLUGINS) break; } while(p); if (p) kmm_release_plugin(p); d->n_info = i; /* now populate the list view */ hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS); #ifdef DEBUG assert(hw); #endif h_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR8, 4, 4); h_icon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_PLUGIN), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); #ifdef DEBUG assert(h_icon); #endif ImageList_AddIcon(h_ilist, h_icon); DestroyIcon(h_icon); h_icon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_PLUGIN_DIS), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); #ifdef DEBUG assert(h_icon); #endif ImageList_AddIcon(h_ilist, h_icon); DestroyIcon(h_icon); h_icon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_PLUGIN_ERR), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); #ifdef DEBUG assert(h_icon); #endif ImageList_AddIcon(h_ilist, h_icon); DestroyIcon(h_icon); ListView_SetImageList(hw, h_ilist, LVSIL_STATE); ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_TEXT | LVCF_WIDTH; GetWindowRect(hw, &r); lvc.cx = ((r.right - r.left) * 95) / 100; lvc.pszText = buf; LoadString(khm_hInstance, IDS_CFG_PI_COL_PLUGINS, buf, ARRAYLENGTH(buf)); ListView_InsertColumn(hw, 0, &lvc); for(i=0; i<d->n_info; i++) { LVITEM lvi; ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; lvi.lParam = (LPARAM) d->info[i]; lvi.pszText = d->info[i]->plugin.reg.name; if (d->info[i]->plugin.flags & KMM_PLUGIN_FLAG_DISABLED) { lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_DISABLED); } else if (d->info[i]->plugin.state < 0) { lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_ERROR); } else { lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_NORMAL); } ListView_InsertItem(hw, &lvi); } d->plugin_ico = (HICON) LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_PLUGIN), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR); } return FALSE; case WM_NOTIFY: { LPNMHDR lpnm; HWND hw; d = (plugin_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) return FALSE; if (wParam == IDC_CFG_PLUGINS && (lpnm = (LPNMHDR) lParam) && lpnm->code == LVN_ITEMCHANGED) { LVITEM lvi; hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS); #ifdef DEBUG assert(hw); #endif if (ListView_GetSelectedCount(hw) != 1) { SetDlgItemText(hwnd, IDC_CFG_DESC, L""); SetDlgItemText(hwnd, IDC_CFG_STATE, L""); SetDlgItemText(hwnd, IDC_CFG_MODULE, L""); SetDlgItemText(hwnd, IDC_CFG_VENDOR, L""); SetDlgItemText(hwnd, IDC_CFG_VERSION, L""); EnableWindow(GetDlgItem(hwnd, IDC_CFG_ENABLE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_DISABLE), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_UNREGISTER), FALSE); SendDlgItemMessage(hwnd, IDC_CFG_DEPS, LB_RESETCONTENT, 0, 0); SendDlgItemMessage(hwnd, IDC_CFG_ICON, STM_SETICON, (WPARAM) d->plugin_ico, 0); d->selected = NULL; } else { int idx; plugin_data * info; idx = ListView_GetNextItem(hw, -1, LVNI_SELECTED); #ifdef DEBUG assert(idx != -1); #endif ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = idx; lvi.iSubItem = 0; lvi.mask = LVIF_PARAM; ListView_GetItem(hw, &lvi); #ifdef DEBUG assert(lvi.lParam != 0); #endif info = (plugin_data *) lvi.lParam; update_dialog_fields(hwnd, d, info); } } } return TRUE; case WM_COMMAND: { d = (plugin_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) return FALSE; switch (wParam) { case MAKEWPARAM(IDC_CFG_ENABLE, BN_CLICKED): if (d->selected != NULL) { khui_alert * alert = NULL; wchar_t buf[KHUI_MAXCCH_MESSAGE]; wchar_t fmt[KHUI_MAXCCH_MESSAGE]; kmm_plugin p; khui_alert_create_empty(&alert); LoadString(khm_hInstance, IDS_CFG_P_ENBCNFT, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_title(alert, buf); LoadString(khm_hInstance, IDS_CFG_P_ENBCNFM, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_message(alert, buf); khui_alert_set_severity(alert, KHERR_INFO); khui_alert_show_modal(alert); kmm_enable_plugin(d->selected->plugin.h_plugin, TRUE); khui_alert_release(alert); p = d->selected->plugin.h_plugin; kmm_hold_plugin(p); kmm_release_plugin_info_i(&d->selected->plugin); kmm_get_plugin_info_i(p, &d->selected->plugin); kmm_release_plugin(p); update_dialog_fields(hwnd, d, d->selected); } break; case MAKEWPARAM(IDC_CFG_DISABLE, BN_CLICKED): if (d->selected != NULL) { khui_alert * alert = NULL; wchar_t buf[KHUI_MAXCCH_MESSAGE]; wchar_t fmt[KHUI_MAXCCH_MESSAGE]; wchar_t depends[KHUI_MAXCCH_MESSAGE]; khm_size i; kmm_plugin p; khui_alert_create_empty(&alert); #ifdef DEBUG assert(alert); #endif if (alert == NULL) break; LoadString(khm_hInstance, IDS_CFG_P_DELCNFT, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_title(alert, buf); LoadString(khm_hInstance, IDS_CFG_P_DELCNFM, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_message(alert, buf); depends[0] = L'\0'; for (i=0; i<d->n_info; i++) { wchar_t * t; t = d->info[i]->plugin.reg.dependencies; while(t) { if (!wcscmp(t, d->selected->plugin.reg.name)) { if (depends[0]) StringCbCat(depends, sizeof(depends), L", "); StringCbCat(depends, sizeof(depends), d->info[i]->plugin.reg.name); break; } t = multi_string_next(t); } } if (depends[0]) { LoadString(khm_hInstance, IDS_CFG_P_DELCNFS, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, depends); khui_alert_set_suggestion(alert, buf); } else { LoadString(khm_hInstance, IDS_CFG_P_DELNDEP, buf, ARRAYLENGTH(buf)); khui_alert_set_suggestion(alert, buf); } khui_alert_add_command(alert, KHUI_PACTION_YES); khui_alert_add_command(alert, KHUI_PACTION_NO); khui_alert_set_severity(alert, KHERR_WARNING); if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) && alert->response == KHUI_PACTION_YES) { kmm_enable_plugin(d->selected->plugin.h_plugin, FALSE); } khui_alert_release(alert); p = d->selected->plugin.h_plugin; kmm_hold_plugin(p); kmm_release_plugin_info_i(&d->selected->plugin); kmm_get_plugin_info_i(p, &d->selected->plugin); kmm_release_plugin(p); update_dialog_fields(hwnd, d, d->selected); } break; case MAKEWPARAM(IDC_CFG_UNREGISTER, BN_CLICKED): { khui_alert * alert = NULL; wchar_t buf[KHUI_MAXCCH_MESSAGE]; wchar_t fmt[KHUI_MAXCCH_MESSAGE]; wchar_t plist[KHUI_MAXCCH_MESSAGE]; khm_size i; if (d->selected == NULL) { #ifdef DEBUG assert(FALSE); #endif break; } khui_alert_create_empty(&alert); LoadString(khm_hInstance, IDS_CFG_P_UNRCNFT, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_title(alert, buf); LoadString(khm_hInstance, IDS_CFG_P_UNRCNFM, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name); khui_alert_set_message(alert, buf); plist[0] = L'\0'; for (i=0; i < d->n_info; i++) { if (!wcscmp(d->info[i]->module.reg.name, d->selected->module.reg.name)) { if (plist[0]) StringCbCat(plist, sizeof(plist), L", "); StringCbCat(plist, sizeof(plist), d->info[i]->plugin.reg.name); } } #ifdef DEBUG /* there should have been at least one plugin */ assert(plist[0]); #endif LoadString(khm_hInstance, IDS_CFG_P_UNRCNFS, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(buf, sizeof(buf), fmt, plist); khui_alert_set_suggestion(alert, buf); khui_alert_add_command(alert, KHUI_PACTION_YES); khui_alert_add_command(alert, KHUI_PACTION_NO); khui_alert_set_severity(alert, KHERR_WARNING); if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) && alert->response == KHUI_PACTION_YES) { kmm_unregister_module(d->selected->module.reg.name, 0); update_dialog_fields(hwnd, d, d->selected); } } break; case MAKEWPARAM(IDC_CFG_REGISTER, BN_CLICKED): { } break; } } return TRUE; case WM_DESTROY: { khm_size i; d = (plugin_dlg_data *) (LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); #ifdef DEBUG assert(d); #endif if (d == NULL) return TRUE; for (i=0; i<d->n_info; i++) { #ifdef DEBUG assert(d->info[i]); #endif kmm_release_plugin_info_i(&d->info[i]->plugin); kmm_release_module_info_i(&d->info[i]->module); PFREE(d->info[i]); } PFREE(d); SetWindowLongPtr(hwnd, DWLP_USER, 0); khm_set_dialog_result(hwnd, 0); } return TRUE; } return FALSE; }
void khm_cred_renew_all_identities(void) { khm_size count; khm_size cb = 0; khm_size n_idents = 0; khm_int32 rv; wchar_t * ident_names = NULL; wchar_t * this_ident; kcdb_credset_get_size(NULL, &count); /* if there are no credentials, we just skip over the renew action. */ if (count == 0) return; ident_names = NULL; while (TRUE) { if (ident_names) { PFREE(ident_names); ident_names = NULL; } cb = 0; rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0, NULL, &cb, &n_idents); if (n_idents == 0 || rv != KHM_ERROR_TOO_LONG || cb == 0) break; ident_names = PMALLOC(cb); ident_names[0] = L'\0'; rv = kcdb_identity_enum(KCDB_IDENT_FLAG_EMPTY, 0, ident_names, &cb, &n_idents); if (KHM_SUCCEEDED(rv)) break; } if (ident_names) { for (this_ident = ident_names; this_ident && *this_ident; this_ident = multi_string_next(this_ident)) { khm_handle ident; if (KHM_FAILED(kcdb_identity_create(this_ident, 0, &ident))) continue; khm_cred_renew_identity(ident); kcdb_identity_release(ident); } PFREE(ident_names); ident_names = NULL; } }
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); } }
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; }