Path: blob/main/crypto/krb5/src/windows/leash/LeashView.cpp
34889 views
//*****************************************************************************1// File: LeashView.cpp2// By: Arthur David Leather3// Created: 12/02/984// Copyright @1998 Massachusetts Institute of Technology - All rights reserved.5// Description: CPP file for LeashView.h. Contains variables and functions6// for the Leash FormView7//8// History:9//10// MM/DD/YY Inits Description of Change11// 12/02/98 ADL Original12// 20030508 JEA Added13//*****************************************************************************1415#include "stdafx.h"16#include <afxpriv.h>17#include "Leash.h"18#include "LeashDoc.h"19#include "LeashView.h"20#include "MainFrm.h"21#include "reminder.h"22#include "lglobals.h"23#include "LeashDebugWindow.h"24#include "LeashMessageBox.h"25#include "LeashAboutBox.h"26#include <krb5.h>2728#ifdef _DEBUG29#define new DEBUG_NEW30#undef THIS_FILE31static CHAR THIS_FILE[] = __FILE__;32#endif3334#pragma comment(lib, "uxtheme")35/////////////////////////////////////////////////////////////////////////////36// CLeashView3738IMPLEMENT_DYNCREATE(CLeashView, CListView)3940BEGIN_MESSAGE_MAP(CLeashView, CListView)41//{{AFX_MSG_MAP(CLeashView)42ON_MESSAGE(WM_WARNINGPOPUP, OnWarningPopup)43ON_MESSAGE(WM_GOODBYE, OnGoodbye)44ON_MESSAGE(WM_TRAYICON, OnTrayIcon)45ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TREEVIEW, OnItemexpandedTreeview)46ON_WM_CREATE()47ON_WM_SHOWWINDOW()48ON_COMMAND(ID_INIT_TICKET, OnInitTicket)49ON_COMMAND(ID_RENEW_TICKET, OnRenewTicket)50ON_COMMAND(ID_DESTROY_TICKET, OnDestroyTicket)51ON_COMMAND(ID_CHANGE_PASSWORD, OnChangePassword)52ON_COMMAND(ID_MAKE_DEFAULT, OnMakeDefault)53ON_COMMAND(ID_UPDATE_DISPLAY, OnUpdateDisplay)54ON_COMMAND(ID_SYN_TIME, OnSynTime)55ON_COMMAND(ID_DEBUG_MODE, OnDebugMode)56ON_COMMAND(ID_LARGE_ICONS, OnLargeIcons)57ON_COMMAND(ID_TIME_ISSUED, OnTimeIssued)58ON_COMMAND(ID_VALID_UNTIL, OnValidUntil)59ON_COMMAND(ID_RENEWABLE_UNTIL, OnRenewableUntil)60ON_COMMAND(ID_SHOW_TICKET_FLAGS, OnShowTicketFlags)61ON_COMMAND(ID_ENCRYPTION_TYPE, OnEncryptionType)62ON_COMMAND(ID_CCACHE_NAME, OnCcacheName)63ON_UPDATE_COMMAND_UI(ID_TIME_ISSUED, OnUpdateTimeIssued)64ON_UPDATE_COMMAND_UI(ID_VALID_UNTIL, OnUpdateValidUntil)65ON_UPDATE_COMMAND_UI(ID_RENEWABLE_UNTIL, OnUpdateRenewableUntil)66ON_UPDATE_COMMAND_UI(ID_SHOW_TICKET_FLAGS, OnUpdateShowTicketFlags)67ON_UPDATE_COMMAND_UI(ID_ENCRYPTION_TYPE, OnUpdateEncryptionType)68ON_UPDATE_COMMAND_UI(ID_CCACHE_NAME, OnUpdateCcacheName)69ON_COMMAND(ID_UPPERCASE_REALM, OnUppercaseRealm)70ON_COMMAND(ID_KILL_TIX_ONEXIT, OnKillTixOnExit)71ON_UPDATE_COMMAND_UI(ID_UPPERCASE_REALM, OnUpdateUppercaseRealm)72ON_UPDATE_COMMAND_UI(ID_KILL_TIX_ONEXIT, OnUpdateKillTixOnExit)73ON_WM_DESTROY()74ON_UPDATE_COMMAND_UI(ID_DESTROY_TICKET, OnUpdateDestroyTicket)75ON_UPDATE_COMMAND_UI(ID_INIT_TICKET, OnUpdateInitTicket)76ON_UPDATE_COMMAND_UI(ID_RENEW_TICKET, OnUpdateRenewTicket)77ON_COMMAND(ID_APP_ABOUT, OnAppAbout)78ON_UPDATE_COMMAND_UI(ID_DEBUG_MODE, OnUpdateDebugMode)79ON_UPDATE_COMMAND_UI(ID_CFG_FILES, OnUpdateCfgFiles)80ON_COMMAND(ID_LEASH_RESTORE, OnLeashRestore)81ON_COMMAND(ID_LEASH_MINIMIZE, OnLeashMinimize)82ON_COMMAND(ID_LOW_TICKET_ALARM, OnLowTicketAlarm)83ON_COMMAND(ID_AUTO_RENEW, OnAutoRenew)84ON_UPDATE_COMMAND_UI(ID_LOW_TICKET_ALARM, OnUpdateLowTicketAlarm)85ON_UPDATE_COMMAND_UI(ID_AUTO_RENEW, OnUpdateAutoRenew)86ON_UPDATE_COMMAND_UI(ID_MAKE_DEFAULT, OnUpdateMakeDefault)87ON_UPDATE_COMMAND_UI(ID_PROPERTIES, OnUpdateProperties)88ON_COMMAND(ID_HELP_KERBEROS_, OnHelpKerberos)89ON_COMMAND(ID_HELP_LEASH32, OnHelpLeash32)90ON_COMMAND(ID_HELP_WHYUSELEASH32, OnHelpWhyuseleash32)91ON_WM_SIZE()92ON_WM_LBUTTONDOWN()93ON_WM_CLOSE()94ON_WM_HSCROLL()95ON_WM_VSCROLL()96ON_WM_SYSCOLORCHANGE()97ON_MESSAGE(ID_OBTAIN_TGT_WITH_LPARAM, OnObtainTGTWithParam)98ON_NOTIFY(HDN_ITEMCHANGED, 0, OnItemChanged)99//}}AFX_MSG_MAP100101ON_NOTIFY_REFLECT(LVN_ITEMCHANGING, &CLeashView::OnLvnItemchanging)102ON_NOTIFY_REFLECT(LVN_ITEMACTIVATE, &CLeashView::OnLvnItemActivate)103ON_NOTIFY_REFLECT(LVN_KEYDOWN, &CLeashView::OnLvnKeydown)104ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CLeashView::OnNMCustomdraw)105END_MESSAGE_MAP()106107108time_t CLeashView::m_ticketTimeLeft = 0; // # of seconds left before tickets expire109INT CLeashView::m_ticketStatusKrb5 = 0; // Defense Condition: are we low on tickets?110INT CLeashView::m_warningOfTicketTimeLeftKrb5 = 0; // Prevents warning box from coming up repeatively111INT CLeashView::m_warningOfTicketTimeLeftLockKrb5 = 0;112INT CLeashView::m_updateDisplayCount;113INT CLeashView::m_alreadyPlayedDisplayCount;114INT CLeashView::m_autoRenewTickets = 0;115BOOL CLeashView::m_lowTicketAlarmSound;116INT CLeashView::m_autoRenewalAttempted = 0;117LONG CLeashView::m_timerMsgNotInProgress = 1;118ViewColumnInfo CLeashView::sm_viewColumns[] =119{120{"Principal", true, -1, 200}, // PRINCIPAL121{"Issued", false, ID_TIME_ISSUED, 100}, // TIME_ISSUED122{"Renewable Until", false, ID_RENEWABLE_UNTIL, 100}, // RENEWABLE_UNTIL123{"Valid Until", true, ID_VALID_UNTIL, 100}, // VALID_UNTIL124{"Encryption Type", false, ID_ENCRYPTION_TYPE, 100}, // ENCRYPTION_TYPE125{"Flags", false, ID_SHOW_TICKET_FLAGS, 100}, // TICKET_FLAGS126{"Credential Cache", false, ID_CCACHE_NAME, 105}, // CACHE_NAME127};128129static struct TicketFlag {130unsigned long m_flag;131const LPTSTR m_description;132} sm_TicketFlags[] =133{134{TKT_FLG_FORWARDABLE, _T("Forwardable")},135{TKT_FLG_FORWARDED, _T("Forwarded")},136{TKT_FLG_PROXIABLE, _T("Proxiable")},137{TKT_FLG_PROXY, _T("Proxy")},138{TKT_FLG_RENEWABLE, _T("Renewable")},139};140141static void krb5TicketFlagsToString(unsigned long flags, LPTSTR *outStr)142{143const int numFlags = sizeof(sm_TicketFlags) / sizeof(sm_TicketFlags[0]);144int strSize = 1;145LPTSTR str;146// pass 1: compute size147for (int i = 0; i < numFlags; i++) {148if (flags & sm_TicketFlags[i].m_flag) {149if (strSize > 1)150strSize += 2;151strSize += strlen(sm_TicketFlags[i].m_description);152}153}154// allocate155str = (LPSTR)malloc(strSize);156if (str != NULL) {157*str = 0;158// pass 2: construct string159for (int i = 0; i < numFlags; i++) {160if (flags & sm_TicketFlags[i].m_flag) {161if (str[0])162_tcscat_s(str, strSize, _T(", "));163_tcscat_s(str, strSize, sm_TicketFlags[i].m_description);164}165}166}167*outStr = str;168}169170171static HFONT CreateBoldFont(HFONT font)172{173// @TODO: Should probably enumerate fonts here instead since this174// does not actually seem to guarantee returning a new font175// distinguishable from the original.176LOGFONT fontAttributes = { 0 };177::GetObject(font, sizeof(fontAttributes), &fontAttributes);178fontAttributes.lfWeight = FW_BOLD;179HFONT boldFont = ::CreateFontIndirect(&fontAttributes);180return boldFont;181}182183static HFONT CreateItalicFont(HFONT font)184{185LOGFONT fontAttributes = { 0 };186::GetObject(font, sizeof(fontAttributes), &fontAttributes);187fontAttributes.lfItalic = TRUE;188HFONT italicFont = ::CreateFontIndirect(&fontAttributes);189return italicFont;190}191192static HFONT CreateBoldItalicFont(HFONT font)193{194LOGFONT fontAttributes = { 0 };195::GetObject(font, sizeof(fontAttributes), &fontAttributes);196fontAttributes.lfWeight = FW_BOLD;197fontAttributes.lfItalic = TRUE;198HFONT boldItalicFont = ::CreateFontIndirect(&fontAttributes);199return boldItalicFont;200}201202bool change_icon_size = true;203204void TimestampToFileTime(time_t t, LPFILETIME pft)205{206// Note that LONGLONG is a 64-bit value207ULONGLONG ll;208209ll = UInt32x32To64((DWORD)t, 10000000) + 116444736000000000;210pft->dwLowDateTime = (DWORD)ll;211pft->dwHighDateTime = ll >> 32;212}213214// allocate outstr215void TimestampToLocalizedString(time_t t, LPTSTR *outStr)216{217FILETIME ft, lft;218SYSTEMTIME st;219TimestampToFileTime(t, &ft);220FileTimeToLocalFileTime(&ft, &lft);221FileTimeToSystemTime(&lft, &st);222TCHAR timeFormat[80]; // 80 is max required for LOCALE_STIMEFORMAT223GetLocaleInfo(LOCALE_SYSTEM_DEFAULT,224LOCALE_STIMEFORMAT,225timeFormat,226sizeof(timeFormat) / sizeof(timeFormat[0]));227228int timeSize = GetTimeFormat(LOCALE_SYSTEM_DEFAULT,229TIME_NOSECONDS,230&st,231timeFormat,232NULL,2330);234// Using dateFormat prevents localization of Month/day order,235// but there is no other way AFAICT to suppress the year236TCHAR * dateFormat = "MMM dd' '";237int dateSize = GetDateFormat(LOCALE_SYSTEM_DEFAULT,2380, // flags239&st,240dateFormat, // format241NULL, // date string2420);243244if (*outStr)245free(*outStr);246247// Allocate string for combined date and time,248// but only need one terminating NULL249LPTSTR str = (LPSTR)malloc((dateSize + timeSize - 1) * sizeof(TCHAR));250if (!str) {251// LeashWarn allocation failure252*outStr = NULL;253return;254}255GetDateFormat(LOCALE_SYSTEM_DEFAULT,2560, // flags257&st,258dateFormat, // format259&str[0],260dateSize);261262GetTimeFormat(LOCALE_SYSTEM_DEFAULT,263TIME_NOSECONDS,264&st,265timeFormat,266&str[dateSize - 1],267timeSize);268*outStr = str;269}270271#define SECONDS_PER_MINUTE (60)272#define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE)273#define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR)274#define MAX_DURATION_STR 255275// convert time in seconds to string276void DurationToString(long delta, LPTSTR *outStr)277{278int days;279int hours;280int minutes;281TCHAR minutesStr[MAX_DURATION_STR+1];282TCHAR hoursStr[MAX_DURATION_STR+1];283284if (*outStr)285free(*outStr);286*outStr = (LPSTR)malloc((MAX_DURATION_STR + 1)* sizeof(TCHAR));287if (!(*outStr))288return;289290days = delta / SECONDS_PER_DAY;291delta -= days * SECONDS_PER_DAY;292hours = delta / SECONDS_PER_HOUR;293delta -= hours * SECONDS_PER_HOUR;294minutes = delta / SECONDS_PER_MINUTE;295296_snprintf(minutesStr, MAX_DURATION_STR, "%d m", minutes);297minutesStr[MAX_DURATION_STR] = 0;298299_snprintf(hoursStr, MAX_DURATION_STR, "%d h", hours);300hoursStr[MAX_DURATION_STR] = 0;301302if (days > 0) {303_snprintf(*outStr, MAX_DURATION_STR, "(%d d, %s remaining)", days,304hoursStr);305} else if (hours > 0) {306_snprintf(*outStr, MAX_DURATION_STR, "(%s, %s remaining)", hoursStr,307minutesStr);308} else {309_snprintf(*outStr, MAX_DURATION_STR, "(%s remaining)", minutesStr);310}311(*outStr)[MAX_DURATION_STR] = 0;312}313314/////////////////////////////////////////////////////////////////////////////315// CLeashView construction/destruction316317CLeashView::CLeashView()318{319////@#+Need removing as well!320m_startup = TRUE;321m_warningOfTicketTimeLeftKrb5 = 0;322m_warningOfTicketTimeLeftLockKrb5 = 0;323m_largeIcons = 0;324m_destroyTicketsOnExit = 0;325m_debugWindow = 0;326m_upperCaseRealm = 0;327m_lowTicketAlarm = 0;328329m_pDebugWindow = NULL;330m_pDebugWindow = new CLeashDebugWindow(this);331if (!m_pDebugWindow)332{333AfxMessageBox("There is a problem with the Leash Debug Window!",334MB_OK|MB_ICONSTOP);335}336337m_debugStartUp = TRUE;338m_isMinimum = FALSE;339m_lowTicketAlarmSound = FALSE;340m_alreadyPlayed = FALSE;341ResetTreeNodes();342m_hMenu = NULL;343m_pApp = NULL;344m_ccacheDisplay = NULL;345m_autoRenewTickets = 0;346m_autoRenewalAttempted = 0;347m_pWarningMessage = NULL;348m_bIconAdded = FALSE;349m_bIconDeleted = FALSE;350m_BaseFont = NULL;351m_BoldFont = NULL;352m_ItalicFont = NULL;353m_aListItemInfo = NULL;354}355356357CLeashView::~CLeashView()358{359CCacheDisplayData *elem = m_ccacheDisplay;360while (elem) {361CCacheDisplayData *next = elem->m_next;362delete elem;363elem = next;364}365m_ccacheDisplay = NULL;366// destroys window if not already destroyed367if (m_pDebugWindow)368delete m_pDebugWindow;369if (m_BoldFont)370DeleteObject(m_BoldFont);371if (m_ItalicFont)372DeleteObject(m_ItalicFont);373if (m_aListItemInfo)374delete[] m_aListItemInfo;375}376377void CLeashView::OnItemChanged(NMHDR* pNmHdr, LRESULT* pResult)378{379NMHEADER* pHdr = (NMHEADER*)pNmHdr;380if (!pHdr->pitem)381return;382if (!pHdr->pitem->mask & HDI_WIDTH)383return;384385// Sync column width and save to registry386for (int i = 0, columnIndex = 0; i < NUM_VIEW_COLUMNS; i++) {387ViewColumnInfo &info = sm_viewColumns[i];388if ((info.m_enabled) && (columnIndex++ == pHdr->iItem)) {389info.m_columnWidth = pHdr->pitem->cxy;390if (m_pApp)391m_pApp->WriteProfileInt("ColumnWidths", info.m_name, info.m_columnWidth);392break;393}394}395}396397BOOL CLeashView::PreCreateWindow(CREATESTRUCT& cs)398{399// TODO: Modify the Window class or styles here by modifying400// the CREATESTRUCT cs401402return CListView::PreCreateWindow(cs);403}404405/////////////////////////////////////////////////////////////////////////////406// CLeashView diagnostics407408#ifdef _DEBUG409VOID CLeashView::AssertValid() const410{411CListView::AssertValid();412}413414VOID CLeashView::Dump(CDumpContext& dc) const415{416CListView::Dump(dc);417}418419/*420LeashDoc* CLeashView::GetDocument() // non-debug version is inline421{422ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(LeashDoc)));423return (LeashDoc*)m_pDocument;424}425*/426#endif //_DEBUG427428/////////////////////////////////////////////////////////////////////////////429// CLeashView message handlers430431BOOL CLeashView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName,432DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,433UINT nID, CCreateContext* pContext)434{435return CListView::Create(lpszClassName, lpszWindowName, dwStyle, rect,436pParentWnd, nID, pContext);437}438439INT CLeashView::OnCreate(LPCREATESTRUCT lpCreateStruct)440{441if (CListView::OnCreate(lpCreateStruct) == -1)442return -1;443return 0;444}445446VOID CLeashView::OnClose(void)447{448printf("OnClose\n");449}450451time_t CLeashView::LeashTime()452{453_tzset();454return time(0);455}456457// Call while possessing a lock to ticketinfo.lockObj458INT CLeashView::GetLowTicketStatus(int ver)459{460BOOL b_notix = (ver == 5 && !ticketinfo.Krb5.btickets);461462if (b_notix)463return NO_TICKETS;464465if (m_ticketTimeLeft <= 0L)466return ZERO_MINUTES_LEFT;467468if (m_ticketTimeLeft <= 20 * 60)469return (INT)(m_ticketTimeLeft / 5 / 60) + 2 -470(m_ticketTimeLeft % (5 * 60) == 0 ? 1 : 0);471472return PLENTY_OF_TIME;473}474475VOID CLeashView::UpdateTicketTime(TICKETINFO& ti)476{477if (!ti.btickets) {478m_ticketTimeLeft = 0L;479return;480}481482m_ticketTimeLeft = ti.valid_until - LeashTime();483484if (m_ticketTimeLeft <= 0L)485ti.btickets = EXPIRED_TICKETS;486}487488489VOID CALLBACK EXPORT CLeashView::TimerProc(HWND hWnd, UINT nMsg,490UINT_PTR nIDEvent, DWORD dwTime)491{492// All of the work is being done in the PreTranslateMessage method493// in order to have access to the object494}495496VOID CLeashView::ApplicationInfoMissingMsg()497{498AfxMessageBox("There is a problem finding Leash application information!",499MB_OK|MB_ICONSTOP);500}501502VOID CLeashView::OnShowWindow(BOOL bShow, UINT nStatus)503{504CListView::OnShowWindow(bShow, nStatus);505506// Get State of Icons Size507m_pApp = AfxGetApp();508if (!m_pApp)509{510ApplicationInfoMissingMsg();511}512else513{514m_largeIcons = m_pApp->GetProfileInt("Settings", "LargeIcons", ON);515516// Get State of Destroy Tickets On Exit517m_destroyTicketsOnExit = m_pApp->GetProfileInt("Settings", "DestroyTicketsOnExit", OFF);518519// Get State of Low Ticket Alarm520m_lowTicketAlarm = m_pApp->GetProfileInt("Settings", "LowTicketAlarm", ON);521522// Get State of Auto Renew Tickets523m_autoRenewTickets = m_pApp->GetProfileInt("Settings", "AutoRenewTickets", ON);524525// Get State of Upper Case Realm526m_upperCaseRealm = pLeash_get_default_uppercaserealm();527528// UI main display column widths529for (int i=0; i<NUM_VIEW_COLUMNS; i++) {530ViewColumnInfo &info = sm_viewColumns[i];531info.m_enabled = m_pApp->GetProfileInt("Settings",532info.m_name,533info.m_enabled);534info.m_columnWidth = m_pApp->GetProfileInt("ColumnWidths",535info.m_name,536info.m_columnWidth);537}538539OnLargeIcons();540}541542SetTimer(1, ONE_SECOND, TimerProc);543544if (!CLeashApp::m_hKrb5DLL)545{546////Update not to mention K4547AfxMessageBox("Kerberos Five is not loaded!!!"548"\r\nYou will not be able to retrieve tickets and/or "549"tokens.",550MB_OK|MB_ICONWARNING);551}552553SetDlgItemText(IDC_LABEL_KERB_TICKETS,554"Your Kerberos Tickets (Issued/Expires/[Renew]/Principal)");555556// CLeashApp::m_krbv5_context = NULL;557}558559VOID CLeashView::OnInitTicket()560{561try {562InitTicket(m_hWnd);563}564catch(...) {565AfxMessageBox("Ticket Getting operation already in progress", MB_OK, 0);566}567}568569UINT CLeashView::InitTicket(void * hWnd)570{571LSH_DLGINFO_EX ldi;572char username[64];573char realm[192];574int i=0, j=0;575if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {576throw("Unable to lock ticketinfo");577}578LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);579char * principal = ticketinfo.Krb5.principal;580if (principal)581for (; principal[i] && principal[i] != '@'; i++)582username[i] = principal[i];583username[i] = '\0';584if (principal && principal[i]) {585for (i++ ; principal[i] ; i++, j++)586{587realm[j] = principal[i];588}589}590realm[j] = '\0';591LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);592ReleaseMutex(ticketinfo.lockObj);593594ldi.size = sizeof(ldi);595ldi.dlgtype = DLGTYPE_PASSWD;596ldi.title = ldi.in.title;597strcpy_s(ldi.in.title,"MIT Kerberos: Get Ticket");598ldi.username = ldi.in.username;599strcpy(ldi.in.username,username);600ldi.realm = ldi.in.realm;601strcpy(ldi.in.realm,realm);602ldi.dlgtype = DLGTYPE_PASSWD;603ldi.use_defaults = 1;604605if (!hWnd)606{607AfxMessageBox("There is a problem finding the Leash Window!",608MB_OK|MB_ICONSTOP);609return 0;610}611612int result = pLeash_kinit_dlg_ex((HWND)hWnd, &ldi);613614if (-1 == result)615{616AfxMessageBox("There is a problem getting tickets!",617MB_OK|MB_ICONSTOP);618}619else if ( result )620{621if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0) {622throw("Unable to lock ticketinfo");623}624m_warningOfTicketTimeLeftKrb5 = 0;625m_ticketStatusKrb5 = 0;626ReleaseMutex(ticketinfo.lockObj);627m_autoRenewalAttempted = 0;628::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);629}630return 0;631}632633static UINT krenew(void *param)634{635char *ccache_name = (char *)param;636krb5_context ctx = 0;637krb5_ccache ccache = NULL;638krb5_principal me = 0;639krb5_principal server = 0;640krb5_creds my_creds;641krb5_data *realm = 0;642643memset(&my_creds, 0, sizeof(krb5_creds));644if (ccache_name == NULL)645// Bad param646goto cleanup;647648krb5_error_code code = pkrb5_init_context(&ctx);649if (code) {650// TODO: spew error651goto cleanup;652}653code = pkrb5_cc_resolve(ctx, ccache_name, &ccache);654if (code) {655// TODO: spew error656goto cleanup;657}658659code = pkrb5_cc_get_principal(ctx, ccache, &me);660if (code)661goto cleanup;662663realm = krb5_princ_realm(ctx, me);664665code = pkrb5_build_principal_ext(ctx, &server,666realm->length, realm->data,667KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,668realm->length, realm->data,6690);670if (code)671goto cleanup;672673my_creds.client = me;674my_creds.server = server;675676#ifdef KRB5_TC_NOTICKET677pkrb5_cc_set_flags(ctx, ccache, 0);678#endif679code = pkrb5_get_renewed_creds(ctx, &my_creds, me, ccache, NULL);680#ifdef KRB5_TC_NOTICKET681pkrb5_cc_set_flags(ctx, ccache, KRB5_TC_NOTICKET);682#endif683if (code) {684/* TODO685if (code != KRB5KDC_ERR_ETYPE_NOSUPP || code != KRB5_KDC_UNREACH)686Leash_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx,687&ccache);688*/689goto cleanup;690}691692code = pkrb5_cc_initialize(ctx, ccache, me);693if (code)694goto cleanup;695696code = pkrb5_cc_store_cred(ctx, ccache, &my_creds);697if (code)698goto cleanup;699700cleanup:701if (my_creds.client == me)702my_creds.client = 0;703if (my_creds.server == server)704my_creds.server = 0;705pkrb5_free_cred_contents(ctx, &my_creds);706if (me != NULL)707pkrb5_free_principal(ctx, me);708if (server != NULL)709pkrb5_free_principal(ctx, server);710if (ccache != NULL)711pkrb5_cc_close(ctx, ccache);712if (ctx != NULL)713pkrb5_free_context(ctx);714if (ccache_name != NULL)715free(ccache_name);716717CLeashApp::m_bUpdateDisplay = TRUE;718return 0;719}720721VOID CLeashView::OnRenewTicket()722{723if ( !CLeashApp::m_hKrb5DLL )724return;725726// @TODO: grab list mutex727CCacheDisplayData *elem = m_ccacheDisplay;728while (elem != NULL) {729if (elem->m_selected) {730char *ccache_name = strdup(elem->m_ccacheName);731if (ccache_name)732AfxBeginThread(krenew, (void *)ccache_name);733}734elem = elem->m_next;735}736// release list mutex737}738739UINT CLeashView::RenewTicket(void * hWnd)740{741if ( !CLeashApp::m_hKrb5DLL )742return 0;743744// Try to renew745BOOL b_renewed = pLeash_renew();746if ( b_renewed ) {747m_warningOfTicketTimeLeftKrb5 = 0;748m_ticketStatusKrb5 = 0;749m_autoRenewalAttempted = 0;750ReleaseMutex(ticketinfo.lockObj);751::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);752return 0;753}754755AfxBeginThread(InitTicket,hWnd);756757return 0;758}759760static void kdestroy(const char *ccache_name)761{762krb5_context ctx;763krb5_ccache ccache=NULL;764int code = pkrb5_init_context(&ctx);765if (code) {766// TODO: spew error767goto cleanup;768}769code = pkrb5_cc_resolve(ctx, ccache_name, &ccache);770if (code) {771// TODO: spew error772goto cleanup;773}774code = pkrb5_cc_destroy(ctx, ccache);775if (code) {776goto cleanup;777}778cleanup:779if (ctx)780pkrb5_free_context(ctx);781}782783784VOID CLeashView::OnDestroyTicket()785{786// @TODO: grab mutex787BOOL destroy = FALSE;788CCacheDisplayData *elem = m_ccacheDisplay;789while (elem) {790if (elem->m_selected) {791// @TODO add princ to msg text792destroy = TRUE;793}794elem = elem->m_next;795}796// release mutex797798if (destroy)799{800INT whatToDo;801802whatToDo = AfxMessageBox("Are you sure you want to destroy these tickets?",803MB_ICONEXCLAMATION|MB_YESNO, 0);804805if (whatToDo == IDYES)806{807// grab list mutex808elem = m_ccacheDisplay;809while (elem) {810if (elem->m_selected)811kdestroy(elem->m_ccacheName);812elem = elem->m_next;813}814// release list mutex815SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);816}817}818m_autoRenewalAttempted = 0;819}820821VOID CLeashView::OnMakeDefault()822{823CCacheDisplayData *elem = m_ccacheDisplay;824int code = 0;825krb5_context ctx;826krb5_ccache cc;827while (elem) {828if (elem->m_selected) {829pkrb5_init_context(&ctx);830code = pkrb5_cc_resolve(ctx, elem->m_ccacheName, &cc);831if (!code)832code = pkrb5_cc_switch(ctx, cc);833if (!code) {834const char *cctype = pkrb5_cc_get_type(ctx, cc);835if (cctype != NULL) {836char defname[20];837sprintf_s(defname, "%s:", cctype);838code = pkrb5int_cc_user_set_default_name(ctx, defname);839}840}841pkrb5_free_context(ctx);842CLeashApp::m_bUpdateDisplay = TRUE;843break;844}845elem = elem->m_next;846}847}848849VOID CLeashView::OnChangePassword()850{851krb5_context ctx = 0;852krb5_ccache ccache = 0;853krb5_principal princ = 0;854char *pname = NULL;855char *username = NULL;856char *realm = NULL;857int code = 0;858859CCacheDisplayData *elem = m_ccacheDisplay;860while (elem != NULL) {861if (elem->m_selected) {862if (elem->m_ccacheName)863break;864}865elem = elem->m_next;866}867if (elem != NULL) {868code = pkrb5_init_context(&ctx);869if (code) {870// TODO: spew error871goto cleanup;872}873code = pkrb5_cc_resolve(ctx, elem->m_ccacheName, &ccache);874if (code) {875// TODO: spew error876goto cleanup;877}878code = pkrb5_cc_get_principal(ctx, ccache, &princ);879if (code) {880goto cleanup;881}882code = pkrb5_unparse_name(ctx, princ, &pname);883if (code) {884goto cleanup;885}886}887888LSH_DLGINFO_EX ldi;889if (pname != NULL) {890username = pname;891realm = strchr(pname, '@');892if (realm != NULL)893*realm++ = '\0';894}895ldi.size = sizeof(ldi);896ldi.dlgtype = DLGTYPE_CHPASSWD;897ldi.title = ldi.in.title;898strcpy_s(ldi.in.title, "MIT Kerberos: Change Password");899ldi.username = ldi.in.username;900strcpy_s(ldi.in.username, username ? username : "");901ldi.realm = ldi.in.realm;902strcpy_s(ldi.in.realm, realm ? realm : "");903ldi.use_defaults = 1;904905int result = pLeash_changepwd_dlg_ex(m_hWnd, &ldi);906if (-1 == result) {907AfxMessageBox("There is a problem changing password!",908MB_OK|MB_ICONSTOP);909}910cleanup:911if (pname != NULL)912pkrb5_free_unparsed_name(ctx, pname);913if (princ != NULL)914pkrb5_free_principal(ctx, princ);915if (ccache != NULL)916pkrb5_cc_close(ctx, ccache);917if (ctx != NULL)918pkrb5_free_context(ctx);919}920921static CCacheDisplayData **922FindCCacheDisplayData(const char * ccacheName, CCacheDisplayData **pList)923{924CCacheDisplayData *elem;925while ((elem = *pList)) {926if (strcmp(ccacheName, elem->m_ccacheName)==0)927return pList;928pList = &elem->m_next;929}930return NULL;931}932933void CLeashView::AddDisplayItem(CListCtrl &list,934CCacheDisplayData *elem,935int iItem,936char *principal,937time_t issued,938time_t valid_until,939time_t renew_until,940char *encTypes,941unsigned long flags,942char *ccache_name)943{944TCHAR* localTimeStr=NULL;945TCHAR* durationStr=NULL;946TCHAR* flagsStr=NULL;947TCHAR tempStr[MAX_DURATION_STR+1];948time_t now = LeashTime();949950list.InsertItem(iItem, principal, -1);951952int iSubItem = 1;953if (sm_viewColumns[TIME_ISSUED].m_enabled) {954if (issued == 0) {955list.SetItemText(iItem, iSubItem++, "Unknown");956} else {957TimestampToLocalizedString(issued, &localTimeStr);958list.SetItemText(iItem, iSubItem++, localTimeStr);959}960}961if (sm_viewColumns[RENEWABLE_UNTIL].m_enabled) {962if (valid_until == 0) {963list.SetItemText(iItem, iSubItem++, "Unknown");964} else if (valid_until < now) {965list.SetItemText(iItem, iSubItem++, "Expired");966} else if (renew_until) {967TimestampToLocalizedString(renew_until, &localTimeStr);968DurationToString(renew_until - now, &durationStr);969if (localTimeStr && durationStr) {970_snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);971tempStr[MAX_DURATION_STR] = 0;972list.SetItemText(iItem, iSubItem++, tempStr);973}974} else {975list.SetItemText(iItem, iSubItem++, "Not renewable");976}977}978if (sm_viewColumns[VALID_UNTIL].m_enabled) {979if (valid_until == 0) {980list.SetItemText(iItem, iSubItem++, "Unknown");981} else if (valid_until < now) {982list.SetItemText(iItem, iSubItem++, "Expired");983} else {984TimestampToLocalizedString(valid_until, &localTimeStr);985DurationToString(valid_until - now, &durationStr);986if (localTimeStr && durationStr) {987_snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);988tempStr[MAX_DURATION_STR] = 0;989list.SetItemText(iItem, iSubItem++, tempStr);990}991}992}993994if (sm_viewColumns[ENCRYPTION_TYPE].m_enabled) {995list.SetItemText(iItem, iSubItem++, encTypes);996}997if (sm_viewColumns[TICKET_FLAGS].m_enabled) {998krb5TicketFlagsToString(flags, &flagsStr);999list.SetItemText(iItem, iSubItem++, flagsStr);1000}1001if (sm_viewColumns[CACHE_NAME].m_enabled) {1002list.SetItemText(iItem, iSubItem++, ccache_name);1003}1004if (flagsStr)1005free(flagsStr);1006if (localTimeStr)1007free(localTimeStr);1008if (durationStr)1009free(durationStr);1010}10111012BOOL CLeashView::IsExpanded(TICKETINFO *info)1013{1014CCacheDisplayData **pElem = FindCCacheDisplayData(info->ccache_name,1015&m_ccacheDisplay);1016return (pElem && (*pElem)->m_expanded) ? TRUE : FALSE;1017}10181019BOOL CLeashView::IsExpired(TICKETINFO *info)1020{1021return LeashTime() > info->valid_until ? TRUE : FALSE;1022}10231024BOOL CLeashView::IsExpired(TicketList *ticket)1025{1026return LeashTime() > ticket->valid_until ? TRUE : FALSE;1027}10281029CCacheDisplayData *1030FindCCacheDisplayElem(CCacheDisplayData *pElem, int itemIndex)1031{1032while (pElem != NULL) {1033if (pElem->m_index == itemIndex)1034return pElem;1035pElem = pElem->m_next;1036}1037return NULL;1038}10391040VOID CLeashView::OnUpdateDisplay()1041{1042CListCtrl& list = GetListCtrl();1043// @TODO: there is probably a more sensible place to initialize these...1044if ((m_BaseFont == NULL) && (list.GetFont())) {1045m_BaseFont = *list.GetFont();1046m_BoldFont = CreateBoldFont(m_BaseFont);1047m_ItalicFont = CreateItalicFont(m_BaseFont);1048m_BoldItalicFont = CreateBoldItalicFont(m_BaseFont);1049}1050// Determine currently focused item1051int focusItem = list.GetNextItem(-1, LVNI_FOCUSED);1052CCacheDisplayData *elem = m_ccacheDisplay;1053while (elem) {1054if (focusItem >= elem->m_index) {1055elem->m_focus = focusItem - elem->m_index;1056focusItem = -1;1057} else {1058elem->m_focus = -1;1059}1060elem = elem->m_next;1061}10621063list.DeleteAllItems();1064ModifyStyle(LVS_TYPEMASK, LVS_REPORT);1065UpdateWindow();1066// Delete all of the columns.1067while (list.DeleteColumn(0));10681069list.SetImageList(&m_imageList, LVSIL_SMALL);10701071// Reconstruct based on current options1072int columnIndex = 0;1073int itemIndex = 0;1074for (int i = 0; i < NUM_VIEW_COLUMNS; i++) {1075ViewColumnInfo &info = sm_viewColumns[i];1076if (info.m_enabled) {1077list.InsertColumn(columnIndex++,1078(info.m_name), // @LOCALIZEME!1079LVCFMT_LEFT,1080info.m_columnWidth,1081itemIndex++);1082}1083}10841085INT ticketIconStatusKrb5;1086INT ticketIconStatus_SelectedKrb5;1087INT iconStatusKrb5;10881089if (WaitForSingleObject( ticketinfo.lockObj, 100 ) != WAIT_OBJECT_0)1090throw("Unable to lock ticketinfo");10911092// Get Kerb 5 tickets in list1093LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);1094if (CLeashApp::m_hKrb5DLL && !CLeashApp::m_krbv5_profile)1095{1096CHAR confname[MAX_PATH];1097if (CLeashApp::GetProfileFile(confname, sizeof(confname)))1098{1099AfxMessageBox("Can't locate Kerberos Five Config. file!",1100MB_OK|MB_ICONSTOP);1101}11021103const char *filenames[2];1104filenames[0] = confname;1105filenames[1] = NULL;1106pprofile_init(filenames, &CLeashApp::m_krbv5_profile);1107}11081109/*1110* Update Ticket Status for Krb5 so that we may use their state1111* to select the appropriate Icon for the Parent Node1112*/11131114/* Krb5 */1115UpdateTicketTime(ticketinfo.Krb5);1116m_ticketStatusKrb5 = GetLowTicketStatus(5);1117if ((!ticketinfo.Krb5.btickets) ||1118EXPIRED_TICKETS == ticketinfo.Krb5.btickets ||1119m_ticketStatusKrb5 == ZERO_MINUTES_LEFT)1120{1121ticketIconStatusKrb5 = EXPIRED_CLOCK;1122ticketIconStatus_SelectedKrb5 = EXPIRED_CLOCK;1123iconStatusKrb5 = EXPIRED_TICKET;1124}1125else if (TICKETS_LOW == ticketinfo.Krb5.btickets ||1126m_ticketStatusKrb5 == FIVE_MINUTES_LEFT ||1127m_ticketStatusKrb5 == TEN_MINUTES_LEFT ||1128m_ticketStatusKrb5 == FIFTEEN_MINUTES_LEFT)1129{1130ticketIconStatusKrb5 = LOW_CLOCK;1131ticketIconStatus_SelectedKrb5 = LOW_CLOCK;1132iconStatusKrb5 = LOW_TICKET;1133}1134else if ( CLeashApp::m_hKrb5DLL )1135{1136ticketIconStatusKrb5 = ACTIVE_CLOCK;1137ticketIconStatus_SelectedKrb5 = ACTIVE_CLOCK;1138iconStatusKrb5 = ACTIVE_TICKET;1139} else1140{1141ticketIconStatusKrb5 = EXPIRED_CLOCK;1142ticketIconStatus_SelectedKrb5 = EXPIRED_CLOCK;1143iconStatusKrb5 = TICKET_NOT_INSTALLED;1144}11451146int trayIcon = NONE_PARENT_NODE;1147if (CLeashApp::m_hKrb5DLL && ticketinfo.Krb5.btickets) {1148switch ( iconStatusKrb5 ) {1149case ACTIVE_TICKET:1150trayIcon = ACTIVE_PARENT_NODE;1151break;1152case LOW_TICKET:1153trayIcon = LOW_PARENT_NODE;1154break;1155case EXPIRED_TICKET:1156trayIcon = EXPIRED_PARENT_NODE;1157break;1158}1159}1160SetTrayIcon(NIM_MODIFY, trayIcon);11611162CCacheDisplayData* prevCCacheDisplay = m_ccacheDisplay;1163m_ccacheDisplay = NULL;11641165const char *def_ccache_name = ticketinfo.Krb5.ccache_name;1166TICKETINFO *principallist = NULL;1167LeashKRB5ListAllTickets(&principallist);1168int iItem = 0;1169TicketList* tempList;1170TICKETINFO *principal = principallist;1171while (principal != NULL) {1172CCacheDisplayData **pOldElem;1173pOldElem = FindCCacheDisplayData(principal->ccache_name,1174&prevCCacheDisplay);1175if (pOldElem) {1176// remove from old list1177elem = *pOldElem;1178*pOldElem = elem->m_next;1179elem->m_next = NULL;1180} else {1181elem = new CCacheDisplayData(principal->ccache_name);1182}1183elem->m_isDefault = def_ccache_name &&1184(strcmp(def_ccache_name, elem->m_ccacheName) == 0);1185elem->m_isRenewable = principal->renew_until != 0;11861187elem->m_next = m_ccacheDisplay;1188m_ccacheDisplay = elem;1189elem->m_index = iItem;11901191AddDisplayItem(list,1192elem,1193iItem++,1194principal->principal,1195principal->issued,1196principal->valid_until,1197principal->renew_until,1198"",1199principal->flags,1200principal->ccache_name);1201if (elem->m_expanded) {1202for (tempList = principal->ticket_list;1203tempList != NULL;1204tempList = tempList->next) {1205AddDisplayItem(list,1206elem,1207iItem++,1208tempList->service,1209tempList->issued,1210tempList->valid_until,1211tempList->renew_until,1212tempList->encTypes,1213tempList->flags,1214principal->ccache_name);1215}1216}1217if ((elem->m_focus >= 0) &&1218(iItem > elem->m_index + elem->m_focus)) {1219list.SetItemState(elem->m_index + elem->m_focus, LVIS_FOCUSED,1220LVIS_FOCUSED);1221}1222if (elem->m_selected)1223list.SetItemState(elem->m_index, LVIS_SELECTED, LVIS_SELECTED);12241225principal = principal->next;1226}12271228// create list item font data array1229if (m_aListItemInfo != NULL)1230delete[] m_aListItemInfo;1231m_aListItemInfo = new ListItemInfo[iItem];1232iItem = 0;1233for (principal = principallist; principal != NULL;1234principal = principal->next) {1235//1236HFONT font, durationFont;1237elem = FindCCacheDisplayElem(m_ccacheDisplay, iItem);1238if (elem != NULL && elem->m_isDefault) {1239font = m_BoldFont;1240durationFont = IsExpired(principal) ? m_BoldItalicFont : m_BoldFont;1241} else {1242font = m_BaseFont;1243durationFont = IsExpired(principal) ? m_ItalicFont : m_BaseFont;1244}1245m_aListItemInfo[iItem].m_font = font;1246m_aListItemInfo[iItem++].m_durationFont = durationFont;12471248if (IsExpanded(principal)) {1249for (TicketList *ticket = principal->ticket_list;1250ticket != NULL; ticket = ticket->next) {1251font = m_BaseFont;1252durationFont = IsExpired(ticket) ? m_ItalicFont : m_BaseFont;1253m_aListItemInfo[iItem].m_font = font;1254m_aListItemInfo[iItem++].m_durationFont = durationFont;1255}1256}1257}12581259// delete ccache items that no longer exist1260while (prevCCacheDisplay != NULL) {1261CCacheDisplayData *next = prevCCacheDisplay->m_next;1262delete prevCCacheDisplay;1263prevCCacheDisplay = next;1264}12651266LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);1267LeashKRB5FreeTickets(&principallist);12681269ReleaseMutex(ticketinfo.lockObj);1270}12711272VOID CLeashView::OnSynTime()1273{1274LONG returnValue;1275returnValue = pLeash_timesync(1);1276}12771278VOID CLeashView::OnActivateView(BOOL bActivate, CView* pActivateView,1279CView* pDeactiveView)1280{1281UINT check = NULL;12821283if (m_alreadyPlayed)1284{1285CListView::OnActivateView(bActivate, pActivateView, pDeactiveView);1286return;1287}12881289// The following code has put here because at the time1290// 'checking and unchecking' a menuitem with the1291// 'OnUpdate.....(CCmdUI* pCmdUI) functions' were unreliable1292// in CLeashView -->> Better done in CMainFrame1293if( CLeashApp::m_hProgram != 0 )1294{1295m_hMenu = ::GetMenu(CLeashApp::m_hProgram);1296} else {1297return;1298}12991300if (m_hMenu) {1301if (!m_largeIcons)1302check = CheckMenuItem(m_hMenu, ID_LARGE_ICONS, MF_CHECKED);1303else1304check = CheckMenuItem(m_hMenu, ID_LARGE_ICONS, MF_UNCHECKED);13051306if( check != MF_CHECKED || check != MF_UNCHECKED )1307{1308m_debugStartUp = 1;1309}13101311if (!m_destroyTicketsOnExit)1312check = CheckMenuItem(m_hMenu, ID_KILL_TIX_ONEXIT, MF_UNCHECKED);1313else1314check = CheckMenuItem(m_hMenu, ID_KILL_TIX_ONEXIT, MF_CHECKED);13151316if (!m_upperCaseRealm)1317check = CheckMenuItem(m_hMenu, ID_UPPERCASE_REALM, MF_UNCHECKED);1318else1319check = CheckMenuItem(m_hMenu, ID_UPPERCASE_REALM, MF_CHECKED);13201321for (int i=0; i<NUM_VIEW_COLUMNS; i++) {1322ViewColumnInfo &info = sm_viewColumns[i];1323if (info.m_id >= 0)1324CheckMenuItem(m_hMenu, info.m_id,1325info.m_enabled ? MF_CHECKED : MF_UNCHECKED);1326}13271328if (!m_lowTicketAlarm)1329CheckMenuItem(m_hMenu, ID_LOW_TICKET_ALARM, MF_UNCHECKED);1330else1331CheckMenuItem(m_hMenu, ID_LOW_TICKET_ALARM, MF_CHECKED);13321333if (!m_autoRenewTickets)1334CheckMenuItem(m_hMenu, ID_AUTO_RENEW, MF_UNCHECKED);1335else1336CheckMenuItem(m_hMenu, ID_AUTO_RENEW, MF_CHECKED);13371338m_debugWindow = m_pApp->GetProfileInt("Settings", "DebugWindow", 0);1339if (!m_debugWindow)1340check = CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_UNCHECKED);1341else1342check = CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_CHECKED);1343}1344m_lowTicketAlarmSound = !!m_lowTicketAlarm;1345m_alreadyPlayed = TRUE;1346if (m_pApp)1347{1348m_debugWindow = m_pApp->GetProfileInt("Settings", "DebugWindow", 0);13491350if (m_hMenu)1351{1352if (!m_debugWindow)1353{1354CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_UNCHECKED);1355}1356else1357{1358CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_CHECKED);1359}1360}1361}1362else1363{1364ApplicationInfoMissingMsg();1365}13661367m_alreadyPlayed = TRUE;13681369if (m_debugStartUp)1370{1371OnDebugMode();1372}13731374m_debugStartUp = FALSE;13751376CListView::OnActivateView(bActivate, pActivateView, pDeactiveView);1377}13781379////@#+Is this KRB4 only?1380VOID CLeashView::OnDebugMode()1381{1382if (!m_pDebugWindow)1383{1384AfxMessageBox("There is a problem with the Leash Debug Window!",1385MB_OK|MB_ICONSTOP);1386return;1387}138813891390// Check all possible 'KRB' system variables, then delete debug file1391CHAR* Env[] = {"TEMP", "TMP", "HOME", NULL};1392CHAR** pEnv = Env;1393CHAR debugFilePath[MAX_PATH];1394*debugFilePath = 0;13951396while (*pEnv)1397{1398CHAR* ptestenv = getenv(*pEnv);1399if (ptestenv)1400{1401// reset debug file1402strcpy(debugFilePath, ptestenv);1403strcat(debugFilePath, "\\LshDebug.log");1404remove(debugFilePath);1405break;1406}14071408pEnv++;1409}14101411if (!m_debugStartUp)1412{1413if (m_debugWindow%2 == 0)1414m_debugWindow = ON;1415else1416m_debugWindow = OFF;1417}14181419if (!m_pApp)1420{1421ApplicationInfoMissingMsg();1422}1423else if (!m_debugWindow)1424{1425if (m_hMenu)1426CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_UNCHECKED);14271428m_pApp->WriteProfileInt("Settings", "DebugWindow", FALSE_FLAG);1429m_pDebugWindow->DestroyWindow();1430return;1431}1432else1433{1434if (m_hMenu)1435CheckMenuItem(m_hMenu, ID_DEBUG_MODE, MF_CHECKED);14361437m_pApp->WriteProfileInt("Settings", "DebugWindow", TRUE_FLAG);1438}14391440// Creates the Debug dialog if not created already1441if (m_pDebugWindow->GetSafeHwnd() == 0)1442{ // displays the Debug Window1443m_pDebugWindow->Create(debugFilePath);1444}1445}14461447void CLeashView::ToggleViewColumn(eViewColumn viewOption)1448{1449if ((viewOption < 0) || (viewOption >= NUM_VIEW_COLUMNS)) {1450//LeashWarn("ToggleViewColumn(): invalid view option index %i", viewOption);1451return;1452}1453ViewColumnInfo &info = sm_viewColumns[viewOption];1454info.m_enabled = !info.m_enabled;1455if (m_pApp)1456m_pApp->WriteProfileInt("Settings", info.m_name, info.m_enabled);1457// Don't update display immediately; wait for next idle so our1458// checkbox controls will be more responsive1459CLeashApp::m_bUpdateDisplay = TRUE;1460}14611462VOID CLeashView::OnRenewableUntil()1463{1464ToggleViewColumn(RENEWABLE_UNTIL);1465}14661467VOID CLeashView::OnUpdateRenewableUntil(CCmdUI *pCmdUI)1468{1469pCmdUI->SetCheck(sm_viewColumns[RENEWABLE_UNTIL].m_enabled);1470}14711472VOID CLeashView::OnShowTicketFlags()1473{1474ToggleViewColumn(TICKET_FLAGS);1475}14761477VOID CLeashView::OnUpdateShowTicketFlags(CCmdUI *pCmdUI)1478{1479pCmdUI->SetCheck(sm_viewColumns[TICKET_FLAGS].m_enabled);1480}14811482VOID CLeashView::OnTimeIssued()1483{1484ToggleViewColumn(TIME_ISSUED);1485}14861487VOID CLeashView::OnUpdateTimeIssued(CCmdUI *pCmdUI)1488{1489pCmdUI->SetCheck(sm_viewColumns[TIME_ISSUED].m_enabled);1490}14911492VOID CLeashView::OnValidUntil()1493{1494ToggleViewColumn(VALID_UNTIL);1495}14961497VOID CLeashView::OnUpdateValidUntil(CCmdUI *pCmdUI)1498{1499pCmdUI->SetCheck(sm_viewColumns[VALID_UNTIL].m_enabled);1500}15011502VOID CLeashView::OnEncryptionType()1503{1504ToggleViewColumn(ENCRYPTION_TYPE);1505}15061507VOID CLeashView::OnUpdateEncryptionType(CCmdUI *pCmdUI)1508{1509pCmdUI->SetCheck(sm_viewColumns[ENCRYPTION_TYPE].m_enabled);1510}15111512VOID CLeashView::OnCcacheName()1513{1514ToggleViewColumn(CACHE_NAME);1515}15161517VOID CLeashView::OnUpdateCcacheName(CCmdUI *pCmdUI)1518{1519pCmdUI->SetCheck(sm_viewColumns[CACHE_NAME].m_enabled);1520}15211522VOID CLeashView::OnLargeIcons()1523{1524INT x, y, n;15251526if (change_icon_size)1527{1528if (m_largeIcons%2 == 0)1529m_largeIcons = ON;1530else1531m_largeIcons = OFF;1532}1533else1534{1535if (m_largeIcons%2 == 0)1536m_largeIcons = OFF;1537else1538m_largeIcons = ON;1539}15401541x = y = SMALL_ICONS;15421543if (!m_pApp)1544ApplicationInfoMissingMsg();1545else1546{1547if (!m_largeIcons)1548{1549if (m_hMenu)1550CheckMenuItem(m_hMenu, ID_LARGE_ICONS, MF_CHECKED);15511552x = y = LARGE_ICONS;15531554if (!m_startup)1555{1556m_pApp->WriteProfileInt("Settings", "LargeIcons", TRUE_FLAG);1557}1558}1559else1560{1561if (m_hMenu)1562CheckMenuItem(m_hMenu, ID_LARGE_ICONS, MF_UNCHECKED);15631564x = y = SMALL_ICONS;15651566if (!m_startup)1567{1568m_pApp->WriteProfileInt("Settings", "LargeIcons", FALSE_FLAG);1569}1570}1571}15721573HICON hIcon[IMAGE_COUNT];1574for (n = 0; n < IMAGE_COUNT; n++)1575{1576hIcon[n] = NULL;1577}15781579m_imageList.DeleteImageList( );15801581UINT bitsPerPixel = GetDeviceCaps( ::GetDC(::GetDesktopWindow()), BITSPIXEL);1582UINT ilcColor;1583if ( bitsPerPixel >= 32 )1584ilcColor = ILC_COLOR32;1585else if ( bitsPerPixel >= 24 )1586ilcColor = ILC_COLOR24;1587else if ( bitsPerPixel >= 16 )1588ilcColor = ILC_COLOR16;1589else if ( bitsPerPixel >= 8 )1590ilcColor = ILC_COLOR8;1591else1592ilcColor = ILC_COLOR;1593m_imageList.Create(x, y, ilcColor | ILC_MASK, IMAGE_COUNT, 1);1594m_imageList.SetBkColor(GetSysColor(COLOR_WINDOW));15951596hIcon[ACTIVE_TRAY_ICON] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_GOOD);1597hIcon[LOW_TRAY_ICON] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_LOW);1598hIcon[EXPIRED_TRAY_ICON] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_EXPIRED);1599hIcon[NONE_TRAY_ICON] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_NONE);1600hIcon[ACTIVE_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_PRINCIPAL_GOOD);1601hIcon[LOW_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_PRINCIPAL_LOW);1602hIcon[EXPIRED_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_PRINCIPAL_EXPIRED);1603hIcon[NONE_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_PRINCIPAL_NONE);1604hIcon[ACTIVE_TICKET] = AfxGetApp()->LoadIcon(IDI_TICKETTYPE_GOOD);1605hIcon[LOW_TICKET] = AfxGetApp()->LoadIcon(IDI_TICKETTYPE_LOW);1606hIcon[EXPIRED_TICKET] = AfxGetApp()->LoadIcon(IDI_TICKETTYPE_EXPIRED);1607hIcon[TICKET_NOT_INSTALLED] = AfxGetApp()->LoadIcon(IDI_TICKETTYPE_NOTINSTALLED);1608hIcon[ACTIVE_CLOCK] = AfxGetApp()->LoadIcon(IDI_TICKET_GOOD);1609hIcon[LOW_CLOCK] = AfxGetApp()->LoadIcon(IDI_TICKET_LOW);1610hIcon[EXPIRED_CLOCK] = AfxGetApp()->LoadIcon(IDI_TICKET_EXPIRED);1611hIcon[TKT_ADDRESS] = AfxGetApp()->LoadIcon(IDI_LEASH_TICKET_ADDRESS);1612hIcon[TKT_SESSION] = AfxGetApp()->LoadIcon(IDI_LEASH_TICKET_SESSION);1613hIcon[TKT_ENCRYPTION] = AfxGetApp()->LoadIcon(IDI_LEASH_TICKET_ENCRYPTION);16141615for (n = 0; n < IMAGE_COUNT; n++)1616{1617if ( !hIcon[n] ) {1618AfxMessageBox("Can't find one or more images in the Leash Ticket Tree!",1619MB_OK|MB_ICONSTOP);1620return;1621}1622m_imageList.Add(hIcon[n]);1623}16241625if (!m_startup)1626SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);1627}16281629VOID CLeashView::OnKillTixOnExit()1630{1631m_destroyTicketsOnExit = !m_destroyTicketsOnExit;16321633if (m_pApp)1634m_pApp->WriteProfileInt("Settings", "DestroyTicketsOnExit",1635m_destroyTicketsOnExit);1636}16371638VOID CLeashView::OnUpdateKillTixOnExit(CCmdUI *pCmdUI)1639{1640pCmdUI->SetCheck(m_destroyTicketsOnExit);1641}16421643VOID CLeashView::OnUppercaseRealm()1644{1645m_upperCaseRealm = !m_upperCaseRealm;16461647pLeash_set_default_uppercaserealm(m_upperCaseRealm);1648}16491650VOID CLeashView::OnUpdateUppercaseRealm(CCmdUI *pCmdUI)1651{1652// description is now 'allow mixed case', so reverse logic1653pCmdUI->SetCheck(!m_upperCaseRealm);1654}16551656VOID CLeashView::ResetTreeNodes()1657{1658m_hPrincipalState = 0;1659m_hKerb5State = 0;1660}16611662VOID CLeashView::OnDestroy()1663{1664CCacheDisplayData *elem;1665SetTrayIcon(NIM_DELETE);16661667if (m_destroyTicketsOnExit) {1668elem = m_ccacheDisplay;1669while (elem != NULL) {1670kdestroy(elem->m_ccacheName);1671elem = elem->m_next;1672}1673}1674CListView::OnDestroy();1675}16761677VOID CLeashView::OnUpdateDestroyTicket(CCmdUI* pCmdUI)1678{1679// @TODO: mutex1680BOOL enable = FALSE;1681CCacheDisplayData *elem = m_ccacheDisplay;1682while (elem != NULL) {1683if (elem->m_selected) {1684enable = TRUE;1685break;1686}1687elem = elem->m_next;1688}16891690pCmdUI->Enable(enable);1691}16921693VOID CLeashView::OnUpdateInitTicket(CCmdUI* pCmdUI)1694{1695if (!CLeashApp::m_hKrb5DLL)1696pCmdUI->Enable(FALSE);1697else1698pCmdUI->Enable(TRUE);1699}17001701VOID CLeashView::OnUpdateRenewTicket(CCmdUI* pCmdUI)1702{1703// @TODO: mutex1704BOOL enable = FALSE;1705CCacheDisplayData *elem = m_ccacheDisplay;1706while (elem != NULL) {1707if (elem->m_selected) { // @TODO: && elem->m_renewable1708enable = TRUE;1709break;1710}1711elem = elem->m_next;1712}17131714pCmdUI->Enable(enable);1715}17161717LRESULT CLeashView::OnGoodbye(WPARAM wParam, LPARAM lParam)1718{1719m_pDebugWindow->DestroyWindow();1720return 0L;1721}17221723VOID CLeashView::OnLeashRestore()1724{1725if ( CMainFrame::m_isMinimum ) {1726CMainFrame * frame = (CMainFrame *)GetParentFrame();1727frame->ShowTaskBarButton(TRUE);1728frame->ShowWindow(SW_SHOWNORMAL);1729}1730}17311732VOID CLeashView::OnLeashMinimize()1733{1734if ( !CMainFrame::m_isMinimum ) {1735CMainFrame * frame = (CMainFrame *)GetParentFrame();1736// frame->ShowTaskBarButton(FALSE);1737frame->ShowWindow(SW_HIDE);1738frame->ShowWindow(SW_MINIMIZE);1739}1740}17411742LRESULT CLeashView::OnTrayIcon(WPARAM wParam, LPARAM lParam)1743{1744switch ( lParam ) {1745case WM_LBUTTONDOWN:1746if ( CMainFrame::m_isMinimum )1747OnLeashRestore();1748else1749OnLeashMinimize();1750break;1751case WM_RBUTTONDOWN:1752{1753int nFlags;1754CMenu * menu = new CMenu();1755menu->CreatePopupMenu();1756if ( !CMainFrame::m_isMinimum )1757menu->AppendMenu(MF_STRING, ID_LEASH_MINIMIZE, "&Close MIT Kerberos Window");1758else1759menu->AppendMenu(MF_STRING, ID_LEASH_RESTORE, "&Open MIT Kerberos Window");1760menu->AppendMenu(MF_SEPARATOR);1761menu->AppendMenu(MF_STRING, ID_INIT_TICKET, "&Get Tickets");1762if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)1763throw("Unable to lock ticketinfo");1764if (!ticketinfo.Krb5.btickets ||1765!CLeashApp::m_hKrb5DLL)1766nFlags = MF_STRING | MF_GRAYED;1767else1768nFlags = MF_STRING;1769menu->AppendMenu(nFlags, ID_RENEW_TICKET, "&Renew Tickets");1770if (!ticketinfo.Krb5.btickets)1771nFlags = MF_STRING | MF_GRAYED;1772else1773nFlags = MF_STRING;1774ReleaseMutex(ticketinfo.lockObj);1775menu->AppendMenu(MF_STRING, ID_DESTROY_TICKET, "&Destroy Tickets");1776menu->AppendMenu(MF_STRING, ID_CHANGE_PASSWORD, "&Change Password");17771778menu->AppendMenu(MF_SEPARATOR);1779if ( m_autoRenewTickets )1780nFlags = MF_STRING | MF_CHECKED;1781else1782nFlags = MF_STRING | MF_UNCHECKED;1783menu->AppendMenu(nFlags, ID_AUTO_RENEW, "&Automatic Ticket Renewal");1784if ( m_lowTicketAlarm )1785nFlags = MF_STRING | MF_CHECKED;1786else1787nFlags = MF_STRING | MF_UNCHECKED;1788menu->AppendMenu(nFlags, ID_LOW_TICKET_ALARM, "&Expiration Alarm");1789menu->AppendMenu(MF_SEPARATOR);1790menu->AppendMenu(MF_STRING, ID_APP_EXIT, "E&xit");1791menu->SetDefaultItem(ID_LEASH_RESTORE);17921793POINT pt;1794GetCursorPos(&pt);17951796SetForegroundWindow();1797menu->TrackPopupMenu(TPM_RIGHTALIGN | TPM_RIGHTBUTTON,1798pt.x, pt.y, GetParentFrame());1799PostMessage(WM_NULL, 0, 0);1800menu->DestroyMenu();1801delete menu;1802}1803break;1804case WM_MOUSEMOVE:1805// SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);1806break;1807}1808return 0L;1809}18101811VOID CLeashView::OnAppAbout()1812{1813CLeashAboutBox leashAboutBox;1814// To debug loaded dlls:1815// leashAboutBox.m_bListModules = TRUE;1816leashAboutBox.DoModal();1817}181818191820VOID CLeashView::OnInitialUpdate()1821{1822CListView::OnInitialUpdate();1823CLeashApp::m_hProgram = ::FindWindow(_T("LEASH.0WNDCLASS"), NULL);1824EnableToolTips();1825}18261827VOID CLeashView::OnItemexpandedTreeview(NMHDR* pNMHDR, LRESULT* pResult)1828{1829NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;18301831if (m_hPrincipal == pNMTreeView->itemNew.hItem)1832m_hPrincipalState = pNMTreeView->action;1833else if (m_hKerb5 == pNMTreeView->itemNew.hItem)1834m_hKerb5State = pNMTreeView->action;18351836CMainFrame::m_isBeingResized = TRUE;1837*pResult = 0;1838}18391840VOID CLeashView::OnUpdateDebugMode(CCmdUI* pCmdUI)1841{1842pCmdUI->Enable(FALSE);1843}18441845VOID CLeashView::OnUpdateCfgFiles(CCmdUI* pCmdUI)1846{1847pCmdUI->Enable(FALSE);1848}18491850/*1851void CLeashView::GetRowWidthHeight(CDC* pDC, LPCSTR theString, int& nRowWidth,1852int& nRowHeight, int& nCharWidth)1853{1854TEXTMETRIC tm;18551856//CEx29aDoc* pDoc = GetDocument();1857pDC->GetTextMetrics(&tm);1858nCharWidth = tm.tmAveCharWidth + 1;1859nRowWidth = strlen(theString);18601861//int nFields = theString.GetLength();18621863//for(int i = 0; i < nFields; i++)1864//{1865// nRowWidth += nCharWidth;1866//}18671868nRowWidth *= nCharWidth;1869nRowHeight = tm.tmHeight;1870}1871*/18721873void CLeashView::SetTrayText(int nim, CString tip)1874{1875if ( (nim == NIM_MODIFY) && (m_bIconDeleted) )1876return;1877if ( (nim == NIM_MODIFY) && (!m_bIconAdded) )1878nim = NIM_ADD;18791880if ( (nim != NIM_DELETE) || IsWindow(m_hWnd) )1881{1882NOTIFYICONDATA nid;1883memset (&nid, 0x00, sizeof(NOTIFYICONDATA));1884nid.cbSize = sizeof(NOTIFYICONDATA);1885nid.hWnd = m_hWnd;1886nid.uID = 0;1887nid.uFlags = NIF_MESSAGE | NIF_TIP;1888nid.uCallbackMessage = WM_TRAYICON;1889strncpy(nid.szTip, (LPCTSTR) tip, sizeof(nid.szTip));1890nid.szTip[sizeof(nid.szTip)-1] = '\0';1891Shell_NotifyIcon (nim, &nid);1892}18931894if ( nim == NIM_ADD )1895m_bIconAdded = TRUE;1896if ( nim == NIM_DELETE )1897m_bIconDeleted = TRUE;1898}18991900void CLeashView::SetTrayIcon(int nim, int state)1901{1902static HICON hIcon[IMAGE_COUNT];1903static BOOL bIconInit = FALSE;19041905if ( (nim == NIM_MODIFY) && (m_bIconDeleted) )1906return;1907if ( (nim == NIM_MODIFY) && (!m_bIconAdded) )1908nim = NIM_ADD;19091910if ( (nim != NIM_DELETE) || IsWindow(m_hWnd) )1911{1912if ( !bIconInit ) {1913// The state is reported as the parent node value although1914// we want to use the Tray Version of the icons1915hIcon[ACTIVE_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_GOOD);1916hIcon[LOW_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_LOW);1917hIcon[EXPIRED_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_EXPIRED);1918hIcon[NONE_PARENT_NODE] = AfxGetApp()->LoadIcon(IDI_LEASH_TRAY_NONE);1919bIconInit = TRUE;1920}19211922NOTIFYICONDATA nid;1923memset (&nid, 0x00, sizeof(NOTIFYICONDATA));1924nid.cbSize = sizeof(NOTIFYICONDATA);1925nid.hWnd = m_hWnd;1926nid.uID = 0;1927nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;1928nid.uCallbackMessage = WM_TRAYICON;1929nid.hIcon = hIcon[state];1930Shell_NotifyIcon (nim, &nid);1931}19321933if ( nim == NIM_ADD )1934m_bIconAdded = TRUE;1935if ( nim == NIM_DELETE )1936m_bIconDeleted = TRUE;1937}19381939BOOL CLeashView::PostWarningMessage(const CString& message)1940{1941if (m_pWarningMessage)1942{1943return FALSE; // can't post more than one warning at a time1944}1945m_pWarningMessage = new CString(message);1946PostMessage(WM_WARNINGPOPUP);1947return TRUE;1948}19491950LRESULT CLeashView::OnWarningPopup(WPARAM wParam, LPARAM lParam)1951{1952CLeashMessageBox leashMessageBox(CMainFrame::m_isMinimum ? GetDesktopWindow() : NULL,1953*m_pWarningMessage, 100000);1954leashMessageBox.DoModal();1955delete m_pWarningMessage;1956m_pWarningMessage = NULL;1957return 0L;1958}19591960BOOL CLeashView::PreTranslateMessage(MSG* pMsg)1961{1962if ( pMsg->message == ID_OBTAIN_TGT_WITH_LPARAM )1963{1964OutputDebugString("Obtain TGT with LParam\n");1965}19661967if ( pMsg->message == WM_TIMER ) {1968try {1969if (InterlockedDecrement(&m_timerMsgNotInProgress) == 0) {19701971CString ticketStatusKrb5 = TCHAR(NOT_INSTALLED);1972CString strTimeDate;1973CString lowTicketWarningKrb5;19741975timer_start:1976if (WaitForSingleObject( ticketinfo.lockObj, 100 ) != WAIT_OBJECT_0)1977throw("Unable to lock ticketinfo");1978if (CLeashApp::m_hKrb5DLL)1979{1980// KRB51981UpdateTicketTime(ticketinfo.Krb5);19821983if (!ticketinfo.Krb5.btickets)1984{1985ticketStatusKrb5 = "Kerb-5: No Tickets";1986}1987else if (EXPIRED_TICKETS == ticketinfo.Krb5.btickets)1988{1989ticketStatusKrb5 = "Kerb-5: Expired Ticket(s)";1990m_ticketTimeLeft = 0;1991lowTicketWarningKrb5 = "Your Kerberos Five ticket(s) have expired";1992if (!m_warningOfTicketTimeLeftLockKrb5)1993m_warningOfTicketTimeLeftKrb5 = 0;1994m_warningOfTicketTimeLeftLockKrb5 = ZERO_MINUTES_LEFT;1995}1996else1997{1998m_ticketStatusKrb5 = GetLowTicketStatus(5);1999switch (m_ticketStatusKrb5)2000{2001case TWENTY_MINUTES_LEFT:2002break;2003case FIFTEEN_MINUTES_LEFT:2004ticketinfo.Krb5.btickets = TICKETS_LOW;2005lowTicketWarningKrb5 = "Less then 15 minutes left on your Kerberos Five ticket(s)";2006break;2007case TEN_MINUTES_LEFT:2008ticketinfo.Krb5.btickets = TICKETS_LOW;2009lowTicketWarningKrb5 = "Less then 10 minutes left on your Kerberos Five ticket(s)";2010if (!m_warningOfTicketTimeLeftLockKrb5)2011m_warningOfTicketTimeLeftKrb5 = 0;2012m_warningOfTicketTimeLeftLockKrb5 = TEN_MINUTES_LEFT;2013break;2014case FIVE_MINUTES_LEFT:2015ticketinfo.Krb5.btickets = TICKETS_LOW;2016if (m_warningOfTicketTimeLeftLockKrb5 == TEN_MINUTES_LEFT)2017m_warningOfTicketTimeLeftKrb5 = 0;2018m_warningOfTicketTimeLeftLockKrb5 = FIVE_MINUTES_LEFT;2019lowTicketWarningKrb5 = "Less then 5 minutes left on your Kerberos Five ticket(s)";2020break;2021default:2022m_ticketStatusKrb5 = 0;2023break;2024}2025}20262027if (CMainFrame::m_isMinimum)2028{2029// minimized display2030ticketStatusKrb5.Format("Kerb-5: %02d:%02d Left",2031(m_ticketTimeLeft / 60L / 60L),2032(m_ticketTimeLeft / 60L % 60L));2033}2034else2035{2036// normal display2037if (GOOD_TICKETS == ticketinfo.Krb5.btickets || TICKETS_LOW == ticketinfo.Krb5.btickets)2038{2039if ( m_ticketTimeLeft >= 60 ) {2040ticketStatusKrb5.Format("Kerb-5 Ticket Life: %02d:%02d",2041(m_ticketTimeLeft / 60L / 60L),2042(m_ticketTimeLeft / 60L % 60L));2043} else {2044ticketStatusKrb5.Format("Kerb-5 Ticket Life: < 1 min");2045}2046}2047#ifndef NO_STATUS_BAR2048if (CMainFrame::m_wndStatusBar)2049{2050CMainFrame::m_wndStatusBar.SetPaneInfo(1, 111112, SBPS_NORMAL, 130);2051CMainFrame::m_wndStatusBar.SetPaneText(1, ticketStatusKrb5, SBT_POPOUT);2052}2053#endif2054}2055}2056else2057{2058// not installed2059ticketStatusKrb5.Format("Kerb-5: Not Available");2060#ifndef NO_STATUS_BAR2061if (CMainFrame::m_wndStatusBar)2062{2063CMainFrame::m_wndStatusBar.SetPaneInfo(1, 111112, SBPS_NORMAL, 130);2064CMainFrame::m_wndStatusBar.SetPaneText(1, ticketStatusKrb5, SBT_POPOUT);2065}2066#endif2067}2068//KRB520692070if ( m_ticketStatusKrb5 == TWENTY_MINUTES_LEFT &&2071m_autoRenewTickets && !m_autoRenewalAttempted && ticketinfo.Krb5.renew_until &&2072(ticketinfo.Krb5.renew_until - LeashTime() > 20 * 60))2073{2074m_autoRenewalAttempted = 1;2075ReleaseMutex(ticketinfo.lockObj);2076AfxBeginThread(RenewTicket,m_hWnd);2077goto timer_start;2078}20792080BOOL warningKrb5 = m_ticketStatusKrb5 > NO_TICKETS &&2081m_ticketStatusKrb5 < TWENTY_MINUTES_LEFT &&2082!m_warningOfTicketTimeLeftKrb5;20832084// Play warning message only once per each case statement above2085if (warningKrb5)2086{20872088CString lowTicketWarning = "";2089int warnings = 0;20902091if (warningKrb5) {2092lowTicketWarning += lowTicketWarningKrb5;2093m_warningOfTicketTimeLeftKrb5 = ON;2094warnings++;2095}20962097ReleaseMutex(ticketinfo.lockObj);2098AlarmBeep();2099PostWarningMessage(lowTicketWarning);2100if (WaitForSingleObject( ticketinfo.lockObj, 100 ) != WAIT_OBJECT_0)2101throw("Unable to lock ticketinfo");2102}21032104CTime tTimeDate = CTime::GetCurrentTime();21052106if (CMainFrame::m_isMinimum)2107{2108strTimeDate = ( "MIT Kerberos - "2109"[" + ticketStatusKrb5 + "] - " +2110"[" + ticketinfo.Krb5.principal + "]" + " - " +2111tTimeDate.Format("%A, %B %d, %Y %H:%M "));2112}2113else2114{2115strTimeDate = ("MIT Kerberos - " +2116tTimeDate.Format("%A, %B %d, %Y %H:%M ")2117//timeDate.Format("%d %b %y %H:%M:%S - ")2118);2119}2120::SetWindowText(CLeashApp::m_hProgram, strTimeDate);21212122if (CLeashApp::m_hKrb5DLL) {2123if ( ticketinfo.Krb5.btickets )2124strTimeDate = ( "MIT Kerberos: "2125"[" + ticketStatusKrb5 + "]" +2126" - [" + ticketinfo.Krb5.principal + "]");2127else2128strTimeDate = "MIT Kerberos: No Tickets";2129}2130ReleaseMutex(ticketinfo.lockObj);21312132SetTrayText(NIM_MODIFY, strTimeDate);21332134m_updateDisplayCount++;2135m_alreadyPlayedDisplayCount++;2136}2137} catch (...) {2138}2139InterlockedIncrement(&m_timerMsgNotInProgress);2140} // WM_TIMER214121422143if (UPDATE_DISPLAY_TIME == m_updateDisplayCount)2144{2145m_updateDisplayCount = 0;2146SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);2147}21482149if (m_alreadyPlayedDisplayCount > 2)2150{2151m_alreadyPlayedDisplayCount = 0;2152m_alreadyPlayed = FALSE;2153}21542155if (CMainFrame::m_isBeingResized)2156{2157m_startup = FALSE;21582159UpdateWindow();21602161CMainFrame::m_isBeingResized = FALSE;2162}21632164if (::IsWindow(pMsg->hwnd))2165return CListView::PreTranslateMessage(pMsg);2166else2167return FALSE;2168}21692170VOID CLeashView::OnLowTicketAlarm()2171{2172m_lowTicketAlarm = !m_lowTicketAlarm;21732174if (m_pApp)2175m_pApp->WriteProfileInt("Settings", "LowTicketAlarm", m_lowTicketAlarm);2176}21772178VOID CLeashView::OnUpdateLowTicketAlarm(CCmdUI* pCmdUI)2179{2180pCmdUI->SetCheck(m_lowTicketAlarm);2181}21822183VOID CLeashView::OnAutoRenew()2184{2185m_autoRenewTickets = !m_autoRenewTickets;21862187if (m_pApp)2188m_pApp->WriteProfileInt("Settings", "AutoRenewTickets", m_autoRenewTickets);21892190m_autoRenewalAttempted = 0;2191}21922193VOID CLeashView::OnUpdateAutoRenew(CCmdUI* pCmdUI)2194{2195pCmdUI->SetCheck(m_autoRenewTickets);2196}21972198VOID CLeashView::OnUpdateMakeDefault(CCmdUI* pCmdUI)2199{2200// enable if exactly one principal is selected and that principal is not2201// the default principal2202BOOL enable = FALSE;2203CCacheDisplayData *elem = m_ccacheDisplay;2204while (elem != NULL) {2205if (elem->m_selected) {2206if (enable) {2207// multiple selection; disable button2208enable = FALSE;2209break;2210}2211if (elem->m_isDefault)2212break;22132214enable = TRUE;2215}2216elem = elem->m_next;2217}2218pCmdUI->Enable(enable);2219}22202221VOID CLeashView::AlarmBeep()2222{2223if (m_lowTicketAlarmSound)2224{2225::Beep(2000, 200);2226::Beep(200, 200);2227::Beep(700, 200);2228}2229}22302231VOID CLeashView::OnUpdateProperties(CCmdUI* pCmdUI)2232{2233if (CLeashApp::m_hKrb5DLL)2234pCmdUI->Enable();2235else2236pCmdUI->Enable(FALSE);2237}22382239void CLeashView::OnHelpLeash32()2240{2241#ifdef CALL_HTMLHELP2242AfxGetApp()->HtmlHelp(HID_LEASH_PROGRAM);2243#else2244AfxGetApp()->WinHelp(HID_LEASH_PROGRAM);2245#endif2246}22472248void CLeashView::OnHelpKerberos()2249{2250#ifdef CALL_HTMLHELP2251AfxGetApp()->HtmlHelp(HID_ABOUT_KERBEROS);2252#else2253AfxGetApp()->WinHelp(HID_ABOUT_KERBEROS);2254#endif2255}22562257void CLeashView::OnHelpWhyuseleash32()2258{2259#ifdef CALL_HTMLHELP2260AfxGetApp()->HtmlHelp(HID_WHY_USE_LEASH32);2261#else2262AfxGetApp()->WinHelp(HID_WHY_USE_LEASH32);2263#endif2264}22652266void CLeashView::OnSysColorChange()2267{2268change_icon_size = FALSE;2269CWnd::OnSysColorChange();2270OnLargeIcons();2271m_imageList.SetBkColor(GetSysColor(COLOR_WINDOW));2272change_icon_size = TRUE;2273}227422752276LRESULT2277CLeashView::OnObtainTGTWithParam(WPARAM wParam, LPARAM lParam)2278{2279LRESULT res = 0;2280char *param = 0;2281LSH_DLGINFO_EX ldi;2282ldi.size = sizeof(ldi);2283ldi.dlgtype = DLGTYPE_PASSWD;2284ldi.use_defaults = 1;2285ldi.title = ldi.in.title;2286ldi.username = ldi.in.username;2287ldi.realm = ldi.in.realm;22882289if (lParam)2290param = (char *) MapViewOfFile((HANDLE)lParam,2291FILE_MAP_ALL_ACCESS,22920,22930,22944096);22952296if ( param ) {2297if ( *param )2298strcpy_s(ldi.in.title,param);2299param += strlen(param) + 1;2300if ( *param )2301strcpy_s(ldi.in.username,param);2302param += strlen(param) + 1;2303if ( *param )2304strcpy_s(ldi.in.realm,param);2305param += strlen(param) + 1;2306if ( *param )2307strcpy_s(ldi.in.ccache,param);2308} else {2309strcpy_s(ldi.in.title, "MIT Kerberos: Get Ticket");2310}23112312if (strlen(ldi.username) > 0 && strlen(ldi.realm) > 0)2313ldi.dlgtype |= DLGFLAG_READONLYPRINC;23142315res = pLeash_kinit_dlg_ex(m_hWnd, &ldi);2316if (param)2317UnmapViewOfFile(param);2318if (lParam)2319CloseHandle((HANDLE )lParam);2320::SendMessage(m_hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);2321return res;2322}232323242325// Find the CCacheDisplayData corresponding to the specified item, if it exists2326static CCacheDisplayData *2327FindCCacheDisplayData(int item, CCacheDisplayData *elem)2328{2329while (elem != NULL) {2330if (elem->m_index == item)2331break;2332elem = elem->m_next;2333}2334return elem;2335}233623372338void CLeashView::OnLvnItemActivate(NMHDR *pNMHDR, LRESULT *pResult)2339{2340LPNMITEMACTIVATE pNMIA = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);2341// TODO: Add your control notification handler code here2342CCacheDisplayData *elem = FindCCacheDisplayData(pNMIA->iItem,2343m_ccacheDisplay);2344if (elem != NULL) {2345elem->m_expanded = !elem->m_expanded;2346OnUpdateDisplay();2347}2348*pResult = 0;2349}235023512352void CLeashView::OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult)2353{2354LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);2355int expand = -1; // -1 = unchanged; 0 = collapse; 1 = expand2356switch (pLVKeyDow->wVKey) {2357case VK_RIGHT:2358// expand focus item2359expand = 1;2360break;2361case VK_LEFT:2362// collapse focus item2363expand = 0;2364break;2365default:2366break;2367}2368if (expand >= 0) {2369int focusedItem = GetListCtrl().GetNextItem(-1, LVNI_FOCUSED);2370if (focusedItem >= 0) {2371CCacheDisplayData *elem = FindCCacheDisplayData(focusedItem,2372m_ccacheDisplay);2373if (elem != NULL) {2374if (elem->m_expanded != expand) {2375elem->m_expanded = expand;2376OnUpdateDisplay();2377}2378}2379}2380}2381*pResult = 0;2382}23832384void CLeashView::OnLvnItemchanging(NMHDR *pNMHDR, LRESULT *pResult)2385{2386CCacheDisplayData *elem;2387LRESULT result = 0;2388LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);2389// TODO: Add your control notification handler code here2390if ((pNMLV->uNewState ^ pNMLV->uOldState) & LVIS_SELECTED) {2391// selection state changing2392elem = FindCCacheDisplayData(pNMLV->iItem, m_ccacheDisplay);2393if (elem == NULL) {2394// this is an individual ticket, not a cache, so prevent selection2395if (pNMLV->uNewState & LVIS_SELECTED) {2396unsigned int newState = pNMLV->uNewState & ~LVIS_SELECTED;2397result = 1; // suppress changes2398if (newState != pNMLV->uOldState) {2399// but need to make other remaining changes still2400GetListCtrl().SetItemState(pNMLV->iItem, newState,2401newState ^ pNMLV->uOldState);2402}2403}2404} else {2405elem->m_selected = (pNMLV->uNewState & LVIS_SELECTED) ? 1 : 0;2406}2407}2408*pResult = result;2409}24102411HFONT CLeashView::GetSubItemFont(int iItem, int iSubItem)2412{2413HFONT retval = m_BaseFont;2414int iColumn, columnSubItem = 0;24152416// Translate subitem to column index2417for (iColumn = 0; iColumn < NUM_VIEW_COLUMNS; iColumn++) {2418if (sm_viewColumns[iColumn].m_enabled) {2419if (columnSubItem == iSubItem)2420break;2421else2422columnSubItem++;2423}2424}2425switch (iColumn) {2426case RENEWABLE_UNTIL:2427case VALID_UNTIL:2428retval = m_aListItemInfo[iItem].m_durationFont;2429break;2430default:2431retval = m_aListItemInfo[iItem].m_font;2432break;2433}2434return retval;2435}24362437void CLeashView::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)2438{2439HFONT font;2440CCacheDisplayData *pElem;2441*pResult = CDRF_DODEFAULT;2442int iItem;24432444LPNMLVCUSTOMDRAW pNMLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);2445switch (pNMLVCD->nmcd.dwDrawStage) {2446case CDDS_PREPAINT:2447*pResult = CDRF_NOTIFYITEMDRAW;2448break;2449case CDDS_ITEMPREPAINT:2450*pResult = CDRF_NOTIFYSUBITEMDRAW;2451break;2452case CDDS_SUBITEM | CDDS_ITEMPREPAINT:2453iItem = pNMLVCD->nmcd.dwItemSpec;2454pElem = FindCCacheDisplayElem(m_ccacheDisplay, iItem);2455font = GetSubItemFont(iItem, pNMLVCD->iSubItem);2456SelectObject(pNMLVCD->nmcd.hdc, font);2457if (pElem != NULL && pNMLVCD->iSubItem == 0) {2458CListCtrl &list = GetListCtrl();2459CRect drawRect, nextRect;2460if (list.GetSubItemRect(iItem, 0, LVIR_BOUNDS, drawRect)) {2461HTHEME hTheme = OpenThemeData(pNMLVCD->nmcd.hdr.hwndFrom,2462L"Explorer::TreeView");2463drawRect.right = drawRect.left +2464(drawRect.bottom - drawRect.top);2465// @TODO: need hot states, too: TVP_HOTGLYPH, HGLPS_OPENED,2466// HGLPS_CLOSED2467int state = pElem->m_expanded ? GLPS_OPENED : GLPS_CLOSED;2468DrawThemeBackground(hTheme,2469pNMLVCD->nmcd.hdc,2470TVP_GLYPH, state,2471&drawRect, NULL);2472}2473}2474*pResult = CDRF_NEWFONT;2475break;2476default:2477break;2478}2479}248024812482