summaryrefslogtreecommitdiffstats
path: root/src/windows
diff options
context:
space:
mode:
authorKevin Wasserman <kevin.wasserman@painless-security.com>2012-07-23 04:30:27 -0400
committerBen Kaduk <kaduk@mit.edu>2012-08-24 12:22:58 -0400
commit9bc411e72fce5bed3ed00ae5b09f8c239309bae0 (patch)
tree0b457e8c5e0d1201f2bc4a58e2540ca3eba44ca4 /src/windows
parentdbfd93ea15b12472e4612af928f8baabb2cda611 (diff)
downloadkrb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.tar.gz
krb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.tar.xz
krb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.zip
kfw support for multiple identities
We need a sense of what the default identity is, then, with a way to set it and list it. The memory management model changes some, as well. Use a bold font to indicate the current default identity in the GUI; while here use an italic font for expired credentials. In the process, rip out some krb4 remenants, and remove ancient code conditional on the lack of KRB5_TC_NOTICKET. Define USE_MESSAGE_BOX when building leash and use MessageBox(). [kaduk@mit.edu: adjust for style, flesh out commit message.] ticket: 7253 (new) queue: kfw target_version: 1.10.4 tags: pullup
Diffstat (limited to 'src/windows')
-rw-r--r--src/windows/include/leashwin.h30
-rw-r--r--src/windows/leash/KrbListTickets.cpp393
-rw-r--r--src/windows/leash/Leash.cpp153
-rw-r--r--src/windows/leash/Leash.h3
-rw-r--r--src/windows/leash/Leash.rc4
-rw-r--r--src/windows/leash/LeashView.cpp1432
-rw-r--r--src/windows/leash/LeashView.h65
-rw-r--r--src/windows/leash/Lglobals.h43
-rw-r--r--src/windows/leash/Makefile.in5
-rw-r--r--src/windows/leash/res/ribbon1.mfcribbon-ms2
-rw-r--r--src/windows/leash/resource.h2
-rw-r--r--src/windows/leashdll/AFSroutines.c3
-rw-r--r--src/windows/leashdll/krb5routines.c790
-rw-r--r--src/windows/leashdll/leash-int.h4
-rw-r--r--src/windows/leashdll/leashdll.h15
-rw-r--r--src/windows/leashdll/leashw32.def1
-rw-r--r--src/windows/leashdll/lshfunc.c45
17 files changed, 1658 insertions, 1332 deletions
diff --git a/src/windows/include/leashwin.h b/src/windows/include/leashwin.h
index 6a26c43f93..39a7d1a45f 100644
--- a/src/windows/include/leashwin.h
+++ b/src/windows/include/leashwin.h
@@ -103,15 +103,29 @@ typedef struct {
2 * NETID_CCACHE_NAME_SZ))
#endif /* NETIDMGR */
-typedef struct {
- char principal[MAX_K_NAME_SZ]; /* Principal name/instance/realm */
+typedef struct TicketList TicketList;
+struct TicketList {
+ TicketList *next;
+ char *service;
+ char *encTypes;
+ krb5_timestamp issued;
+ krb5_timestamp valid_until;
+ krb5_timestamp renew_until;
+ unsigned long flags;
+};
+
+typedef struct TICKETINFO TICKETINFO;
+struct TICKETINFO {
+ TICKETINFO *next;
+ char *principal; /* Principal name/instance@realm */
+ char *ccache_name;
+ TicketList *ticket_list;
int btickets; /* Do we have tickets? */
- long lifetime; /* Lifetime -- needs to have
- room for 255 5-minute
- periods * 5 * 60 */
- long issue_date; /* The issue time */
- long renew_till; /* The Renew time (k5 only) */
-} TICKETINFO;
+ long issued; /* The issue time */
+ long valid_until; /* */
+ long renew_until; /* The Renew time (k5 only) */
+ unsigned long flags;
+};
int FAR Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo);
int FAR Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfoex);
diff --git a/src/windows/leash/KrbListTickets.cpp b/src/windows/leash/KrbListTickets.cpp
new file mode 100644
index 0000000000..71a4c635cc
--- /dev/null
+++ b/src/windows/leash/KrbListTickets.cpp
@@ -0,0 +1,393 @@
+#include "stdafx.h"
+#include "lglobals.h"
+#include "krb5.h"
+
+static void
+FreeTicketList(TicketList** ticketList)
+{
+ TicketList* tempList = *ticketList, *killList;
+
+ while (tempList) {
+ killList = tempList;
+ tempList = tempList->next;
+ free(killList->service);
+ if (killList->encTypes)
+ free(killList->encTypes);
+ free(killList);
+ }
+
+ *ticketList = NULL;
+}
+
+void
+LeashKRB5FreeTicketInfo(TICKETINFO *ticketinfo)
+{
+ if (ticketinfo->principal) {
+ free(ticketinfo->principal);
+ ticketinfo->principal = NULL;
+ }
+ if (ticketinfo->ccache_name) {
+ free(ticketinfo->ccache_name);
+ ticketinfo->ccache_name = NULL;
+ }
+ if (ticketinfo->ticket_list)
+ FreeTicketList(&ticketinfo->ticket_list);
+}
+
+void
+LeashKRB5FreeTickets(TICKETINFO **ticketinfolist)
+{
+ TICKETINFO *ticketinfo = *ticketinfolist, *next;
+ while (ticketinfo) {
+ next = ticketinfo->next;
+ LeashKRB5FreeTicketInfo(ticketinfo);
+ free(ticketinfo);
+ ticketinfo = next;
+ }
+ *ticketinfolist = NULL;
+}
+
+/*
+ * LeashKRB5Error()
+ */
+int
+LeashKRB5Error(krb5_error_code rc, LPCSTR FailedFunctionName)
+{
+#ifdef USE_MESSAGE_BOX
+ char message[256];
+ const char *errText;
+
+ errText = perror_message(rc);
+ _snprintf(message, sizeof(message),
+ "%s\n(Kerberos error %ld)\n\n%s failed",
+ errText,
+ rc,
+ FailedFunctionName);
+ message[sizeof(message)-1] = 0;
+
+ MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
+ MB_TASKMODAL |
+ MB_SETFOREGROUND);
+#endif /* USE_MESSAGE_BOX */
+ return rc;
+}
+
+
+static char *
+etype_string(krb5_enctype enctype)
+{
+ static char buf[100];
+
+ krb5_error_code retval;
+
+ if ((retval = pkrb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf)))) {
+ /* XXX if there's an error != EINVAL, I should probably report it */
+ sprintf_s(buf, "etype %d", enctype);
+ }
+
+ return buf;
+}
+
+
+static void
+CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo)
+{
+ ticketinfo->issued = KRBv5Credentials.times.starttime;
+ ticketinfo->valid_until = KRBv5Credentials.times.endtime;
+ ticketinfo->renew_until = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
+ KRBv5Credentials.times.renew_till : 0;
+ _tzset();
+ if ( ticketinfo->valid_until - time(0) <= 0L )
+ ticketinfo->btickets = EXPD_TICKETS;
+ else
+ ticketinfo->btickets = GOOD_TICKETS;
+}
+
+static int
+CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials,
+ char *PrincipalName, TicketList ***ticketListTail)
+{
+ krb5_error_code code = 0;
+ krb5_ticket *tkt=NULL;
+ char *sServerName = NULL;
+ char Buffer[256];
+ char *functionName = NULL;
+ TicketList *list = NULL;
+
+ functionName = "krb5_unparse_name()";
+ code = (*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName);
+ if (code)
+ goto cleanup;
+
+ if (!KRBv5Credentials.times.starttime)
+ KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
+
+ memset(Buffer, '\0', sizeof(Buffer));
+
+ // @fixme: calloc for ptr init
+ list = (TicketList *)calloc(1, sizeof(TicketList));
+ if (!list) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
+ }
+ list->service = strdup(sServerName);
+ if (!list->service) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
+ }
+ list->issued = KRBv5Credentials.times.starttime;
+ list->valid_until = KRBv5Credentials.times.endtime;
+ if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE)
+ list->renew_until = KRBv5Credentials.times.renew_till;
+ else
+ list->renew_until = 0;
+
+ if (!pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
+ wsprintf(Buffer, "Session Key: %s Ticket: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype),
+ etype_string(tkt->enc_part.enctype));
+ pkrb5_free_ticket(ctx, tkt);
+ tkt = NULL;
+ } else {
+ wsprintf(Buffer, "Session Key: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype));
+ }
+
+ list->encTypes = (char *)calloc(1, strlen(Buffer)+1);
+ if (!list->encTypes) {
+ functionName = "calloc()";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ strcpy(list->encTypes, Buffer);
+
+ list->flags = KRBv5Credentials.ticket_flags;
+cleanup:
+ if (code) {
+ LeashKRB5Error(code, functionName);
+ if (list)
+ FreeTicketList(&list);
+ } else {
+ **ticketListTail = list;
+ *ticketListTail = &list->next;
+ }
+
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
+
+ return code;
+}
+
+// return 0 if ticketinfo was successfully appended to list, 1 otherwise
+int
+do_ccache(krb5_context ctx,
+ krb5_ccache cache,
+ TICKETINFO **ticketInfoTail)
+{
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ krb5_principal princ = NULL;
+ krb5_flags flags;
+ krb5_error_code code;
+ char *defname = NULL;
+ char *functionName = NULL;
+ TicketList **ticketListTail;
+ TICKETINFO *ticketinfo = NULL;
+ int retval = 1;
+
+ // Don't need the actual ticket, also turns off OPENCLOSE mode
+ flags = KRB5_TC_NOTICKET;
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ if (code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND) {
+ // Normal behavior; skip cache but suppress error message box
+ code = 0;
+ } else {
+ functionName = "krb5_cc_set_flags";
+ }
+ goto cleanup;
+ }
+ code = pkrb5_cc_get_principal(ctx, cache, &princ);
+ if (code) {
+ // Normal behavior; skip cache but suppress error message box
+ code = 0;
+ goto cleanup;
+ }
+ code = pkrb5_unparse_name(ctx, princ, &defname);
+ if (code) {
+ functionName = "krb5_unparse_name";
+ goto cleanup;
+ }
+ code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_start_seq_get";
+ goto cleanup;
+ }
+ if (*ticketInfoTail)
+ ticketinfo = *ticketInfoTail;
+ else
+ // @fixme: calloc to init pointers
+ ticketinfo = (TICKETINFO *)calloc(1, sizeof(TICKETINFO));
+
+ if (ticketinfo == NULL) {
+ functionName = "calloc";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
+ ticketinfo->principal = strdup(defname);
+ if (ticketinfo->principal == NULL) {
+ functionName = "strdup";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ code = pkrb5_cc_get_full_name(ctx, cache, &ticketinfo->ccache_name);
+ if (code) {
+ functionName = "krb5_cc_get_full_name";
+ goto cleanup;
+ }
+ *ticketInfoTail = ticketinfo;
+ ticketListTail = &ticketinfo->ticket_list;
+ while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
+ if (!pkrb5_is_config_principal(ctx, creds.server)) {
+ CredToTicketList(ctx, creds, defname, &ticketListTail);
+ CredToTicketInfo(creds, ticketinfo);
+ }
+ pkrb5_free_cred_contents(ctx, &creds);
+ }
+ if (code == KRB5_CC_END) {
+ code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_end_seq_get";
+ goto cleanup;
+ }
+ flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ functionName = "krb5_cc_set_flags";
+ goto cleanup;
+ }
+ } else {
+ functionName = "krb5_cc_next_cred";
+ goto cleanup;
+ }
+cleanup:
+ if (code)
+ LeashKRB5Error(code, functionName);
+ if (ticketinfo) {
+ if (ticketinfo == *ticketInfoTail)
+ retval = 0;
+ else
+ LeashKRB5FreeTickets(&ticketinfo);
+ }
+ if (defname)
+ pkrb5_free_unparsed_name(ctx, defname);
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+ return retval;
+}
+
+
+//
+// Returns 0 for success, 1 for failure
+//
+int
+do_all_ccaches(krb5_context ctx, TICKETINFO **ticketinfotail)
+{
+ krb5_error_code code;
+ krb5_ccache cache;
+ krb5_cccol_cursor cursor;
+ int retval = 1;
+ char *functionName = NULL;
+
+ code = pkrb5_cccol_cursor_new(ctx, &cursor);
+ if (code) {
+ functionName = "krb5_cccol_cursor_new";
+ goto cleanup;
+ }
+ retval = 0;
+ while (!(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&
+ cache != NULL) {
+ // Note that ticketinfotail will be updated here to point to the tail
+ // of the list but the caller of this function will remain with a
+ // pointer to the head.
+ if (do_ccache(ctx, cache, ticketinfotail) == 0)
+ ticketinfotail = &((*ticketinfotail)->next);
+ pkrb5_cc_close(ctx, cache);
+ }
+ if (code)
+ functionName = "krb5_cccol_cursor_next";
+ pkrb5_cccol_cursor_free(ctx, &cursor);
+cleanup:
+ if (code)
+ LeashKRB5Error(code, functionName);
+ return retval;
+}
+
+void
+LeashKRB5ListDefaultTickets(TICKETINFO *ticketinfo)
+{
+ krb5_error_code code;
+ krb5_context ctx = 0;
+ krb5_ccache cache = 0;
+ char *functionName = NULL;
+
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal = NULL;
+ ticketinfo->ccache_name = NULL;
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
+ ticketinfo->renew_until = 0;
+ ticketinfo->valid_until = 0;
+ ticketinfo->issued = 0;
+
+ code = pkrb5_init_context(&ctx);
+ if (code) {
+ functionName = "krb5_init_context";
+ goto cleanup;
+ }
+
+ code = pkrb5_cc_default(ctx, &cache);
+ if (code) {
+ functionName = "krb5_cc_default";
+ goto cleanup;
+ }
+ if (cache != NULL)
+ do_ccache(ctx, cache, &ticketinfo);
+cleanup:
+ if (code)
+ LeashKRB5Error(code, functionName);
+ if (cache)
+ pkrb5_cc_close(ctx, cache);
+ if (ctx)
+ pkrb5_free_context(ctx);
+}
+
+
+/*
+ * LeashKRB5ListAllTickets()
+ */
+
+void
+LeashKRB5ListAllTickets(TICKETINFO **ticketinfo)
+{
+ krb5_error_code code;
+ krb5_context ctx = 0;
+ char *functionName = NULL;
+
+ code = pkrb5_init_context(&ctx);
+ if (code) {
+ functionName = "krb5_init_context";
+ goto cleanup;
+ }
+
+ do_all_ccaches(ctx, ticketinfo);
+cleanup:
+ if (code)
+ LeashKRB5Error(code, functionName);
+ if (ctx)
+ pkrb5_free_context(ctx);
+}
diff --git a/src/windows/leash/Leash.cpp b/src/windows/leash/Leash.cpp
index 29e377ae8f..44e687b31f 100644
--- a/src/windows/leash/Leash.cpp
+++ b/src/windows/leash/Leash.cpp
@@ -49,9 +49,6 @@ static char THIS_FILE[] = __FILE__;
extern "C" int VScheckVersion(HWND hWnd, HANDLE hThisInstance);
TicketInfoWrapper ticketinfo;
-#ifndef KRB5_TC_NOTICKET /* test for krb5 1.4 and thread safety */
-HANDLE m_tgsReqMutex = 0;
-#endif
HWND CLeashApp::m_hProgram = 0;
HINSTANCE CLeashApp::m_hLeashDLL = 0;
@@ -69,6 +66,7 @@ krb5_context CLeashApp::m_krbv5_context = 0;
profile_t CLeashApp::m_krbv5_profile = 0;
HINSTANCE CLeashApp::m_hKrbLSA = 0;
int CLeashApp::m_useRibbon = TRUE;
+BOOL CLeashApp::m_bUpdateDisplay = FALSE;
/////////////////////////////////////////////////////////////////////////////
// CLeashApp
@@ -95,9 +93,6 @@ CLeashApp::CLeashApp()
memset(&ticketinfo, 0, sizeof(ticketinfo));
ticketinfo.lockObj = CreateMutex(NULL, FALSE, NULL);
-#ifndef KRB5_TC_NOTICKET
- m_tgsReqMutex = CreateMutex(NULL, FALSE, NULL);
-#endif
#ifdef USE_HTMLHELP
#if _MSC_VER >= 1300
@@ -121,9 +116,6 @@ CLeashApp::~CLeashApp()
#ifdef COMMENT
/* Do not free the locking objects. Doing so causes an invalid handle access */
CloseHandle(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- CloseHandle(m_tgsReqMutex);
-#endif
#endif
AfxFreeLibrary(m_hLeashDLL);
#ifndef NO_KRB4
@@ -170,6 +162,7 @@ BOOL CLeashApp::InitInstance()
// NOTE: Not used at this time
/// Set LEASH_DLL to the path where the Leash.exe is
char modulePath[MAX_PATH];
+ krb5_error_code code;
DWORD result = GetModuleFileName(AfxGetInstanceHandle(), modulePath, MAX_PATH);
ASSERT(result);
@@ -189,6 +182,11 @@ BOOL CLeashApp::InitInstance()
HWND hMsg = GetForegroundWindow();
if (!InitDLLs())
return FALSE; //exit program, can't load LEASHDLL
+ code = pkrb5_init_context(&m_krbv5_context);
+ if (code) {
+ // @TODO: report error
+ return FALSE;
+ }
// Check for args (switches)
LPCTSTR exeFile = __targv[0];
@@ -207,17 +205,12 @@ BOOL CLeashApp::InitInstance()
char username[64]="";
char realm[192]="";
int i=0, j=0;
- TicketList* ticketList = NULL;
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
throw("Unable to lock ticketinfo");
- pLeashKRB5GetTickets(&ticketinfo.Krb5, &ticketList,
- &CLeashApp::m_krbv5_context);
- pLeashFreeTicketList(&ticketList);
- pLeashKRB4GetTickets(&ticketinfo.Krb4, &ticketList);
- pLeashFreeTicketList(&ticketList);
+ LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
- if ( ticketinfo.Krb5.btickets && ticketinfo.Krb5.principal[0] ) {
+ if ( ticketinfo.Krb5.btickets && ticketinfo.Krb5.principal ) {
for (; ticketinfo.Krb5.principal[i] && ticketinfo.Krb5.principal[i] != '@'; i++)
{
username[i] = ticketinfo.Krb5.principal[i];
@@ -230,20 +223,10 @@ BOOL CLeashApp::InitInstance()
}
}
realm[j] = '\0';
- } else if ( ticketinfo.Krb4.btickets && ticketinfo.Krb4.principal[0] ) {
- for (; ticketinfo.Krb4.principal[i] && ticketinfo.Krb4.principal[i] != '@'; i++)
- {
- username[i] = ticketinfo.Krb4.principal[i];
- }
- username[i] = '\0';
- if (ticketinfo.Krb4.principal[i]) {
- for (i++ ; ticketinfo.Krb4.principal[i] ; i++, j++)
- {
- realm[j] = ticketinfo.Krb4.principal[i];
- }
- }
- realm[j] = '\0';
}
+
+ LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
+
ReleaseMutex(ticketinfo.lockObj);
ldi.size = LSH_DLGINFO_EX_V1_SZ;
@@ -415,14 +398,11 @@ BOOL CLeashApp::InitInstance()
// Check to see if there are any tickets in the cache
// If not and the Windows Logon Session is Kerberos authenticated attempt an import
{
- TicketList* ticketList = NULL;
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
throw("Unable to lock ticketinfo");
- pLeashKRB5GetTickets(&ticketinfo.Krb5, &ticketList, &CLeashApp::m_krbv5_context);
- pLeashFreeTicketList(&ticketList);
- pLeashKRB4GetTickets(&ticketinfo.Krb4, &ticketList);
- pLeashFreeTicketList(&ticketList);
- BOOL b_autoinit = !ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets;
+ LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
+ BOOL b_autoinit = !ticketinfo.Krb5.btickets;
+ LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
ReleaseMutex(ticketinfo.lockObj);
DWORD dwMsLsaImport = pLeash_get_default_mslsa_import();
@@ -503,9 +483,7 @@ BOOL CLeashApp::InitInstance()
// leash functions
DECL_FUNC_PTR(not_an_API_LeashKRB4GetTickets);
-DECL_FUNC_PTR(not_an_API_LeashKRB5GetTickets);
DECL_FUNC_PTR(not_an_API_LeashAFSGetToken);
-DECL_FUNC_PTR(not_an_API_LeashFreeTicketList);
DECL_FUNC_PTR(not_an_API_LeashGetTimeServerName);
DECL_FUNC_PTR(Leash_kdestroy);
DECL_FUNC_PTR(Leash_changepwd_dlg);
@@ -552,9 +530,7 @@ DECL_FUNC_PTR(Leash_reset_defaults);
FUNC_INFO leash_fi[] = {
MAKE_FUNC_INFO(not_an_API_LeashKRB4GetTickets),
- MAKE_FUNC_INFO(not_an_API_LeashKRB5GetTickets),
MAKE_FUNC_INFO(not_an_API_LeashAFSGetToken),
- MAKE_FUNC_INFO(not_an_API_LeashFreeTicketList),
MAKE_FUNC_INFO(not_an_API_LeashGetTimeServerName),
MAKE_FUNC_INFO(Leash_kdestroy),
MAKE_FUNC_INFO(Leash_changepwd_dlg),
@@ -795,7 +771,7 @@ BOOL CLeashApp::InitDLLs()
#endif
m_hKrb5DLL = AfxLoadLibrary(KERB5DLL);
m_hKrb5ProfileDLL = AfxLoadLibrary(KERB5_PPROFILE_DLL);
- m_hComErr - AfxLoadLibrary(COMERR_DLL);
+ m_hComErr = AfxLoadLibrary(COMERR_DLL);
#ifndef NO_AFS
afscompat_init();
@@ -1504,31 +1480,19 @@ CLeashApp::ProbeKDC(void)
VOID
CLeashApp::ObtainTicketsViaUserIfNeeded(HWND hWnd)
{
- TicketList* ticketList = NULL;
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
throw("Unable to lock ticketinfo");
- pLeashKRB5GetTickets(&ticketinfo.Krb5, &ticketList, &CLeashApp::m_krbv5_context);
- pLeashFreeTicketList(&ticketList);
- pLeashKRB4GetTickets(&ticketinfo.Krb4, &ticketList);
- pLeashFreeTicketList(&ticketList);
+ LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
+ int btickets = ticketinfo.Krb5.btickets;
+ LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
+ ReleaseMutex(ticketinfo.lockObj);
- if ( !ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets ) {
- ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS mutex");
-#endif
+ if ( !btickets ) {
if ( pLeash_importable() ) {
if (pLeash_import())
CLeashView::m_importedTickets = 1;
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
}
else if ( ProbeKDC() ) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
LSH_DLGINFO_EX ldi;
ldi.size = LSH_DLGINFO_EX_V1_SZ;
ldi.dlgtype = DLGTYPE_PASSWD;
@@ -1540,54 +1504,12 @@ CLeashApp::ObtainTicketsViaUserIfNeeded(HWND hWnd)
pLeash_kinit_dlg_ex(hWnd, &ldi);
}
-#ifndef KRB5_TC_NOTICKET
- else {
- ReleaseMutex(m_tgsReqMutex);
- }
-#endif
- } else if ( ticketinfo.Krb5.btickets ) {
- ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to TGS mutex");
-#endif
+ } else {
if ( CLeashView::m_importedTickets && pLeash_importable() ) {
if (pLeash_import())
CLeashView::m_importedTickets = 1;
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
}
else if ( ProbeKDC() && !pLeash_renew() ) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- LSH_DLGINFO_EX ldi;
- ldi.size = LSH_DLGINFO_EX_V1_SZ;
- ldi.dlgtype = DLGTYPE_PASSWD;
- ldi.title = "Get Ticket";
- ldi.username = NULL;
- ldi.realm = NULL;
- ldi.dlgtype = DLGTYPE_PASSWD;
- ldi.use_defaults = 1;
-
- pLeash_kinit_dlg_ex(hWnd, &ldi);
- }
-#ifndef KRB5_TC_NOTICKET
- else {
- ReleaseMutex(m_tgsReqMutex);
- }
-#endif
- } else if ( ticketinfo.Krb4.btickets ) {
- ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS mutex");
-#endif
- if ( ProbeKDC() ) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
LSH_DLGINFO_EX ldi;
ldi.size = LSH_DLGINFO_EX_V1_SZ;
ldi.dlgtype = DLGTYPE_PASSWD;
@@ -1599,14 +1521,6 @@ CLeashApp::ObtainTicketsViaUserIfNeeded(HWND hWnd)
pLeash_kinit_dlg_ex(hWnd, &ldi);
}
-#ifndef KRB5_TC_NOTICKET
- else {
- ReleaseMutex(m_tgsReqMutex);
- }
-#endif
- } else {
- ReleaseMutex(ticketinfo.lockObj);
- // Do nothing ...
}
return;
}
@@ -1681,10 +1595,6 @@ CLeashApp::IpAddrChangeMonitorInit(HWND hWnd)
UINT
CLeashApp::InitWorker(void * hWnd)
{
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock tgsReq");
-#endif
if ( ProbeKDC() ) {
LSH_DLGINFO_EX ldi;
ldi.size = LSH_DLGINFO_EX_V1_SZ;
@@ -1694,16 +1604,9 @@ CLeashApp::InitWorker(void * hWnd)
ldi.realm = NULL;
ldi.use_defaults = 1;
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
pLeash_kinit_dlg_ex((HWND)hWnd, &ldi);
::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
}
-#ifndef KRB5_TC_NOTICKET
- else
- ReleaseMutex(m_tgsReqMutex);
-#endif
return 0;
}
@@ -1724,3 +1627,15 @@ CLeashApp::WinHelp(DWORD dwData, UINT nCmd)
}
#endif
#endif
+
+
+BOOL CLeashApp::OnIdle(LONG lCount)
+{
+ // TODO: Add your specialized code here and/or call the base class
+ BOOL retval = CWinAppEx::OnIdle(lCount);
+ if ((lCount == 0) && m_bUpdateDisplay) {
+ m_bUpdateDisplay = FALSE;
+ m_pMainWnd->SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);
+ }
+ return retval;
+}
diff --git a/src/windows/leash/Leash.h b/src/windows/leash/Leash.h
index 377f0fc7a8..6d5f815a9f 100644
--- a/src/windows/leash/Leash.h
+++ b/src/windows/leash/Leash.h
@@ -120,6 +120,7 @@ public:
static profile_t m_krbv5_profile;
static HINSTANCE m_hKrbLSA;
static int m_useRibbon; // temporary while ribbon UI in dev
+ static BOOL m_bUpdateDisplay;
CLeashApp();
virtual ~CLeashApp();
@@ -155,6 +156,8 @@ public:
//{{AFX_MSG(CLeashApp)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
+public:
+ virtual BOOL OnIdle(LONG lCount);
};
extern CLeashApp theApp;
diff --git a/src/windows/leash/Leash.rc b/src/windows/leash/Leash.rc
index f4100b71a0..23da2cc9c7 100644
--- a/src/windows/leash/Leash.rc
+++ b/src/windows/leash/Leash.rc
@@ -689,6 +689,10 @@ BEGIN
BOTTOMMARGIN, 190
END
+ IDD_LEASH_MESSAGE_BOX, DIALOG
+ BEGIN
+ END
+
IDD_KRB4_PROP_LOCATION, DIALOG
BEGIN
LEFTMARGIN, 6
diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp
index 6a28727c89..c139ff76e3 100644
--- a/src/windows/leash/LeashView.cpp
+++ b/src/windows/leash/LeashView.cpp
@@ -55,6 +55,7 @@ BEGIN_MESSAGE_MAP(CLeashView, CListView)
ON_COMMAND(ID_IMPORT_TICKET, OnImportTicket)
ON_COMMAND(ID_DESTROY_TICKET, OnDestroyTicket)
ON_COMMAND(ID_CHANGE_PASSWORD, OnChangePassword)
+ ON_COMMAND(ID_MAKE_DEFAULT, OnMakeDefault)
ON_COMMAND(ID_UPDATE_DISPLAY, OnUpdateDisplay)
ON_COMMAND(ID_SYN_TIME, OnSynTime)
ON_COMMAND(ID_DEBUG_MODE, OnDebugMode)
@@ -94,6 +95,7 @@ BEGIN_MESSAGE_MAP(CLeashView, CListView)
ON_UPDATE_COMMAND_UI(ID_KRB4_PROPERTIES, OnUpdateKrb4Properties)
ON_UPDATE_COMMAND_UI(ID_KRB5_PROPERTIES, OnUpdateKrb5Properties)
ON_UPDATE_COMMAND_UI(ID_AFS_CONTROL_PANEL, OnUpdateAfsControlPanel)
+ ON_UPDATE_COMMAND_UI(ID_MAKE_DEFAULT, OnUpdateMakeDefault)
ON_COMMAND(ID_PROPERTIES, OnKrbProperties)
ON_UPDATE_COMMAND_UI(ID_PROPERTIES, OnUpdateProperties)
ON_COMMAND(ID_HELP_KERBEROS_, OnHelpKerberos)
@@ -109,6 +111,10 @@ BEGIN_MESSAGE_MAP(CLeashView, CListView)
ON_NOTIFY(HDN_ITEMCHANGED, 0, OnItemChanged)
//}}AFX_MSG_MAP
+ ON_NOTIFY_REFLECT(LVN_ITEMCHANGING, &CLeashView::OnLvnItemchanging)
+ ON_NOTIFY_REFLECT(LVN_ITEMACTIVATE, &CLeashView::OnLvnItemActivate)
+ ON_NOTIFY_REFLECT(LVN_KEYDOWN, &CLeashView::OnLvnKeydown)
+ ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CLeashView::OnNMCustomdraw)
END_MESSAGE_MAP()
@@ -145,10 +151,149 @@ ViewColumnInfo CLeashView::sm_viewColumns[] =
};
+static HFONT CreateBoldFont(HFONT font)
+{
+ // @TODO: Should probably enumerate fonts here instead since this
+ // does not actually seem to guarantee returning a new font
+ // distinguishable from the original.
+ LOGFONT fontAttributes = { 0 };
+ ::GetObject(font, sizeof(fontAttributes), &fontAttributes);
+ fontAttributes.lfWeight = FW_BOLD;
+ HFONT boldFont = ::CreateFontIndirect(&fontAttributes);
+ return boldFont;
+}
+
+static HFONT CreateItalicFont(HFONT font)
+{
+ LOGFONT fontAttributes = { 0 };
+ ::GetObject(font, sizeof(fontAttributes), &fontAttributes);
+ fontAttributes.lfItalic = TRUE;
+ HFONT boldFont = ::CreateFontIndirect(&fontAttributes);
+ return boldFont;
+}
+
+
bool change_icon_size = true;
-#ifndef KRB5_TC_NOTICKET
-extern HANDLE m_tgsReqMutex;
-#endif
+
+void krb5TimestampToFileTime(krb5_timestamp t, LPFILETIME pft)
+{
+ // Note that LONGLONG is a 64-bit value
+ LONGLONG ll;
+
+ ll = Int32x32To64(t, 10000000) + 116444736000000000;
+ pft->dwLowDateTime = (DWORD)ll;
+ pft->dwHighDateTime = ll >> 32;
+}
+
+// allocate outstr
+void krb5TimestampToLocalizedString(krb5_timestamp t, LPTSTR *outStr)
+{
+ FILETIME ft, lft;
+ SYSTEMTIME st;
+ krb5TimestampToFileTime(t, &ft);
+ FileTimeToLocalFileTime(&ft, &lft);
+ FileTimeToSystemTime(&lft, &st);
+ TCHAR timeFormat[80]; // 80 is max required for LOCALE_STIMEFORMAT
+ GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,
+ LOCALE_STIMEFORMAT,
+ timeFormat,
+ sizeof(timeFormat) / sizeof(timeFormat[0]));
+
+ int timeSize = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
+ TIME_NOSECONDS,
+ &st,
+ timeFormat,
+ NULL,
+ 0);
+ // Using dateFormat prevents localization of Month/day order,
+ // but there is no other way AFAICT to suppress the year
+ TCHAR * dateFormat = "MMM dd' '";
+ int dateSize = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
+ 0, // flags
+ &st,
+ dateFormat, // format
+ NULL, // date string
+ 0);
+
+ if (*outStr)
+ free(*outStr);
+
+ // Allocate string for combined date and time,
+ // but only need one terminating NULL
+ LPTSTR str = (LPSTR)malloc((dateSize + timeSize - 1) * sizeof(TCHAR));
+ if (!str) {
+ // LeashWarn allocation failure
+ *outStr = NULL;
+ return;
+ }
+ GetDateFormat(LOCALE_SYSTEM_DEFAULT,
+ 0, // flags
+ &st,
+ dateFormat, // format
+ &str[0],
+ dateSize);
+
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
+ TIME_NOSECONDS,
+ &st,
+ timeFormat,
+ &str[dateSize - 1],
+ timeSize);
+ *outStr = str;
+}
+
+#define SECONDS_PER_MINUTE (60)
+#define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE)
+#define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR)
+#define MAX_DURATION_STR 255
+// convert time in seconds to string
+void DurationToString(long delta, LPTSTR *outStr)
+{
+ int days;
+ int hours;
+ int minutes;
+ TCHAR minutesStr[MAX_DURATION_STR+1];
+ TCHAR hoursStr[MAX_DURATION_STR+1];
+
+ if (*outStr)
+ free(*outStr);
+ *outStr = (LPSTR)malloc((MAX_DURATION_STR + 1)* sizeof(TCHAR));
+ if (!(*outStr))
+ return;
+
+ days = delta / SECONDS_PER_DAY;
+ delta -= days * SECONDS_PER_DAY;
+ hours = delta / SECONDS_PER_HOUR;
+ delta -= hours * SECONDS_PER_HOUR;
+ minutes = delta / SECONDS_PER_MINUTE;
+
+ if (minutes != 1)
+ _snprintf(minutesStr, MAX_DURATION_STR, "%d minutes", minutes);
+ else
+ _snprintf(minutesStr, MAX_DURATION_STR, "1 minute");
+ minutesStr[MAX_DURATION_STR] = 0;
+
+ if (hours != 1)
+ _snprintf(hoursStr, MAX_DURATION_STR, "%d hours", hours);
+ else
+ _snprintf(hoursStr, MAX_DURATION_STR, "1 hour");
+ hoursStr[MAX_DURATION_STR] = 0;
+
+ if (days > 0) {
+ if (days > 1)
+ _snprintf(*outStr, MAX_DURATION_STR, "(%d days, %s remaining)",
+ days, hoursStr);
+ else
+ _snprintf(*outStr, MAX_DURATION_STR, "(1 day, %s remaining)",
+ hoursStr);
+ } else if (hours > 0) {
+ _snprintf(*outStr, MAX_DURATION_STR, "(%s, %s remaining)", hoursStr,
+ minutesStr);
+ } else {
+ _snprintf(*outStr, MAX_DURATION_STR, "(%s remaining)", minutesStr);
+ }
+ (*outStr)[MAX_DURATION_STR] = 0;
+}
/////////////////////////////////////////////////////////////////////////////
// CLeashView construction/destruction
@@ -159,7 +304,6 @@ CLeashView::CLeashView()
#ifndef NO_KRB4
m_listKrb4 = NULL;
#endif
- m_listKrb5 = NULL;
m_listAfs = NULL;
m_startup = TRUE;
m_warningOfTicketTimeLeftKrb4 = 0;
@@ -188,7 +332,7 @@ CLeashView::CLeashView()
ResetTreeNodes();
m_hMenu = NULL;
m_pApp = NULL;
- m_pImageList = NULL;
+ m_ccacheDisplay = NULL;
m_forwardableTicket = 0;
m_proxiableTicket = 0;
m_renewableTicket = 0;
@@ -199,20 +343,31 @@ CLeashView::CLeashView()
m_pWarningMessage = NULL;
m_bIconAdded = FALSE;
m_bIconDeleted = FALSE;
-#ifndef KRB5_TC_NOTICKET
- m_tgsReqMutex = CreateMutex(NULL, FALSE, NULL);
-#endif
+ m_BaseFont = NULL;
+ m_BoldFont = NULL;
+ m_ItalicFont = NULL;
+ m_aListItemInfo = NULL;
}
CLeashView::~CLeashView()
{
-#ifndef KRB5_TC_NOTICKET
- CloseHandle(m_tgsReqMutex);
-#endif
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem) {
+ CCacheDisplayData *next = elem->m_next;
+ delete elem;
+ elem = next;
+ }
+ m_ccacheDisplay = NULL;
// destroys window if not already destroyed
if (m_pDebugWindow)
delete m_pDebugWindow;
+ if (m_BoldFont)
+ DeleteObject(m_BoldFont);
+ if (m_ItalicFont)
+ DeleteObject(m_ItalicFont);
+ if (m_aListItemInfo)
+ delete[] m_aListItemInfo;
}
void CLeashView::OnItemChanged(NMHDR* pNmHdr, LRESULT* pResult)
@@ -298,8 +453,7 @@ time_t CLeashView::LeashTime()
// Call while possessing a lock to ticketinfo.lockObj
INT CLeashView::GetLowTicketStatus(int ver)
{
- BOOL b_notix = (ver == 4 && !ticketinfo.Krb4.btickets) ||
- (ver == 5 && !ticketinfo.Krb5.btickets) ||
+ BOOL b_notix = (ver == 5 && !ticketinfo.Krb5.btickets) ||
(ver == 1 && !ticketinfo.Afs.btickets);
if (b_notix)
@@ -317,14 +471,12 @@ INT CLeashView::GetLowTicketStatus(int ver)
VOID CLeashView::UpdateTicketTime(TICKETINFO& ti)
{
- if (!ti.btickets)
- {
+ if (!ti.btickets) {
m_ticketTimeLeft = 0L;
return;
}
- m_ticketTimeLeft = ti.issue_date + ti.lifetime -
- LeashTime();
+ m_ticketTimeLeft = ti.valid_until - LeashTime();
if (m_ticketTimeLeft <= 0L)
ti.btickets = EXPIRED_TICKETS;
@@ -443,10 +595,6 @@ VOID CLeashView::OnInitTicket()
UINT CLeashView::InitTicket(void * hWnd)
{
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
m_importedTickets = 0;
LSH_DLGINFO_EX ldi;
@@ -454,33 +602,28 @@ UINT CLeashView::InitTicket(void * hWnd)
char realm[192];
int i=0, j=0;
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
throw("Unable to lock ticketinfo");
}
-
+ LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
char * principal = ticketinfo.Krb5.principal;
- if (!*principal)
- principal = ticketinfo.Krb4.principal;
- for (; principal[i] && principal[i] != '@'; i++)
- {
- username[i] = principal[i];
- }
+ if (principal)
+ for (; principal[i] && principal[i] != '@'; i++)
+ username[i] = principal[i];
username[i] = '\0';
- if (principal[i]) {
+ if (principal && principal[i]) {
for (i++ ; principal[i] ; i++, j++)
{
realm[j] = principal[i];
}
}
realm[j] = '\0';
+ LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
ReleaseMutex(ticketinfo.lockObj);
ldi.size = sizeof(ldi);
ldi.dlgtype = DLGTYPE_PASSWD;
ldi.title = ldi.in.title;
- strcpy(ldi.in.title,"Initialize Ticket");
+ strcpy(ldi.in.title,"Get Ticket");
ldi.username = ldi.in.username;
strcpy(ldi.in.username,username);
ldi.realm = ldi.in.realm;
@@ -492,15 +635,9 @@ UINT CLeashView::InitTicket(void * hWnd)
{
AfxMessageBox("There is a problem finding the Leash Window!",
MB_OK|MB_ICONSTOP);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
return 0;
}
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
int result = pLeash_kinit_dlg_ex((HWND)hWnd, &ldi);
if (-1 == result)
@@ -510,26 +647,15 @@ UINT CLeashView::InitTicket(void * hWnd)
}
else if ( result )
{
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
throw("Unable to lock ticketinfo");
}
- ticketinfo.Krb4.btickets = GOOD_TICKETS;
m_warningOfTicketTimeLeftKrb4 = 0;
m_warningOfTicketTimeLeftKrb5 = 0;
m_ticketStatusKrb4 = 0;
m_ticketStatusKrb5 = 0;
ReleaseMutex(ticketinfo.lockObj);
m_autoRenewalAttempted = 0;
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
}
return 0;
@@ -550,19 +676,10 @@ UINT CLeashView::ImportTicket(void * hWnd)
if ( !CLeashApp::m_hKrb5DLL )
return 0;
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
- int import = 0;
- int warning = 0;
-
krb5_error_code code;
krb5_ccache mslsa_ccache=0;
krb5_principal princ = 0;
char * pname = 0;
- LONG krb5Error = 0;
- TicketList * tlist = NULL;
if (code = pkrb5_cc_resolve(CLeashApp::m_krbv5_context, "MSLSA:", &mslsa_ccache))
goto cleanup;
@@ -573,21 +690,7 @@ UINT CLeashView::ImportTicket(void * hWnd)
if (code = pkrb5_unparse_name(CLeashApp::m_krbv5_context, princ, &pname))
goto cleanup;
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- throw("Unable to lock ticketinfo");
- }
- krb5Error = pLeashKRB5GetTickets( &ticketinfo.Krb5, &tlist,
- &CLeashApp::m_krbv5_context);
- if ( tlist )
- pLeashFreeTicketList(&tlist);
-
- warning = strcmp(ticketinfo.Krb5.principal, pname) && ticketinfo.Krb5.btickets;
- ReleaseMutex(ticketinfo.lockObj);
-
- cleanup:
+cleanup:
if (pname)
pkrb5_free_unparsed_name(CLeashApp::m_krbv5_context, pname);
@@ -598,105 +701,41 @@ UINT CLeashView::ImportTicket(void * hWnd)
pkrb5_cc_close(CLeashApp::m_krbv5_context, mslsa_ccache);
if ( code == 0 ) {
- if (warning)
+ int result = pLeash_import();
+ if (-1 == result)
{
- INT whatToDo;
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- if (!CLeashApp::m_hAfsDLL
-////@#+Need to rework this logic. I am confused what !m_hKrb4DLL means in this case!
-#ifndef NO_KRB4
- || !CLeashApp::m_hKrb4DLL
-#endif
- )
- whatToDo = AfxMessageBox("You are about to replace your existing ticket(s)\n"
- "with a ticket imported from the Windows credential cache!",
- MB_OKCANCEL, 0);
- else
- whatToDo = AfxMessageBox("You are about to replace your existing ticket(s)/token(s)"
- "with ticket imported from the Windows credential cache!",
- MB_OKCANCEL, 0);
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock tgsReqMutex");
-#endif
- if (whatToDo == IDOK)
- {
- pLeash_kdestroy();
- import = 1;
- }
- } else {
- import = 1;
+ AfxMessageBox("There is a problem importing tickets!",
+ MB_OK|MB_ICONSTOP);
+ ::SendMessage((HWND)hWnd,WM_COMMAND, ID_UPDATE_DISPLAY, 0);
+ m_importedTickets = 0;
}
-
- if ( import ) {
- int result = pLeash_import();
- if (-1 == result)
- {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- AfxMessageBox("There is a problem importing tickets!",
- MB_OK|MB_ICONSTOP);
- ::SendMessage((HWND)hWnd,WM_COMMAND, ID_UPDATE_DISPLAY, 0);
- m_importedTickets = 0;
+ else
+ {
+ if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
+ throw("Unable to lock ticketinfo");
}
- else
- {
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- throw("Unable to lock ticketinfo");
- }
- ticketinfo.Krb4.btickets = GOOD_TICKETS;
- ticketinfo.Krb5.btickets = GOOD_TICKETS;
- m_warningOfTicketTimeLeftKrb4 = 0;
- m_warningOfTicketTimeLeftKrb5 = 0;
- m_ticketStatusKrb4 = 0;
- m_ticketStatusKrb5 = 0;
- ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- ::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
+ ticketinfo.Krb5.btickets = GOOD_TICKETS;
+ m_warningOfTicketTimeLeftKrb4 = 0;
+ m_warningOfTicketTimeLeftKrb5 = 0;
+ m_ticketStatusKrb4 = 0;
+ m_ticketStatusKrb5 = 0;
+ ReleaseMutex(ticketinfo.lockObj);
+ ::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock tgsReqMutex");
-#endif
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- throw("Unable to lock ticketinfo");
- }
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
+ if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
+ throw("Unable to lock ticketinfo");
+ }
- if (ticketinfo.Krb5.btickets != GOOD_TICKETS) {
- ReleaseMutex(ticketinfo.lockObj);
- AfxBeginThread(InitTicket,hWnd);
- } else {
- ReleaseMutex(ticketinfo.lockObj);
- m_importedTickets = 1;
- m_autoRenewalAttempted = 0;
- }
+ if (ticketinfo.Krb5.btickets != GOOD_TICKETS) {
+ ReleaseMutex(ticketinfo.lockObj);
+ AfxBeginThread(InitTicket,hWnd);
+ } else {
+ ReleaseMutex(ticketinfo.lockObj);
+ m_importedTickets = 1;
+ m_autoRenewalAttempted = 0;
}
}
-#ifndef KRB5_TC_NOTICKET
- else {
- ReleaseMutex(m_tgsReqMutex);
- }
-#endif
- }
-#ifndef KRB5_TC_NOTICKET
- else {
- ReleaseMutex(m_tgsReqMutex);
}
-#endif
return 0;
}
@@ -718,38 +757,17 @@ UINT CLeashView::RenewTicket(void * hWnd)
if ( !CLeashApp::m_hKrb5DLL )
return 0;
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
-
// Try to renew
BOOL b_renewed = pLeash_renew();
- TicketList * tlist = NULL;
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- throw("Unable to lock ticketinfo");
- }
- LONG krb5Error = pLeashKRB5GetTickets(&ticketinfo.Krb5, &tlist,
- &CLeashApp::m_krbv5_context);
- pLeashFreeTicketList(&tlist);
if ( b_renewed ) {
- if (!krb5Error && ticketinfo.Krb5.btickets == GOOD_TICKETS) {
- ticketinfo.Krb4.btickets = GOOD_TICKETS;
- m_warningOfTicketTimeLeftKrb4 = 0;
- m_warningOfTicketTimeLeftKrb5 = 0;
- m_ticketStatusKrb4 = 0;
- m_ticketStatusKrb5 = 0;
- m_autoRenewalAttempted = 0;
- ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
- ::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
- return 0;
- }
+ m_warningOfTicketTimeLeftKrb4 = 0;
+ m_warningOfTicketTimeLeftKrb5 = 0;
+ m_ticketStatusKrb4 = 0;
+ m_ticketStatusKrb5 = 0;
+ m_autoRenewalAttempted = 0;
+ ReleaseMutex(ticketinfo.lockObj);
+ ::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
+ return 0;
}
krb5_error_code code;
@@ -770,8 +788,6 @@ UINT CLeashView::RenewTicket(void * hWnd)
m_importedTickets = 1;
cleanup:
- ReleaseMutex(ticketinfo.lockObj);
-
if (pname)
pkrb5_free_unparsed_name(CLeashApp::m_krbv5_context, pname);
@@ -781,9 +797,6 @@ UINT CLeashView::RenewTicket(void * hWnd)
if (mslsa_ccache)
pkrb5_cc_close(CLeashApp::m_krbv5_context, mslsa_ccache);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
// If imported from Kerberos LSA, re-import
// Otherwise, init the tickets
if ( m_importedTickets )
@@ -794,28 +807,61 @@ UINT CLeashView::RenewTicket(void * hWnd)
return 0;
}
+static void kdestroy(const char *ccache_name)
+{
+ krb5_context ctx;
+ krb5_ccache ccache=NULL;
+ int code = pkrb5_init_context(&ctx);
+ if (code) {
+ // TODO: spew error
+ goto cleanup;
+ }
+ code = pkrb5_cc_resolve(ctx, ccache_name, &ccache);
+ if (code) {
+ // TODO: spew error
+ goto cleanup;
+ }
+ code = pkrb5_cc_destroy(ctx, ccache);
+ if (code) {
+ goto cleanup;
+ }
+cleanup:
+ if (ctx)
+ pkrb5_free_context(ctx);
+}
+
+
VOID CLeashView::OnDestroyTicket()
{
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock ticketinfo");
- BOOL b_destroy =ticketinfo.Krb4.btickets || ticketinfo.Krb5.btickets || ticketinfo.Afs.btickets;
- ReleaseMutex(ticketinfo.lockObj);
+ // @TODO: grab mutex
+ BOOL destroy = FALSE;
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem) {
+ if (elem->m_selected) {
+ // @TODO add princ to msg text
+ destroy = TRUE;
+ }
+ elem = elem->m_next;
+ }
+ // release mutex
- if (b_destroy)
+ if (destroy)
{
INT whatToDo;
- if (!CLeashApp::m_hAfsDLL)
- whatToDo = AfxMessageBox("Are you sure you want to destroy these tickets?",
- MB_ICONEXCLAMATION|MB_YESNO, 0);
- else
- whatToDo = AfxMessageBox("You are about to destroy your ticket(s)/token(s)!",
- MB_ICONEXCLAMATION|MB_YESNO, 0);
+ whatToDo = AfxMessageBox("Are you sure you want to destroy these tickets?",
+ MB_ICONEXCLAMATION|MB_YESNO, 0);
if (whatToDo == IDYES)
{
- pLeash_kdestroy();
- ResetTreeNodes();
+ // grab list mutex
+ elem = m_ccacheDisplay;
+ while (elem) {
+ if (elem->m_selected)
+ kdestroy(elem->m_ccacheName);
+ elem = elem->m_next;
+ }
+ // release list mutex
SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);
}
}
@@ -823,6 +869,26 @@ VOID CLeashView::OnDestroyTicket()
m_autoRenewalAttempted = 0;
}
+VOID CLeashView::OnMakeDefault()
+{
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ int code = 0;
+ krb5_context ctx;
+ krb5_ccache cc;
+ while (elem) {
+ if (elem->m_selected) {
+ pkrb5_init_context(&ctx);
+ code = pkrb5_cc_resolve(ctx, elem->m_ccacheName, &cc);
+ if (!code)
+ code = pkrb5_cc_switch(ctx, cc);
+ pkrb5_free_context(ctx);
+ CLeashApp::m_bUpdateDisplay = TRUE;
+ break;
+ }
+ elem = elem->m_next;
+ }
+}
+
VOID CLeashView::OnChangePassword()
{
if (!m_hWnd)
@@ -839,20 +905,14 @@ VOID CLeashView::OnChangePassword()
char username[64];
char realm[192];
char * principal = ticketinfo.Krb5.principal;
- if (!*principal)
- principal = ticketinfo.Krb4.principal;
int i=0, j=0;
- for (; principal[i] && principal[i] != '@'; i++)
- {
- username[i] = principal[i];
- }
+ if (principal)
+ for (; principal[i] && principal[i] != '@'; i++)
+ username[i] = principal[i];
username[i] = '\0';
- if (principal[i]) {
- for (i++ ; principal[i] ; i++, j++)
- {
- realm[j] = principal[i];
- }
- }
+ if (principal && principal[i])
+ for (i++ ; principal[i] ; i++, j++)
+ realm[j] = principal[i];
realm[j] = '\0';
ReleaseMutex(ticketinfo.lockObj);
@@ -874,17 +934,145 @@ VOID CLeashView::OnChangePassword()
}
}
+static CCacheDisplayData **
+FindCCacheDisplayData(const char * ccacheName, CCacheDisplayData **pList)
+{
+ CCacheDisplayData *elem;
+ while ((elem = *pList)) {
+ if (strcmp(ccacheName, elem->m_ccacheName)==0)
+ return pList;
+ pList = &elem->m_next;
+ }
+ return NULL;
+}
+
+void CLeashView::AddDisplayItem(CListCtrl &list,
+ CCacheDisplayData *elem,
+ int iItem,
+ char *principal,
+ long issued,
+ long valid_until,
+ long renew_until,
+ char *encTypes,
+ unsigned long flags)
+{
+ TCHAR* localTimeStr=NULL;
+ TCHAR* durationStr=NULL;
+ TCHAR tempStr[MAX_DURATION_STR+1];
+ int imageIndex;
+ time_t now = LeashTime();
+ if (iItem != elem->m_index)
+ imageIndex = -1;
+ else if (elem->m_expanded)
+ imageIndex = 0;
+ else
+ imageIndex = 2;
+
+ list.InsertItem(iItem, principal, imageIndex);
+
+ int iSubItem = 1;
+ if (sm_viewColumns[TIME_ISSUED].m_enabled) {
+ if (issued == 0) {
+ list.SetItemText(iItem, iSubItem++, "Unknown");
+ } else {
+ krb5TimestampToLocalizedString(issued, &localTimeStr);
+ list.SetItemText(iItem, iSubItem++, localTimeStr);
+ }
+ }
+ if (sm_viewColumns[RENEWABLE_UNTIL].m_enabled) {
+ if (valid_until == 0) {
+ list.SetItemText(iItem, iSubItem++, "Unknown");
+ } else if (valid_until < now) {
+ list.SetItemText(iItem, iSubItem++, "Expired");
+ } else if (renew_until) {
+ krb5TimestampToLocalizedString(renew_until, &localTimeStr);
+ DurationToString(renew_until - now, &durationStr);
+ if (localTimeStr && durationStr) {
+ _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);
+ tempStr[MAX_DURATION_STR] = 0;
+ list.SetItemText(iItem, iSubItem++, tempStr);
+ }
+ } else {
+ list.SetItemText(iItem, iSubItem++, "Not renewable");
+ }
+ }
+ if (sm_viewColumns[VALID_UNTIL].m_enabled) {
+ if (valid_until == 0) {
+ list.SetItemText(iItem, iSubItem++, "Unknown");
+ } else if (valid_until < now) {
+ list.SetItemText(iItem, iSubItem++, "Expired");
+ } else {
+ krb5TimestampToLocalizedString(valid_until, &localTimeStr);
+ DurationToString(valid_until - now, &durationStr);
+ if (localTimeStr && durationStr) {
+ _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);
+ tempStr[MAX_DURATION_STR] = 0;
+ list.SetItemText(iItem, iSubItem++, tempStr);
+ }
+ }
+ }
+
+ if (sm_viewColumns[ENCRYPTION_TYPE].m_enabled) {
+ list.SetItemText(iItem, iSubItem++, encTypes);
+ }
+ if (sm_viewColumns[TICKET_FLAGS].m_enabled) {
+ list.SetItemText(iItem, iSubItem++, "ticket flags here");
+ }
+ if (localTimeStr)
+ free(localTimeStr);
+ if (durationStr)
+ free(durationStr);
+}
+
+BOOL CLeashView::IsExpanded(TICKETINFO *info)
+{
+ CCacheDisplayData **pElem = FindCCacheDisplayData(info->ccache_name,
+ &m_ccacheDisplay);
+ return (pElem && (*pElem)->m_expanded) ? TRUE : FALSE;
+}
+
+BOOL CLeashView::IsExpired(TICKETINFO *info)
+{
+ return LeashTime() > info->valid_until ? TRUE : FALSE;
+}
+
+BOOL CLeashView::IsExpired(TicketList *ticket)
+{
+ return LeashTime() > ticket->valid_until ? TRUE : FALSE;
+}
+
VOID CLeashView::OnUpdateDisplay()
{
BOOL AfsEnabled = m_pApp->GetProfileInt("Settings", "AfsStatus", 1);
CListCtrl& list = GetListCtrl();
+ // @TODO: there is probably a more sensible place to initialize these...
+ if ((m_BaseFont == NULL) && (list.GetFont())) {
+ m_BaseFont = *list.GetFont();
+ m_BoldFont = CreateBoldFont(m_BaseFont);
+ m_ItalicFont = CreateItalicFont(m_BaseFont);
+ }
+ // Determine currently focused item
+ int focusItem = list.GetNextItem(-1, LVNI_FOCUSED);
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem) {
+ if (focusItem >= elem->m_index) {
+ elem->m_focus = focusItem - elem->m_index;
+ focusItem = -1;
+ } else {
+ elem->m_focus = -1;
+ }
+ elem = elem->m_next;
+ }
+
list.DeleteAllItems();
ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
UpdateWindow();
// Delete all of the columns.
while (list.DeleteColumn(0));
+ list.SetImageList(&m_imageList, LVSIL_SMALL);
+
// Reconstruct based on current options
int columnIndex = 0;
int itemIndex = 0;
@@ -899,16 +1087,6 @@ VOID CLeashView::OnUpdateDisplay()
}
}
- m_pImageList = &m_imageList;
- if (!m_pImageList)
- {
- AfxMessageBox("There is a problem finding images for the Ticket Tree!",
- MB_OK|MB_ICONSTOP);
- return;
- }
-
- TV_INSERTSTRUCT m_tvinsert;
-
#ifndef NO_KRB4
INT ticketIconStatusKrb4;
INT ticketIconStatus_SelectedKrb4;
@@ -926,7 +1104,6 @@ VOID CLeashView::OnUpdateDisplay()
#ifndef NO_KRB4
LONG krb4Error;
#endif
- LONG krb5Error;
LONG afsError;
if (WaitForSingleObject( ticketinfo.lockObj, 100 ) != WAIT_OBJECT_0)
@@ -938,24 +1115,20 @@ VOID CLeashView::OnUpdateDisplay()
#endif
// Get Kerb 5 tickets in list
- krb5Error = pLeashKRB5GetTickets(&ticketinfo.Krb5, &m_listKrb5,
- &CLeashApp::m_krbv5_context);
- if (!krb5Error || krb5Error == KRB5_FCC_NOFILE)
+ LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
+ if (CLeashApp::m_hKrb5DLL && !CLeashApp::m_krbv5_profile)
{
- if (CLeashApp::m_hKrb5DLL && !CLeashApp::m_krbv5_profile)
+ CHAR confname[MAX_PATH];
+ if (CLeashApp::GetProfileFile(confname, sizeof(confname)))
{
- CHAR confname[MAX_PATH];
- if (CLeashApp::GetProfileFile(confname, sizeof(confname)))
- {
- AfxMessageBox("Can't locate Kerberos Five Config. file!",
- MB_OK|MB_ICONSTOP);
- }
-
- const char *filenames[2];
- filenames[0] = confname;
- filenames[1] = NULL;
- pprofile_init(filenames, &CLeashApp::m_krbv5_profile);
+ AfxMessageBox("Can't locate Kerberos Five Config. file!",
+ MB_OK|MB_ICONSTOP);
}
+
+ const char *filenames[2];
+ filenames[0] = confname;
+ filenames[1] = NULL;
+ pprofile_init(filenames, &CLeashApp::m_krbv5_profile);
}
// Get AFS Tokens in list
@@ -963,15 +1136,13 @@ VOID CLeashView::OnUpdateDisplay()
char * principal;
if ( ticketinfo.Krb5.principal[0] )
principal = ticketinfo.Krb5.principal;
- else if ( ticketinfo.Krb4.principal[0] )
- principal = ticketinfo.Krb4.principal;
else
principal = "";
afsError = pLeashAFSGetToken(&ticketinfo.Afs, &m_listAfs, principal);
}
/*
- * Update Ticket Status for Krb4 and Krb5 so that we may use their state
+ * Update Ticket Status for Krb5 so that we may use their state
* to select the appropriate Icon for the Parent Node
*/
@@ -1012,8 +1183,9 @@ VOID CLeashView::OnUpdateDisplay()
/* Krb5 */
UpdateTicketTime(ticketinfo.Krb5);
m_ticketStatusKrb5 = GetLowTicketStatus(5);
- if (!m_listKrb5 || EXPIRED_TICKETS == ticketinfo.Krb5.btickets ||
- m_ticketStatusKrb5 == ZERO_MINUTES_LEFT)
+ if ((!ticketinfo.Krb5.btickets) ||
+ EXPIRED_TICKETS == ticketinfo.Krb5.btickets ||
+ m_ticketStatusKrb5 == ZERO_MINUTES_LEFT)
{
ticketIconStatusKrb5 = EXPIRED_CLOCK;
ticketIconStatus_SelectedKrb5 = EXPIRED_CLOCK;
@@ -1071,268 +1243,117 @@ VOID CLeashView::OnUpdateDisplay()
iconStatusAfs = TICKET_NOT_INSTALLED;
}
- m_tvinsert.hParent = NULL;
- m_tvinsert.hInsertAfter = TVI_LAST;
- m_tvinsert.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- m_tvinsert.item.hItem = NULL;
- m_tvinsert.item.state = 0;
- m_tvinsert.item.stateMask = 0; //TVIS_EXPANDED;
- m_tvinsert.item.cchTextMax = 6;
-
- if (CLeashApp::m_hKrb5DLL && m_listKrb5) {
- m_tvinsert.item.pszText = ticketinfo.Krb5.principal;
- m_tvinsert.item.mask |= TVIF_TEXT;
+ int trayIcon = NONE_PARENT_NODE;
+ if (CLeashApp::m_hKrb5DLL && ticketinfo.Krb5.btickets) {
switch ( iconStatusKrb5 ) {
case ACTIVE_TICKET:
- m_tvinsert.item.iSelectedImage = ACTIVE_PARENT_NODE;
- break;
- case LOW_TICKET:
- m_tvinsert.item.iSelectedImage = LOW_PARENT_NODE;
- break;
- case EXPIRED_TICKET:
- m_tvinsert.item.iSelectedImage = EXPIRED_PARENT_NODE;
- break;
- }
-////
-#ifndef NO_KRB4
- } else if (CLeashApp::m_hKrb4DLL && m_listKrb4) {
- m_tvinsert.item.pszText = ticketinfo.Krb4.principal;
- m_tvinsert.item.mask |= TVIF_TEXT;
- switch ( iconStatusKrb4 ) {
- case ACTIVE_TICKET:
- m_tvinsert.item.iSelectedImage = ACTIVE_PARENT_NODE;
+ trayIcon = ACTIVE_PARENT_NODE;
break;
case LOW_TICKET:
- m_tvinsert.item.iSelectedImage = LOW_PARENT_NODE;
+ trayIcon = LOW_PARENT_NODE;
break;
case EXPIRED_TICKET:
- m_tvinsert.item.iSelectedImage = EXPIRED_PARENT_NODE;
+ trayIcon = EXPIRED_PARENT_NODE;
break;
}
-#endif
- } else {
- m_tvinsert.item.iSelectedImage = NONE_PARENT_NODE;
- m_tvinsert.item.pszText = NULL;
}
- m_tvinsert.item.iImage = m_tvinsert.item.iSelectedImage;
- m_tvinsert.item.cChildren = 0;
- m_tvinsert.item.lParam = 0;
- m_tvinsert.hParent = NULL;
-
- SetTrayIcon(NIM_MODIFY, m_tvinsert.item.iImage);
-
- // Krb5
- m_tvinsert.hParent = m_hPrincipal;
-
- if (CLeashApp::m_hKrb5DLL)
- {
- // kerb5 installed
- m_tvinsert.item.pszText = "Kerberos Five Tickets";
- m_tvinsert.item.iImage = iconStatusKrb5;
- m_tvinsert.item.iSelectedImage = iconStatusKrb5;
- }
- else
- {
- // kerb5 not installed
- ticketinfo.Krb5.btickets = NO_TICKETS;
- m_tvinsert.item.pszText = "Kerberos Five Tickets (Not Available)";
- m_tvinsert.item.iImage = TICKET_NOT_INSTALLED;
- m_tvinsert.item.iSelectedImage = TICKET_NOT_INSTALLED;
- }
-
- TicketList* tempList = m_listKrb5, *killList;
- while (tempList)
- {
- m_tvinsert.hParent = m_hKerb5;
- m_tvinsert.item.iImage = ticketIconStatusKrb5;
- m_tvinsert.item.iSelectedImage = ticketIconStatus_SelectedKrb5;
- m_tvinsert.item.pszText = tempList->theTicket;
-
- if ( tempList->tktEncType ) {
- m_tvinsert.hParent = m_hk5tkt;
- m_tvinsert.item.iImage = TKT_ENCRYPTION;
- m_tvinsert.item.iSelectedImage = TKT_ENCRYPTION;
- m_tvinsert.item.pszText = tempList->tktEncType;
- }
- if ( tempList->keyEncType ) {
- m_tvinsert.hParent = m_hk5tkt;
- m_tvinsert.item.iImage = TKT_SESSION;
- m_tvinsert.item.iSelectedImage = TKT_SESSION;
- m_tvinsert.item.pszText = tempList->keyEncType;
+ SetTrayIcon(NIM_MODIFY, trayIcon);
+
+ CCacheDisplayData* prevCCacheDisplay = m_ccacheDisplay;
+ m_ccacheDisplay = NULL;
+
+ const char *def_ccache_name = ticketinfo.Krb5.ccache_name;
+ TICKETINFO *principallist = NULL;
+ LeashKRB5ListAllTickets(&principallist);
+ int iItem = 0;
+ TicketList* tempList;
+ TICKETINFO *principal = principallist;
+ while (principal != NULL) {
+ CCacheDisplayData **pOldElem;
+ pOldElem = FindCCacheDisplayData(principal->ccache_name,
+ &prevCCacheDisplay);
+ if (pOldElem) {
+ // remove from old list
+ elem = *pOldElem;
+ *pOldElem = elem->m_next;
+ elem->m_next = NULL;
+ } else {
+ elem = new CCacheDisplayData(principal->ccache_name);
}
-
- if ( tempList->addrCount && tempList->addrList ) {
- for ( int n=0; n<tempList->addrCount; n++ ) {
- m_tvinsert.hParent = m_hk5tkt;
- m_tvinsert.item.iImage = TKT_ADDRESS;
- m_tvinsert.item.iSelectedImage = TKT_ADDRESS;
- m_tvinsert.item.pszText = tempList->addrList[n];
-// m_pTree->InsertItem(&m_tvinsert);
+ elem->m_isDefault = def_ccache_name &&
+ (strcmp(def_ccache_name, elem->m_ccacheName) == 0);
+ elem->m_isRenewable = principal->renew_until != 0;
+
+ elem->m_next = m_ccacheDisplay;
+ m_ccacheDisplay = elem;
+ elem->m_index = iItem;
+
+ AddDisplayItem(list,
+ elem,
+ iItem++,
+ principal->principal,
+ principal->issued,
+ principal->valid_until,
+ principal->renew_until,
+ "",
+ principal->flags);
+ if (elem->m_expanded) {
+ for (tempList = principal->ticket_list;
+ tempList != NULL;
+ tempList = tempList->next) {
+ AddDisplayItem(list,
+ elem,
+ iItem++,
+ tempList->service,
+ tempList->issued,
+ tempList->valid_until,
+ tempList->renew_until,
+ tempList->encTypes,
+ tempList->flags);
}
}
- tempList = tempList->next;
- }
-
- pLeashFreeTicketList(&m_listKrb5);
-
-// if (m_hKerb5State == NODE_IS_EXPANDED)
-// m_pTree->Expand(m_hKerb5, TVE_EXPAND);
-
- // Krb4
- m_tvinsert.hParent = m_hPrincipal;
-
-#ifndef NO_KRB4
- if (CLeashApp::m_hKrb4DLL)
- {
- m_tvinsert.item.pszText = "Kerberos Four Tickets";
- m_tvinsert.item.iImage = iconStatusKrb4;
- m_tvinsert.item.iSelectedImage = iconStatusKrb4;
- }
- else
- {
-#endif
-////Can this be removed altogether?
- ticketinfo.Krb4.btickets = NO_TICKETS;
- m_tvinsert.item.pszText = "Kerberos Four Tickets (Not Available)";
- m_tvinsert.item.iImage = TICKET_NOT_INSTALLED;
- m_tvinsert.item.iSelectedImage = TICKET_NOT_INSTALLED;
-#ifndef NO_KRB4
- }
-#endif
-
-#ifndef NO_KRB4
- m_hKerb4 = m_pTree ->InsertItem(&m_tvinsert);
-
- if (m_hPrincipalState == NODE_IS_EXPANDED)
- m_pTree->Expand(m_hPrincipal, TVE_EXPAND);
-
- m_tvinsert.hParent = m_hKerb4;
- m_tvinsert.item.iImage = ticketIconStatusKrb4;
- m_tvinsert.item.iSelectedImage = ticketIconStatus_SelectedKrb4;
-
-
-////What does the original do?
- tempList = m_listKrb4, *killList;
- while (tempList)
- {
- m_tvinsert.item.pszText = tempList->theTicket;
- m_pTree->InsertItem(&m_tvinsert);
- tempList = tempList->next;
- }
-
- pLeashFreeTicketList(&m_listKrb4);
-
- if (m_hKerb4State == NODE_IS_EXPANDED)
- m_pTree->Expand(m_hKerb4, TVE_EXPAND);
-#endif
-
- // AFS
- m_tvinsert.hParent = m_hPrincipal;
-
- if (!CLeashApp::m_hAfsDLL)
- { // AFS service not started or just no tickets
- m_tvinsert.item.pszText = "AFS Tokens (Not Available)";
- m_tvinsert.item.iImage = TICKET_NOT_INSTALLED;
- m_tvinsert.item.iSelectedImage = TICKET_NOT_INSTALLED;
- }
-
- if (!afsError && CLeashApp::m_hAfsDLL && m_tvinsert.item.pszText)
- { // AFS installed
-
- if (AfsEnabled)
- {
- m_tvinsert.item.pszText = "AFS Tokens";
- m_tvinsert.item.iImage = iconStatusAfs;
- m_tvinsert.item.iSelectedImage = iconStatusAfs;
- }
- else
- {
- m_tvinsert.item.pszText = "AFS Tokens (Disabled)";
- m_tvinsert.item.iImage = TICKET_NOT_INSTALLED;
- m_tvinsert.item.iSelectedImage = TICKET_NOT_INSTALLED;
+ if ((elem->m_focus >= 0) &&
+ (iItem > elem->m_index + elem->m_focus)) {
+ list.SetItemState(elem->m_index + elem->m_focus, LVIS_FOCUSED,
+ LVIS_FOCUSED);
}
-
- m_tvinsert.hParent = m_hAFS;
- m_tvinsert.item.iImage = ticketIconStatusAfs;
- m_tvinsert.item.iSelectedImage = ticketIconStatus_SelectedAfs;
-
- tempList = m_listAfs, *killList;
- while (tempList)
- {
- m_tvinsert.item.pszText = tempList->theTicket;
- tempList = tempList->next;
+ if (elem->m_selected)
+ list.SetItemState(elem->m_index, LVIS_SELECTED, LVIS_SELECTED);
+
+ principal = principal->next;
+ }
+
+ // create list item font data array
+ if (m_aListItemInfo != NULL)
+ delete[] m_aListItemInfo;
+ m_aListItemInfo = new ListItemInfo[iItem];
+ iItem = 0;
+ for (principal = principallist; principal != NULL;
+ principal = principal->next) {
+ //
+ HFONT font = IsExpired(principal) ? m_ItalicFont : m_BaseFont;
+ m_aListItemInfo[iItem++].m_font = font;
+ if (IsExpanded(principal)) {
+ for (TicketList *ticket = principal->ticket_list;
+ ticket != NULL; ticket = ticket->next) {
+ HFONT font = IsExpired(ticket) ? m_ItalicFont : m_BaseFont;
+ m_aListItemInfo[iItem++].m_font = font;
+ }
}
-
- pLeashFreeTicketList(&m_listAfs);
- }
- else if (!afsError && CLeashApp::m_hAfsDLL && !m_tvinsert.item.pszText)
- {
- m_tvinsert.item.pszText = "AFS Tokens";
- m_tvinsert.item.iImage = EXPIRED_TICKET;;
- m_tvinsert.item.iSelectedImage = EXPIRED_TICKET;
}
- if (m_startup)
- {
- //m_startup = FALSE;
- UpdateTicketTime(ticketinfo.Krb4);
+ // delete ccache items that no longer exist
+ while (prevCCacheDisplay != NULL) {
+ CCacheDisplayData *next = prevCCacheDisplay->m_next;
+ delete prevCCacheDisplay;
+ prevCCacheDisplay = next;
}
- CString sPrincipal = ticketinfo.Krb5.principal;
- if (sPrincipal.IsEmpty())
- sPrincipal = ticketinfo.Krb4.principal;
+ LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
+ LeashKRB5FreeTickets(&principallist);
- // if no tickets
- if (!ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets)
- sPrincipal = " No Tickets ";
+ // @TODO: AFS-specific here
- // if no tickets and tokens
- if (!ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets && !ticketinfo.Afs.btickets) //&& sPrincipal.IsEmpty())
- {
- // No tickets
- m_tvinsert.hParent = NULL;
- m_tvinsert.item.pszText = " No Tickets/Tokens ";
- m_tvinsert.item.iImage = NONE_PARENT_NODE;
- m_tvinsert.item.iSelectedImage = NONE_PARENT_NODE;
-
-/* if (CMainFrame::m_wndToolBar)
- {
- CToolBarCtrl *_toolBar = NULL;
- CToolBarCtrl& toolBar = CMainFrame::m_wndToolBar.GetToolBarCtrl();
- _toolBar = &toolBar;
- if (_toolBar)
- {
- toolBar.SetState(ID_DESTROY_TICKET, TBSTATE_INDETERMINATE);
- }
- else
- {
- AfxMessageBox("There is a problem with the Leash Toolbar!",
- MB_OK|MB_ICONSTOP);
- }
- }
-*/
- }
- else
- {
- // We have some tickets
-// m_pTree->SetItemText(m_hPrincipal, sPrincipal);
-/*
- if (CMainFrame::m_wndToolBar)
- {
- CToolBarCtrl *_toolBar = NULL;
- CToolBarCtrl& toolBar = CMainFrame::m_wndToolBar.GetToolBarCtrl();
- _toolBar = &toolBar;
- if (_toolBar)
- {
- toolBar.SetState(ID_DESTROY_TICKET, TBSTATE_ENABLED);
- }
- else
- {
- AfxMessageBox("There is a problem with the Leash Toolbar!", MB_OK|MB_ICONSTOP);
- }
- }
-*/
- }
ReleaseMutex(ticketinfo.lockObj);
}
@@ -1534,7 +1555,9 @@ void CLeashView::ToggleViewColumn(eViewColumn viewOption)
info.m_enabled = !info.m_enabled;
if (m_pApp)
m_pApp->WriteProfileInt("Settings", info.m_name, info.m_enabled);
- OnUpdateDisplay();
+ // Don't update display immediately; wait for next idle so our
+ // checkbox controls will be more responsive
+ CLeashApp::m_bUpdateDisplay = TRUE;
}
VOID CLeashView::OnRenewableUntil()
@@ -1738,7 +1761,7 @@ VOID CLeashView::OnDestroy()
CListView::OnDestroy();
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
throw("Unable to lock ticketinfo");
- BOOL b_destroy = m_destroyTicketsOnExit && (ticketinfo.Krb4.btickets || ticketinfo.Krb5.btickets);
+ BOOL b_destroy = m_destroyTicketsOnExit && ticketinfo.Krb5.btickets;
ReleaseMutex(ticketinfo.lockObj);
if (b_destroy)
@@ -1753,20 +1776,18 @@ VOID CLeashView::OnDestroy()
VOID CLeashView::OnUpdateDestroyTicket(CCmdUI* pCmdUI)
{
- if (!CLeashApp::m_hAfsDLL)
- pCmdUI->SetText("&Destroy Ticket(s)\tCtrl+D");
- else
- pCmdUI->SetText("&Destroy Ticket(s)/Token(s)\tCtrl+D");
-
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock ticketinfo");
- BOOL b_enable =!ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets && !ticketinfo.Afs.btickets;
- ReleaseMutex(ticketinfo.lockObj);
+ // @TODO: mutex
+ BOOL enable = FALSE;
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem != NULL) {
+ if (elem->m_selected) {
+ enable = TRUE;
+ break;
+ }
+ elem = elem->m_next;
+ }
- if (b_enable)
- pCmdUI->Enable(FALSE);
- else
- pCmdUI->Enable(TRUE);
+ pCmdUI->Enable(enable);
}
VOID CLeashView::OnUpdateInitTicket(CCmdUI* pCmdUI)
@@ -1790,39 +1811,24 @@ VOID CLeashView::OnUpdateInitTicket(CCmdUI* pCmdUI)
VOID CLeashView::OnUpdateRenewTicket(CCmdUI* pCmdUI)
{
- if (!CLeashApp::m_hAfsDLL)
- pCmdUI->SetText("&Renew Ticket(s)\tCtrl+R");
- else
- pCmdUI->SetText("&Renew Ticket(s)/Token(s)\tCtrl+R");
-
- if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock ticketinfo");
- BOOL b_enable = !(
-#ifndef NO_KRB4
- ticketinfo.Krb4.btickets ||
-#endif
- ticketinfo.Krb5.btickets) ||
-////Not sure about the boolean logic here
-#ifndef NO_KRB4
- !CLeashApp::m_hKrb4DLL &&
-#endif
- !CLeashApp::m_hKrb5DLL && !CLeashApp::m_hAfsDLL;
- ReleaseMutex(ticketinfo.lockObj);
+ // @TODO: mutex
+ BOOL enable = FALSE;
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem != NULL) {
+ if (elem->m_selected) { // @TODO: && elem->m_renewable
+ enable = TRUE;
+ break;
+ }
+ elem = elem->m_next;
+ }
- if (b_enable)
- pCmdUI->Enable(FALSE);
- else
- pCmdUI->Enable(TRUE);
+ pCmdUI->Enable(enable);
}
VOID CLeashView::OnUpdateImportTicket(CCmdUI* pCmdUI)
{
bool ccIsMSLSA = false;
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
if (CLeashApp::m_krbv5_context)
{
const char *ccName = pkrb5_cc_default_name(CLeashApp::m_krbv5_context);
@@ -1835,9 +1841,6 @@ VOID CLeashView::OnUpdateImportTicket(CCmdUI* pCmdUI)
pCmdUI->Enable(FALSE);
else
pCmdUI->Enable(TRUE);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
}
LRESULT CLeashView::OnGoodbye(WPARAM wParam, LPARAM lParam)
@@ -1885,10 +1888,6 @@ LRESULT CLeashView::OnTrayIcon(WPARAM wParam, LPARAM lParam)
menu->AppendMenu(MF_STRING, ID_LEASH_RESTORE, "&Open Leash Window");
menu->AppendMenu(MF_SEPARATOR);
menu->AppendMenu(MF_STRING, ID_INIT_TICKET, "&Get Tickets");
-#ifndef KRB5_TC_NOTICKET
- if (WaitForSingleObject( m_tgsReqMutex, INFINITE ) != WAIT_OBJECT_0)
- throw("Unable to lock TGS request mutex");
-#endif
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
throw("Unable to lock ticketinfo");
if (!(
@@ -1911,14 +1910,11 @@ LRESULT CLeashView::OnTrayIcon(WPARAM wParam, LPARAM lParam)
else
nFlags = MF_STRING;
menu->AppendMenu(MF_STRING, ID_IMPORT_TICKET, "&Import Tickets");
- if (!ticketinfo.Krb4.btickets && !ticketinfo.Krb5.btickets && !ticketinfo.Afs.btickets)
+ if (!ticketinfo.Krb5.btickets && !ticketinfo.Afs.btickets)
nFlags = MF_STRING | MF_GRAYED;
else
nFlags = MF_STRING;
ReleaseMutex(ticketinfo.lockObj);
-#ifndef KRB5_TC_NOTICKET
- ReleaseMutex(m_tgsReqMutex);
-#endif
menu->AppendMenu(MF_STRING, ID_DESTROY_TICKET, "&Destroy Tickets");
menu->AppendMenu(MF_STRING, ID_CHANGE_PASSWORD, "&Change Password");
@@ -2169,11 +2165,9 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
try {
if (InterlockedDecrement(&m_timerMsgNotInProgress) == 0) {
- CString ticketStatusKrb4 = TCHAR(NOT_INSTALLED);
CString ticketStatusKrb5 = TCHAR(NOT_INSTALLED);
CString ticketStatusAfs = TCHAR(NOT_INSTALLED);
CString strTimeDate;
- CString lowTicketWarningKrb4;
CString lowTicketWarningKrb5;
CString lowTicketWarningAfs;
@@ -2272,115 +2266,6 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
}
//KRB5
-#ifndef NO_KRB4
- if (CLeashApp::m_hKrb4DLL)
- {
- // KRB4
- UpdateTicketTime(ticketinfo.Krb4);
- if (!ticketinfo.Krb4.btickets)
- {
- ticketStatusKrb4 = "Kerb-4: No Tickets";
- }
- else if (EXPIRED_TICKETS == ticketinfo.Krb4.btickets)
- {
-#ifndef NO_KRB5
- if (ticketinfo.Krb5.btickets &&
- EXPIRED_TICKETS != ticketinfo.Krb5.btickets &&
- m_autoRenewTickets &&
- !m_autoRenewalAttempted &&
- ticketinfo.Krb5.renew_till &&
- (ticketinfo.Krb5.issue_date + ticketinfo.Krb5.renew_till -LeashTime() > 20 * 60) &&
- pLeash_get_default_use_krb4()
- )
- {
- m_autoRenewalAttempted = 1;
- ReleaseMutex(ticketinfo.lockObj);
- AfxBeginThread(RenewTicket,m_hWnd);
- goto timer_start;
- }
-#endif /* NO_KRB5 */
- ticketStatusKrb4 = "Kerb-4: Expired Tickets";
- lowTicketWarningKrb4 = "Your Kerberos Four ticket(s) have expired";
- if (!m_warningOfTicketTimeLeftLockKrb4)
- m_warningOfTicketTimeLeftKrb4 = 0;
- m_warningOfTicketTimeLeftLockKrb4 = ZERO_MINUTES_LEFT;
- m_ticketTimeLeft = 0;
- }
- else if ( pLeash_get_default_use_krb4() )
- {
- m_ticketStatusKrb4 = GetLowTicketStatus(4);
- switch (m_ticketStatusKrb4)
- {
- case FIFTEEN_MINUTES_LEFT:
- ticketinfo.Krb4.btickets = TICKETS_LOW;
- lowTicketWarningKrb4 = "Less then 15 minutes left on your Kerberos Four ticket(s)";
- break;
- case TEN_MINUTES_LEFT:
- ticketinfo.Krb4.btickets = TICKETS_LOW;
- lowTicketWarningKrb4 = "Less then 10 minutes left on your Kerberos Four ticket(s)";
- if (!m_warningOfTicketTimeLeftLockKrb4)
- m_warningOfTicketTimeLeftKrb4 = 0;
- m_warningOfTicketTimeLeftLockKrb4 = TEN_MINUTES_LEFT;
- break;
- case FIVE_MINUTES_LEFT:
- ticketinfo.Krb4.btickets = TICKETS_LOW;
- if (m_warningOfTicketTimeLeftLockKrb4 == TEN_MINUTES_LEFT)
- m_warningOfTicketTimeLeftKrb4 = 0;
- m_warningOfTicketTimeLeftLockKrb4 = FIVE_MINUTES_LEFT;
- lowTicketWarningKrb4 = "Less then 5 minutes left on your Kerberos Four ticket(s)";
- break;
- default:
- m_ticketStatusKrb4 = 0;
- break;
- }
-
- }
-
- if (CMainFrame::m_isMinimum)
- {
- // minimized dispay
- ticketStatusKrb4.Format("Kerb-4: %02d:%02d Left",
- (m_ticketTimeLeft / 60L / 60L),
- (m_ticketTimeLeft / 60L % 60L));
- }
- else
- {
- // normal display
- if (GOOD_TICKETS == ticketinfo.Krb4.btickets ||
- TICKETS_LOW == ticketinfo.Krb4.btickets)
- {
- if ( m_ticketTimeLeft >= 60 ) {
- ticketStatusKrb4.Format("Kerb-4 Ticket Life: %02d:%02d",
- (m_ticketTimeLeft / 60L / 60L),
- (m_ticketTimeLeft / 60L % 60L));
- } else {
- ticketStatusKrb4.Format("Kerb-4 Ticket Life: < 1 min");
- }
- }
-
- if (CMainFrame::m_wndStatusBar)
- {
- CMainFrame::m_wndStatusBar.SetPaneInfo(2, 111111, SBPS_NORMAL, 130);
- CMainFrame::m_wndStatusBar.SetPaneText(2, ticketStatusKrb4, SBT_POPOUT);
- }
- }
- }
- else
- {
-#endif
-////Should this be removed altogether?
- // not installed
- ticketStatusKrb4.Format("Kerb-4: Not Available");
-
- if (CMainFrame::m_wndStatusBar)
- {
- CMainFrame::m_wndStatusBar.SetPaneInfo(2, 111111, SBPS_NORMAL, 130);
- CMainFrame::m_wndStatusBar.SetPaneText(2, ticketStatusKrb4, SBT_POPOUT);
- }
-#ifndef NO_KRB4
- }
- // KRB4
-#endif
if (CLeashApp::m_hAfsDLL)
{
@@ -2401,8 +2286,8 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
EXPIRED_TICKETS != ticketinfo.Krb5.btickets &&
m_autoRenewTickets &&
!m_autoRenewalAttempted &&
- ticketinfo.Krb5.renew_till &&
- (ticketinfo.Krb5.issue_date + ticketinfo.Krb5.renew_till -LeashTime() > 20 * 60) &&
+ ticketinfo.Krb5.renew_until &&
+ (ticketinfo.Krb5.issued + ticketinfo.Krb5.renew_until -LeashTime() > 20 * 60) &&
!stricmp(ticketinfo.Krb5.principal,ticketinfo.Afs.principal)
)
{
@@ -2485,26 +2370,12 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
#endif
}
}
-#ifdef COMMENT
- // we do not set this field because the field does not exist when AfsDLL is NULL
- else
- {
- // not installed
- ticketStatusAfs.Format("AFS: Not Available");
-
- if (CMainFrame::m_wndStatusBar)
- {
- CMainFrame::m_wndStatusBar.SetPaneInfo(3, 111113, SBPS_NORMAL, 130);
- CMainFrame::m_wndStatusBar.SetPaneText(3, ticketStatusAfs, SBT_POPOUT);
- }
- }
-#endif /* COMMENT */
// AFS
#ifndef NO_KRB5
if ( m_ticketStatusKrb5 == TWENTY_MINUTES_LEFT &&
- m_autoRenewTickets && !m_autoRenewalAttempted && ticketinfo.Krb5.renew_till &&
- (ticketinfo.Krb5.issue_date + ticketinfo.Krb5.renew_till - LeashTime() > 20 * 60))
+ m_autoRenewTickets && !m_autoRenewalAttempted && ticketinfo.Krb5.renew_until &&
+ (ticketinfo.Krb5.issued + ticketinfo.Krb5.renew_until - LeashTime() > 20 * 60))
{
m_autoRenewalAttempted = 1;
ReleaseMutex(ticketinfo.lockObj);
@@ -2516,15 +2387,12 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
BOOL warningKrb5 = m_ticketStatusKrb5 > NO_TICKETS &&
m_ticketStatusKrb5 < TWENTY_MINUTES_LEFT &&
!m_warningOfTicketTimeLeftKrb5;
- BOOL warningKrb4 = m_ticketStatusKrb4 > NO_TICKETS &&
- m_ticketStatusKrb4 < TWENTY_MINUTES_LEFT &&
- !m_warningOfTicketTimeLeftKrb4;
BOOL warningAfs = m_ticketStatusAfs > NO_TICKETS &&
m_ticketStatusAfs < TWENTY_MINUTES_LEFT &&
!m_warningOfTicketTimeLeftAfs;
// Play warning message only once per each case statement above
- if (warningKrb4 || warningKrb5 || warningAfs)
+ if (warningKrb5 || warningAfs)
{
CString lowTicketWarning = "";
@@ -2535,13 +2403,6 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
m_warningOfTicketTimeLeftKrb5 = ON;
warnings++;
}
- if (warningKrb4) {
- if ( warnings )
- lowTicketWarning += "\n";
- lowTicketWarning += lowTicketWarningKrb4;
- m_warningOfTicketTimeLeftKrb4 = ON;
- warnings++;
- }
if (warningAfs) {
if ( warnings )
lowTicketWarning += "\n";
@@ -2564,14 +2425,12 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
if ( CLeashApp::m_hAfsDLL )
strTimeDate = ( "Leash - "
"[" + ticketStatusKrb5 + "] - " +
- "[" + ticketStatusKrb4 + "] - " +
"[" + ticketStatusAfs + "] - " +
"[" + ticketinfo.Krb5.principal + "]" + " - " +
tTimeDate.Format("%A, %B %d, %Y %H:%M "));
else
strTimeDate = ( "Leash - "
"[" + ticketStatusKrb5 + "] - " +
- "[" + ticketStatusKrb4 + "] - " +
"[" + ticketinfo.Krb5.principal + "]" + " - " +
tTimeDate.Format("%A, %B %d, %Y %H:%M "));
}
@@ -2591,13 +2450,6 @@ BOOL CLeashView::PreTranslateMessage(MSG* pMsg)
" - [" + ticketinfo.Krb5.principal + "]");
else
strTimeDate = "Leash: Kerb-5 No Tickets";
- } else {
- if ( ticketinfo.Krb4.btickets )
- strTimeDate = ( "Leash: "
- "[" + ticketStatusKrb4 + "]" +
- " - [" + ticketinfo.Krb4.principal + "]");
- else
- strTimeDate = "Leash: Kerb-4 No Tickets";
}
ReleaseMutex(ticketinfo.lockObj);
@@ -2667,6 +2519,29 @@ VOID CLeashView::OnUpdateAutoRenew(CCmdUI* pCmdUI)
pCmdUI->SetCheck(m_autoRenewTickets);
}
+VOID CLeashView::OnUpdateMakeDefault(CCmdUI* pCmdUI)
+{
+ // enable if exactly one principal is selected and that principal is not
+ // the default principal
+ BOOL enable = FALSE;
+ CCacheDisplayData *elem = m_ccacheDisplay;
+ while (elem != NULL) {
+ if (elem->m_selected) {
+ if (enable) {
+ // multiple selection; disable button
+ enable = FALSE;
+ break;
+ }
+ if (elem->m_isDefault)
+ break;
+
+ enable = TRUE;
+ }
+ elem = elem->m_next;
+ }
+ pCmdUI->Enable(enable);
+}
+
VOID CLeashView::AlarmBeep()
{
if (m_lowTicketAlarmSound)
@@ -2781,7 +2656,7 @@ CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)
if ( *param )
strcpy(ldi.in.ccache,param);
} else {
- strcpy(ldi.in.title,"Initialize Ticket");
+ strcpy(ldi.in.title,"Get Ticket");
}
res = pLeash_kinit_dlg_ex(m_hWnd, &ldi);
@@ -2789,3 +2664,162 @@ CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)
::SendMessage(m_hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
return res;
}
+
+
+// Find the CCacheDisplayData corresponding to the specified item, if it exists
+static CCacheDisplayData *
+FindCCacheDisplayData(int item, CCacheDisplayData *elem)
+{
+ while (elem != NULL) {
+ if (elem->m_index == item)
+ break;
+ elem = elem->m_next;
+ }
+ return elem;
+}
+
+
+void CLeashView::OnLvnItemActivate(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMITEMACTIVATE pNMIA = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
+ // TODO: Add your control notification handler code here
+ CCacheDisplayData *elem = FindCCacheDisplayData(pNMIA->iItem,
+ m_ccacheDisplay);
+ if (elem != NULL) {
+ elem->m_expanded = !elem->m_expanded;
+ OnUpdateDisplay();
+ }
+ *pResult = 0;
+}
+
+
+void CLeashView::OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
+ int expand = -1; // -1 = unchanged; 0 = collapse; 1 = expand
+ switch (pLVKeyDow->wVKey) {
+ case VK_RIGHT:
+ // expand focus item
+ expand = 1;
+ break;
+ case VK_LEFT:
+ // collapse focus item
+ expand = 0;
+ break;
+ default:
+ break;
+ }
+ if (expand >= 0) {
+ int focusedItem = GetListCtrl().GetNextItem(-1, LVNI_FOCUSED);
+ if (focusedItem >= 0) {
+ CCacheDisplayData *elem = FindCCacheDisplayData(focusedItem,
+ m_ccacheDisplay);
+ if (elem != NULL) {
+ if (elem->m_expanded != expand) {
+ elem->m_expanded = expand;
+ OnUpdateDisplay();
+ }
+ }
+ }
+ }
+ *pResult = 0;
+}
+
+void CLeashView::OnLvnItemchanging(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ CCacheDisplayData *elem;
+ LRESULT result = 0;
+ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+ // TODO: Add your control notification handler code here
+ if ((pNMLV->uNewState ^ pNMLV->uOldState) & LVIS_SELECTED) {
+ // selection state changing
+ elem = FindCCacheDisplayData(pNMLV->iItem, m_ccacheDisplay);
+ if (elem == NULL) {
+ // this is an individual ticket, not a cache, so prevent selection
+ if (pNMLV->uNewState & LVIS_SELECTED) {
+ unsigned int newState = pNMLV->uNewState & ~LVIS_SELECTED;
+ result = 1; // suppress changes
+ if (newState != pNMLV->uOldState) {
+ // but need to make other remaining changes still
+ GetListCtrl().SetItemState(pNMLV->iItem, newState,
+ newState ^ pNMLV->uOldState);
+ }
+ }
+ } else {
+ elem->m_selected = (pNMLV->uNewState & LVIS_SELECTED) ? 1 : 0;
+ }
+ }
+ *pResult = result;
+}
+
+CCacheDisplayData *
+FindCCacheDisplayElem(CCacheDisplayData *pElem, int itemIndex)
+{
+ while (pElem != NULL) {
+ if (pElem->m_index == itemIndex)
+ return pElem;
+ pElem = pElem->m_next;
+ }
+ return NULL;
+}
+
+HFONT CLeashView::GetSubItemFont(int iItem, int iSubItem)
+{
+ HFONT retval = m_BaseFont;
+ int iColumn, columnSubItem = 0;
+
+ // Translate subitem to column index
+ for (iColumn = 0; iColumn < NUM_VIEW_COLUMNS; iColumn++) {
+ if (sm_viewColumns[iColumn].m_enabled) {
+ if (columnSubItem == iSubItem)
+ break;
+ else
+ columnSubItem++;
+ }
+ }
+ switch (iColumn) {
+ case RENEWABLE_UNTIL:
+ case VALID_UNTIL:
+ retval = m_aListItemInfo[iItem].m_font;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+void CLeashView::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ HFONT font;
+ CCacheDisplayData *pElem;
+ *pResult = CDRF_DODEFAULT;
+ LPNMLVCUSTOMDRAW pNMLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
+ switch (pNMLVCD->nmcd.dwDrawStage) {
+ case CDDS_PREPAINT:
+ *pResult = CDRF_NOTIFYITEMDRAW;
+ break;
+ case CDDS_ITEMPREPAINT:
+ *pResult = CDRF_NOTIFYSUBITEMDRAW;
+ break;
+ case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+ pElem = FindCCacheDisplayElem(m_ccacheDisplay,
+ pNMLVCD->nmcd.dwItemSpec);
+ if (pNMLVCD->iSubItem == 0) {
+ // set bold font if default princ
+ if (pElem && pElem->m_isDefault) {
+ font = m_BoldFont;
+ } else {
+ font = m_BaseFont;
+ }
+ } else {
+ // set italic font for 'valid until' and 'renewable until'
+ // columns if expired ticket
+ font = GetSubItemFont(pNMLVCD->nmcd.dwItemSpec, pNMLVCD->iSubItem);
+ }
+ SelectObject(pNMLVCD->nmcd.hdc, font);
+ *pResult = CDRF_NEWFONT;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/src/windows/leash/LeashView.h b/src/windows/leash/LeashView.h
index cbdb77fc29..307c36dda2 100644
--- a/src/windows/leash/LeashView.h
+++ b/src/windows/leash/LeashView.h
@@ -86,6 +86,43 @@ enum eViewColumn {
NUM_VIEW_COLUMNS
};
+class CCacheDisplayData
+{
+public:
+ CCacheDisplayData(const char *ccache_name) :
+ m_next(NULL),
+ m_ccacheName(strdup(ccache_name)),
+ m_index(-1),
+ m_focus(-1),
+ m_expanded(0),
+ m_selected(0),
+ m_isRenewable(0),
+ m_isDefault(0)
+ {
+ }
+
+ ~CCacheDisplayData()
+ {
+ if (m_ccacheName)
+ free(m_ccacheName);
+ }
+
+ CCacheDisplayData *m_next;
+ char *m_ccacheName;
+ int m_index; // item index in list view
+ int m_focus; // sub-item with focus
+ unsigned int m_expanded; // true when each individual ticket is displayed
+ unsigned int m_selected; // true when this ccache is selected
+ unsigned int m_isRenewable; // true when tgt is renewable
+ unsigned int m_isDefault; // true when this is the default ccache
+};
+
+struct ListItemInfo
+{
+ ListItemInfo() : m_font(NULL) {}
+ HFONT m_font;
+};
+
class CLeashView : public CListView
{
private:
@@ -93,11 +130,10 @@ private:
#ifndef NO_KRB4
TicketList* m_listKrb4;
#endif
- TicketList* m_listKrb5;
TicketList* m_listAfs;
CLeashDebugWindow* m_pDebugWindow;
+ CCacheDisplayData* m_ccacheDisplay;
CImageList m_imageList;
- CImageList *m_pImageList;
CWinApp* m_pApp;
HTREEITEM m_hPrincipal;
////@#+Remove
@@ -127,6 +163,10 @@ private:
CString* m_pWarningMessage;
BOOL m_bIconAdded;
BOOL m_bIconDeleted;
+ HFONT m_BaseFont;
+ HFONT m_BoldFont;
+ HFONT m_ItalicFont;
+ ListItemInfo* m_aListItemInfo;
static ViewColumnInfo sm_viewColumns[NUM_VIEW_COLUMNS];
@@ -159,6 +199,7 @@ private:
VOID UpdateBars();
VOID GetScrollBarSizes(CSize& sizeSb);
BOOL GetTrueClientSize(CSize& size, CSize& sizeSb);
+ HFONT GetSubItemFont(int iItem, int iSubItem);
//void GetRowWidthHeight(CDC* pDC, LPCSTR theString, int& nRowWidth,
// int& nRowHeight, int& nCharWidth);
@@ -168,6 +209,17 @@ private:
static VOID UpdateTicketTime(TICKETINFO& ticketinfo);
static INT GetLowTicketStatus(int);
static time_t LeashTime();
+ static BOOL IsExpired(TicketList *ticket);
+ static BOOL IsExpired(TICKETINFO *info);
+ static VOID AddDisplayItem(CListCtrl &list,
+ CCacheDisplayData *elem,
+ int iItem,
+ char *principal,
+ long issued,
+ long valid_until,
+ long renew_until,
+ char *encTypes,
+ unsigned long flags);
void SetTrayIcon(int nim, int state=0);
void SetTrayText(int nim, CString tip);
@@ -183,6 +235,8 @@ private:
BOOL PostWarningMessage(const CString& message);
afx_msg LRESULT OnWarningPopup(WPARAM wParam, LPARAM lParam);
+ BOOL IsExpanded(TICKETINFO *);
+
protected: // create from serialization only
DECLARE_DYNCREATE(CLeashView)
@@ -238,6 +292,7 @@ protected:
afx_msg VOID OnRenewTicket();
afx_msg VOID OnImportTicket();
afx_msg VOID OnDestroyTicket();
+ afx_msg VOID OnMakeDefault();
afx_msg VOID OnChangePassword();
afx_msg VOID OnUpdateDisplay();
afx_msg VOID OnSynTime();
@@ -264,6 +319,7 @@ protected:
afx_msg VOID OnUpdateKillTixOnExit(CCmdUI* pCmdUI);
afx_msg VOID OnUpdateLowTicketAlarm(CCmdUI* pCmdUI);
afx_msg VOID OnUpdateAutoRenew(CCmdUI* pCmdUI);
+ afx_msg VOID OnUpdateMakeDefault(CCmdUI* pCmdUI);
afx_msg VOID OnAppAbout();
afx_msg VOID OnAfsControlPanel();
afx_msg VOID OnUpdateDebugMode(CCmdUI* pCmdUI);
@@ -290,6 +346,11 @@ protected:
afx_msg void OnItemChanged(NMHDR* pNmHdr, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
+public:
+ afx_msg void OnLvnItemchanging(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnLvnItemActivate(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
};
/*
diff --git a/src/windows/leash/Lglobals.h b/src/windows/leash/Lglobals.h
index 7ad47a24ea..87fdd09935 100644
--- a/src/windows/leash/Lglobals.h
+++ b/src/windows/leash/Lglobals.h
@@ -22,19 +22,7 @@
////#include <loadfuncs-krb.h>
#include <loadfuncs-profile.h>
#include <loadfuncs-leash.h>
-
-typedef struct TicketList
-{
- char* theTicket;
- TicketList* next;
- char* tktEncType;
- char* keyEncType;
- int addrCount;
- char ** addrList;
- char * name;
- char * inst;
- char * realm;
-} TicketList;
+#include <krb5.h>
// toolhelp functions
TYPEDEF_FUNC(
@@ -82,32 +70,18 @@ TYPEDEF_FUNC(
TYPEDEF_FUNC(
long,
WINAPIV,
- not_an_API_LeashKRB5GetTickets,
- (TICKETINFO *, TicketList **, krb5_context *)
- );
-TYPEDEF_FUNC(
- long,
- WINAPIV,
not_an_API_LeashAFSGetToken,
(TICKETINFO *, TicketList **, char *)
);
TYPEDEF_FUNC(
long,
WINAPIV,
- not_an_API_LeashFreeTicketList,
- (TicketList**)
- );
-TYPEDEF_FUNC(
- long,
- WINAPIV,
not_an_API_LeashGetTimeServerName,
(char *, const char*)
);
extern DECL_FUNC_PTR(not_an_API_LeashKRB4GetTickets);
-extern DECL_FUNC_PTR(not_an_API_LeashKRB5GetTickets);
extern DECL_FUNC_PTR(not_an_API_LeashAFSGetToken);
-extern DECL_FUNC_PTR(not_an_API_LeashFreeTicketList);
extern DECL_FUNC_PTR(not_an_API_LeashGetTimeServerName);
extern DECL_FUNC_PTR(Leash_kdestroy);
extern DECL_FUNC_PTR(Leash_changepwd_dlg);
@@ -154,9 +128,7 @@ extern DECL_FUNC_PTR(Leash_reset_defaults);
////Do we still need this one?
#define pLeashKRB4GetTickets pnot_an_API_LeashKRB4GetTickets
-#define pLeashKRB5GetTickets pnot_an_API_LeashKRB5GetTickets
#define pLeashAFSGetToken pnot_an_API_LeashAFSGetToken
-#define pLeashFreeTicketList pnot_an_API_LeashFreeTicketList
#define pLeashGetTimeServerName pnot_an_API_LeashGetTimeServerName
// psapi functions
@@ -266,6 +238,17 @@ extern BOOL SetRegistryVariable(const CString& regVariable,
extern VOID LeashErrorBox(LPCSTR errorMsg, LPCSTR insertedString,
LPCSTR errorFlag = "Error");
+// Get ticket info for the default ccache only
+extern void LeashKRB5ListDefaultTickets(TICKETINFO *ticketinfo);
+// clean up ticket info
+extern void LeashKRB5FreeTicketInfo(TICKETINFO *ticketinfo);
+
+// Allocate TICKETINFO for each ccache that contain tickets
+extern void LeashKRB5ListAllTickets(TICKETINFO **ticketinfolist);
+// clean up ticket info list
+extern void LeashKRB5FreeTickets(TICKETINFO **ticketinfolist);
+
+
class Directory
{
@@ -283,8 +266,6 @@ public:
class TicketInfoWrapper {
public:
HANDLE lockObj;
-////Can this be commented out?
- TICKETINFO Krb4;
TICKETINFO Krb5;
TICKETINFO Afs;
};
diff --git a/src/windows/leash/Makefile.in b/src/windows/leash/Makefile.in
index 97439fd5c0..99bdc763eb 100644
--- a/src/windows/leash/Makefile.in
+++ b/src/windows/leash/Makefile.in
@@ -51,7 +51,8 @@ OBJS= \
$(OUTPRE)StdAfx.obj \
$(OUTPRE)AfsProperties.obj \
$(OUTPRE)VSroutines.obj \
- $(OUTPRE)KrbMiscConfigOpt.obj
+ $(OUTPRE)KrbMiscConfigOpt.obj \
+ $(OUTPRE)KrbListTickets.obj
RESFILE = $(OUTPRE)Leash.res
XOBJS = $(RESFILE)
@@ -66,7 +67,7 @@ LOCALINCLUDES= -I$(BUILDTOP) -I$(BUILDTOP)\include -I$(BUILDTOP)\windows\include
RFLAGS = $(LOCALINCLUDES)
RCFLAGS = $(RFLAGS) -D_WIN32 -DLEASH_APP
-DEFINES = -DWINSOCK -DWIN32 -DWINDOWS -D_AFXDLL -D_MBCS -DNO_KRB4 -DNO_STATUS_BAR
+DEFINES = -DWINSOCK -DWIN32 -DWINDOWS -D_AFXDLL -D_MBCS -DNO_KRB4 -DNO_STATUS_BAR -DUSE_MESSAGE_BOX
!ifdef NODEBUG
DEFINES = $(DEFINES)
!else
diff --git a/src/windows/leash/res/ribbon1.mfcribbon-ms b/src/windows/leash/res/ribbon1.mfcribbon-ms
index 81338d1c51..fe8f5c66b2 100644
--- a/src/windows/leash/res/ribbon1.mfcribbon-ms
+++ b/src/windows/leash/res/ribbon1.mfcribbon-ms
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<AFX_RIBBON><HEADER><VERSION>1</VERSION></HEADER><RIBBON_BAR><ELEMENT_NAME>RibbonBar</ELEMENT_NAME><ENABLE_TOOLTIPS>TRUE</ENABLE_TOOLTIPS><ENABLE_TOOLTIPS_DESCRIPTION>TRUE</ENABLE_TOOLTIPS_DESCRIPTION><ENABLE_KEYS>TRUE</ENABLE_KEYS><ENABLE_PRINTPREVIEW>TRUE</ENABLE_PRINTPREVIEW><ENABLE_DRAWUSINGFONT>FALSE</ENABLE_DRAWUSINGFONT><BUTTON_MAIN><ELEMENT_NAME>Button_Main</ELEMENT_NAME><ID><NAME>ID_BUTTON2</NAME><VALUE>32813</VALUE></ID><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><IMAGE><ID><NAME>IDB_BITMAP2</NAME><VALUE>268</VALUE></ID></IMAGE></BUTTON_MAIN><CATEGORY_MAIN><ELEMENT_NAME>Category_Main</ELEMENT_NAME><NAME>Category1</NAME><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_APP_EXIT</NAME><VALUE>57665</VALUE></ID><TEXT>E&amp;xit</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_HELP_KERBEROS_</NAME><VALUE>32784</VALUE></ID><TEXT>&amp;Help</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS><RECENT_FILE_LIST><ENABLE>FALSE</ENABLE><LABEL>Recent Documents</LABEL><WIDTH>300</WIDTH></RECENT_FILE_LIST></CATEGORY_MAIN><CATEGORIES><CATEGORY><ELEMENT_NAME>Category</ELEMENT_NAME><NAME>Home</NAME><IMAGE_SMALL><ID><NAME>IDB_HOMESMALL</NAME><VALUE>266</VALUE></ID></IMAGE_SMALL><IMAGE_LARGE><ID><NAME>IDB_HOMELARGE</NAME><VALUE>267</VALUE></ID></IMAGE_LARGE><PANELS><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_INIT_TICKET</NAME><VALUE>32807</VALUE></ID><TEXT>&amp;Get Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>2</INDEX_SMALL><INDEX_LARGE>2</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_RENEW_TICKET</NAME><VALUE>32776</VALUE></ID><TEXT>&amp;Renew Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>3</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_IMPORT_TICKET</NAME><VALUE>32806</VALUE></ID><TEXT>&amp;Import Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>4</INDEX_SMALL><INDEX_LARGE>4</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_DESTROY_TICKET</NAME><VALUE>32777</VALUE></ID><TEXT>&amp;Destroy Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><NAME>View</NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_TIME_ISSUED</NAME><VALUE>32810</VALUE></ID><TEXT>&amp;Issued</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_RENEWABLE_UNTIL</NAME><VALUE>32811</VALUE></ID><TEXT>&amp;Renewable Until</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_VALID_UNTIL</NAME><VALUE>32828</VALUE></ID><TEXT>&amp;Valid Until</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_ENCRYPTION_TYPE</NAME><VALUE>32826</VALUE></ID><TEXT>&amp;Encryption Type</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_SHOW_TICKET_FLAGS</NAME><VALUE>32812</VALUE></ID><TEXT>&amp;Flags</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><NAME>Options</NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_KILL_TIX_ONEXIT</NAME><VALUE>32785</VALUE></ID><TEXT>&amp;Destroy Tickets on Exit</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_UPPERCASE_REALM</NAME><VALUE>32787</VALUE></ID><TEXT>Allow &amp;Mixed Case Realm Name</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_AUTO_RENEW</NAME><VALUE>32808</VALUE></ID><TEXT>Automatic Ticket &amp;Renewal</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_LOW_TICKET_ALARM</NAME><VALUE>32798</VALUE></ID><TEXT>Expiration &amp;Alarm</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT></ELEMENTS></PANEL></PANELS></CATEGORY></CATEGORIES></RIBBON_BAR></AFX_RIBBON>
+<AFX_RIBBON><HEADER><VERSION>1</VERSION></HEADER><RIBBON_BAR><ELEMENT_NAME>RibbonBar</ELEMENT_NAME><ENABLE_TOOLTIPS>TRUE</ENABLE_TOOLTIPS><ENABLE_TOOLTIPS_DESCRIPTION>TRUE</ENABLE_TOOLTIPS_DESCRIPTION><ENABLE_KEYS>TRUE</ENABLE_KEYS><ENABLE_PRINTPREVIEW>TRUE</ENABLE_PRINTPREVIEW><ENABLE_DRAWUSINGFONT>FALSE</ENABLE_DRAWUSINGFONT><BUTTON_MAIN><ELEMENT_NAME>Button_Main</ELEMENT_NAME><ID><NAME>ID_BUTTON2</NAME><VALUE>32813</VALUE></ID><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><IMAGE><ID><NAME>IDB_BITMAP2</NAME><VALUE>268</VALUE></ID></IMAGE></BUTTON_MAIN><CATEGORY_MAIN><ELEMENT_NAME>Category_Main</ELEMENT_NAME><NAME>Category1</NAME><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_HELP_KERBEROS_</NAME><VALUE>32784</VALUE></ID><TEXT>&amp;Help</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_APP_ABOUT</NAME><VALUE>57664</VALUE></ID><TEXT>&amp;About</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_APP_EXIT</NAME><VALUE>57665</VALUE></ID><TEXT>E&amp;xit</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS><RECENT_FILE_LIST><ENABLE>FALSE</ENABLE><LABEL>Recent Documents</LABEL><WIDTH>300</WIDTH></RECENT_FILE_LIST></CATEGORY_MAIN><CATEGORIES><CATEGORY><ELEMENT_NAME>Category</ELEMENT_NAME><NAME>Home</NAME><IMAGE_SMALL><ID><NAME>IDB_HOMESMALL</NAME><VALUE>266</VALUE></ID></IMAGE_SMALL><IMAGE_LARGE><ID><NAME>IDB_HOMELARGE</NAME><VALUE>267</VALUE></ID></IMAGE_LARGE><PANELS><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_INIT_TICKET</NAME><VALUE>32807</VALUE></ID><TEXT>&amp;Get Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>2</INDEX_SMALL><INDEX_LARGE>2</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_RENEW_TICKET</NAME><VALUE>32776</VALUE></ID><TEXT>&amp;Renew Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>3</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_IMPORT_TICKET</NAME><VALUE>32806</VALUE></ID><TEXT>&amp;Import Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>4</INDEX_SMALL><INDEX_LARGE>4</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_DESTROY_TICKET</NAME><VALUE>32777</VALUE></ID><TEXT>&amp;Destroy Ticket</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>TRUE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_MAKE_DEFAULT</NAME><VALUE>32835</VALUE></ID><TEXT>&amp;Make Default</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>6</INDEX_SMALL><INDEX_LARGE>6</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button</ELEMENT_NAME><ID><NAME>ID_CHANGE_PASSWORD</NAME><VALUE>32779</VALUE></ID><TEXT>&amp;Change Password</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>5</INDEX_SMALL><INDEX_LARGE>5</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND><ALWAYS_DESCRIPTION>FALSE</ALWAYS_DESCRIPTION></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><NAME>View</NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_TIME_ISSUED</NAME><VALUE>32810</VALUE></ID><TEXT>&amp;Issued</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_RENEWABLE_UNTIL</NAME><VALUE>32811</VALUE></ID><TEXT>&amp;Renewable Until</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_VALID_UNTIL</NAME><VALUE>32828</VALUE></ID><TEXT>&amp;Valid Until</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_ENCRYPTION_TYPE</NAME><VALUE>32826</VALUE></ID><TEXT>&amp;Encryption Type</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_SHOW_TICKET_FLAGS</NAME><VALUE>32812</VALUE></ID><TEXT>&amp;Flags</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT></ELEMENTS></PANEL><PANEL><ELEMENT_NAME>Panel</ELEMENT_NAME><NAME>Options</NAME><INDEX>-1</INDEX><JUSTIFY_COLUMNS>FALSE</JUSTIFY_COLUMNS><CENTER_COLUMN_VERT>FALSE</CENTER_COLUMN_VERT><ELEMENTS><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_KILL_TIX_ONEXIT</NAME><VALUE>32785</VALUE></ID><TEXT>&amp;Destroy Tickets on Exit</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_UPPERCASE_REALM</NAME><VALUE>32787</VALUE></ID><TEXT>Allow &amp;Mixed Case Realm Name</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_AUTO_RENEW</NAME><VALUE>32808</VALUE></ID><TEXT>Automatic Ticket &amp;Renewal</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT><ELEMENT><ELEMENT_NAME>Button_Check</ELEMENT_NAME><ID><NAME>ID_LOW_TICKET_ALARM</NAME><VALUE>32798</VALUE></ID><TEXT>Expiration &amp;Alarm</TEXT><PALETTE_TOP>FALSE</PALETTE_TOP><ALWAYS_LARGE>FALSE</ALWAYS_LARGE><INDEX_SMALL>-1</INDEX_SMALL><INDEX_LARGE>-1</INDEX_LARGE><DEFAULT_COMMAND>TRUE</DEFAULT_COMMAND></ELEMENT></ELEMENTS></PANEL></PANELS></CATEGORY></CATEGORIES></RIBBON_BAR></AFX_RIBBON>
diff --git a/src/windows/leash/resource.h b/src/windows/leash/resource.h
index 6347318449..875b8443cc 100644
--- a/src/windows/leash/resource.h
+++ b/src/windows/leash/resource.h
@@ -334,9 +334,9 @@
#define ID_BUTTON2 32813
#define ID_BUTTON5 32816
#define ID_BUTTON4 32818
+#define ID_ABOUT 32818
#define ID_ENCRYPTION_TYPE 32826
#define ID_VALID_UNTIL 32828
-#define ID_BUTTON3 32835
#define ID_MAKE_DEFAULT 32835
// Next default values for new objects
diff --git a/src/windows/leashdll/AFSroutines.c b/src/windows/leashdll/AFSroutines.c
index 3c1dbc02d3..f04ab29792 100644
--- a/src/windows/leashdll/AFSroutines.c
+++ b/src/windows/leashdll/AFSroutines.c
@@ -207,8 +207,7 @@ not_an_API_LeashAFSGetToken(
list->name = strdup(aclient.name);
list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL;
list->realm = strdup(aclient.cell);
- list->tktEncType = NULL;
- list->keyEncType = NULL;
+ list->encTypes = NULL;
list->addrCount = 0;
list->addrList = NULL;
diff --git a/src/windows/leashdll/krb5routines.c b/src/windows/leashdll/krb5routines.c
index 48240bfc97..8de3179004 100644
--- a/src/windows/leashdll/krb5routines.c
+++ b/src/windows/leashdll/krb5routines.c
@@ -315,412 +315,326 @@ one_addr(krb5_address *a)
return(retstr);
}
-/*
- * LeashKRB5GetTickets() treats krbv5Context as an in/out variable.
- * If the caller does not provide a krb5_context, one will be allocated.
- * It is up to the caller to ensure that the context is eventually freed.
- * A context can be returned even if the function returns an error.
- */
+static void
+CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo)
+{
+ ticketinfo->issued = KRBv5Credentials.times.starttime;
+ ticketinfo->valid_until = KRBv5Credentials.times.endtime;
+ ticketinfo->renew_until =
+ KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
+ KRBv5Credentials.times.renew_till : 0;
+ _tzset();
+ if (ticketinfo->valid_until - time(0) <= 0L)
+ ticketinfo->btickets = EXPD_TICKETS;
+ else
+ ticketinfo->btickets = GOOD_TICKETS;
+}
-long
-not_an_API_LeashKRB5GetTickets(
- TICKETINFO * ticketinfo,
- TicketList** ticketList,
- krb5_context *krbv5Context
- )
+static int
+CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials,
+ char *PrincipalName, TicketList ***ticketListTail)
{
-#ifdef NO_KRB5
- return(0);
-#else
- krb5_context ctx = 0;
- krb5_ccache cache = 0;
- krb5_error_code code;
- krb5_principal KRBv5Principal;
- krb5_flags flags = 0;
- krb5_cc_cursor KRBv5Cursor;
- krb5_creds KRBv5Credentials;
- krb5_ticket *tkt=NULL;
- int StartMonth;
- int EndMonth;
- int RenewMonth;
- int StartDay;
- int EndDay;
- int RenewDay;
- char StartTimeString[256];
- char EndTimeString[256];
- char RenewTimeString[256];
- char fill;
- char *ClientName;
- char *PrincipalName;
- char *sServerName;
- char Buffer[256];
- char Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
- char StartTime[16];
- char EndTime[16];
- char RenewTime[16];
- char temp[128];
- char *sPtr;
- char *ticketFlag;
- LPCSTR functionName;
- TicketList *list = NULL;
-
- if ( ticketinfo ) {
- ticketinfo->btickets = NO_TICKETS;
- ticketinfo->principal[0] = '\0';
- }
+ krb5_error_code code = 0;
+ krb5_ticket *tkt=NULL;
+ char *sServerName = NULL;
+ char Buffer[256];
+ char *ticketFlag;
+ char *functionName = NULL;
+ TicketList *list = NULL;
+
+ functionName = "krb5_unparse_name()";
+ code = (*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName);
+ if (code)
+ goto cleanup;
- if ((code = Leash_krb5_initialize(&(*krbv5Context), &cache)))
- return(code);
+ if (!KRBv5Credentials.times.starttime)
+ KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
- ctx = (*krbv5Context);
+ memset(Buffer, '\0', sizeof(Buffer));
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#endif
- if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- Leash_krb5_error(code, "krb5_cc_set_flags()", 0, &ctx,
- &cache);
- else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND))
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
- return code;
- }
+ ticketFlag = GetTicketFlag(&KRBv5Credentials);
- if ((code = pkrb5_cc_get_principal(ctx, cache, &KRBv5Principal)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- Leash_krb5_error(code, "krb5_cc_get_principal()", 0, &ctx, &cache);
- else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND))
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
- return code;
+ // @fixme: calloc for ptr init
+ list = calloc(1, sizeof(TicketList));
+ if (list == NULL) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
}
-
- PrincipalName = NULL;
- ClientName = NULL;
- sServerName = NULL;
- if ((code = (*pkrb5_unparse_name)(ctx, KRBv5Principal,
- (char **)&PrincipalName)))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
-
- return(code);
+ list->service = strdup(sServerName);
+ if (!list->service) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
}
-
- if (!strcspn(PrincipalName, "@" ))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
-
- return(code);
+ list->issued = KRBv5Credentials.times.starttime;
+ list->valid_until = KRBv5Credentials.times.endtime;
+ if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE)
+ list->renew_until = KRBv5Credentials.times.renew_till;
+ else
+ list->renew_until = 0;
+
+ if (!pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
+ wsprintf(Buffer, "Session Key: %s Ticket: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype),
+ etype_string(tkt->enc_part.enctype));
+ pkrb5_free_ticket(ctx, tkt);
+ tkt = NULL;
+ } else {
+ wsprintf(Buffer, "Session Key: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype));
}
- if ( strcmp(ticketinfo->principal, PrincipalName) )
- wsprintf(ticketinfo->principal, "%s", PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if ((code = pkrb5_cc_start_seq_get(ctx, cache, &KRBv5Cursor)))
- {
- functionName = "krb5_cc_start_seq_get()";
- goto on_error;
+ list->encTypes = calloc(1, strlen(Buffer)+1);
+ if (list->encTypes == NULL) {
+ functionName = "calloc()";
+ code = ENOMEM;
+ goto cleanup;
}
+ strcpy(list->encTypes, Buffer);
- memset(&KRBv5Credentials, '\0', sizeof(KRBv5Credentials));
-
- while (!(code = pkrb5_cc_next_cred(ctx, cache, &KRBv5Cursor, &KRBv5Credentials)))
- {
- if ((*pkrb5_is_config_principal)(ctx, KRBv5Credentials.server))
- { /* skip configuration credentials */
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- continue;
- }
- if (!list)
- {
- list = (TicketList*) calloc(1, sizeof(TicketList));
- (*ticketList) = list;
- }
- else
- {
- list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
- list = (TicketList*) list->next;
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, &ctx, NULL);
+ if (list != NULL) {
+ not_an_API_LeashFreeTicketList(&list);
}
+ } else {
+ **ticketListTail = list;
+ *ticketListTail = &list->next;
+ }
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.client, &ClientName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
- ClientName = NULL;
- sServerName = NULL;
- continue;
- }
+ return code;
+}
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+int
+do_ccache(krb5_context ctx,
+ krb5_ccache cache,
+ TICKETINFO ***ticketInfoTail)
+{
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ krb5_principal princ = NULL;
+ krb5_flags flags;
+ krb5_error_code code;
+ char *defname = NULL;
+ char *functionName = NULL;
+ TicketList **ticketListTail;
+ TICKETINFO *ticketinfo;
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
+ flags = 0; /* turns off OPENCLOSE mode */
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ functionName = "krb5_cc_set_flags";
+ goto cleanup;
+ }
+ code = pkrb5_cc_get_principal(ctx, cache, &princ);
+ if (code) {
+ functionName = "krb5_cc_get_principal";
+ goto cleanup;
+ }
+ code = pkrb5_unparse_name(ctx, princ, &defname);
+ if (code) {
+ functionName = "krb5_unparse_name";
+ goto cleanup;
+ }
+ code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_start_seq_get";
+ goto cleanup;
+ }
- ClientName = NULL;
- sServerName = NULL;
+ ticketinfo = calloc(1, sizeof(TICKETINFO));
+ if (ticketinfo == NULL) {
+ functionName = "calloc";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
+ ticketinfo->principal = strdup(defname);
+ if (ticketinfo->principal == NULL) {
+ functionName = "strdup";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
+ if (ticketinfo->ccache_name == NULL) {
+ functionName = "strdup";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ **ticketInfoTail = ticketinfo;
+ *ticketInfoTail = &ticketinfo->next;
+ ticketListTail = &ticketinfo->ticket_list;
+ while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
+ if (pkrb5_is_config_principal(ctx, creds.server))
continue;
+ CredToTicketList(ctx, creds, defname, &ticketListTail);
+ CredToTicketInfo(creds, ticketinfo);
+ pkrb5_free_cred_contents(ctx, &creds);
+ }
+ if (code == KRB5_CC_END) {
+ code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_end_seq_get";
+ goto cleanup;
}
-
- if (!KRBv5Credentials.times.starttime)
- KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
-
- fill = ' ';
- memset(StartTimeString, '\0', sizeof(StartTimeString));
- memset(EndTimeString, '\0', sizeof(EndTimeString));
- memset(RenewTimeString, '\0', sizeof(RenewTimeString));
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.starttime, StartTimeString, 17, &fill);
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.endtime, EndTimeString, 17, &fill);
- if (KRBv5Credentials.times.renew_till >= 0)
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.renew_till, RenewTimeString, 17, &fill);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, StartTimeString, 2);
- StartDay = atoi(temp);
- memset(temp, (int)'\0', (size_t)sizeof(temp));
- memcpy(temp, EndTimeString, 2);
- EndDay = atoi(temp);
- memset(temp, (int)'\0', (size_t)sizeof(temp));
- memcpy(temp, RenewTimeString, 2);
- RenewDay = atoi(temp);
-
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &StartTimeString[3], 2);
- StartMonth = atoi(temp);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &EndTimeString[3], 2);
- EndMonth = atoi(temp);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &RenewTimeString[3], 2);
- RenewMonth = atoi(temp);
-
- while (1)
- {
- if ((sPtr = strrchr(StartTimeString, ' ')) == NULL)
- break;
-
- if (strlen(sPtr) != 1)
- break;
-
- (*sPtr) = 0;
+ flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ functionName = "krb5_cc_set_flags";
+ goto cleanup;
}
+ } else {
+ functionName = "krb5_cc_next_cred";
+ goto cleanup;
+ }
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, NULL, NULL);
+ }
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+ if (defname)
+ pkrb5_free_unparsed_name(ctx, defname);
+ return code ? 1 : 0;
+}
- while (1)
- {
- if ((sPtr = strrchr(EndTimeString, ' ')) == NULL)
- break;
-
- if (strlen(sPtr) != 1)
- break;
- (*sPtr) = 0;
- }
+//
+// Returns 0 for success, 1 for failure
+//
+int
+do_all_ccaches(krb5_context ctx, TICKETINFO **ticketinfotail)
+{
+ krb5_error_code code;
+ krb5_ccache cache;
+ krb5_cccol_cursor cursor;
+ int retval = 0;
+ char *functionName = NULL;
- while (1)
- {
- if ((sPtr = strrchr(RenewTimeString, ' ')) == NULL)
- break;
+ code = pkrb5_cccol_cursor_new(ctx, &cursor);
+ if (code) {
+ functionName = "krb5_cccol_cursor_new";
+ goto cleanup;
+ }
+ retval = 0;
+ while (!(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&
+ cache != NULL) {
+ // Note that ticketList will be updated here to point to the tail
+ // of the list but the caller of this function will remain with a
+ // pointer to the head.
+ do_ccache(ctx, cache, &ticketinfotail);
+ pkrb5_cc_close(ctx, cache);
+ }
+ if (code)
+ functionName = "krb5_cccol_cursor_next";
+ pkrb5_cccol_cursor_free(ctx, &cursor);
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, NULL, NULL);
+ }
+ return retval;
+}
- if (strlen(sPtr) != 1)
- break;
+static void FreeTicketInfo(TICKETINFO *ticketinfo)
+{
+ if (ticketinfo->principal) {
+ free(ticketinfo->principal);
+ ticketinfo->principal = NULL;
+ }
+ if (ticketinfo->ccache_name) {
+ free(ticketinfo->ccache_name);
+ ticketinfo->ccache_name = NULL;
+ }
+ if (ticketinfo->ticket_list)
+ not_an_API_LeashFreeTicketList(&ticketinfo->ticket_list);
+}
- (*sPtr) = 0;
+long
+not_an_API_LeashKRB5FreeTickets(TICKETINFO *ticketinfo)
+{
+ TICKETINFO *initial = ticketinfo; // @TEMP fixme
+ TICKETINFO *next;
+ while (ticketinfo != NULL) {
+ next = ticketinfo->next;
+ FreeTicketInfo(ticketinfo);
+ // @TEMP fixme
+ if (ticketinfo != initial) {
+ free(ticketinfo);
}
+ ticketinfo = next;
+ }
+ return 0;
+}
- memset(StartTime, '\0', sizeof(StartTime));
- memcpy(StartTime, &StartTimeString[strlen(StartTimeString) - 5], 5);
- memset(EndTime, '\0', sizeof(EndTime));
- memcpy(EndTime, &EndTimeString[strlen(EndTimeString) - 5], 5);
- memset(RenewTime, '\0', sizeof(RenewTime));
- memcpy(RenewTime, &RenewTimeString[strlen(RenewTimeString) - 5], 5);
-
- memset(temp, '\0', sizeof(temp));
- strcpy(temp, ClientName);
- if (!strcmp(ClientName, PrincipalName))
- memset(temp, '\0', sizeof(temp));
+/*
+ * LeashKRB5GetTickets() treats krbv5Context as an in/out variable.
+ * If the caller does not provide a krb5_context, one will be allocated.
+ * It is up to the caller to ensure that the context is eventually freed.
+ * A context can be returned even if the function returns an error.
+ */
- memset(Buffer, '\0', sizeof(Buffer));
+long
+not_an_API_LeashKRB5GetTickets(TICKETINFO *ticketinfo,
+ krb5_context *krbv5Context)
+{
+ krb5_error_code code;
+ krb5_principal me = 0;
+ krb5_context ctx = 0;
+ krb5_ccache cache = 0;
+ char *PrincipalName = NULL;
- ticketFlag = GetTicketFlag(&KRBv5Credentials);
+ code = Leash_krb5_initialize(krbv5Context);
+ if (code)
+ return code;
- if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) {
- wsprintf(Buffer,"%s %02d %s %s %02d %s [%s %02d %s] %s %s %s",
- Months[StartMonth - 1], StartDay, StartTime,
- Months[EndMonth - 1], EndDay, EndTime,
- Months[RenewMonth - 1], RenewDay, RenewTime,
- sServerName,
- temp, ticketFlag);
- } else {
- wsprintf(Buffer,"%s %02d %s %s %02d %s %s %s %s",
- Months[StartMonth - 1], StartDay, StartTime,
- Months[EndMonth - 1], EndDay, EndTime,
- sServerName,
- temp, ticketFlag);
- }
- list->theTicket = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->theTicket)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->theTicket, Buffer);
- list->name = NULL;
- list->inst = NULL;
- list->realm = NULL;
-
- if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
- wsprintf(Buffer, "Ticket Encryption Type: %s", etype_string(tkt->enc_part.enctype));
- list->tktEncType = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->tktEncType)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->tktEncType, Buffer);
+ ctx = *krbv5Context;
- pkrb5_free_ticket(ctx, tkt);
- tkt = NULL;
- } else {
- list->tktEncType = NULL;
- }
+ // @TEMP fixme; shouldn't be necessary
+ // save default principal name in ticketinfo
+ if (ticketinfo != NULL) {
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal = NULL;
+ ticketinfo->ccache_name = NULL;
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
- wsprintf(Buffer, "Session Key Type: %s", etype_string(KRBv5Credentials.keyblock.enctype));
- list->keyEncType = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->keyEncType)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
+ code = pkrb5_cc_default(ctx, &cache);
+ if (code)
+ goto cleanup;
+ ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
+ if (ticketinfo->ccache_name == NULL) {
+ code = ENOMEM;
+ goto cleanup;
}
- strcpy(list->keyEncType, Buffer);
-
- if ( KRBv5Credentials.addresses && KRBv5Credentials.addresses[0] ) {
- int n = 0;
- while ( KRBv5Credentials.addresses[n] )
- n++;
- list->addrList = calloc(1, n * sizeof(char *));
- if (!list->addrList) {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
+ if (!pkrb5_cc_get_principal(ctx, cache, &me)) {
+ code = (*pkrb5_unparse_name)(ctx, me, &PrincipalName);
+ if (code)
+ goto cleanup;
+ if (PrincipalName) {
+ ticketinfo->principal = strdup(PrincipalName);
+ pkrb5_free_unparsed_name(ctx, PrincipalName);
}
- list->addrCount = n;
- for ( n=0; n<list->addrCount; n++ ) {
- wsprintf(Buffer, "Address: %s", one_addr(KRBv5Credentials.addresses[n]));
- list->addrList[n] = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->addrList[n])
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->addrList[n], Buffer);
- }
- }
-
- ticketinfo->issue_date = KRBv5Credentials.times.starttime;
- ticketinfo->lifetime = KRBv5Credentials.times.endtime - KRBv5Credentials.times.starttime;
- ticketinfo->renew_till = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
- KRBv5Credentials.times.renew_till : 0;
- _tzset();
- if ( ticketinfo->issue_date + ticketinfo->lifetime - time(0) <= 0L )
- ticketinfo->btickets = EXPD_TICKETS;
- else
- ticketinfo->btickets = GOOD_TICKETS;
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
-
- if (sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
-
- ClientName = NULL;
- sServerName = NULL;
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- }
-
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
-
- if (sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
-
- if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
- {
- if ((code = pkrb5_cc_end_seq_get(ctx, cache, &KRBv5Cursor)))
- {
- functionName = "krb5_cc_end_seq_get()";
- goto on_error;
}
-
- flags = KRB5_TC_OPENCLOSE;
-#ifdef KRB5_TC_NOTICKET
- flags |= KRB5_TC_NOTICKET;
-#endif
- if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
- {
- functionName = "krb5_cc_set_flags()";
- goto on_error;
- }
- }
- else
- {
- functionName = "krb5_cc_next_cred()";
- goto on_error;
- }
-
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
}
- return(code);
+ do_all_ccaches(*krbv5Context, &ticketinfo->next);
+ // @TEMP aggregate ticket info here?
- on_error:
- Leash_krb5_error(code, functionName, 0, &(*krbv5Context), &cache);
- return(code);
-#endif //!NO_KER5
+cleanup:
+ if (code)
+ not_an_API_LeashKRB5FreeTickets(ticketinfo);
+ if (cache)
+ pkrb5_cc_close(ctx, cache);
+ if (me)
+ pkrb5_free_principal(ctx, me);
+ return code;
}
@@ -831,13 +745,15 @@ DWORD publicIP
#else
krb5_error_code code = 0;
krb5_context ctx = 0;
- krb5_ccache cc = 0;
+ krb5_ccache cc = 0, defcache = 0;
krb5_principal me = 0;
char* name = 0;
krb5_creds my_creds;
krb5_get_init_creds_opt * options = NULL;
krb5_address ** addrs = NULL;
int i = 0, addr_count = 0;
+ int cc_new = 0;
+ const char * deftype = NULL;
if (!pkrb5_init_context)
return 0;
@@ -857,12 +773,29 @@ DWORD publicIP
code = pkrb5_get_init_creds_opt_alloc(ctx, &options);
if (code) goto cleanup;
- code = pkrb5_cc_default(ctx, &cc);
+ code = pkrb5_cc_default(ctx, &defcache);
if (code) goto cleanup;
code = pkrb5_parse_name(ctx, principal_name, &me);
if (code) goto cleanup;
+ deftype = pkrb5_cc_get_type(ctx, defcache);
+ if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) {
+ /* Use an existing cache for the specified principal if we can. */
+ code = pkrb5_cc_cache_match(ctx, me, &cc);
+ if (code != 0 && code != KRB5_CC_NOTFOUND)
+ goto cleanup;
+ if (code == KRB5_CC_NOTFOUND) {
+ code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc);
+ if (code)
+ goto cleanup;
+ cc_new = 1;
+ }
+ pkrb5_cc_close(ctx, defcache);
+ } else {
+ cc = defcache;
+ }
+
code = pkrb5_unparse_name(ctx, me, &name);
if (code) goto cleanup;
@@ -957,7 +890,24 @@ DWORD publicIP
0, // start time
0, // service name
options);
+ // @TODO: make this an option
+ if ((!code) && (cc != defcache)) {
+ code = pkrb5_cc_switch(ctx, cc);
+ if (!code) {
+ const char *cctype = pkrb5_cc_get_type(ctx, cc);
+ if (cctype != NULL) {
+ char defname[20];
+ sprintf_s(defname, sizeof(defname), "%s:", cctype);
+ pkrb5int_cc_user_set_default_name(ctx, defname);
+ }
+ }
+ }
cleanup:
+ if (code && cc_new) {
+ // don't leave newly-generated empty ccache lying around on failure
+ pkrb5_cc_destroy(ctx, cc);
+ cc = NULL;
+ }
if ( addrs ) {
for ( i=0;i<addr_count;i++ ) {
if ( addrs[i] ) {
@@ -1002,7 +952,11 @@ Leash_krb5_kdestroy(
ctx = NULL;
cache = NULL;
- if (rc = Leash_krb5_initialize(&ctx, &cache))
+ rc = Leash_krb5_initialize(&ctx);
+ if (rc)
+ return(rc);
+
+ if (rc = pkrb5_cc_default(ctx, &cache))
return(rc);
rc = pkrb5_cc_destroy(ctx, cache);
@@ -1015,56 +969,62 @@ Leash_krb5_kdestroy(
#endif //!NO_KRB5
}
+krb5_error_code
+Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache)
+{
+ krb5_error_code rc;
+ krb5_flags flags;
+
+ char *functionName = NULL;
+ if (*cache == 0) {
+ rc = pkrb5_cc_default(*ctx, cache);
+ if (rc) {
+ functionName = "krb5_cc_default()";
+ goto on_error;
+ }
+ }
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#endif
+ rc = pkrb5_cc_set_flags(*ctx, *cache, flags);
+ if (rc) {
+ if (rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) {
+ if (*cache != NULL && *ctx != NULL)
+ pkrb5_cc_close(*ctx, *cache);
+ } else {
+ functionName = "krb5_cc_set_flags()";
+ goto on_error;
+ }
+ }
+on_error:
+ if (rc && functionName) {
+ Leash_krb5_error(rc, functionName, 0, ctx, cache);
+ }
+ return rc;
+}
+
/**************************************/
/* Leash_krb5_initialize(): */
/**************************************/
-int Leash_krb5_initialize(krb5_context *ctx, krb5_ccache *cache)
+int Leash_krb5_initialize(krb5_context *ctx)
{
#ifdef NO_KRB5
return(0);
#else
LPCSTR functionName = NULL;
- int freeContextFlag = 0;
krb5_error_code rc;
- krb5_flags flags;
if (pkrb5_init_context == NULL)
return 1;
if (*ctx == 0) {
- if (rc = (*pkrb5_init_context)(ctx))
- {
- functionName = "krb5_init_context()";
- goto on_error;
- }
- freeContextFlag = 1;
- }
-
- if (*cache == 0 && (rc = pkrb5_cc_default(*ctx, cache)))
- {
- functionName = "krb5_cc_default()";
- goto on_error;
- }
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#endif
- if ((rc = pkrb5_cc_set_flags(*ctx, *cache, flags)))
- {
- if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
- Leash_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
- cache);
- else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL)
- {
- if (*cache != NULL)
- pkrb5_cc_close(*ctx, *cache);
+ if (rc = (*pkrb5_init_context)(ctx)) {
+ functionName = "krb5_init_context()";
+ return Leash_krb5_error(rc, functionName, 0, ctx, NULL);
}
- return rc;
}
- return 0;
-
- on_error:
- return Leash_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
+ return 0;
#endif //!NO_KRB5
}
@@ -1083,36 +1043,25 @@ Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
#ifdef USE_MESSAGE_BOX
char message[256];
const char *errText;
- int krb5Error = ((int)(rc & 255));
-
- /*
- switch (krb5Error)
- {
- // Wrong password
- case 31:
- case 8:
- return;
- }
- */
errText = perror_message(rc);
_snprintf(message, sizeof(message),
"%s\n(Kerberos error %ld)\n\n%s failed",
errText,
- krb5Error,
+ rc,
FailedFunctionName);
+ message[sizeof(message)-1] = 0;
MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
MB_TASKMODAL |
MB_SETFOREGROUND);
#endif /* USE_MESSAGE_BOX */
- if (*ctx != NULL)
- {
- if (*cache != NULL) {
- pkrb5_cc_close(*ctx, *cache);
- *cache = NULL;
- }
+ if (ctx != NULL && *ctx != NULL) {
+ if (cache != NULL && *cache != NULL) {
+ pkrb5_cc_close(*ctx, *cache);
+ *cache = NULL;
+ }
if (FreeContextFlag) {
pkrb5_free_context(*ctx);
@@ -1139,7 +1088,6 @@ Leash_ms2mit(BOOL save_creds)
krb5_creds creds;
krb5_cc_cursor cursor=0;
krb5_principal princ = 0;
- char *cache_name=NULL;
BOOL rc = FALSE;
if ( !pkrb5_init_context )
diff --git a/src/windows/leashdll/leash-int.h b/src/windows/leashdll/leash-int.h
index fb7617ed34..b5c0b2738b 100644
--- a/src/windows/leashdll/leash-int.h
+++ b/src/windows/leashdll/leash-int.h
@@ -162,7 +162,9 @@ BOOL IsKerberosLogon(VOID);
int Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
int FreeContextFlag, krb5_context *ctx,
krb5_ccache *cache);
-int Leash_krb5_initialize(krb5_context *, krb5_ccache *);
+int Leash_krb5_initialize(krb5_context *);
+krb5_error_code
+Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache);
#endif /* NO_KRB5 */
LPSTR err_describe(LPSTR buf, long code);
diff --git a/src/windows/leashdll/leashdll.h b/src/windows/leashdll/leashdll.h
index a045583da2..63cfe234f8 100644
--- a/src/windows/leashdll/leashdll.h
+++ b/src/windows/leashdll/leashdll.h
@@ -58,6 +58,8 @@ void FAR Leash_load_com_err_callback(FARPROC,FARPROC,FARPROC);
#endif
#include <ntsecapi.h>
+#include <krb5.h>
+
#ifndef NO_KRB4
extern HINSTANCE hKrb4;
#endif
@@ -73,19 +75,6 @@ extern HINSTANCE hProfile;
#define LEASH_PRIORITY_LOW 0
#define LEASH_PRIORITY_HIGH 1
-typedef struct TicketList
-{
- char* theTicket;
- struct TicketList* next;
- char* tktEncType;
- char* keyEncType;
- int addrCount;
- char ** addrList;
- char * name;
- char * inst;
- char * realm;
-} TicketList;
-
///////////////////////////////////////////////////////////////////////////////
#ifdef _WIN64
diff --git a/src/windows/leashdll/leashw32.def b/src/windows/leashdll/leashw32.def
index 25af0e2ea8..5df8309ae4 100644
--- a/src/windows/leashdll/leashw32.def
+++ b/src/windows/leashdll/leashw32.def
@@ -106,3 +106,4 @@ EXPORTS
not_an_API_LeashKRB4GetTickets
not_an_API_LeashGetTimeServerName
not_an_API_Leash_AcquireInitialTicketsIfNeeded
+ not_an_API_LeashKRB5FreeTickets
diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c
index 1a0bf14305..614bb799eb 100644
--- a/src/windows/leashdll/lshfunc.c
+++ b/src/windows/leashdll/lshfunc.c
@@ -867,26 +867,9 @@ not_an_API_LeashFreeTicketList(TicketList** ticketList)
killList = tempList;
tempList = (TicketList*)tempList->next;
- free(killList->theTicket);
- if (killList->tktEncType)
- free(killList->tktEncType);
- if (killList->keyEncType)
- free(killList->keyEncType);
- if (killList->addrCount) {
- int n;
- for ( n=0; n<killList->addrCount; n++) {
- if (killList->addrList[n])
- free(killList->addrList[n]);
- }
- }
- if (killList->addrList)
- free(killList->addrList);
- if (killList->name)
- free(killList->name);
- if (killList->inst)
- free(killList->inst);
- if (killList->realm)
- free(killList->realm);
+ free(killList->service);
+ if (killList->encTypes)
+ free(killList->encTypes);
free(killList);
}
@@ -2873,8 +2856,7 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
}
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
if ( ticketinfo.btickets != GOOD_TICKETS &&
dwMsLsaImport && Leash_importable() ) {
@@ -2939,8 +2921,8 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
if ( import ) {
Leash_import();
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
}
}
@@ -2958,7 +2940,7 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
strncpy(ccname, ccachename, cclen);
ccname[cclen-1] = '\0';
}
-
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
if ( !context )
pkrb5_free_context(ctx);
}
@@ -2968,7 +2950,6 @@ static void
acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
char * ccname, int cclen)
{
- TicketList *list = NULL;
TICKETINFO ticketinfo;
krb5_context ctx;
DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
@@ -2992,8 +2973,7 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
}
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
pkrb5_unparse_name(ctx, desiredPrincipal, &name);
@@ -3032,14 +3012,14 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
SetEnvironmentVariable("KRB5CCNAME", ccachename);
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
if (ticketinfo.btickets != GOOD_TICKETS) {
Leash_import();
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
}
}
}
@@ -3059,6 +3039,7 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
ccname[cclen-1] = '\0';
}
}
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
if (name)
pkrb5_free_unparsed_name(ctx, name);