void khm_cred_destroy_creds(khm_boolean sync, khm_boolean quiet) { khui_action_context * pctx; pctx = PMALLOC(sizeof(*pctx)); #ifdef DEBUG assert(pctx); #endif khui_context_get(pctx); if(pctx->scope == KHUI_SCOPE_NONE && !quiet) { /* this really shouldn't be necessary once we start enabling and disbling actions based on context */ wchar_t title[256]; wchar_t message[256]; LoadString(khm_hInstance, IDS_ALERT_NOSEL_TITLE, title, ARRAYLENGTH(title)); LoadString(khm_hInstance, IDS_ALERT_NOSEL, message, ARRAYLENGTH(message)); khui_alert_show_simple(title, message, KHERR_WARNING); khui_context_release(pctx); PFREE(pctx); return; } _begin_task(KHERR_CF_TRANSITIVE); _report_sr0(KHERR_NONE, IDS_CTX_DESTROY_CREDS); _describe(); if (sync) kmq_send_message(KMSG_CRED, KMSG_CRED_DESTROY_CREDS, 0, (void *) pctx); else kmq_post_message(KMSG_CRED, KMSG_CRED_DESTROY_CREDS, 0, (void *) pctx); _end_task(); }
void khm_cred_set_default(void) { khui_action_context ctx; khm_int32 rv; khui_context_get(&ctx); if (ctx.identity) { rv = kcdb_identity_set_default(ctx.identity); } khui_context_release(&ctx); }
/* called with cs_alert held */ static void free_alert(khui_alert * alert) { assert(alert->magic == KHUI_ALERT_MAGIC); LDELETE(&kh_alerts, alert); if(alert->flags & KHUI_ALERT_FLAG_FREE_TITLE) { assert(alert->title); PFREE(alert->title); alert->title = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_TITLE; } if(alert->flags & KHUI_ALERT_FLAG_FREE_MESSAGE) { assert(alert->message); PFREE(alert->message); alert->message = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_MESSAGE; } if(alert->flags & KHUI_ALERT_FLAG_FREE_SUGGEST) { assert(alert->suggestion); PFREE(alert->suggestion); alert->suggestion = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_SUGGEST; } khui_context_release(&alert->ctx); if (alert->err_context) { kherr_release_context(alert->err_context); alert->err_context = NULL; } if(alert->flags & KHUI_ALERT_FLAG_FREE_STRUCT) { alert->flags &= ~KHUI_ALERT_FLAG_FREE_STRUCT; alert->magic = 0; PFREE(alert); } }
KHMEXP khm_int32 KHMAPI khui_alert_set_ctx(khui_alert * alert, khui_scope scope, khm_handle identity, khm_int32 cred_type, khm_handle cred) { khm_int32 rv = KHM_ERROR_SUCCESS; assert(alert->magic == KHUI_ALERT_MAGIC); EnterCriticalSection(&cs_alerts); khui_context_release(&alert->ctx); khui_context_create(&alert->ctx, scope, identity, cred_type, cred); alert->flags |= KHUI_ALERT_FLAG_MODIFIED; LeaveCriticalSection(&cs_alerts); return rv; }
void khm_cred_obtain_new_creds_for_ident(khm_handle ident, wchar_t * title) { khui_action_context ctx; if (ident == NULL) khm_cred_obtain_new_creds(title); khui_context_get(&ctx); khui_context_set(KHUI_SCOPE_IDENT, ident, KCDB_CREDTYPE_INVALID, NULL, NULL, 0, NULL); khm_cred_obtain_new_creds(title); khui_context_set_indirect(&ctx); khui_context_release(&ctx); }
khm_int32 krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) { switch(msg_subtype) { case KMSG_CRED_NEW_CREDS: { khui_new_creds * nc; khui_new_creds_by_type * nct; khm_size cbsize; wchar_t wbuf[256]; nc = (khui_new_creds *) vparam; nct = PMALLOC(sizeof(*nct)); #ifdef DEBUG assert(nct); #endif ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb4; nct->ordinal = 3; LoadString(hResModule, IDS_NC_K4_SHORT, wbuf, ARRAYLENGTH(wbuf)); StringCbLength(wbuf, sizeof(wbuf), &cbsize); cbsize += sizeof(wchar_t); nct->name = PMALLOC(cbsize); StringCbCopy(nct->name, cbsize, wbuf); nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; nct->h_module = hResModule; nct->dlg_proc = k4_nc_dlg_proc; nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4); khui_cw_add_type(nc, nct); } break; case KMSG_CRED_RENEW_CREDS: { khui_new_creds * nc; khui_new_creds_by_type * nct; khm_size cbsize; wchar_t wbuf[256]; khui_action_context * pctx = NULL; nc = (khui_new_creds *) vparam; pctx = khui_cw_get_ctx(nc); if (!pctx->identity) break; nct = PMALLOC(sizeof(*nct)); #ifdef DEBUG assert(nct); #endif ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb4; nct->ordinal = 3; LoadString(hResModule, IDS_NC_K4_SHORT, wbuf, ARRAYLENGTH(wbuf)); StringCbLength(wbuf, sizeof(wbuf), &cbsize); cbsize += sizeof(wchar_t); nct->name = PMALLOC(cbsize); StringCbCopy(nct->name, cbsize, wbuf); nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; khui_cw_add_type(nc, nct); } break; case KMSG_CRED_DIALOG_SETUP: break; case KMSG_CRED_PROCESS: { khui_new_creds * nc; khui_new_creds_by_type * nct = NULL; khm_handle ident = NULL; khui_action_context * pctx = NULL; k4_dlg_data * d = NULL; long code = 0; wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; khm_size cb; khm_int32 subtype; nc = (khui_new_creds *) vparam; if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) break; subtype = khui_cw_get_subtype(nc); if (subtype == KMSG_CRED_NEW_CREDS || subtype == KMSG_CRED_RENEW_CREDS) { khm_int32 method; if (subtype == KMSG_CRED_NEW_CREDS) { d = (k4_dlg_data *) nct->aux; if (KHM_FAILED(khui_cw_get_primary_id(nc, &ident))) break; if (!d || khui_cw_get_result(nc) != KHUI_NC_RESULT_PROCESS) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } if (!d->k4_enabled) { k4_write_identity_data(d); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } method = d->method; cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); _begin_task(0); _report_sr0(KHERR_NONE, IDS_MSG_K4NEW); _resolve(); _describe(); } else if (subtype == KMSG_CRED_RENEW_CREDS) { pctx = khui_cw_get_ctx(nc); if ((pctx->scope == KHUI_SCOPE_IDENT && pctx->identity != NULL) || (pctx->scope == KHUI_SCOPE_CREDTYPE && pctx->cred_type == credtype_id_krb4 && pctx->identity != NULL) || (pctx->scope == KHUI_SCOPE_CRED && pctx->cred_type == credtype_id_krb4 && pctx->identity != NULL && pctx->cred != NULL)) { ident = pctx->identity; kcdb_identity_hold(ident); if (!k4_should_identity_get_k4(ident)) { _reportf(L"Kerberos 4 is not enabled for this identity. Skipping"); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } } else { _reportf(L"Kerberos 4 is not within renewal scope. Skipping"); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); break; } method = K4_METHOD_K524; /* only k524 is supported for renewals */ _begin_task(0); cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); _report_sr0(KHERR_NONE, IDS_MSG_K4RENEW); _resolve(); _describe(); } else { assert(FALSE); break; } _progress(0,1); if ((method == K4_METHOD_AUTO || method == K4_METHOD_K524) && khui_cw_type_succeeded(nc, credtype_id_krb5)) { khm_handle tgt; FILETIME ft_prev; FILETIME ft_new; khm_size cb; _report_cs0(KHERR_INFO, L"Trying K524..."); tgt = khm_krb4_find_tgt(NULL, ident); _progress(1,3); if (tgt) { cb = sizeof(ft_prev); if (KHM_FAILED(kcdb_cred_get_attr(tgt, KCDB_ATTR_EXPIRE, NULL, &ft_prev, &cb))) ZeroMemory(&ft_prev, sizeof(ft_prev)); kcdb_cred_release(tgt); } code = khm_convert524(ident); _progress(2,3); _reportf(L"khm_convert524 returns code %d", code); if (code == 0) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); if (subtype == KMSG_CRED_NEW_CREDS) { assert(d != NULL); k4_write_identity_data(d); } else if (subtype == KMSG_CRED_RENEW_CREDS && (pctx->scope == KHUI_SCOPE_CREDTYPE || pctx->scope == KHUI_SCOPE_CRED)) { khm_krb4_list_tickets(); tgt = khm_krb4_find_tgt(NULL, ident); if (tgt) { cb = sizeof(ft_new); ZeroMemory(&ft_new, sizeof(ft_new)); kcdb_cred_get_attr(tgt, KCDB_ATTR_EXPIRE, NULL, &ft_new, &cb); kcdb_cred_release(tgt); } if (!tgt || CompareFileTime(&ft_new, &ft_prev) <= 0) { /* The new TGT wasn't much of an improvement over what we already had. We should go out and try to renew the identity now. */ khui_action_context ctx; _reportf(L"Renewal of Krb4 creds failed to get a longer TGT. Triggering identity renewal"); khui_context_create(&ctx, KHUI_SCOPE_IDENT, pctx->identity, KCDB_CREDTYPE_INVALID, NULL); khui_action_trigger(KHUI_ACTION_RENEW_CRED, &ctx); khui_context_release(&ctx); } } _progress(1,1); _end_task(); if (ident) kcdb_identity_release(ident); break; } else if (method == K4_METHOD_K524) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); if (subtype == KMSG_CRED_RENEW_CREDS && (pctx->scope == KHUI_SCOPE_CREDTYPE || pctx->scope == KHUI_SCOPE_CRED)) { /* We were trying to get a new Krb4 TGT for this identity. Sometimes this fails because of restrictions placed on K524d regarding the lifetime of the issued K4 TGT. In this case, we trigger a renewal of the identity in the hope that the new K5 TGT will allow us to successfully get a new K4 TGT next time over using the new K5 TGT. */ khui_action_context ctx; _reportf(L"Renewal of Krb4 creds failed using k524. Triggerring identity renewal."); khui_context_create(&ctx, KHUI_SCOPE_IDENT, pctx->identity, KCDB_CREDTYPE_INVALID, NULL); khui_action_trigger(KHUI_ACTION_RENEW_CRED, &ctx); khui_context_release(&ctx); } _progress(1,1); _end_task(); if (ident) kcdb_identity_release(ident); break; } } /* only supported for new credentials */ if (method == K4_METHOD_AUTO || method == K4_METHOD_PASSWORD) { khm_size n_prompts = 0; khm_size idx; khm_size cb; wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE]; char pwd[KHUI_MAXCCH_PROMPT_VALUE]; wchar_t widname[KCDB_IDENT_MAXCCH_NAME]; char idname[KCDB_IDENT_MAXCCH_NAME]; char * aname = NULL; char * inst = NULL; char * realm = NULL; assert(subtype == KMSG_CRED_NEW_CREDS); _report_cs0(KHERR_INFO, L"Trying password ..."); code = TRUE; /* just has to be non-zero */ khui_cw_get_prompt_count(nc, &n_prompts); if (n_prompts == 0) goto _skip_pwd; for (idx = 0; idx < n_prompts; idx++) { khui_new_creds_prompt * p; if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p))) continue; if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD) break; } if (idx >= n_prompts) { _reportf(L"Password prompt not found"); goto _skip_pwd; } khui_cw_sync_prompt_values(nc); cb = sizeof(wpwd); if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx, wpwd, &cb))) { _reportf(L"Failed to obtain password value"); goto _skip_pwd; } UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd); cb = sizeof(widname); kcdb_identity_get_name(ident, widname, &cb); UnicodeStrToAnsi(idname, sizeof(idname), widname); { char * atsign; atsign = strchr(idname, '@'); if (atsign == NULL) { _reportf(L"Identity name does not contain an '@'"); goto _skip_pwd; } *atsign++ = 0; realm = atsign; } { char * slash; slash = strchr(idname, '/'); if (slash != NULL) { *slash++ = 0; inst = slash; } else { inst = ""; } } aname = idname; code = khm_krb4_kinit(aname, inst, realm, (long) d->lifetime, pwd); _progress(2,3); _reportf(L"khm_krb4_kinit returns code %d", code); _skip_pwd: if (code) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_EXIT | KHUI_NC_RESPONSE_FAILED); } else { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_EXIT | KHUI_NC_RESPONSE_SUCCESS); if (subtype == KMSG_CRED_NEW_CREDS) { assert(d != NULL); k4_write_identity_data(d); } } } _progress(1,1); _end_task(); } if (ident) kcdb_identity_release(ident); } break; case KMSG_CRED_END: { khui_new_creds * nc; khui_new_creds_by_type * nct = NULL; nc = (khui_new_creds *) vparam; if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) break; khui_cw_del_type(nc, credtype_id_krb4); if (nct->name) PFREE(nct->name); if (nct->credtext) PFREE(nct->credtext); PFREE(nct); } break; } return KHM_ERROR_SUCCESS; }
void khm_cred_obtain_new_creds(wchar_t * title) { khui_new_creds * nc; LPNETID_DLGINFO pdlginfo; khm_size cb; if (!khm_cred_begin_dialog()) return; khui_cw_create_cred_blob(&nc); nc->subtype = KMSG_CRED_NEW_CREDS; dialog_nc = nc; khui_context_get(&nc->ctx); kcdb_identpro_get_ui_cb((void *) &nc->ident_cb); if (nc->ident_cb == NULL) { wchar_t title[256]; wchar_t msg[512]; wchar_t suggestion[512]; khui_alert * a; LoadString(khm_hInstance, IDS_ERR_TITLE_NO_IDENTPRO, title, ARRAYLENGTH(title)); LoadString(khm_hInstance, IDS_ERR_MSG_NO_IDENTPRO, msg, ARRAYLENGTH(msg)); LoadString(khm_hInstance, IDS_ERR_SUGG_NO_IDENTPRO, suggestion, ARRAYLENGTH(suggestion)); khui_alert_create_simple(title, msg, KHERR_ERROR, &a); khui_alert_set_suggestion(a, suggestion); khui_alert_show(a); khui_alert_release(a); khui_context_release(&nc->ctx); nc->result = KHUI_NC_RESULT_CANCEL; khm_cred_end_dialog(nc); khui_cw_destroy_cred_blob(nc); return; } if (title) { if (SUCCEEDED(StringCbLength(title, KHUI_MAXCB_TITLE, &cb))) { cb += sizeof(wchar_t); nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif StringCbCopy(nc->window_title, cb, title); } } else if (nc->ctx.cb_vparam == sizeof(NETID_DLGINFO) && (pdlginfo = nc->ctx.vparam) && pdlginfo->size == NETID_DLGINFO_V1_SZ && pdlginfo->in.title[0] && SUCCEEDED(StringCchLength(pdlginfo->in.title, NETID_TITLE_SZ, &cb))) { cb = (cb + 1) * sizeof(wchar_t); nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif StringCbCopy(nc->window_title, cb, pdlginfo->in.title); } khm_create_newcredwnd(khm_hwnd_main, nc); if (nc->hwnd != NULL) { _begin_task(KHERR_CF_TRANSITIVE); _report_sr0(KHERR_NONE, IDS_CTX_NEW_CREDS); _describe(); kmq_post_message(KMSG_CRED, KMSG_CRED_NEW_CREDS, 0, (void *) nc); _end_task(); } else { khui_context_release(&nc->ctx); nc->result = KHUI_NC_RESULT_CANCEL; khm_cred_end_dialog(nc); khui_cw_destroy_cred_blob(nc); } }
/* Completion handler for KMSG_CRED messages. We control the overall logic of credentials acquisition and other operations here. Once a credentials operation is triggered, each successive message completion notification will be used to dispatch the messages for the next step in processing the operation. */ void KHMAPI kmsg_cred_completion(kmq_message *m) { khui_new_creds * nc; #ifdef DEBUG assert(m->type == KMSG_CRED); #else if(m->type != KMSG_CRED) return; /* huh? */ #endif switch(m->subtype) { case KMSG_CRED_PASSWORD: /* fallthrough */ case KMSG_CRED_NEW_CREDS: /* Cred types have attached themselves. Trigger the next phase. */ kmq_post_message(KMSG_CRED, KMSG_CRED_DIALOG_SETUP, 0, m->vparam); break; case KMSG_CRED_RENEW_CREDS: nc = (khui_new_creds *) m->vparam; /* khm_cred_dispatch_process_message() deals with the case where there are no credential types that wants to participate in this operation. */ khm_cred_dispatch_process_message(nc); break; case KMSG_CRED_DIALOG_SETUP: nc = (khui_new_creds *) m->vparam; khm_prep_newcredwnd(nc->hwnd); /* all the controls have been created. Now initialize them */ if (nc->n_types > 0) { kmq_post_subs_msg(nc->type_subs, nc->n_types, KMSG_CRED, KMSG_CRED_DIALOG_PRESTART, 0, m->vparam); } else { PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0); } break; case KMSG_CRED_DIALOG_PRESTART: /* all prestart stuff is done. Now to activate the dialog */ nc = (khui_new_creds *) m->vparam; khm_show_newcredwnd(nc->hwnd); kmq_post_subs_msg(nc->type_subs, nc->n_types, KMSG_CRED, KMSG_CRED_DIALOG_START, 0, m->vparam); /* at this point, the dialog window takes over. We let it run the show until KMSG_CRED_DIALOG_END is posted by the dialog procedure. */ break; case KMSG_CRED_PROCESS: /* a wave of these messages have completed. We should check if there's more */ nc = (khui_new_creds *) m->vparam; /* if we are done processing all the plug-ins, then check if there were any errors reported. Otherwise we dispatch another set of messages. */ if(!khm_cred_dispatch_process_level(nc)) { if(kherr_is_error()) { khui_alert * alert; kherr_event * evt; kherr_context * ctx; wchar_t ws_tfmt[512]; wchar_t w_idname[KCDB_IDENT_MAXCCH_NAME]; wchar_t ws_title[ARRAYLENGTH(ws_tfmt) + KCDB_IDENT_MAXCCH_NAME]; khm_size cb; /* For renewals, we suppress the error message for the following case: - The renewal was for an identity - There are no identity credentials for the identity (no credentials that have the same type as the identity provider). */ if (nc->subtype == KMSG_CRED_RENEW_CREDS && nc->ctx.scope == KHUI_SCOPE_IDENT && nc->ctx.identity != NULL) { khm_handle tcs = NULL; /* credential set */ khm_size count = 0; khm_int32 id_ctype = KCDB_CREDTYPE_INVALID; khm_int32 delta = 0; kcdb_identity_get_type(&id_ctype); kcdb_credset_create(&tcs); kcdb_credset_collect(tcs, NULL, nc->ctx.identity, id_ctype, &delta); kcdb_credset_get_size(tcs, &count); kcdb_credset_delete(tcs); if (count == 0) { goto done_with_op; } } ctx = kherr_peek_context(); evt = kherr_get_err_event(ctx); kherr_evaluate_event(evt); khui_alert_create_empty(&alert); if (nc->subtype == KMSG_CRED_NEW_CREDS) { khui_alert_set_type(alert, KHUI_ALERTTYPE_ACQUIREFAIL); cb = sizeof(w_idname); if (nc->n_identities == 0 || KHM_FAILED(kcdb_identity_get_name(nc->identities[0], w_idname, &cb))) { /* an identity could not be determined */ LoadString(khm_hInstance, IDS_NC_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->identities[0], KCDB_CREDTYPE_INVALID, NULL); } } else if (nc->subtype == KMSG_CRED_PASSWORD) { khui_alert_set_type(alert, KHUI_ALERTTYPE_CHPW); cb = sizeof(w_idname); if (nc->n_identities == 0 || KHM_FAILED(kcdb_identity_get_name(nc->identities[0], w_idname, &cb))) { LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->identities[0], KCDB_CREDTYPE_INVALID, NULL); } } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { khui_alert_set_type(alert, KHUI_ALERTTYPE_RENEWFAIL); cb = sizeof(w_idname); if (nc->ctx.identity == NULL || KHM_FAILED(kcdb_identity_get_name(nc->ctx.identity, w_idname, &cb))) { LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->ctx.identity, KCDB_CREDTYPE_INVALID, NULL); } } else { #ifdef DEBUG assert(FALSE); #endif } khui_alert_set_title(alert, ws_title); khui_alert_set_severity(alert, evt->severity); if(!evt->long_desc) khui_alert_set_message(alert, evt->short_desc); else khui_alert_set_message(alert, evt->long_desc); if(evt->suggestion) khui_alert_set_suggestion(alert, evt->suggestion); if (nc->subtype == KMSG_CRED_RENEW_CREDS && nc->ctx.identity != NULL) { khm_int32 n_cmd; n_cmd = khm_get_identity_new_creds_action(nc->ctx.identity); if (n_cmd != 0) { khui_alert_add_command(alert, n_cmd); khui_alert_add_command(alert, KHUI_PACTION_CLOSE); khui_alert_set_flags(alert, KHUI_ALERT_FLAG_DISPATCH_CMD, KHUI_ALERT_FLAG_DISPATCH_CMD); } } khui_alert_show(alert); khui_alert_release(alert); kherr_release_context(ctx); kherr_clear_error(); } done_with_op: if (nc->subtype == KMSG_CRED_RENEW_CREDS) { kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, m->vparam); } else { PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0); } } break; case KMSG_CRED_END: /* all is done. */ { khui_new_creds * nc; khm_boolean continue_cmdline = TRUE; nc = (khui_new_creds *) m->vparam; if (nc->subtype == KMSG_CRED_NEW_CREDS || nc->subtype == KMSG_CRED_PASSWORD) { khm_cred_end_dialog(nc); } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { /* if this is a renewal that was triggered while we were processing the commandline, then we need to update the pending renewal count. */ if (khm_startup.processing) { LONG renewals; renewals = InterlockedDecrement(&khm_startup.pending_renewals); if (renewals != 0) { continue_cmdline = FALSE; } } } khui_cw_destroy_cred_blob(nc); kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); if (continue_cmdline) kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); } break; /* property sheet stuff */ case KMSG_CRED_PP_BEGIN: /* all the pages should have been added by now. Just send out the precreate message */ kmq_post_message(KMSG_CRED, KMSG_CRED_PP_PRECREATE, 0, m->vparam); break; case KMSG_CRED_PP_END: kmq_post_message(KMSG_CRED, KMSG_CRED_PP_DESTROY, 0, m->vparam); break; case KMSG_CRED_DESTROY_CREDS: #ifdef DEBUG assert(m->vparam != NULL); #endif khui_context_release((khui_action_context *) m->vparam); PFREE(m->vparam); kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); break; case KMSG_CRED_IMPORT: { khm_boolean continue_cmdline = FALSE; LONG pending_renewals; /* once an import operation ends, we have to trigger a renewal so that other plug-ins that didn't participate in the import operation can have a chance at getting the necessary credentials. If we are in the middle of processing the commandline, we have to be a little bit careful. We can't issue a commandline conituation message right now because the import action is still ongoing (since the renewals are part of the action). Once the renewals have completed, the completion handler will automatically issue a commandline continuation message. However, if there were no identities to renew, then we have to issue the message ourselves. */ InterlockedIncrement(&khm_startup.pending_renewals); khm_cred_renew_all_identities(); pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals); if (pending_renewals == 0 && khm_startup.processing) kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); } break; case KMSG_CRED_REFRESH: kcdb_identity_refresh_all(); break; } }