diff options
author | Kevin Wasserman <kevin.wasserman@painless-security.com> | 2012-07-23 04:30:27 -0400 |
---|---|---|
committer | Ben Kaduk <kaduk@mit.edu> | 2012-08-24 12:22:58 -0400 |
commit | 9bc411e72fce5bed3ed00ae5b09f8c239309bae0 (patch) | |
tree | 0b457e8c5e0d1201f2bc4a58e2540ca3eba44ca4 | |
parent | dbfd93ea15b12472e4612af928f8baabb2cda611 (diff) | |
download | krb5-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
-rw-r--r-- | src/windows/include/leashwin.h | 30 | ||||
-rw-r--r-- | src/windows/leash/KrbListTickets.cpp | 393 | ||||
-rw-r--r-- | src/windows/leash/Leash.cpp | 153 | ||||
-rw-r--r-- | src/windows/leash/Leash.h | 3 | ||||
-rw-r--r-- | src/windows/leash/Leash.rc | 4 | ||||
-rw-r--r-- | src/windows/leash/LeashView.cpp | 1432 | ||||
-rw-r--r-- | src/windows/leash/LeashView.h | 65 | ||||
-rw-r--r-- | src/windows/leash/Lglobals.h | 43 | ||||
-rw-r--r-- | src/windows/leash/Makefile.in | 5 | ||||
-rw-r--r-- | src/windows/leash/res/ribbon1.mfcribbon-ms | 2 | ||||
-rw-r--r-- | src/windows/leash/resource.h | 2 | ||||
-rw-r--r-- | src/windows/leashdll/AFSroutines.c | 3 | ||||
-rw-r--r-- | src/windows/leashdll/krb5routines.c | 790 | ||||
-rw-r--r-- | src/windows/leashdll/leash-int.h | 4 | ||||
-rw-r--r-- | src/windows/leashdll/leashdll.h | 15 | ||||
-rw-r--r-- | src/windows/leashdll/leashw32.def | 1 | ||||
-rw-r--r-- | src/windows/leashdll/lshfunc.c | 45 |
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&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>&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>&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>&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>&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>&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>&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>&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>&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>&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>&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>&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 &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 &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 &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>&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>&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&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>&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>&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>&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>&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>&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>&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>&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>&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>&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>&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>&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>&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 &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 &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 &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); |