khm_int32 handle_kmsg_system_idprov(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) { switch(msg_subtype) { case KMSG_SYSTEM_INIT: { kmq_create_subscription(idprov_msg_proc, &idprov_sub); } break; case KMSG_SYSTEM_EXIT: { } break; } return KHM_ERROR_SUCCESS; }
/* process KMSG_SYSTEM messages */ khm_int32 KHMAPI afs_msg_system(khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) { khm_int32 rv = KHM_ERROR_UNKNOWN; switch(msg_subtype) { case KMSG_SYSTEM_INIT: /* If we are building against an older SDK, we should try to load newer APIs if it's available at run-time. */ #if KH_VERSION_API < 7 do { khm_version libver; khm_ui_4 apiver; khm_get_lib_version(&libver, &apiver); if (apiver < 7) break; hm_netidmgr = LoadLibrary(NIMDLLNAME); if (hm_netidmgr == NULL) break; pkhui_action_lock = (void (KHMAPI *)(void)) GetProcAddress(hm_netidmgr, API_khui_action_lock); pkhui_action_unlock = (void (KHMAPI *)(void)) GetProcAddress(hm_netidmgr, API_khui_action_unlock); pkhui_refresh_actions = (void (KHMAPI *)(void)) GetProcAddress(hm_netidmgr, API_khui_refresh_actions); pkhui_request_UI_callback = (khm_int32 (KHMAPI *)(khm_ui_callback, void *)) GetProcAddress(hm_netidmgr, API_khui_request_UI_callback); } while (FALSE); #endif /* Add the icon now. On NIM v2.x, doing so after tokens were reported may result in a deadlock as we try to switch to the UI thread and the UI thread is blocked on a resource request to this plug-in. */ afs_icon_set_state(AFSICON_SERVICE_STOPPED, NULL); /* Perform critical registrations and data structure initalization */ { kcdb_credtype ct; wchar_t buf[KCDB_MAXCCH_LONG_DESC]; size_t cbsize; kcdb_attrib att; khm_handle csp_afscred = NULL; khm_int32 disable_afscreds = FALSE; ZeroMemory(&ct, sizeof(ct)); /* first of all, register the AFS token credential type */ ct.id = KCDB_CREDTYPE_AUTO; ct.name = AFS_CREDTYPE_NAME; if(LoadString(hResModule, IDS_AFS_SHORT_DESC, buf, ARRAYLENGTH(buf)) != 0) { StringCbLength(buf, sizeof(buf), &cbsize); cbsize += sizeof(wchar_t); ct.short_desc = PMALLOC(cbsize); StringCbCopy(ct.short_desc, cbsize, buf); } else ct.short_desc = NULL; if(LoadString(hResModule, IDS_AFS_LONG_DESC, buf, ARRAYLENGTH(buf)) != 0) { StringCbLength(buf, sizeof(buf), &cbsize); cbsize += sizeof(wchar_t); ct.long_desc = PMALLOC(cbsize); StringCbCopy(ct.long_desc, cbsize, buf); } else ct.long_desc = NULL; ct.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_AFSTOKEN), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); kmq_create_subscription(afs_plugin_cb, &afs_sub); ct.sub = afs_sub; kcdb_credtype_register(&ct, &afs_credtype_id); /* register the attribute types */ { kcdb_type type; ZeroMemory(&type, sizeof(type)); type.comp = afs_type_principal_comp; type.dup = afs_type_principal_dup; type.isValid = afs_type_principal_isValid; type.toString = afs_type_principal_toString; type.name = AFS_TYPENAME_PRINCIPAL; type.id = KCDB_TYPE_INVALID; type.cb_max = sizeof(struct ktc_principal); type.cb_min = sizeof(struct ktc_principal); type.flags = KCDB_TYPE_FLAG_CB_FIXED; if(KHM_FAILED(kcdb_type_register(&type, &afs_type_principal))) goto _exit_init; } { kcdb_type type; kcdb_type *ti32 = NULL; kcdb_type_get_info(KCDB_TYPE_INT32, &ti32); ZeroMemory(&type, sizeof(type)); type.comp = ti32->comp; type.dup = ti32->dup; type.isValid = ti32->isValid; type.toString = afs_type_method_toString; type.name = AFS_TYPENAME_METHOD; type.id = KCDB_TYPE_INVALID; type.cb_max = sizeof(khm_int32); type.cb_min = sizeof(khm_int32); type.flags = KCDB_TYPE_FLAG_CB_FIXED; if(KHM_FAILED(kcdb_type_register(&type, &afs_type_method))) { kcdb_type_release_info(ti32); goto _exit_init; } kcdb_type_release_info(ti32); } /* now register the attributes */ { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; ZeroMemory(&att, sizeof(att)); att.type = KCDB_TYPE_STRING; att.name = AFS_ATTRNAME_CELL; LoadString(hResModule, IDS_ATTR_CELL_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); att.short_desc = short_desc; att.long_desc = NULL; att.id = KCDB_ATTR_INVALID; att.flags = KCDB_ATTR_FLAG_TRANSIENT; if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_cell))) goto _exit_init; } { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; ZeroMemory(&att, sizeof(att)); att.type = KCDB_TYPE_STRING; att.name = AFS_ATTRNAME_REALM; LoadString(hResModule, IDS_ATTR_REALM_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); att.short_desc = short_desc; att.long_desc = NULL; att.id = KCDB_ATTR_INVALID; att.flags = KCDB_ATTR_FLAG_TRANSIENT; if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_realm))) goto _exit_init; } { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; ZeroMemory(&att, sizeof(att)); att.type = afs_type_method; att.name = AFS_ATTRNAME_METHOD; LoadString(hResModule, IDS_ATTR_METHOD_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); att.short_desc = short_desc; att.long_desc = NULL; att.id = KCDB_ATTR_INVALID; att.flags = KCDB_ATTR_FLAG_TRANSIENT; if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_method))) goto _exit_init; } { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; ZeroMemory(&att, sizeof(att)); att.type = afs_type_principal; att.name = AFS_ATTRNAME_CLIENT_PRINC; LoadString(hResModule, IDS_ATTR_CLIENT_PRINC_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); att.short_desc = short_desc; att.long_desc = NULL; att.id = KCDB_ATTR_INVALID; att.flags = KCDB_ATTR_FLAG_TRANSIENT; if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_client_princ))) goto _exit_init; } { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; ZeroMemory(&att, sizeof(att)); att.type = afs_type_principal; att.name = AFS_ATTRNAME_SERVER_PRINC; LoadString(hResModule, IDS_ATTR_SERVER_PRINC_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); att.short_desc = short_desc; att.long_desc = NULL; att.id = KCDB_ATTR_INVALID; att.flags = KCDB_ATTR_FLAG_TRANSIENT; if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_server_princ))) goto _exit_init; } /* afs_credset is our stock credentials set that we use for all our credset needs (instead of creating a new one every time) */ if(KHM_FAILED(rv = kcdb_credset_create(&afs_credset))) goto _exit_init; if(KHM_FAILED(rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME, &krb5_credtype_id))) goto _exit_init; /* register the configuration nodes */ { khui_config_node node_ident; khui_config_node_reg reg; wchar_t wshort_desc[KHUI_MAXCCH_SHORT_DESC]; wchar_t wlong_desc[KHUI_MAXCCH_LONG_DESC]; if (KHM_FAILED(rv = khui_cfg_open(NULL, L"KhmIdentities", &node_ident))) goto _exit_init; ZeroMemory(®, sizeof(reg)); reg.name = AFS_CONFIG_NODE_MAIN; reg.short_desc = wshort_desc; reg.long_desc = wlong_desc; reg.h_module = hResModule; reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_AFS); reg.dlg_proc = afs_cfg_main_proc; reg.flags = 0; LoadString(hResModule, IDS_CFG_MAIN_LONG, wlong_desc, ARRAYLENGTH(wlong_desc)); LoadString(hResModule, IDS_CFG_MAIN_SHORT, wshort_desc, ARRAYLENGTH(wshort_desc)); khui_cfg_register(NULL, ®); ZeroMemory(®, sizeof(reg)); reg.name = AFS_CONFIG_NODE_IDS; reg.short_desc = wshort_desc; reg.long_desc = wshort_desc; reg.h_module = hResModule; reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_TAB); reg.dlg_proc = afs_cfg_ids_proc; reg.flags = KHUI_CNFLAG_SUBPANEL; LoadString(hResModule, IDS_CFG_IDS_TAB, wshort_desc, ARRAYLENGTH(wshort_desc)); khui_cfg_register(node_ident, ®); ZeroMemory(®, sizeof(reg)); reg.name = AFS_CONFIG_NODE_ID; reg.short_desc = wshort_desc; reg.long_desc = wshort_desc; reg.h_module = hResModule; reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_TAB); reg.dlg_proc = afs_cfg_id_proc; reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL; LoadString(hResModule, IDS_CFG_ID_TAB, wshort_desc, ARRAYLENGTH(wshort_desc)); khui_cfg_register(node_ident, ®); } /* and register the AFS message type */ rv = kmq_register_type(AFS_MSG_TYPENAME, &afs_msg_type_id); if (KHM_SUCCEEDED(rv)) kmq_subscribe(afs_msg_type_id, afs_plugin_cb); /* if the configuration is set to disable afscreds.exe, then we look for the shortcut and remove it if found. */ if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME, 0, &csp_afscred))) { wchar_t wpath[MAX_PATH]; khc_read_int32(csp_afscred, L"Disableafscreds", &disable_afscreds); if (disable_afscreds && afs_cfg_get_afscreds_shortcut(wpath)) { DeleteFile(wpath); } khc_close_space(csp_afscred); } /* try to register the "AFS Help" menu item, if possible */ { khm_handle h_sub = NULL; wchar_t short_desc[KHUI_MAXCCH_SHORT_DESC]; wchar_t long_desc[KHUI_MAXCCH_LONG_DESC]; #if KH_VERSION_API < 7 if (pkhui_action_lock == NULL || pkhui_action_unlock == NULL || pkhui_refresh_actions == NULL || pkhui_request_UI_callback == NULL) goto no_custom_help; #endif kmq_create_subscription(afs_plugin_cb, &h_sub); LoadString(hResModule, IDS_ACTION_AFS_HELP, short_desc, ARRAYLENGTH(short_desc)); LoadString(hResModule, IDS_ACTION_AFS_HELP_TT, long_desc, ARRAYLENGTH(long_desc)); action_id_afs_help = khui_action_create(NULL, short_desc, long_desc, NULL, KHUI_ACTIONTYPE_TRIGGER, h_sub); if (action_id_afs_help != 0) { khm_size s; khm_size i; khui_menu_def * help_menu; khm_boolean refresh = FALSE; khui_action_lock(); help_menu = khui_find_menu(KHUI_MENU_HELP); if (help_menu) { s = khui_menu_get_size(help_menu); for (i=0; i < s; i++) { khui_action_ref * aref; aref = khui_menu_get_action(help_menu, i); if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) && aref->action == KHUI_ACTION_HELP_INDEX) { khui_menu_insert_action(help_menu, i + 1, action_id_afs_help, 0); refresh = TRUE; break; } } } khui_action_unlock(); if (refresh) khui_refresh_actions(); } #if KH_VERSION_API < 7 no_custom_help: ; #endif } _exit_init: if(ct.short_desc) PFREE(ct.short_desc); if(ct.long_desc) PFREE(ct.long_desc); } /* now that the critical stuff is done, we move on to the non-critical stuff */ if(KHM_SUCCEEDED(rv)) { initialized = TRUE; /* obtain existing tokens */ afs_list_tokens(); } /* define this so that if there are no TGT's, we don't deadlock trying to open a new creds dialog from within the new creds dialog. */ SetEnvironmentVariable(L"KERBEROSLOGIN_NEVER_PROMPT", L"1"); break; /* end of KMSG_SYSTEM_INIT */ case KMSG_SYSTEM_EXIT: afs_remove_icon(); /* Try to remove the AFS plug-in action from Help menu if it was successfully registered. Also, delete the action. */ if (action_id_afs_help != 0) { khui_menu_def * help_menu; khm_boolean menu_changed = FALSE; khui_action_lock(); help_menu = khui_find_menu(KHUI_MENU_HELP); if (help_menu) { khm_size s; khm_size i; s = khui_menu_get_size(help_menu); for (i=0; i < s; i++) { khui_action_ref * aref = khui_menu_get_action(help_menu, i); if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) && aref->action == action_id_afs_help) { khui_menu_remove_action(help_menu, i); menu_changed = TRUE; break; } } } khui_action_delete(action_id_afs_help); khui_action_unlock(); if (menu_changed) khui_refresh_actions(); action_id_afs_help = 0; } if (afs_msg_type_id != -1) { kmq_unsubscribe(afs_msg_type_id, afs_plugin_cb); kmq_unregister_type(afs_msg_type_id); } if(afs_credtype_id >= 0) { kcdb_credtype_unregister(afs_credtype_id); } #if 0 if(afs_attr_client >= 0) { kcdb_attrib_unregister(afs_attr_client); } #endif if(afs_attr_cell >= 0) { kcdb_attrib_unregister(afs_attr_cell); } if(afs_attr_realm >= 0) { kcdb_attrib_unregister(afs_attr_realm); } if(afs_attr_method >= 0) { kcdb_attrib_unregister(afs_attr_method); } if(afs_attr_client_princ >= 0) { kcdb_attrib_unregister(afs_attr_client_princ); } if(afs_attr_server_princ >= 0) { kcdb_attrib_unregister(afs_attr_server_princ); } if(afs_type_principal >= 0) { kcdb_type_unregister(afs_type_principal); } if(afs_type_method >= 0) { kcdb_type_unregister(afs_type_method); } initialized = FALSE; if(afs_credset) kcdb_credset_delete(afs_credset); /* afs_sub doesn't need to be deleted. That is taken care of when unregistering the afs cred type */ afs_sub = NULL; #if KH_VERSION_API < 7 if (hm_netidmgr) FreeLibrary(hm_netidmgr); pkhui_action_lock = NULL; pkhui_action_unlock = NULL; pkhui_refresh_actions = NULL; pkhui_request_UI_callback = NULL; #endif rv = KHM_ERROR_SUCCESS; break; /* end of KMSG_SYSTEM_EXIT */ } return rv; }
/* 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: { wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; wchar_t long_desc[KCDB_MAXCCH_LONG_DESC]; #ifdef USE_CONFIGURATION_PANELS khui_config_node_reg creg; #endif afs_msg_announce announce; if (KHM_FAILED(kmq_find_type(AFS_MSG_TYPENAME, &msg_type_afs))) { return KHM_ERROR_UNKNOWN; } /* We must first announce our extension plug-in, so that the AFS plug-in will know we exist */ announce.cbsize = sizeof(announce); announce.version = AFS_PLUGIN_VERSION; announce.name = MYPLUGIN_NAMEW; kmq_create_subscription(handle_AFS_MSG, &announce.sub); /* Set to TRUE if we are providing a token acquisition method */ announce.provide_token_acq = TRUE; LoadString(hResModule, IDS_TKMETHOD_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); announce.token_acq.short_desc = short_desc; LoadString(hResModule, IDS_TKMETHOD_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); announce.token_acq.long_desc = long_desc; if (KHM_FAILED(kmq_send_message(msg_type_afs, AFS_MSG_ANNOUNCE, 0, &announce))) { kmq_delete_subscription(announce.sub); announce.sub = NULL; return KHM_ERROR_UNKNOWN; } tk_method = announce.token_acq.method_id; #ifdef USE_CONFIGURATION_PANELS /* Register our configuration panels. */ /* Registering configuration panels is not required for extension plug-in. As such, this bit of code is commented out. However, if you wish to provide a configuration panel, you should uncomment this block and fill in the stub functions in config_main.c */ 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 } break; /* This is the last message that will be received by the plugin. */ case KMSG_SYSTEM_EXIT: { khui_config_node cnode; /* 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. */ /* 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); } /* TODO: Perform additional uninitialization operations. */ } break; } return rv; }
khm_int32 handle_kmsg_system_init(void) { 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; khm_int32 rv; assert (h_idprov_event == NULL); h_idprov_event = CreateEvent(NULL, TRUE, FALSE, L"Local\\" IDPROV_NAMEW L"Waiter"); /* First and foremost, we need to register a credential type. */ ZeroMemory(&ct, sizeof(ct)); ct.id = KCDB_CREDTYPE_AUTO; ct.name = CREDTYPE_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(credprov_msg_proc, &ct.sub); ct.is_equal = cred_is_equal; rv = kcdb_credtype_register(&ct, &credtype_id); if (KHM_FAILED(rv)) return rv; /* 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); /* Now we register our configuration panels. */ /* This configuration panel is the one that controls general options. We leave the identity specific and identity defaults for other configuration panels. */ ZeroMemory(&creg, sizeof(creg)); short_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); long_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); creg.name = CONFIGNODE_MAIN; creg.short_desc = short_desc; creg.long_desc = long_desc; creg.h_module = hResModule; creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG); creg.dlg_proc = config_dlgproc; creg.flags = 0; khui_cfg_register(NULL, &creg); /* Now we do the identity specific and identity default configuration panels. "KhmIdentities" is a predefined configuration node under which all the identity spcific configuration is managed. */ if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) { /* this should always work */ assert(FALSE); return KHM_ERROR_NOT_FOUND; } /* 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); /* TODO: Perform additional initialization operations. */ /* TODO: Also list out the credentials of this type that already exist. */ return KHM_ERROR_SUCCESS; }
k5_kinit_task * k5_kinit_task_create(khui_new_creds * nc) { k5_kinit_task * kt; k5_dlg_data * d; wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; khm_size cbbuf; LPNETID_DLGINFO pdlginfo; khui_action_context * pctx = NULL; khm_handle hsub = NULL; khui_cw_find_type(nc, credtype_id_krb5, (khui_new_creds_by_type **) &d); if (!d) return NULL; kt = (k5_kinit_task *) PMALLOC(sizeof(*kt)); memset(kt, 0, sizeof(*kt)); kt->magic = K5_KINIT_TASK_MAGIC; kt->nc = nc; kt->dlg_data = d; kt->nct = &d->nct; kt->context = 0; khui_cw_get_primary_id(nc, &kt->identity); cbbuf = sizeof(idname); kcdb_identity_get_name(kt->identity, idname, &cbbuf); cbbuf = (cbbuf * sizeof(char)) / sizeof(wchar_t); kt->principal = PMALLOC(cbbuf); UnicodeStrToAnsi(kt->principal, cbbuf, idname); kt->password = NULL; kt->params = d->params; kt->params.lifetime = (krb5_deltat) d->tc_lifetime.current; kt->params.renew_life = (krb5_deltat) d->tc_renew.current; /* if we have external parameters, we should use them as well */ pctx = khui_cw_get_ctx(nc); if (pctx && pctx->cb_vparam == sizeof(NETID_DLGINFO) && (pdlginfo = pctx->vparam) != NULL && pdlginfo->size == NETID_DLGINFO_V1_SZ) { wchar_t * t; size_t size; if (pdlginfo->in.ccache[0] && SUCCEEDED(StringCchLength(pdlginfo->in.ccache, NETID_CCACHE_NAME_SZ, &size))) { kt->ccache = PMALLOC(sizeof(char) * (size + 1)); UnicodeStrToAnsi(kt->ccache, size + 1, pdlginfo->in.ccache); /* this is the same as the output cache */ StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache), pdlginfo->in.ccache); } else { wchar_t ccache[KRB5_MAXCCH_CCNAME]; size = sizeof(ccache); khm_krb5_get_identity_default_ccache(kt->identity, ccache, &size); StringCbCopy(pdlginfo->out.ccache, sizeof(pdlginfo->out.ccache), ccache); } t = khm_get_realm_from_princ(idname); if (t) { StringCbCopy(pdlginfo->out.realm, sizeof(pdlginfo->out.realm), t); if ((t - idname) > 1) { StringCchCopyN(pdlginfo->out.username, ARRAYLENGTH(pdlginfo->out.username), idname, (t - idname) - 1); } else { StringCbCopy(pdlginfo->out.username, sizeof(pdlginfo->out.username), L""); } } else { StringCbCopy(pdlginfo->out.username, sizeof(pdlginfo->out.username), idname); StringCbCopy(pdlginfo->out.realm, sizeof(pdlginfo->out.realm), L""); } } kt->state = K5_KINIT_STATE_PREP; InitializeCriticalSection(&kt->cs); kt->h_task_wait = CreateEvent(NULL, FALSE, FALSE, NULL); kt->h_parent_wait = CreateEvent(NULL, FALSE, FALSE, NULL); kt->refcount = 2; /* One hold for the caller, one hold for the thread */ kmq_create_subscription(k5_msg_callback, &hsub); kt->task = task_create(NULL, 32 * 4096, kinit_task_proc, kt, hsub, 0); return kt; }
/*! \internal \brief Manages a plugin message thread. Each plugin gets its own plugin thread which is used to dispatch messages to the plugin. This acts as the thread function for the plugin thread.*/ DWORD WINAPI kmmint_plugin_broker(LPVOID lpParameter) { DWORD rv = 0; kmm_plugin_i * p = (kmm_plugin_i *) lpParameter; PDESCTHREAD(p->p.name, L"KMM"); _begin_task(0); _report_mr1(KHERR_NONE, MSG_PB_START, _cstr(p->p.name)); _describe(); TlsSetValue(tls_kmm, (LPVOID) p); kmm_hold_plugin(kmm_handle_from_plugin(p)); p->tid_thread = GetCurrentThreadId(); if (IsBadCodePtr(p->p.msg_proc)) { _report_mr0(KHERR_WARNING, MSG_PB_INVALID_CODE_PTR); rv = KHM_ERROR_INVALID_PARAM; } else { rv = (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_INIT, 0, (void *) &(p->p)); _report_mr1(KHERR_INFO, MSG_PB_INIT_RV, _int32(rv)); } /* if it fails to initialize, we exit the plugin */ if(KHM_FAILED(rv)) { kherr_report(KHERR_ERROR, (wchar_t *) MSG_PB_INIT_FAIL_S, (wchar_t *) KHERR_FACILITY, NULL, (wchar_t *) MSG_PB_INIT_FAIL, (wchar_t *) MSG_PB_INIT_FAIL_G, KHERR_FACILITY_ID, KHERR_SUGGEST_NONE, _cstr(p->p.name), _cstr(p->p.description), _cstr(p->module->path), _cstr(p->module->support), KHERR_RF_MSG_SHORT_DESC | KHERR_RF_MSG_LONG_DESC | KHERR_RF_MSG_SUGGEST #ifdef _WIN32 ,KHERR_HMODULE #endif ); _resolve(); /* exit the plugin first. Otherwise it may not uninitialize correctly */ (*p->p.msg_proc)(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p)); kmmint_remove_from_plugin_queue(p); rv = 1; _end_task(); p->state = KMM_PLUGIN_STATE_FAIL_INIT; goto _exit; } /* subscribe to default message classes by plugin type */ if(p->p.type == KHM_PITYPE_CRED) { kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc); kmq_subscribe(KMSG_KCDB, p->p.msg_proc); kmq_subscribe(KMSG_CRED, p->p.msg_proc); } else if(p->p.type == KHM_PITYPE_IDENT) { khm_handle h = NULL; kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc); kmq_subscribe(KMSG_KCDB, p->p.msg_proc); kmq_create_subscription(p->p.msg_proc, &h); kcdb_identity_set_provider(h); /* kcdb deletes the subscription when it's done with it */ } else if(p->p.type == KHM_PITYPE_CONFIG) { /*TODO: subscribe to configuration provider messages here */ } p->state = KMM_PLUGIN_STATE_RUNNING; _report_mr0(KHERR_INFO, MSG_PB_INIT_DONE); _end_task(); /* if there were any plugins that were waiting for this one to start, we should start them too */ EnterCriticalSection(&cs_kmm); do { kmm_plugin_i * pd; int i; for(i=0; i < p->n_dependants; i++) { pd = p->dependants[i]; pd->n_unresolved--; if(pd->n_unresolved == 0) { kmmint_add_to_plugin_queue(pd); kmm_hold_plugin(kmm_handle_from_plugin(pd)); kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_INIT_PLUGIN, (void *) pd); } } } while(FALSE); LeaveCriticalSection(&cs_kmm); kmmint_remove_from_plugin_queue(p); /* main message loop */ while(KHM_SUCCEEDED(kmq_dispatch(INFINITE))); /* unsubscribe from default message classes by plugin type */ if(p->p.type == KHM_PITYPE_CRED) { kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc); kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc); kmq_unsubscribe(KMSG_CRED, p->p.msg_proc); } else if (p->p.type == KHM_PITYPE_IDENT) { kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc); kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc); kcdb_identity_set_provider(NULL); } else if(p->p.type == KHM_PITYPE_CONFIG) { /*TODO: unsubscribe from configuration provider messages here */ } p->p.msg_proc(KMSG_SYSTEM, KMSG_SYSTEM_EXIT, 0, (void *) &(p->p)); _exit: if (p->state >= 0) p->state = KMM_PLUGIN_STATE_EXITED; /* the following call will automatically release the plugin */ kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p); TlsSetValue(tls_kmm, (LPVOID) 0); ExitThread(rv); /* not reached */ return rv; }
/* Handler for system messages. The only two we handle are KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */ khm_int32 KHMAPI handle_kmsg_system(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) { khm_int32 rv = KHM_ERROR_SUCCESS; switch (msg_subtype) { /* This is the first message that will be received by a plugin. We use it to perform initialization operations such as registering any credential types, data types and attributes. */ case KMSG_SYSTEM_INIT: { kcdb_credtype ct; wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC]; wchar_t long_desc[KCDB_MAXCCH_LONG_DESC]; khui_config_node cnode; khui_config_node_reg creg; /* First and foremost, we need to register a credential type. */ ZeroMemory(&ct, sizeof(ct)); ct.id = KCDB_CREDTYPE_AUTO; ct.name = MYCREDTYPE_NAMEW; short_desc[0] = L'\0'; LoadString(hResModule, IDS_CT_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); long_desc[0] = L'\0'; LoadString(hResModule, IDS_CT_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); ct.icon = NULL; /* We skip the icon for now, but you can assign a handle to an icon here. The icon will be used to represent the credentials type.*/ kmq_create_subscription(plugin_msg_proc, &ct.sub); ct.is_equal = cred_is_equal; rv = kcdb_credtype_register(&ct, &credtype_id); /* We create a global credential set that we use in the plug-in thread. This alleviates the need to create one everytime we need one. Keep in mind that this should only be used in the plug-in thread and should not be touched from the UI thread or any other thread. */ kcdb_credset_create(&g_credset); /* TODO: Perform additional initialization operations. */ /* TODO: Also list out the credentials of this type that already exist. */ /* Now we register our configuration panels. */ /* This configuration panel is the one that controls general options. We leave the identity specific and identity defaults for other configuration panels. */ ZeroMemory(&creg, sizeof(creg)); short_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); long_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); creg.name = CONFIGNODE_MAIN; creg.short_desc = short_desc; creg.long_desc = long_desc; creg.h_module = hResModule; creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG); creg.dlg_proc = config_dlgproc; creg.flags = 0; khui_cfg_register(NULL, &creg); /* Now we do the identity specific and identity default configuration panels. "KhmIdentities" is a predefined configuration node under which all the identity spcific configuration is managed. */ if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) { /* this should always work */ assert(FALSE); rv = KHM_ERROR_NOT_FOUND; break; } /* First the tab panel for defaults for all identities */ ZeroMemory(&creg, sizeof(creg)); short_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); long_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_IDS_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); creg.name = CONFIGNODE_ALL_ID; creg.short_desc = short_desc; creg.long_desc = long_desc; creg.h_module = hResModule; creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS); creg.dlg_proc = config_ids_dlgproc; creg.flags = KHUI_CNFLAG_SUBPANEL; khui_cfg_register(cnode, &creg); /* Now the panel for per identity configuration */ ZeroMemory(&creg, sizeof(creg)); short_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_ID_SHORT_DESC, short_desc, ARRAYLENGTH(short_desc)); long_desc[0] = L'\0'; LoadString(hResModule, IDS_CFG_ID_LONG_DESC, long_desc, ARRAYLENGTH(long_desc)); creg.name = CONFIGNODE_PER_ID; creg.short_desc = short_desc; creg.long_desc = long_desc; creg.h_module = hResModule; creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID); creg.dlg_proc = config_id_dlgproc; creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE; khui_cfg_register(cnode, &creg); khui_cfg_release(cnode); /* get IdentProvider handle to which this plugin belongs it is possible to use kcdb_identity_create_ex() function with proper h_idprov */ if (KHM_FAILED(kcdb_identpro_find(IDPROV_NAMEW, &h_idprov))) { return KHM_ERROR_UNKNOWN; } } break; /* This is the last message that will be received by the plugin. */ case KMSG_SYSTEM_EXIT: { khui_config_node cnode; khui_config_node cn_idents; /* It should not be assumed that initialization of the plugin went well at this point since we receive a KMSG_SYSTEM_EXIT even if the initialization failed. */ if (credtype_id != KCDB_CREDTYPE_INVALID) { kcdb_credtype_unregister(credtype_id); credtype_id = KCDB_CREDTYPE_INVALID; } if (g_credset) { kcdb_credset_delete(g_credset); g_credset = NULL; } /* Now unregister any configuration nodes we registered. */ if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) { khui_cfg_remove(cnode); khui_cfg_release(cnode); } if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) { if (KHM_SUCCEEDED(khui_cfg_open(cn_idents, CONFIGNODE_ALL_ID, &cnode))) { khui_cfg_remove(cnode); khui_cfg_release(cnode); } if (KHM_SUCCEEDED(khui_cfg_open(cn_idents, CONFIGNODE_PER_ID, &cnode))) { khui_cfg_remove(cnode); khui_cfg_release(cnode); } khui_cfg_release(cn_idents); } /* TODO: Perform additional uninitialization operations. */ kcdb_identpro_release(h_idprov); } break; } return rv; }
/* 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; }