summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/windows/identity/apiversion.txt5
-rw-r--r--src/windows/identity/config/Makefile3
-rw-r--r--src/windows/identity/config/Makefile.w2k6
-rw-r--r--src/windows/identity/config/Makefile.w324
-rw-r--r--src/windows/identity/kcreddb/identity.c4
-rw-r--r--src/windows/identity/kcreddb/kcreddb.h1
-rw-r--r--src/windows/identity/plugins/krb5/krb5funcs.c134
-rw-r--r--src/windows/identity/plugins/krb5/krb5identpro.c163
-rw-r--r--src/windows/identity/plugins/krb5/krb5newcreds.c82
-rw-r--r--src/windows/identity/plugins/krb5/krb5plugin.c19
-rw-r--r--src/windows/identity/plugins/krb5/krbcred.h3
-rw-r--r--src/windows/identity/plugins/krb5/lang/en_us/langres.rc8
-rw-r--r--src/windows/identity/ui/cfg_identities_wnd.c362
-rw-r--r--src/windows/identity/ui/configwnd.c209
-rw-r--r--src/windows/identity/ui/credfuncs.c23
-rw-r--r--src/windows/identity/ui/htwnd.c3
-rw-r--r--src/windows/identity/ui/lang/en_us/khapp.rc23
-rw-r--r--src/windows/identity/ui/newcredwnd.c6
-rw-r--r--src/windows/identity/ui/notifier.c1
-rw-r--r--src/windows/identity/ui/resource.h9
-rw-r--r--src/windows/identity/ui/timer.c230
-rw-r--r--src/windows/identity/ui/timer.h6
-rw-r--r--src/windows/identity/uilib/configui.c13
-rw-r--r--src/windows/identity/uilib/creddlg.c2
-rw-r--r--src/windows/identity/uilib/khprops.h2
25 files changed, 1078 insertions, 243 deletions
diff --git a/src/windows/identity/apiversion.txt b/src/windows/identity/apiversion.txt
index 2a49540cd..4399861e8 100644
--- a/src/windows/identity/apiversion.txt
+++ b/src/windows/identity/apiversion.txt
@@ -1,5 +1,4 @@
-# Copyright (c) 2004-2006 Massachusetts Institute of Technology
-# Copyright (c) 2006 Secure Endpoints Inc.
+# Copyright (c) 2004 Massachusetts Institute of Technology
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
@@ -213,3 +212,5 @@ Date=(TBD)
!kcdb_buf_get_attrib(), kcdb_buf_get_attrib_string(), kcbd_buf_set_attrib()
# attr_name is now a const pointer
++KCDB_OP_DELCONFIG
+# notification that the configuration information for an identity is to be removed.
diff --git a/src/windows/identity/config/Makefile b/src/windows/identity/config/Makefile
index f1ac2ac67..41e29bf82 100644
--- a/src/windows/identity/config/Makefile
+++ b/src/windows/identity/config/Makefile
@@ -1,5 +1,6 @@
#
-# Copyright (c) 2004 Massachusetts Institute of Technology
+# Copyright (c) 2004,2005,2006 Massachusetts Institute of Technology
+# Copyright (c) 2006 Secure Endpoints Inc.
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
diff --git a/src/windows/identity/config/Makefile.w2k b/src/windows/identity/config/Makefile.w2k
index 0677d13c9..dbc2690cd 100644
--- a/src/windows/identity/config/Makefile.w2k
+++ b/src/windows/identity/config/Makefile.w2k
@@ -3,7 +3,7 @@
# This file will be included by all the makefiles
# in the build tree.
#
-# Copyright (c) 2004,2005 Massachusetts Institute of Technology
+# Copyright (c) 2004,2005,2006 Massachusetts Institute of Technology
# Copyright (c) 2006 Secure Endpoints Inc.
#
# Permission is hereby granted, free of charge, to any person
@@ -47,8 +47,8 @@ KHIMAIRA_WIN32_CONFIG=1
# Version info
NETIDMGR_VERSION_MAJOR=1
NETIDMGR_VERSION_MINOR=1
-NETIDMGR_VERSION_PATCH=1
-NETIDMGR_VERSION_AUX=2
+NETIDMGR_VERSION_PATCH=2
+NETIDMGR_VERSION_AUX=0
NETIDMGR_RELEASEDESC=
# The API version. This number must be incremented each time the API
diff --git a/src/windows/identity/config/Makefile.w32 b/src/windows/identity/config/Makefile.w32
index 0f47bcb13..7d259d19c 100644
--- a/src/windows/identity/config/Makefile.w32
+++ b/src/windows/identity/config/Makefile.w32
@@ -47,8 +47,8 @@ KHIMAIRA_WIN32_CONFIG=1
# Version info
NETIDMGR_VERSION_MAJOR=1
NETIDMGR_VERSION_MINOR=1
-NETIDMGR_VERSION_PATCH=0
-NETIDMGR_VERSION_AUX=2
+NETIDMGR_VERSION_PATCH=2
+NETIDMGR_VERSION_AUX=0
NETIDMGR_RELEASEDESC=
# The API version. This number must be incremented each time the API
diff --git a/src/windows/identity/kcreddb/identity.c b/src/windows/identity/kcreddb/identity.c
index 15c36130f..4236c2795 100644
--- a/src/windows/identity/kcreddb/identity.c
+++ b/src/windows/identity/kcreddb/identity.c
@@ -617,9 +617,13 @@ kcdb_identity_get_config(khm_handle vid,
&hident);
if(KHM_FAILED(rv)) {
+ khm_int32 oldflags;
EnterCriticalSection(&cs_ident);
+ oldflags = id->flags;
id->flags &= ~KCDB_IDENT_FLAG_CONFIG;
LeaveCriticalSection(&cs_ident);
+ if (oldflags & KCDB_IDENT_FLAG_CONFIG)
+ kcdbint_ident_post_message(KCDB_OP_DELCONFIG, id);
goto _exit;
}
diff --git a/src/windows/identity/kcreddb/kcreddb.h b/src/windows/identity/kcreddb/kcreddb.h
index 1b5d9b67c..060f556ac 100644
--- a/src/windows/identity/kcreddb/kcreddb.h
+++ b/src/windows/identity/kcreddb/kcreddb.h
@@ -3310,6 +3310,7 @@ kcdb_buf_release(khm_handle record);
#define KCDB_OP_SETSEARCH 8
#define KCDB_OP_UNSETSEARCH 9
#define KCDB_OP_NEW_DEFAULT 10
+#define KCDB_OP_DELCONFIG 11
/*@}*/
diff --git a/src/windows/identity/plugins/krb5/krb5funcs.c b/src/windows/identity/plugins/krb5/krb5funcs.c
index 95f9a38c6..331e789dc 100644
--- a/src/windows/identity/plugins/krb5/krb5funcs.c
+++ b/src/windows/identity/plugins/krb5/krb5funcs.c
@@ -702,6 +702,19 @@ khm_krb5_renew_cred(khm_handle cred)
khm_boolean brenewIdentity = FALSE;
khm_boolean istgt = FALSE;
+ khm_int32 flags;
+
+ cbname = sizeof(wname);
+ kcdb_cred_get_name(cred, wname, &cbname);
+ _reportf(L"Krb5 renew cred for %s", wname);
+
+ kcdb_cred_get_flags(cred, &flags);
+
+ if (!(flags & KCDB_CRED_FLAG_INITIAL)) {
+ _reportf(L"Krb5 skipping renewal because this is not an initial credential");
+ return 0;
+ }
+
memset(&in_creds, 0, sizeof(in_creds));
memset(&cc_creds, 0, sizeof(cc_creds));
@@ -2161,80 +2174,79 @@ khm_krb5_changepwd(char * principal,
if ( !pkrb5_init_context )
goto cleanup;
- if (rc = pkrb5_init_context(&context)) {
- goto cleanup;
- }
-
- if (rc = pkrb5_parse_name(context, principal, &princ)) {
- goto cleanup;
- }
-
- pkrb5_get_init_creds_opt_init(&opts);
- pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
- pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
- pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
- pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
- pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
-
- if (rc = pkrb5_get_init_creds_password(context, &creds, princ,
- password, 0, 0, 0,
- "kadmin/changepw", &opts)) {
- if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ if (rc = pkrb5_init_context(&context)) {
+ goto cleanup;
+ }
+
+ if (rc = pkrb5_parse_name(context, principal, &princ)) {
+ goto cleanup;
+ }
+
+ pkrb5_get_init_creds_opt_init(&opts);
+ pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
+ pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);
+ pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);
+ pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);
+ pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);
+
+ if (rc = pkrb5_get_init_creds_password(context, &creds, princ,
+ password, 0, 0, 0,
+ "kadmin/changepw", &opts)) {
+ if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
#if 0
- com_err(argv[0], 0,
- "Password incorrect while getting initial ticket");
+ com_err(argv[0], 0,
+ "Password incorrect while getting initial ticket");
#endif
- }
- else {
+ } else {
#if 0
- com_err(argv[0], ret, "getting initial ticket");
+ com_err(argv[0], ret, "getting initial ticket");
#endif
- }
- goto cleanup;
- }
+ }
+ goto cleanup;
+ }
- if (rc = pkrb5_change_password(context, &creds, newpassword,
- &result_code, &result_code_string,
- &result_string)) {
+ if (rc = pkrb5_change_password(context, &creds, newpassword,
+ &result_code, &result_code_string,
+ &result_string)) {
#if 0
- com_err(argv[0], ret, "changing password");
+ com_err(argv[0], ret, "changing password");
#endif
- goto cleanup;
- }
-
- if (result_code) {
- int len = result_code_string.length +
- (result_string.length ? (sizeof(": ") - 1) : 0) +
- result_string.length;
- if (len && error_str) {
- *error_str = PMALLOC(len + 1);
- if (*error_str)
- StringCchPrintfA(*error_str, len+1,
- "%.*s%s%.*s",
- result_code_string.length,
- result_code_string.data,
- result_string.length?": ":"",
- result_string.length,
- result_string.data);
- }
- rc = result_code;
- goto cleanup;
- }
+ goto cleanup;
+ }
+
+ if (result_code) {
+ int len = result_code_string.length +
+ (result_string.length ? (sizeof(": ") - 1) : 0) +
+ result_string.length;
+ if (len && error_str) {
+ *error_str = PMALLOC(len + 1);
+ if (*error_str)
+ StringCchPrintfA(*error_str, len+1,
+ "%.*s%s%.*s",
+ result_code_string.length,
+ result_code_string.data,
+ result_string.length?": ":"",
+ result_string.length,
+ result_string.data);
+ }
+ rc = result_code;
+ goto cleanup;
+ }
cleanup:
- if (result_string.data)
- pkrb5_free_data_contents(context, &result_string);
+ if (result_string.data)
+ pkrb5_free_data_contents(context, &result_string);
- if (result_code_string.data)
- pkrb5_free_data_contents(context, &result_code_string);
+ if (result_code_string.data)
+ pkrb5_free_data_contents(context, &result_code_string);
- if (princ)
- pkrb5_free_principal(context, princ);
+ if (princ)
+ pkrb5_free_principal(context, princ);
- if (context)
- pkrb5_free_context(context);
+ if (context)
+ pkrb5_free_context(context);
- return rc;
+ return rc;
}
khm_int32 KHMAPI
diff --git a/src/windows/identity/plugins/krb5/krb5identpro.c b/src/windows/identity/plugins/krb5/krb5identpro.c
index 11a7410b1..05f93fcd3 100644
--- a/src/windows/identity/plugins/krb5/krb5identpro.c
+++ b/src/windows/identity/plugins/krb5/krb5identpro.c
@@ -226,8 +226,10 @@ update_crossfeed(khui_new_creds * nc,
un_realm = khm_get_realm_from_princ(un);
- if (un_realm == NULL)
+ if (un_realm == NULL) {
+ EnableWindow(d->hw_realm, TRUE);
return FALSE;
+ }
if (ctrl_id_src == K5_NCID_UN) {
@@ -270,6 +272,15 @@ update_crossfeed(khui_new_creds * nc,
SetWindowText(d->hw_realm,
un_realm);
+ if (GetFocus() == d->hw_realm) {
+ HWND hw_next = GetNextDlgTabItem(nc->hwnd, d->hw_realm,
+ FALSE);
+ if (hw_next)
+ SetFocus(hw_next);
+ }
+
+ EnableWindow(d->hw_realm, FALSE);
+
return TRUE;
}
/* else... */
@@ -739,6 +750,7 @@ k5_ident_valiate_name(khm_int32 msg_type,
char princ_name[KCDB_IDENT_MAXCCH_NAME];
kcdb_ident_name_xfer * nx;
krb5_error_code code;
+ wchar_t * atsign;
nx = (kcdb_ident_name_xfer *) vparam;
@@ -759,11 +771,18 @@ k5_ident_valiate_name(khm_int32 msg_type,
return KHM_ERROR_SUCCESS;
}
- if (princ != NULL)
+ if (princ != NULL)
pkrb5_free_principal(k5_identpro_ctx,
princ);
- nx->result = KHM_ERROR_SUCCESS;
+ /* krb5_parse_name() accepts principal names with no realm or an
+ empty realm. We don't. */
+ atsign = wcschr(nx->name_src, L'@');
+ if (atsign == NULL || atsign[1] == L'\0') {
+ nx->result = KHM_ERROR_INVALID_NAME;
+ } else {
+ nx->result = KHM_ERROR_SUCCESS;
+ }
return KHM_ERROR_SUCCESS;
}
@@ -1032,15 +1051,23 @@ k5_ident_notify_create(khm_int32 msg_type,
return KHM_ERROR_SUCCESS;
}
+struct k5_ident_update_data {
+ khm_handle identity;
+
+ FILETIME ft_expire; /* expiration */
+ FILETIME ft_issue; /* issue */
+ FILETIME ft_rexpire; /* renew expiration */
+ wchar_t ccname[KRB5_MAXCCH_CCNAME];
+ khm_int32 k5_flags;
+};
+
static khm_int32 KHMAPI
k5_ident_update_apply_proc(khm_handle cred,
void * rock) {
- wchar_t ccname[KRB5_MAXCCH_CCNAME];
- khm_handle tident = (khm_handle) rock;
+ struct k5_ident_update_data * d = (struct k5_ident_update_data *) rock;
khm_handle ident = NULL;
khm_int32 t;
khm_int32 flags;
- FILETIME t_expire;
FILETIME t_cexpire;
FILETIME t_rexpire;
khm_size cb;
@@ -1049,12 +1076,15 @@ k5_ident_update_apply_proc(khm_handle cred,
if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||
t != credtype_id_krb5 ||
KHM_FAILED(kcdb_cred_get_identity(cred, &ident)))
+
return KHM_ERROR_SUCCESS;
- if (!kcdb_identity_is_equal(ident,tident))
+ if (!kcdb_identity_is_equal(ident,d->identity))
+
goto _cleanup;
if (KHM_FAILED(kcdb_cred_get_flags(cred, &flags)))
+
flags = 0;
if (flags & KCDB_CRED_FLAG_INITIAL) {
@@ -1064,13 +1094,9 @@ k5_ident_update_apply_proc(khm_handle cred,
NULL,
&t_cexpire,
&cb))) {
- cb = sizeof(t_expire);
- if (KHM_FAILED(kcdb_identity_get_attr(tident,
- KCDB_ATTR_EXPIRE,
- NULL,
- &t_expire,
- &cb)) ||
- CompareFileTime(&t_cexpire, &t_expire) > 0) {
+ if ((d->ft_expire.dwLowDateTime == 0 &&
+ d->ft_expire.dwHighDateTime == 0) ||
+ CompareFileTime(&t_cexpire, &d->ft_expire) > 0) {
goto update_identity;
}
}
@@ -1080,52 +1106,35 @@ k5_ident_update_apply_proc(khm_handle cred,
update_identity:
- kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE,
- &t_cexpire, sizeof(t_cexpire));
+ d->ft_expire = t_cexpire;
- cb = sizeof(ccname);
- if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION,
- NULL,
- ccname,
- &cb))) {
- kcdb_identity_set_attr(tident, attr_id_krb5_ccname,
- ccname, cb);
- } else {
- kcdb_identity_set_attr(tident, attr_id_krb5_ccname,
- NULL, 0);
+ cb = sizeof(d->ccname);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION, NULL, d->ccname, &cb))) {
+ d->ccname[0] = L'\0';
}
-
- cb = sizeof(t);
- if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
- attr_id_krb5_flags,
- NULL,
- &t,
- &cb))) {
- kcdb_identity_set_attr(tident, attr_id_krb5_flags,
- &t, sizeof(t));
+ cb = sizeof(d->k5_flags);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, attr_id_krb5_flags, NULL,
+ &d->k5_flags, &cb))) {
+ d->k5_flags = 0;
+ }
- cb = sizeof(t_rexpire);
- if (!(t & TKT_FLG_RENEWABLE) ||
- KHM_FAILED(kcdb_cred_get_attr(cred,
- KCDB_ATTR_RENEW_EXPIRE,
- NULL,
- &t_rexpire,
- &cb))) {
- kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,
- NULL, 0);
- } else {
- kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,
- &t_rexpire, sizeof(t_rexpire));
- }
- } else {
- kcdb_identity_set_attr(tident, attr_id_krb5_flags,
- NULL, 0);
- kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,
- NULL, 0);
+ cb = sizeof(d->ft_issue);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, NULL, &d->ft_issue, &cb))) {
+ ZeroMemory(&d->ft_issue, sizeof(d->ft_issue));
}
- rv = KHM_ERROR_EXIT;
+ cb = sizeof(t_rexpire);
+ if ((d->k5_flags & TKT_FLG_RENEWABLE) &&
+ KHM_SUCCEEDED(kcdb_cred_get_attr(cred,
+ KCDB_ATTR_RENEW_EXPIRE,
+ NULL,
+ &t_rexpire,
+ &cb))) {
+ d->ft_rexpire = t_rexpire;
+ } else {
+ ZeroMemory(&d->ft_rexpire, sizeof(d->ft_rexpire));
+ }
_cleanup:
if (ident)
@@ -1140,6 +1149,7 @@ k5_ident_update(khm_int32 msg_type,
khm_ui_4 uparam,
void * vparam) {
+ struct k5_ident_update_data d;
khm_handle ident;
khm_handle tident;
krb5_ccache cc = NULL;
@@ -1153,9 +1163,52 @@ k5_ident_update(khm_int32 msg_type,
if (ident == NULL)
return KHM_ERROR_SUCCESS;
+ ZeroMemory(&d, sizeof(d));
+ d.identity = ident;
+
kcdb_credset_apply(NULL,
k5_ident_update_apply_proc,
- (void *) ident);
+ (void *) &d);
+
+ if (d.ft_expire.dwLowDateTime != 0 ||
+ d.ft_expire.dwHighDateTime != 0) {
+
+ /* we found a TGT */
+
+ kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE,
+ &d.ft_expire, sizeof(d.ft_expire));
+ if (d.ft_issue.dwLowDateTime != 0 ||
+ d.ft_issue.dwHighDateTime != 0)
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE,
+ &d.ft_issue, sizeof(d.ft_issue));
+ else
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
+
+ if (d.ft_rexpire.dwLowDateTime != 0 ||
+ d.ft_rexpire.dwHighDateTime != 0)
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE,
+ &d.ft_rexpire, sizeof(d.ft_rexpire));
+ else
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
+
+ kcdb_identity_set_attr(ident, attr_id_krb5_flags,
+ &d.k5_flags, sizeof(d.k5_flags));
+
+ if (d.ccname[0])
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname,
+ d.ccname, KCDB_CBSIZE_AUTO);
+ else
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
+
+ } else {
+ /* Clear out the attributes. We don't have any information
+ about this identity */
+ kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE, NULL, 0);
+ kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);
+ kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);
+ kcdb_identity_set_attr(ident, attr_id_krb5_flags, NULL, 0);
+ kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);
+ }
if (KHM_SUCCEEDED(kcdb_identity_get_default(&tident))) {
kcdb_identity_release(tident);
diff --git a/src/windows/identity/plugins/krb5/krb5newcreds.c b/src/windows/identity/plugins/krb5/krb5newcreds.c
index db9462eb6..e7641df8a 100644
--- a/src/windows/identity/plugins/krb5/krb5newcreds.c
+++ b/src/windows/identity/plugins/krb5/krb5newcreds.c
@@ -232,6 +232,20 @@ k5_handle_wmnc_notify(HWND hwnd,
d->pwd_change = TRUE;
+ if (is_k5_identpro &&
+ d->nc->n_identities > 0 &&
+ d->nc->identities[0]) {
+
+ kcdb_identity_set_flags(d->nc->identities[0],
+ KCDB_IDENT_FLAG_VALID,
+ KCDB_IDENT_FLAG_VALID);
+
+ }
+
+ PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),
+ (LPARAM) d->nc);
+
return TRUE;
}
}
@@ -347,7 +361,7 @@ k5_handle_wmnc_notify(HWND hwnd,
/* the above notification effectively takes all our
changes into account. The data we have is no
longer out of sync */
- d->sync = FALSE;
+ d->sync = TRUE;
}
}
break;
@@ -1574,6 +1588,47 @@ k5_find_tgt_filter(khm_handle cred,
}
khm_int32
+k5_remove_from_LRU(khm_handle identity)
+{
+ wchar_t * wbuf = NULL;
+ wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
+ khm_size cb;
+ khm_size cb_ms;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ cb = sizeof(idname);
+ rv = kcdb_identity_get_name(identity, idname, &cb);
+ assert(rv == KHM_ERROR_SUCCESS);
+
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);
+ if (rv != KHM_ERROR_TOO_LONG)
+ cb_ms = sizeof(wchar_t) * 2;
+
+ wbuf = PMALLOC(cb_ms);
+ assert(wbuf);
+
+ cb = cb_ms;
+
+ if (rv == KHM_ERROR_TOO_LONG) {
+ rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);
+ assert(KHM_SUCCEEDED(rv));
+
+ if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {
+ multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);
+ }
+ } else {
+ multi_string_init(wbuf, cb_ms);
+ }
+
+ rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);
+
+ if (wbuf)
+ PFREE(wbuf);
+
+ return rv;
+}
+
+khm_int32
k5_update_LRU(khm_handle identity)
{
wchar_t * wbuf = NULL;
@@ -1915,6 +1970,13 @@ k5_msg_cred_dialog(khm_int32 msg_type,
assert(nc->subtype == KMSG_CRED_NEW_CREDS);
+ /* If we are forcing a password change, then we don't do
+ anything here. Note that if the identity changed, then
+ this field would have been reset, so we would proceed
+ as usual. */
+ if (d->pwd_change)
+ return KHM_ERROR_SUCCESS;
+
/* if the fiber is already in a kinit, cancel it */
if(g_fjob.state == FIBER_STATE_KINIT) {
g_fjob.command = FIBER_CMD_CANCEL;
@@ -1965,7 +2027,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
break;
case KRB5KDC_ERR_KEY_EXP:
- /* password needs changing */
+ /* password needs changing. */
LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,
msg, ARRAYLENGTH(msg));
break;
@@ -2320,7 +2382,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
kherr_suggestion sug_id;
/* if we failed to get new tickets, but the
- identity isstill valid, then we assume that
+ identity is still valid, then we assume that
the current tickets are still good enough
for other credential types to obtain their
credentials. */
@@ -2374,7 +2436,13 @@ k5_msg_cred_dialog(khm_int32 msg_type,
khui_cw_lock_nc(nc);
- if (nc->n_identities == 0 ||
+ if (nc->result == KHUI_NC_RESULT_CANCEL) {
+
+ khui_cw_set_response(nc, credtype_id_krb5,
+ KHUI_NC_RESPONSE_SUCCESS |
+ KHUI_NC_RESPONSE_EXIT);
+
+ } else if (nc->n_identities == 0 ||
nc->identities[0] == NULL) {
_report_mr0(KHERR_ERROR, MSG_PWD_NO_IDENTITY);
_suggest_mr(MSG_PWD_S_NO_IDENTITY, KHERR_SUGGEST_RETRY);
@@ -2382,6 +2450,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
khui_cw_set_response(nc, credtype_id_krb5,
KHUI_NC_RESPONSE_FAILED |
KHUI_NC_RESPONSE_NOEXIT);
+
} else {
wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
char idname[KCDB_IDENT_MAXCCH_NAME];
@@ -2483,9 +2552,12 @@ k5_msg_cred_dialog(khm_int32 msg_type,
goto _pwd_exit;
}
+ /* the password change phase is now done */
+ d->pwd_change = FALSE;
+
code = khm_krb5_kinit(NULL, /* context (create one) */
idname, /* principal_name */
- npwd, /* password */
+ npwd, /* new password */
NULL, /* ccache name (figure out the identity cc)*/
(krb5_deltat) d->tc_lifetime.current,
d->forwardable,
diff --git a/src/windows/identity/plugins/krb5/krb5plugin.c b/src/windows/identity/plugins/krb5/krb5plugin.c
index 7c5287769..e80e01c47 100644
--- a/src/windows/identity/plugins/krb5/krb5plugin.c
+++ b/src/windows/identity/plugins/krb5/krb5plugin.c
@@ -169,6 +169,23 @@ k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
return rv;
}
+khm_int32 KHMAPI
+k5_msg_kcdb(khm_int32 msg_type, khm_int32 msg_subtype,
+ khm_ui_4 uparam, void * vparam)
+{
+ khm_int32 rv = KHM_ERROR_SUCCESS;
+
+ switch(msg_subtype) {
+ case KMSG_KCDB_IDENT:
+ if (uparam == KCDB_OP_DELCONFIG) {
+ k5_remove_from_LRU((khm_handle) vparam);
+ }
+ break;
+ }
+
+ return rv;
+}
+
/* Handler for CRED type messages
@@ -241,6 +258,8 @@ k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype,
return k5_msg_system(msg_type, msg_subtype, uparam, vparam);
case KMSG_CRED:
return k5_msg_cred(msg_type, msg_subtype, uparam, vparam);
+ case KMSG_KCDB:
+ return k5_msg_kcdb(msg_type, msg_subtype, uparam, vparam);
}
return KHM_ERROR_SUCCESS;
}
diff --git a/src/windows/identity/plugins/krb5/krbcred.h b/src/windows/identity/plugins/krb5/krbcred.h
index f31bde4e6..694323ce3 100644
--- a/src/windows/identity/plugins/krb5/krbcred.h
+++ b/src/windows/identity/plugins/krb5/krbcred.h
@@ -200,6 +200,9 @@ k5_msg_ident(khm_int32 msg_type,
khm_ui_4 uparam,
void * vparam);
+khm_int32
+k5_remove_from_LRU(khm_handle identity);
+
int
k5_get_realm_from_nc(khui_new_creds * nc,
wchar_t * buf,
diff --git a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc
index 54f3ed787..dde30e387 100644
--- a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc
+++ b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc
@@ -59,7 +59,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Kerberos 5 Ticket Options",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN | WS_GROUP,7,7,286,11
LTEXT "Realm",IDC_STATIC,7,25,52,13
- COMBOBOX IDC_NCK5_REALM,60,25,233,17,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_NCK5_REALM,60,25,233,51,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Specify &additional realms ...",IDC_NCK5_ADD_REALMS,181,43,112,16,BS_NOTIFY | NOT WS_VISIBLE | WS_DISABLED
LTEXT "&Lifetime",IDC_STATIC,7,67,61,12
EDITTEXT IDC_NCK5_LIFETIME_EDIT,85,67,107,12,ES_AUTOHSCROLL
@@ -119,7 +119,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "Default Realm",IDC_CFG_LBL_REALM,13,9,46,8
- COMBOBOX IDC_CFG_DEFREALM,76,7,166,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CFG_DEFREALM,76,7,166,51,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure Realms ...",IDC_CFG_CFGREALMS,76,25,84,14,NOT WS_VISIBLE | WS_DISABLED
GROUPBOX "Keberos Configuration File",IDC_CFG_CFGFILEGRP,7,45,241,61
LTEXT "Location",IDC_CFG_LBL_CFGFILE,13,61,28,8
@@ -134,7 +134,7 @@ BEGIN
LTEXT "Domain",IDC_CFG_LBL_DOMAIN,13,141,24,8
EDITTEXT IDC_CFG_DOMAIN,76,138,166,14,ES_AUTOHSCROLL | ES_READONLY
LTEXT "Import tickets",IDC_LBL_IMPORT,13,158,45,8
- COMBOBOX IDC_CFG_IMPORT,76,156,166,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CFG_IMPORT,76,156,166,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
END
IDD_CFG_REALMS DIALOGEX 0, 0, 255, 182
@@ -195,7 +195,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "Kerberos 5 Change Password Options",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN | WS_GROUP,7,7,286,11
LTEXT "Realm",IDC_STATIC,7,25,52,13
- COMBOBOX IDC_NCK5_REALM,60,25,233,17,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_NCK5_REALM,60,25,233,51,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Specify &additional realms ...",IDC_NCK5_ADD_REALMS,181,43,112,16,BS_NOTIFY | WS_DISABLED
END
diff --git a/src/windows/identity/ui/cfg_identities_wnd.c b/src/windows/identity/ui/cfg_identities_wnd.c
index 3297b05be..3f92ad839 100644
--- a/src/windows/identity/ui/cfg_identities_wnd.c
+++ b/src/windows/identity/ui/cfg_identities_wnd.c
@@ -130,10 +130,11 @@ apply_all(HWND hwnd,
khui_config_node_reg reg;
int idx;
int count;
+ BOOL cont = TRUE;
count = TabCtrl_GetItemCount(hw_tab);
- for (idx = 0; idx < count; idx++) {
+ for (idx = 0; idx < count && cont; idx++) {
ZeroMemory(&tci, sizeof(tci));
@@ -156,7 +157,7 @@ apply_all(HWND hwnd,
#endif
SendMessage(hw, KHUI_WM_CFG_NOTIFY,
- MAKEWPARAM(0, WMCFG_APPLY), 0);
+ MAKEWPARAM(0, WMCFG_APPLY), (LPARAM) &cont);
}
}
@@ -317,6 +318,7 @@ typedef struct tag_idents_data {
ident_data * idents;
khm_size n_idents;
khm_size nc_idents;
+#define IDENTS_DATA_ALLOC_INCR 8
/* global options */
global_props saved;
@@ -430,6 +432,7 @@ write_params_ident(ident_data * d) {
if (d->removed) {
khm_handle h = NULL;
+ khm_int32 flags = 0;
khc_remove_space(csp_ident);
@@ -444,6 +447,10 @@ write_params_ident(ident_data * d) {
#endif
khc_close_space(h);
}
+#ifdef DEBUG
+ kcdb_identity_get_flags(d->ident, &flags);
+ assert(!(flags & KCDB_IDENT_FLAG_CONFIG));
+#endif
} else {
@@ -470,11 +477,15 @@ write_params_ident(ident_data * d) {
if (d->hwnd)
PostMessage(d->hwnd, KHUI_WM_CFG_NOTIFY,
MAKEWPARAM(0, WMCFG_UPDATE_STATE), 0);
+
+ khm_refresh_config();
}
static void
write_params_idents(void) {
+#if 0
int i;
+#endif
khm_handle csp_cw;
if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
@@ -500,9 +511,11 @@ write_params_idents(void) {
khc_close_space(csp_cw);
}
+#if 0
for (i=0; i < (int)cfg_idents.n_idents; i++) {
write_params_ident(&cfg_idents.idents[i]);
}
+#endif
if (cfg_idents.hwnd)
PostMessage(cfg_idents.hwnd, KHUI_WM_CFG_NOTIFY,
@@ -622,6 +635,9 @@ init_idents_data(void) {
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]);
@@ -712,82 +728,258 @@ refresh_view_idents_state(HWND hwnd) {
KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);
}
+struct ctrl_row_dimensions {
+ RECT enclosure;
+ RECT label;
+ RECT control;
+};
+
+typedef struct tag_add_ident_data {
+ khui_new_creds * nc;
+
+ struct ctrl_row_dimensions dim_small;
+ struct ctrl_row_dimensions dim_medium;
+ struct ctrl_row_dimensions dim_large;
+ int row_gap;
+
+ int current_y;
+ int current_x;
+
+ HWND hwnd_last_ctrl;
+} add_ident_data;
+
+void
+get_ctrl_row_metrics(struct ctrl_row_dimensions * dim, HWND hw_lbl, HWND hw_ctl) {
+
+ assert(hw_lbl);
+ assert(hw_ctl);
+
+ GetWindowRect(hw_lbl, &dim->label);
+ GetWindowRect(hw_ctl, &dim->control);
+
+ UnionRect(&dim->enclosure, &dim->label, &dim->control);
+ OffsetRect(&dim->label,
+ -dim->enclosure.left,
+ -dim->enclosure.top);
+ OffsetRect(&dim->control,
+ -dim->enclosure.left,
+ -dim->enclosure.top);
+ OffsetRect(&dim->enclosure,
+ -dim->enclosure.left,
+ -dim->enclosure.top);
+}
+
/* dialog box procedure for the "Add new identity" dialog */
INT_PTR CALLBACK
khm_cfg_add_ident_proc(HWND hwnd,
UINT umsg,
WPARAM wParam,
- LPARAM lparam) {
+ LPARAM lParam) {
+ add_ident_data * d;
+
switch(umsg) {
case WM_INITDIALOG:
- /* set the max length of the edit control first */
- SendDlgItemMessage(hwnd, IDC_CFG_IDNAME,
- EM_SETLIMITTEXT,
- KCDB_IDENT_MAXCCH_NAME - 1,
- 0);
+ /* we create a new credentials blob and pull in the identity
+ selectors from the identity provider. */
+ d = PMALLOC(sizeof(*d));
+ ZeroMemory(d, sizeof(*d));
+
+ khui_cw_create_cred_blob(&d->nc);
+#ifdef DEBUG
+ assert(d->nc != NULL);
+#endif
+ if (d->nc == NULL) {
+ PFREE(d);
+ break;
+ }
+
+ if (KHM_FAILED(kcdb_identpro_get_ui_cb(&d->nc->ident_cb))) {
+ /* this should have worked. The only reason it would fail
+ is if there is no identity provider or if the identity
+ provider does not support providing idnetity
+ selectors. */
+ khui_cw_destroy_cred_blob(d->nc);
+ PFREE(d);
+ break;
+ }
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
+#pragma warning(pop)
+
+ /* get metrics for dynamic controls */
+ get_ctrl_row_metrics(&d->dim_small,
+ GetDlgItem(hwnd, IDC_SM_LBL),
+ GetDlgItem(hwnd, IDC_SM_CTL));
+ get_ctrl_row_metrics(&d->dim_medium,
+ GetDlgItem(hwnd, IDC_MED_LBL),
+ GetDlgItem(hwnd, IDC_MED_CTL));
+ get_ctrl_row_metrics(&d->dim_large,
+ GetDlgItem(hwnd, IDC_LG_LBL),
+ GetDlgItem(hwnd, IDC_LG_CTL));
+
+ {
+ RECT rlbl;
+ RECT rctl;
+ RECT rwnd;
+
+ GetWindowRect(GetDlgItem(hwnd, IDC_SM_LBL),
+ &rlbl);
+ GetWindowRect(GetDlgItem(hwnd, IDC_SM_CTL),
+ &rctl);
+ GetWindowRect(hwnd, &rwnd);
+
+ OffsetRect(&rlbl, -rwnd.left, -rwnd.top);
+ OffsetRect(&rctl, -rwnd.left, -rwnd.top);
+
+ d->current_x = rlbl.left;
+ d->current_y = rctl.top - GetSystemMetrics(SM_CYCAPTION);
+
+ GetWindowRect(GetDlgItem(hwnd, IDC_MED_CTL),
+ &rlbl);
+ OffsetRect(&rlbl, -rwnd.left, -rwnd.top);
+
+ d->row_gap = rlbl.top - rctl.bottom;
+ }
+
+ d->nc->hwnd = hwnd;
+
+ /* now call the UI callback and make it create the
+ controls. */
+ d->nc->ident_cb(d->nc, WMNC_IDENT_INIT, NULL, 0, 0,
+ (LPARAM) hwnd);
+
break;
case WM_DESTROY:
- /* nor do we have to do anything here */
+ d = (add_ident_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+ if (d == NULL)
+ break;
+
+ d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);
+
+ khui_cw_destroy_cred_blob(d->nc);
+ PFREE(d);
break;
+ case KHUI_WM_NC_NOTIFY:
+ d = (add_ident_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ switch(HIWORD(wParam)) {
+ case WMNC_ADD_CONTROL_ROW:
+ {
+ khui_control_row * row;
+ RECT r_lbl, r_inp, r_enc;
+ struct ctrl_row_dimensions * dim;
+ HFONT hf;
+
+ row = (khui_control_row *) lParam;
+
+#ifdef DEBUG
+ assert(row->label);
+ assert(row->input);
+ assert(d);
+#endif
+
+ if (row->size == KHUI_CTRLSIZE_SMALL) {
+ dim = &d->dim_small;
+ } else if (row->size == KHUI_CTRLSIZE_HALF) {
+ dim = &d->dim_medium;
+ } else {
+ dim = &d->dim_large;
+#ifdef DEBUG
+ assert(row->size == KHUI_CTRLSIZE_FULL);
+#endif
+ }
+
+ CopyRect(&r_enc, &dim->enclosure);
+ CopyRect(&r_lbl, &dim->label);
+ CopyRect(&r_inp, &dim->control);
+
+ OffsetRect(&r_enc, d->current_x, d->current_y);
+ OffsetRect(&r_lbl, r_enc.left, r_enc.top);
+ OffsetRect(&r_inp, r_enc.left, r_enc.top);
+
+ d->current_y += r_enc.bottom - r_enc.top;
+
+ hf = (HFONT) SendDlgItemMessage(hwnd, IDOK, WM_GETFONT, 0, 0);
+
+ if (row->label) {
+ SetWindowPos(row->label,
+ ((d->hwnd_last_ctrl != NULL)?
+ d->hwnd_last_ctrl :
+ HWND_TOP),
+ r_lbl.left, r_lbl.top,
+ r_lbl.right - r_lbl.left,
+ r_lbl.bottom - r_lbl.top,
+ SWP_DEFERERASE | SWP_NOACTIVATE |
+ SWP_NOOWNERZORDER);
+ if (hf)
+ SendMessage(row->label, WM_SETFONT,
+ (WPARAM) hf,
+ TRUE);
+ d->hwnd_last_ctrl = row->label;
+ }
+
+ if (row->input) {
+ SetWindowPos(row->input,
+ ((d->hwnd_last_ctrl != NULL)?
+ d->hwnd_last_ctrl :
+ HWND_TOP),
+ r_inp.left, r_inp.top,
+ r_inp.right - r_inp.left,
+ r_inp.bottom - r_inp.top,
+ SWP_DEFERERASE | SWP_NOACTIVATE |
+ SWP_NOOWNERZORDER);
+ if (hf)
+ SendMessage(row->input, WM_SETFONT,
+ (WPARAM) hf,
+ TRUE);
+ d->hwnd_last_ctrl = row->input;
+ }
+ }
+ break;
+
+ case WMNC_IDENTITY_CHANGE:
+ break;
+ }
+ return TRUE;
+
case WM_COMMAND:
if (LOWORD(wParam) == IDOK) {
wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
- khm_int32 rv = KHM_ERROR_SUCCESS;
+ wchar_t err_msg[1024];
khm_handle ident = NULL;
khm_handle csp_ident = NULL;
- khm_size i;
- wchar_t err_msg[512] = L"";
-
- GetDlgItemText(hwnd, IDC_CFG_IDNAME, idname,
- ARRAYLENGTH(idname));
-
- idname[ARRAYLENGTH(idname) - 1] = L'\0';
- if (KHM_FAILED(rv = kcdb_identpro_validate_name(idname)) &&
- rv != KHM_ERROR_NO_PROVIDER &&
- rv != KHM_ERROR_NOT_IMPLEMENTED) {
- /* the supplied name was invalid or something */
-
- wchar_t fmt[256];
+ khm_size cb;
+ khm_int32 rv = KHM_ERROR_SUCCESS;
- LoadString(khm_hInstance, IDS_CFG_IDNAME_INV,
- fmt, ARRAYLENGTH(fmt));
- StringCbPrintf(err_msg, sizeof(err_msg), fmt, idname);
+ d = (add_ident_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
- goto show_failure;
- }
+ if (!d || !d->nc)
+ break;
- /* now check if this is actually a new identity */
- for (i=0; i < cfg_idents.n_idents; i++) {
- if (!kcdb_identpro_compare_name(cfg_idents.idents[i].idname,
- idname))
- break;
- }
+ /* check if there was an identity selected */
+ if (d->nc->n_identities == 0 ||
+ d->nc->identities[0] == NULL) {
- if (i < cfg_idents.n_idents) {
- wchar_t fmt[256];
+ StringCbCopy(idname, sizeof(idname), L"");
- LoadString(khm_hInstance, IDS_CFG_IDNAME_EXT,
- fmt, ARRAYLENGTH(fmt));
- StringCbPrintf(err_msg, sizeof(err_msg), fmt, idname);
+ LoadString(khm_hInstance, IDS_CFG_IDNAME_NON,
+ err_msg, ARRAYLENGTH(err_msg));
goto show_failure;
}
- /* ok. now we are all set to add the new identity */
- if (KHM_FAILED(rv = kcdb_identity_create(idname,
- KCDB_IDENT_FLAG_CREATE,
- &ident))) {
- /* oops */
- wchar_t fmt[256];
-
- LoadString(khm_hInstance, IDS_CFG_IDNAME_CCR,
- fmt, ARRAYLENGTH(fmt));
- StringCbPrintf(err_msg, sizeof(err_msg), fmt, rv);
+ ident = d->nc->identities[0];
+ kcdb_identity_hold(ident);
- goto show_failure;
- }
+ cb = sizeof(idname);
+ kcdb_identity_get_name(ident, idname, &cb);
/* now we have to create the identity configuration. */
if (KHM_FAILED(rv = kcdb_identity_get_config(ident,
@@ -804,6 +996,11 @@ khm_cfg_add_ident_proc(HWND hwnd,
goto show_failure;
}
+ /* create a value so that the configuration space will
+ actually be created in the registry. We don't want
+ this new identity to be sticky. */
+ khc_write_int32(csp_ident, L"Sticky", 0);
+
khm_refresh_config();
kcdb_identity_release(ident);
@@ -833,6 +1030,14 @@ khm_cfg_add_ident_proc(HWND hwnd,
} else if (LOWORD(wParam) == IDCANCEL) {
EndDialog(hwnd, 1);
+ } else {
+ d = (add_ident_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ if (d && d->nc && d->nc->ident_cb) {
+ return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG,
+ hwnd, umsg, wParam, lParam);
+ }
}
break;
}
@@ -1023,6 +1228,7 @@ find_ident_by_node(khui_config_node node) {
khm_size cb;
wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
int i;
+ khm_handle ident = NULL;
cb = sizeof(idname);
khui_cfg_get_name(node, idname, &cb);
@@ -1034,8 +1240,56 @@ find_ident_by_node(khui_config_node node) {
if (i < (int)cfg_idents.n_idents)
return &cfg_idents.idents[i];
- else
+
+ /* there is no identity data for this configuration node. We try
+ to create it. */
+ if (KHM_FAILED(kcdb_identity_create(idname, 0, &ident)))
return NULL;
+
+ if (cfg_idents.n_idents >= cfg_idents.nc_idents) {
+ cfg_idents.nc_idents = UBOUNDSS(cfg_idents.n_idents + 1,
+ IDENTS_DATA_ALLOC_INCR,
+ IDENTS_DATA_ALLOC_INCR);
+#ifdef DEBUG
+ assert(cfg_idents.nc_idents > cfg_idents.n_idents);
+#endif
+ cfg_idents.idents = PREALLOC(cfg_idents.idents,
+ sizeof(*cfg_idents.idents) *
+ cfg_idents.nc_idents);
+#ifdef DEBUG
+ assert(cfg_idents.idents);
+#endif
+ ZeroMemory(&(cfg_idents.idents[cfg_idents.n_idents]),
+ sizeof(*cfg_idents.idents) *
+ (cfg_idents.nc_idents - cfg_idents.n_idents));
+ }
+
+ i = (int) cfg_idents.n_idents;
+
+ StringCbLength(idname, 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, idname);
+
+ 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]);
+
+ cfg_idents.n_idents++;
+
+ /* leave ident held. */
+
+ return &cfg_idents.idents[i];
}
static void
@@ -1191,13 +1445,17 @@ khm_cfg_id_tab_proc(HWND hwnd,
case KHUI_WM_CFG_NOTIFY:
{
ident_data * d;
+ BOOL * cont;
khui_cfg_get_dialog_data(hwnd, &idata, NULL);
switch (HIWORD(wParam)) {
case WMCFG_APPLY:
+ cont = (BOOL *) lParam;
d = find_ident_by_node(idata->ctx_node);
write_params_ident(d);
+ if (d->removed && cont)
+ *cont = FALSE;
khui_cfg_set_flags_inst(idata, KHUI_CNFLAG_APPLIED,
KHUI_CNFLAG_APPLIED |
KHUI_CNFLAG_MODIFIED);
diff --git a/src/windows/identity/ui/configwnd.c b/src/windows/identity/ui/configwnd.c
index 24f9a619c..660c1fae8 100644
--- a/src/windows/identity/ui/configwnd.c
+++ b/src/windows/identity/ui/configwnd.c
@@ -423,6 +423,209 @@ cfgui_apply_settings(khui_config_node node) {
}
static void
+cfgui_remove_item(HWND hwtv,
+ HTREEITEM hItem) {
+ khui_config_node node;
+ HTREEITEM hChild;
+ TVITEMEX itemex;
+
+ for (hChild = TreeView_GetChild(hwtv, hItem);
+ hChild;
+ hChild = TreeView_GetChild(hwtv, hItem)) {
+
+ cfgui_remove_item(hwtv, hChild);
+
+ }
+
+ ZeroMemory(&itemex, sizeof(itemex));
+
+ itemex.mask = TVIF_PARAM;
+ itemex.hItem = hItem;
+
+ TreeView_GetChild(hwtv, &itemex);
+
+ node = (khui_config_node) itemex.lParam;
+
+ if (node) {
+ HWND hw;
+ hw = khui_cfg_get_hwnd(node);
+
+ if (hw)
+ DestroyWindow(hw);
+
+ khui_cfg_release(node);
+ }
+
+ TreeView_DeleteItem(hwtv, hItem);
+}
+
+struct cfgui_child_info {
+ HTREEITEM hItem;
+ khui_config_node node;
+ BOOL checked;
+};
+
+#define CI_ALLOC_INCR 8
+
+static void
+cfgui_sync_node(cfgui_wnd_data * d,
+ HWND hwtv,
+ khui_config_node c,
+ HTREEITEM hItem) {
+ khui_config_node child;
+ HTREEITEM hChild;
+ struct cfgui_child_info * childinfo = NULL;
+ khm_size n_childinfo = 0;
+ khm_size nc_childinfo = 0;
+ khm_size i;
+
+ /* first, get the list of children from the treeview control */
+ for (hChild = TreeView_GetChild(hwtv, hItem);
+ hChild;
+ hChild = TreeView_GetNextSibling(hwtv, hChild)) {
+
+ if (n_childinfo >= nc_childinfo) {
+ nc_childinfo = UBOUNDSS(n_childinfo + 1,
+ CI_ALLOC_INCR, CI_ALLOC_INCR);
+#ifdef DEBUG
+ assert(nc_childinfo > n_childinfo);
+#endif
+ childinfo = PREALLOC(childinfo,
+ sizeof(*childinfo) * nc_childinfo);
+#ifdef DEBUG
+ assert(childinfo);
+#endif
+ }
+
+ ZeroMemory(&childinfo[n_childinfo],
+ sizeof(childinfo[n_childinfo]));
+
+ childinfo[n_childinfo].hItem = hChild;
+ childinfo[n_childinfo].checked = FALSE;
+ n_childinfo++;
+ }
+
+ /* now, go through the list of actual nodes and make sure they
+ match up */
+ child = NULL;
+ for (khui_cfg_get_first_child(c, &child);
+ child;
+ khui_cfg_get_next_release(&child)) {
+
+ hChild = (HTREEITEM) khui_cfg_get_param(child);
+
+ for (i=0; i < n_childinfo; i++) {
+ if (childinfo[i].hItem == hChild)
+ break;
+ }
+
+ if (i < n_childinfo) {
+ childinfo[i].checked = TRUE;
+ } else {
+ /* add it to the list, so we can create the node in the
+ tree view control later. */
+ if (n_childinfo >= nc_childinfo) {
+ nc_childinfo = UBOUNDSS(n_childinfo + 1,
+ CI_ALLOC_INCR, CI_ALLOC_INCR);
+#ifdef DEBUG
+ assert(nc_childinfo > n_childinfo);
+#endif
+ childinfo = PREALLOC(childinfo,
+ sizeof(*childinfo) * nc_childinfo);
+#ifdef DEBUG
+ assert(childinfo);
+#endif
+ }
+
+ ZeroMemory(&childinfo[n_childinfo],
+ sizeof(childinfo[n_childinfo]));
+
+ childinfo[n_childinfo].node = child;
+ khui_cfg_hold(child);
+ n_childinfo++;
+ }
+ }
+
+ /* by this point, the childinfo list contains items of the
+ following forms:
+
+ 1. childinfo[i].hItem != NULL && childinfo[i].checked == TRUE
+
+ Corresponds to a tree view item that has a matching
+ configuration node. Nothing to do here.
+
+ 2. childinfo[i].hItem != NULL && childinfo[i].checked == FALSE
+
+ Corresponds to a tree view item that has no matching
+ configuration node. These should be removed.
+
+ 3. childinfo[i].hItem == NULL && childinfo[i].node != NULL
+
+ Corresponds to a configuration node that has no matching
+ tree view item. These nodes should be added.
+ */
+
+ /* first do the removals */
+ for (i=0; i < n_childinfo; i++) {
+ if (childinfo[i].hItem == NULL)
+ break; /* nothing more to see from this point
+ on */
+ if (!childinfo[i].checked) {
+ /* remove! */
+ cfgui_remove_item(hwtv, childinfo[i].hItem);
+ }
+ }
+
+ /* continue from where the previous loop left off */
+ for (; i < n_childinfo; i++) {
+#ifdef DEBUG
+ assert(childinfo[i].hItem == NULL);
+ assert(childinfo[i].node != NULL);
+#endif
+
+ cfgui_add_node(d, hwtv, childinfo[i].node, c, FALSE);
+
+ khui_cfg_release(childinfo[i].node);
+ childinfo[i].node = NULL;
+ }
+
+ if (childinfo)
+ PFREE(childinfo);
+
+ /* finally recurse through to the next level */
+ for (hChild = TreeView_GetChild(hwtv, hItem);
+ hChild;
+ hChild = TreeView_GetNextSibling(hwtv, hChild)) {
+
+ TVITEMEX itemex;
+
+ ZeroMemory(&itemex, sizeof(itemex));
+
+ itemex.mask = TVIF_PARAM;
+ itemex.hItem = hChild;
+
+ TreeView_GetItem(hwtv, &itemex);
+
+ if (itemex.lParam) {
+ child = (khui_config_node) itemex.lParam;
+
+ cfgui_sync_node(d, hwtv, child, hChild);
+ }
+ }
+}
+
+static void
+cfgui_sync_node_list(cfgui_wnd_data * d, HWND hwnd) {
+ HWND hwtv;
+ HTREEITEM hItem;
+
+ hwtv = GetDlgItem(hwnd, IDC_CFG_NODELIST);
+ hItem = TreeView_GetRoot(hwtv);
+
+ cfgui_sync_node(d, hwtv, NULL, hItem);
+}
+
+static void
cfgui_update_state(HWND hwnd,
khm_int32 flags,
khui_config_node node) {
@@ -670,7 +873,8 @@ cfgui_dlgproc(HWND hwnd,
break;
case WMCFG_SYNC_NODE_LIST:
- /*TODO: synchronize the node lists here */
+ d = cfgui_get_wnd_data(hwnd);
+ cfgui_sync_node_list(d, hwnd);
break;
}
@@ -825,6 +1029,9 @@ void khm_refresh_config(void) {
khui_cfg_remove(cfg_iter);
}
+
+ if (tident)
+ kcdb_identity_release(tident);
}
/* Now iterate through the root level configuration nodes and make
diff --git a/src/windows/identity/ui/credfuncs.c b/src/windows/identity/ui/credfuncs.c
index d695afead..530ef0852 100644
--- a/src/windows/identity/ui/credfuncs.c
+++ b/src/windows/identity/ui/credfuncs.c
@@ -267,8 +267,9 @@ kmsg_cred_completion(kmq_message *m)
kcdb_credset_get_size(tcs, &count);
kcdb_credset_delete(tcs);
- if (count == 0)
- break;
+ if (count == 0) {
+ goto done_with_op;
+ }
}
ctx = kherr_peek_context();
@@ -348,6 +349,8 @@ kmsg_cred_completion(kmq_message *m)
kherr_clear_error();
}
+ done_with_op:
+
if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0,
m->vparam);
@@ -994,11 +997,23 @@ khm_cred_process_startup_actions(void) {
}
if (khm_startup.autoinit) {
- khm_size count;
+ khm_size count = 0;
+ khm_handle credset = NULL;
+ khm_int32 ctype_ident = KCDB_CREDTYPE_INVALID;
+ khm_int32 delta = 0;
khm_startup.autoinit = FALSE;
- kcdb_credset_get_size(NULL, &count);
+ kcdb_credset_create(&credset);
+ kcdb_identity_get_type(&ctype_ident);
+
+ kcdb_credset_collect(credset, NULL,
+ defident, ctype_ident,
+ &delta);
+
+ kcdb_credset_get_size(credset, &count);
+
+ kcdb_credset_delete(credset);
if (count == 0) {
if (defident)
diff --git a/src/windows/identity/ui/htwnd.c b/src/windows/identity/ui/htwnd.c
index f65525690..afb68aa02 100644
--- a/src/windows/identity/ui/htwnd.c
+++ b/src/windows/identity/ui/htwnd.c
@@ -806,7 +806,8 @@ static LRESULT htw_paint(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
EndPaint(hwnd, &ps);
- if (d->ext_width < ext_width) {
+ if (d->ext_width < ext_width ||
+ d->ext_height < ext_height) {
SCROLLINFO si;
LONG l;
diff --git a/src/windows/identity/ui/lang/en_us/khapp.rc b/src/windows/identity/ui/lang/en_us/khapp.rc
index eb84b8f1e..48f577684 100644
--- a/src/windows/identity/ui/lang/en_us/khapp.rc
+++ b/src/windows/identity/ui/lang/en_us/khapp.rc
@@ -370,9 +370,9 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
GROUPBOX "Font for credentials display",IDC_STATIC,7,7,241,137
LTEXT "&Font name",IDC_STATIC,17,22,35,8
- COMBOBOX IDC_CFG_FONTS,62,20,178,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CFG_FONTS,62,20,178,51,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "&Size",IDC_STATIC,62,43,14,8
- COMBOBOX IDC_CFG_SIZE,87,41,48,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_CFG_SIZE,87,41,48,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
CONTROL "&Bold",IDC_CFG_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,42,29,10
CONTROL "&Italics",IDC_CFG_ITALICS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,42,35,10
EDITTEXT IDC_CFG_SAMPLE_NORMAL,62,66,178,21,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_STATICEDGE
@@ -380,15 +380,19 @@ BEGIN
PUSHBUTTON "&Revert to default",IDC_CFG_REVERT,168,122,72,14
END
-IDD_CFG_ADDIDENT DIALOGEX 0, 0, 325, 70
+IDD_CFG_ADDIDENT DIALOGEX 0, 0, 279, 95
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add new identity"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- LTEXT "&Identity name",IDC_STATIC,7,10,46,8
- EDITTEXT IDC_CFG_IDNAME,67,7,195,14,ES_AUTOHSCROLL
- DEFPUSHBUTTON "OK",IDOK,268,7,50,14
- PUSHBUTTON "Cancel",IDCANCEL,268,24,50,14
+ LTEXT "&Identity name",IDC_SM_LBL,7,10,46,8,NOT WS_VISIBLE
+ EDITTEXT IDC_SM_CTL,67,7,205,14,ES_AUTOHSCROLL | NOT WS_VISIBLE
+ DEFPUSHBUTTON "OK",IDOK,145,74,71,14
+ PUSHBUTTON "Cancel",IDCANCEL,222,74,50,14
+ LTEXT "&Identity name",IDC_MED_LBL,7,27,130,8,NOT WS_VISIBLE
+ EDITTEXT IDC_MED_CTL,141,24,131,14,ES_AUTOHSCROLL | NOT WS_VISIBLE
+ LTEXT "&Identity name",IDC_LG_LBL,7,41,265,8,NOT WS_VISIBLE
+ EDITTEXT IDC_LG_CTL,141,50,131,14,ES_AUTOHSCROLL | NOT WS_VISIBLE
END
@@ -531,9 +535,9 @@ BEGIN
IDD_CFG_ADDIDENT, DIALOG
BEGIN
LEFTMARGIN, 7
- RIGHTMARGIN, 318
+ RIGHTMARGIN, 272
TOPMARGIN, 7
- BOTTOMMARGIN, 63
+ BOTTOMMARGIN, 88
END
END
#endif // APSTUDIO_INVOKED
@@ -777,6 +781,7 @@ END
STRINGTABLE
BEGIN
IDS_NC_REN_FAILED_TITLE_I "Failed to renew creds for %s"
+ IDS_CFG_IDNAME_NON "No identity selected. Please select an identity and try again."
END
#endif // English (U.S.) resources
diff --git a/src/windows/identity/ui/newcredwnd.c b/src/windows/identity/ui/newcredwnd.c
index f5b302ec0..a52d09b41 100644
--- a/src/windows/identity/ui/newcredwnd.c
+++ b/src/windows/identity/ui/newcredwnd.c
@@ -522,7 +522,8 @@ nc_update_credtext(khui_nc_wnd_data * d)
}
if (!(d->nc->response & KHUI_NC_RESPONSE_PROCESSING)) {
- if(validId || d->nc->subtype == KMSG_CRED_PASSWORD) {
+ if(validId ||
+ d->nc->subtype == KMSG_CRED_PASSWORD) {
/* TODO: check if all the required fields have valid values
before enabling the Ok button */
okEnable = TRUE;
@@ -876,9 +877,8 @@ nc_add_control_row(khui_nc_wnd_data * d,
SetRectEmpty(&r_input);
#ifdef DEBUG
assert(FALSE);
-#else
- return;
#endif
+ return;
}
if (label)
diff --git a/src/windows/identity/ui/notifier.c b/src/windows/identity/ui/notifier.c
index 12b746b1f..9804abfae 100644
--- a/src/windows/identity/ui/notifier.c
+++ b/src/windows/identity/ui/notifier.c
@@ -305,6 +305,7 @@ notifier_wnd_proc(HWND hwnd,
khm_timer_fire(hwnd);
} else if (wParam == KHUI_REFRESH_TIMER_ID) {
KillTimer(hwnd, KHUI_REFRESH_TIMER_ID);
+ kcdb_identity_refresh_all();
khm_timer_refresh(hwnd);
}
}
diff --git a/src/windows/identity/ui/resource.h b/src/windows/identity/ui/resource.h
index 35b493e91..b8dc0ec04 100644
--- a/src/windows/identity/ui/resource.h
+++ b/src/windows/identity/ui/resource.h
@@ -293,6 +293,7 @@
#define IDS_NC_FAILED_TITLE_I 286
#define IDS_NC_PWD_FAILED_TITLE_I 287
#define IDS_NC_REN_FAILED_TITLE_I 288
+#define IDS_CFG_IDNAME_NON 289
#define IDC_NC_USERNAME 1007
#define IDC_NC_PASSWORD 1008
#define IDC_NC_CREDTEXT_LABEL 1009
@@ -389,7 +390,13 @@
#define IDC_CFG_ITALICS 1132
#define IDC_CFG_ADDIDENT 1133
#define IDC_CFG_IDNAME 1134
+#define IDC_SM_CTL 1134
#define IDC_CFG_SHOWLOG 1135
+#define IDC_MED_CTL 1135
+#define IDC_LG_CTL 1136
+#define IDC_SM_LBL 1137
+#define IDC_MED_LBL 1138
+#define IDC_LG_LBL 1139
#define IDA_ACTIVATE_MENU 40003
#define IDA_UP 40004
#define IDA_DOWN 40005
@@ -404,7 +411,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 212
#define _APS_NEXT_COMMAND_VALUE 40010
-#define _APS_NEXT_CONTROL_VALUE 1136
+#define _APS_NEXT_CONTROL_VALUE 1140
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/src/windows/identity/ui/timer.c b/src/windows/identity/ui/timer.c
index 40464d5ad..3adf9e9a4 100644
--- a/src/windows/identity/ui/timer.c
+++ b/src/windows/identity/ui/timer.c
@@ -92,17 +92,21 @@ khm_timer_exit(void) {
static void
tmr_fire_timer(void) {
int i;
- unsigned __int64 curtime;
- unsigned __int64 err;
- unsigned __int64 next_event;
+ khm_int64 curtime;
+ khm_int64 err;
+ khm_int64 next_event;
int tmr_count[KHUI_N_TTYPES];
- unsigned __int64 tmr_offset[KHUI_N_TTYPES];
+ khm_int64 tmr_offset[KHUI_N_TTYPES];
int t;
khm_handle eff_ident = NULL;
khui_timer_type eff_type = 0; /* meaningless */
int fire_count = 0;
FILETIME ft;
+ _begin_task(0);
+ _report_cs0(KHERR_DEBUG_1, L"Checking for expired timers");
+ _describe();
+
TimetToFileTimeInterval(KHUI_TIMEEQ_ERROR_SMALL, &ft);
err = FtToInt(&ft);
GetSystemTimeAsFileTime(&ft);
@@ -119,10 +123,16 @@ tmr_fire_timer(void) {
khui_timers[i].type != KHUI_TTYPE_ID_MARK &&
khui_timers[i].expire < curtime + err) {
+ _report_cs3(KHERR_DEBUG_1, L"Expiring timer index=%1!d!, type=%2!d!, key=%3!p!",
+ _int32(i), _int32(khui_timers[i].type),
+ _cptr(khui_timers[i].key));
+
t = khui_timers[i].type;
switch(t) {
case KHUI_TTYPE_ID_RENEW:
+ _report_cs1(KHERR_DEBUG_1, L"Renewing identity %1!p!",
+ _cptr(khui_timers[i].key));
khm_cred_renew_identity(khui_timers[i].key);
khui_timers[i].flags |= KHUI_TE_FLAG_EXPIRED;
break;
@@ -134,6 +144,8 @@ tmr_fire_timer(void) {
we assume that it is safe to trigger a renew_cred
call here without checking if there's an imminent
renew_identity call. */
+ _report_cs1(KHERR_DEBUG_1, L"Renewing credential %1!p!",
+ _cptr(khui_timers[i].key));
khm_cred_renew_cred(khui_timers[i].key);
khui_timers[i].flags |= KHUI_TE_FLAG_EXPIRED;
break;
@@ -184,7 +196,7 @@ tmr_fire_timer(void) {
wchar_t wtime[128];
wchar_t wmsg[256];
wchar_t wtitle[64];
- unsigned __int64 second;
+ khm_int64 second;
khui_alert * alert = NULL;
khm_size cb;
@@ -249,6 +261,9 @@ tmr_fire_timer(void) {
khui_alert_show(alert);
khui_alert_release(alert);
}
+
+ _end_task();
+
}
void
@@ -264,6 +279,85 @@ static int
tmr_update(khm_handle key, khui_timer_type type, __int64 expire,
__int64 offset, void * data, khm_boolean reinstate) {
int i;
+ wchar_t name[KCDB_MAXCCH_NAME];
+ wchar_t tstamp[128];
+ wchar_t *type_str = NULL;
+ SYSTEMTIME st;
+ FILETIME ft;
+ FILETIME ftl;
+ khm_size cb;
+
+ switch(type) {
+ case KHUI_TTYPE_ID_MARK:
+ type_str = L"marker";
+ break;
+
+ case KHUI_TTYPE_CRED_WARN:
+ case KHUI_TTYPE_ID_WARN:
+ type_str = L"warning";
+ break;
+
+ case KHUI_TTYPE_CRED_CRIT:
+ case KHUI_TTYPE_ID_CRIT:
+ type_str = L"critical";
+ break;
+
+ case KHUI_TTYPE_CRED_EXP:
+ case KHUI_TTYPE_ID_EXP:
+ type_str = L"expiry";
+ break;
+
+ case KHUI_TTYPE_CRED_RENEW:
+ case KHUI_TTYPE_ID_RENEW:
+ type_str = L"renew";
+ break;
+ }
+
+ ft = IntToFt(expire);
+ FileTimeToLocalFileTime(&ft, &ftl);
+ FileTimeToSystemTime(&ftl, &st);
+ StringCbPrintf(tstamp, sizeof(tstamp),
+ L"%d-%d-%d %d:%d:%d",
+ st.wYear, st.wMonth, st.wDay,
+ st.wHour, st.wMinute, st.wSecond);
+
+ cb = sizeof(name); name[0] = L'\0';
+ if (type_str == NULL) {
+
+ _report_cs2(KHERR_DEBUG_1,
+ L"Updating uknown timer of type %1!d! exp(%2!s!)",
+ _int32(type),
+ _cstr(tstamp));
+ _resolve();
+
+ } else if (type == KHUI_TTYPE_ID_MARK ||
+ type == KHUI_TTYPE_ID_WARN ||
+ type == KHUI_TTYPE_ID_CRIT ||
+ type == KHUI_TTYPE_ID_EXP ||
+ type == KHUI_TTYPE_ID_RENEW) {
+
+ kcdb_identity_get_name(key, name, &cb);
+ _report_cs3(KHERR_DEBUG_1,
+ L"Updating identity %1!s! timer for %2!s! exp(%3!s!)",
+ _cstr(type_str),
+ _cstr(name),
+ _cstr(tstamp));
+ _resolve();
+
+ } else if (type == KHUI_TTYPE_CRED_RENEW ||
+ type == KHUI_TTYPE_CRED_WARN ||
+ type == KHUI_TTYPE_CRED_CRIT ||
+ type == KHUI_TTYPE_CRED_EXP) {
+
+ kcdb_cred_get_name(key, name, &cb);
+ _report_cs3(KHERR_DEBUG_1,
+ L"Updating credential %1!s! timer for %2!s! exp(%3!s!)",
+ _cstr(type_str),
+ _cstr(name),
+ _cstr(tstamp));
+ _resolve();
+
+ }
for (i=0; i < (int) khui_n_timers; i++) {
if (khui_timers[i].key == key &&
@@ -385,7 +479,7 @@ tmr_next_halflife_timeout(int idx, FILETIME * issue, FILETIME * expire) {
not expired. However, we leave it to the caller to update the
actual timer and mark it as not stale. */
if (idx >= 0 &&
- khui_timers[idx].expire < (khm_ui_8) iret) {
+ khui_timers[idx].expire < iret) {
khui_timers[idx].flags &= ~KHUI_TE_FLAG_EXPIRED;
khui_timers[idx].expire = iret;
@@ -394,7 +488,8 @@ tmr_next_halflife_timeout(int idx, FILETIME * issue, FILETIME * expire) {
return ret;
}
-/* called with cs_timers held */
+/* called with cs_timers held. Called once for each credential in the
+ root credentials set. */
static khm_int32 KHMAPI
tmr_cred_apply_proc(khm_handle cred, void * rock) {
khm_handle ident = NULL;
@@ -410,40 +505,56 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
FILETIME fte;
FILETIME ft_reinst;
khm_size cb;
+ wchar_t wname[KCDB_MAXCCH_NAME];
+
+ cb = sizeof(wname);
+ wname[0] = L'\0';
+ kcdb_cred_get_name(cred, wname, &cb);
+
+ _report_cs1(KHERR_DEBUG_1, L"Looking at cred [%1!s!]",
+ _cstr(wname));
+ _resolve();
kcdb_cred_get_identity(cred, &ident);
#ifdef DEBUG
assert(ident);
#endif
- /* now get the expiry */
+ /* now get the expiry for the identity*/
cb = sizeof(ft_expiry);
if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE,
NULL,
&ft_expiry, &cb))) {
+
+ /* failing which, we get the expiry for this credential */
cb = sizeof(ft_expiry);
if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE,
NULL,
&ft_expiry, &cb))) {
/* we don't have an expiry time to work with */
+ _report_cs1(KHERR_DEBUG_1, L"Skipping cred [%1!s!]. No expiry time",
+ _cstr(wname));
+ _resolve();
+
kcdb_identity_release(ident);
return KHM_ERROR_SUCCESS;
+ } else {
+ /* and the time of issue */
+ cb = sizeof(ft_issue);
+ if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,
+ NULL, &ft_issue, &cb)))
+ ZeroMemory(&ft_issue, sizeof(ft_issue));
}
- }
- cb = sizeof(ft_issue);
- if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE,
- NULL,
- &ft_issue, &cb))) {
+ } else {
+ /* also try to get the time of issue. */
cb = sizeof(ft_issue);
- if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,
- NULL,
- &ft_issue, &cb))) {
- /* we don't really abandon the timer. In this case, we
- fall back to using the threshold value to set the
- expiry timer. */
+ if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE,
+ NULL, &ft_issue, &cb)))
+ /* if we fail, we just zero out the time of issue and
+ failover to using the threshold value to set the expiry
+ timer instead of the half life algorithm. */
ZeroMemory(&ft_issue, sizeof(ft_issue));
- }
}
/* and the current time */
@@ -540,7 +651,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
prev =
tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0);
- if (do_halflife)
+ if (do_halflife && (ft_issue.dwLowDateTime != 0 ||
+ ft_issue.dwHighDateTime != 0))
fte = tmr_next_halflife_timeout(prev, &ft_issue, &ft_expiry);
else
fte = FtSub(&ft_expiry, &ft);
@@ -613,15 +725,22 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE,
NULL,
&ft_cred_expiry,
- &cb)))
+ &cb))) {
+ _report_cs1(KHERR_DEBUG_1, L"Skipping cred [%1!s!]. Can't lookup cred expiry",
+ _cstr(wname));
+ _resolve();
goto _cleanup;
+ }
cb = sizeof(ft_cred_issue);
if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,
NULL,
&ft_cred_issue,
- &cb)))
- goto _cleanup;
+ &cb))) {
+
+ ZeroMemory(&ft_cred_issue, sizeof(ft_cred_issue));
+
+ }
TimetToFileTimeInterval(KHUI_TIMEEQ_ERROR, &ft);
@@ -636,8 +755,14 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
ft_delta = FtSub(&ft_expiry, &ft_cred_expiry);
if (CompareFileTime(&ft_cred_expiry, &ft_expiry) >= 0 ||
- CompareFileTime(&ft_delta, &ft) < 0)
+ CompareFileTime(&ft_delta, &ft) < 0) {
+
+ _report_cs1(KHERR_DEBUG_1,
+ L"Skipping credential [%1!s!]. The expiry time is too close to the identity expiry.",
+ _cstr(wname));
+ _resolve();
goto _cleanup;
+ }
}
if ((idx = tmr_find(ident, KHUI_TTYPE_ID_WARN, 0, 0)) >= 0 &&
@@ -669,8 +794,34 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
if ((idx = tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0)) >= 0 &&
!(khui_timers[idx].flags & KHUI_TE_FLAG_STALE)) {
- //fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset);
- fte = tmr_next_halflife_timeout(idx, &ft_cred_issue, &ft_cred_expiry);
+ int cidx = tmr_find(cred, KHUI_TTYPE_CRED_RENEW, 0, 0);
+
+ if (ft_cred_issue.dwLowDateTime == 0 &&
+ ft_cred_issue.dwHighDateTime == 0) {
+ fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset);
+ /* a special case, for a credential whose remaining
+ lifetime is less than the offset, we try half life on
+ the current time and the expiry. */
+ if (CompareFileTime(&fte, &ft_current) <= 0 &&
+ CompareFileTime(&ft_current, &ft_expiry) < 0) {
+ fte = tmr_next_halflife_timeout(cidx, &ft_current, &ft_cred_expiry);
+#if 0
+ /* now, if we already have a renew timer for this
+ credential that hasn't expired yet and that is set
+ for earlier than fte, we let it be. */
+ if (cidx >= 0 &&
+ khui_timers[cidx].expire < FtToInt(&fte) &&
+ khui_timers[cidx].expire > FtToInt(&ft_current) &&
+ !(khui_timers[cidx].flags & KHUI_TE_FLAG_EXPIRED)) {
+
+ fte = IntToFt(khui_timers[cidx].expire);
+
+ }
+#endif
+ }
+ } else {
+ fte = tmr_next_halflife_timeout(cidx, &ft_cred_issue, &ft_cred_expiry);
+ }
if (CompareFileTime(&fte, &ft_current) > 0) {
tmr_update(cred, KHUI_TTYPE_CRED_RENEW,
@@ -754,13 +905,18 @@ tmr_purge(void) {
khui_n_timers = j;
}
-/* go through all the credentials and set timers as appropriate. */
+/* go through all the credentials and set timers as appropriate. hwnd
+ is the window that will receive the timer events.*/
void
khm_timer_refresh(HWND hwnd) {
int i;
- unsigned __int64 next_event = 0;
- unsigned __int64 curtime;
- unsigned __int64 diff;
+ khm_int64 next_event = 0;
+ khm_int64 curtime;
+ khm_int64 diff;
+
+ _begin_task(0);
+ _report_cs0(KHERR_DEBUG_1, L"Refreshing timers");
+ _describe();
EnterCriticalSection(&cs_timers);
@@ -788,12 +944,18 @@ khm_timer_refresh(HWND hwnd) {
#endif
}
+ _report_cs1(KHERR_DEBUG_1, L"Starting with %1!d! timers",
+ _int32(khui_n_timers));
+
kcdb_credset_apply(NULL,
tmr_cred_apply_proc,
NULL);
tmr_purge();
+ _report_cs1(KHERR_DEBUG_1, L"Leaving with %1!d! timers",
+ _int32(khui_n_timers));
+
_check_next_event:
/* Before we return, we should check if any timers are set to
@@ -805,9 +967,11 @@ khm_timer_refresh(HWND hwnd) {
if (!(khui_timers[i].flags & KHUI_TE_FLAG_EXPIRED) &&
khui_timers[i].type != KHUI_TTYPE_ID_MARK &&
(next_event == 0 ||
- next_event > khui_timers[i].expire))
+ next_event > khui_timers[i].expire)) {
next_event = khui_timers[i].expire;
+
+ }
}
if (next_event != 0) {
@@ -833,4 +997,6 @@ khm_timer_refresh(HWND hwnd) {
}
LeaveCriticalSection(&cs_timers);
+
+ _end_task();
}
diff --git a/src/windows/identity/ui/timer.h b/src/windows/identity/ui/timer.h
index 081d27852..130ae999a 100644
--- a/src/windows/identity/ui/timer.h
+++ b/src/windows/identity/ui/timer.h
@@ -58,9 +58,9 @@ typedef struct tag_khui_timer_event {
khm_handle key;
khui_timer_type type;
- unsigned __int64 expire; /* time at which the timer expires */
- unsigned __int64 offset; /* time offset at which the event that
- the timer warns of happens */
+ khm_int64 expire; /* time at which the timer expires */
+ khm_int64 offset; /* time offset at which the event that the
+ timer warns of happens */
void * data;
khm_int32 flags;
} khui_timer_event;
diff --git a/src/windows/identity/uilib/configui.c b/src/windows/identity/uilib/configui.c
index 79e570820..c8c61f5cb 100644
--- a/src/windows/identity/uilib/configui.c
+++ b/src/windows/identity/uilib/configui.c
@@ -349,7 +349,9 @@ khui_cfg_get_first_child(khui_config_node vparent,
if (parent) {
for(c = TFIRSTCHILD(parent);
- c && (c->reg.flags & KHUI_CNFLAG_SUBPANEL);
+ c &&
+ ((c->reg.flags & KHUI_CNFLAG_SUBPANEL) ||
+ (c->flags & KHUI_CN_FLAG_DELETED));
c = LNEXT(c));
} else {
c = NULL;
@@ -390,7 +392,9 @@ khui_cfg_get_first_subpanel(khui_config_node vparent,
if (parent) {
for(c = TFIRSTCHILD(parent);
- c && !(c->reg.flags & KHUI_CNFLAG_SUBPANEL);
+ c &&
+ (!(c->reg.flags & KHUI_CNFLAG_SUBPANEL) ||
+ (c->flags & KHUI_CN_FLAG_DELETED));
c = LNEXT(c));
} else {
c = NULL;
@@ -458,8 +462,9 @@ khui_cfg_get_next_release(khui_config_node * pvnode) {
node = cfgui_node_i_from_handle(*pvnode);
for(nxt_node = LNEXT(node);
nxt_node &&
- ((node->reg.flags ^ nxt_node->reg.flags) &
- KHUI_CNFLAG_SUBPANEL);
+ (((node->reg.flags ^ nxt_node->reg.flags) &
+ KHUI_CNFLAG_SUBPANEL) ||
+ (nxt_node->flags & KHUI_CN_FLAG_DELETED));
nxt_node = LNEXT(nxt_node));
if (nxt_node)
cfgui_hold_node(nxt_node);
diff --git a/src/windows/identity/uilib/creddlg.c b/src/windows/identity/uilib/creddlg.c
index 84d6e17ed..1d36d3c5b 100644
--- a/src/windows/identity/uilib/creddlg.c
+++ b/src/windows/identity/uilib/creddlg.c
@@ -57,6 +57,8 @@ khui_cw_create_cred_blob(khui_new_creds ** ppnc)
c->result = KHUI_NC_RESULT_CANCEL;
c->mode = KHUI_NC_MODE_MINI;
+ khui_context_create(&c->ctx, KHUI_SCOPE_NONE, NULL, KCDB_CREDTYPE_INVALID, NULL);
+
*ppnc = c;
return KHM_ERROR_SUCCESS;
diff --git a/src/windows/identity/uilib/khprops.h b/src/windows/identity/uilib/khprops.h
index fc5629dc9..c0977b80c 100644
--- a/src/windows/identity/uilib/khprops.h
+++ b/src/windows/identity/uilib/khprops.h
@@ -27,6 +27,8 @@
#ifndef __KHIMAIRA_KHPROPS_H
#define __KHIMAIRA_KHPROPS_H
+#include<prsht.h>
+
/*********************************************************************
Property sheets
**********************************************************************/