diff options
Diffstat (limited to 'src/windows/leash/LeashView.cpp')
| -rw-r--r-- | src/windows/leash/LeashView.cpp | 1432 |
1 files changed, 733 insertions, 699 deletions
diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp index 6a28727c8..c139ff76e 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; + } +} |
