Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2101 lines
50 KiB

  1. /*--
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. kerbtray.c
  5. Abstract:
  6. Displays a dialog with list of Kerberos tickets for the current user.
  7. Author:
  8. 14-Dec-1998 (jbrezak)
  9. Environment:
  10. User mode only.
  11. Requires ANSI C extensions: slash-slash comments, long external names.
  12. Revision History:
  13. 12-Apr-2002 JBrezak Cleanup prefast issues and security review.
  14. --*/
  15. #define UNICODE
  16. #define _UNICODE
  17. #define STRICT
  18. #include <windows.h>
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <shellapi.h>
  23. #include <shlwapi.h>
  24. #include <commctrl.h>
  25. #include <commdlg.h>
  26. #include <time.h>
  27. #include <assert.h>
  28. #include <string.h>
  29. #include <malloc.h>
  30. #define SECURITY_WIN32
  31. #include <security.h>
  32. #include <ntsecapi.h>
  33. #ifndef NO_CRYPTDLL
  34. #include "cryptdll.h"
  35. #endif
  36. #include "kerbtray.h"
  37. #define SEC_SUCCESS(Status) ((Status) >= 0)
  38. #define TSIZE(b) (sizeof(b)/sizeof(TCHAR))
  39. #define IDI_FIRST_CLOCK IDI_0_MIN
  40. #define IDI_LAST_CLOCK IDI_TICKET
  41. #define MAX_ICONS (IDI_LAST_CLOCK - IDI_FIRST_CLOCK + 1)
  42. #define KWIN_UPDATE_PERIOD 60000 // Every 60 seconds update the screen
  43. #define PPAGE_NAMES 0
  44. #define PPAGE_TIMES 1
  45. #define PPAGE_FLAGS 2
  46. #define PPAGE_ETYPES 3
  47. #define C_PAGES 4
  48. #define CX_ICON 20
  49. #define CY_ICON 20
  50. #define TPS (10*1000*1000)
  51. typedef struct
  52. {
  53. HWND hwndTab;
  54. HWND hwndDisplay;
  55. RECT rcDisplay;
  56. DLGTEMPLATE *apRes[C_PAGES];
  57. PKERB_QUERY_TKT_CACHE_RESPONSE Tickets;
  58. } DLGTABHDR;
  59. OSVERSIONINFO osvers;
  60. HWND hWnd, hDlgTickets;
  61. HINSTANCE hInstance;
  62. HANDLE hModule;
  63. #define SHORTSTRING 40
  64. #define LONGSTRING 256
  65. TCHAR progname[SHORTSTRING];
  66. ULONG PackageId;
  67. HANDLE LogonHandle = NULL;
  68. HWND hWndUsers;
  69. HIMAGELIST himl;
  70. HTREEITEM tgt = NULL;
  71. static HICON kwin_icons[MAX_ICONS]; // Icons depicting time
  72. static INT domain_icon;
  73. static LPCTSTR dt_output_dhms = TEXT("%d %s %02d:%02d:%02d");
  74. static LPCTSTR dt_day_plural = TEXT("days");
  75. static LPCTSTR dt_day_singular = TEXT("day");
  76. static LPCTSTR dt_output_donly = TEXT("%d %s");
  77. static LPCTSTR dt_output_hms = TEXT("%d:%02d:%02d");
  78. static LPCTSTR ftime_default_fmt = TEXT("%02d/%02d/%02d %02d:%02d");
  79. #define WM_NOTIFY_ICON (WM_APP+100)
  80. #ifndef NO_CRYPTDLL
  81. typedef NTSTATUS (NTAPI *CDLOCATECSYSTEM)(ULONG dwEtype, PCRYPTO_SYSTEM * ppcsSystem);
  82. CDLOCATECSYSTEM pCDLocateCSystem;
  83. #endif
  84. LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
  85. LRESULT CALLBACK AboutProc(HWND, UINT, WPARAM, LPARAM);
  86. LRESULT CALLBACK TicketsProc(HWND, UINT, WPARAM, LPARAM);
  87. void About(void);
  88. void Tickets(void);
  89. void PurgeCache(void);
  90. void PropsheetDisplay(HWND hDlg);
  91. void SelectTicket(HWND hDlg);
  92. void FillinTicket(HWND hDlg);
  93. LPTSTR etype_string(int enctype);
  94. LPTSTR GetStringRes(int);
  95. #ifdef DEBUG
  96. #define DPRINTF(s) dprintf s
  97. int debug = 1;
  98. void dprintf(LPCTSTR fmt, ...)
  99. {
  100. TCHAR szTemp[512];
  101. va_list ap;
  102. if (!debug)
  103. return;
  104. va_start (ap, fmt);
  105. #ifdef UNICODE
  106. _vsnwprintf(szTemp, TSIZE(szTemp), fmt, ap);
  107. #else
  108. _vsnprintf(szTemp, TSIZE(szTemp), fmt, ap);
  109. #endif
  110. szTemp[TSIZE(szTemp)-1] = 0;
  111. OutputDebugString(szTemp);
  112. va_end (ap);
  113. }
  114. #else
  115. #define DPRINTF(s)
  116. #endif
  117. void
  118. ShowMessage(int level, LPCTSTR msg)
  119. /*++
  120. Routine Description:
  121. Arguments:
  122. Return Value:
  123. --*/
  124. {
  125. if (level)
  126. MessageBeep(level);
  127. MessageBox(NULL, msg, progname,
  128. level | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  129. }
  130. void
  131. Error(LPCTSTR fmt, ...)
  132. /*++
  133. Routine Description:
  134. Arguments:
  135. Return Value:
  136. --*/
  137. {
  138. TCHAR szTemp[512];
  139. va_list ap;
  140. va_start (ap, fmt);
  141. #ifdef UNICODE
  142. _vsnwprintf(szTemp, TSIZE(szTemp), fmt, ap);
  143. #else
  144. _vsnprintf(szTemp, TSIZE(szTemp), fmt, ap);
  145. #endif
  146. szTemp[TSIZE(szTemp)-1] = 0;
  147. OutputDebugString(szTemp);
  148. ShowMessage(MB_ICONINFORMATION, szTemp);
  149. va_end (ap);
  150. }
  151. void
  152. ErrorExit(LPCTSTR lpszMessage)
  153. /*++
  154. Routine Description:
  155. Arguments:
  156. Return Value:
  157. --*/
  158. {
  159. MessageBox(hWnd, lpszMessage, TEXT("Error"), MB_OK);
  160. ExitProcess(0);
  161. }
  162. int
  163. GetIconIndex(long dt)
  164. /*++
  165. Routine Description:
  166. Arguments:
  167. Return Value:
  168. --*/
  169. {
  170. int ixicon;
  171. dt = dt / 60; // convert to minutes
  172. if (dt <= 0)
  173. ixicon = IDI_EXPIRED - IDI_FIRST_CLOCK;
  174. else if (dt > 60)
  175. ixicon = IDI_TICKET - IDI_FIRST_CLOCK;
  176. else
  177. ixicon = (int)(dt / 5);
  178. return ixicon;
  179. }
  180. void
  181. SetTray(
  182. HWND hwnd,
  183. HICON hIcon,
  184. LPCTSTR tip
  185. )
  186. /*++
  187. Routine Description:
  188. Activate or update the tray icon
  189. Arguments:
  190. Return Value:
  191. --*/
  192. {
  193. static tray_inited = 0;
  194. NOTIFYICONDATA tnd;
  195. tnd.cbSize = sizeof(NOTIFYICONDATA);
  196. tnd.hWnd = hwnd;
  197. tnd.uID = IDI_KDC;
  198. tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  199. tnd.uCallbackMessage = WM_NOTIFY_ICON;
  200. tnd.hIcon = hIcon;
  201. StrNCpy(tnd.szTip, tip, TSIZE(tnd.szTip));
  202. Shell_NotifyIcon((tray_inited)?NIM_MODIFY:NIM_ADD, &tnd);
  203. if (tray_inited == 0)
  204. tray_inited++;
  205. DestroyIcon(tnd.hIcon);
  206. }
  207. void
  208. DeleteTray(HWND hwnd)
  209. /*++
  210. Routine Description:
  211. Remove the tray icon
  212. Arguments:
  213. Return Value:
  214. --*/
  215. {
  216. NOTIFYICONDATA tnd;
  217. tnd.cbSize = sizeof(NOTIFYICONDATA);
  218. tnd.hWnd = hwnd;
  219. tnd.uID = IDI_KDC;
  220. tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  221. tnd.uCallbackMessage = WM_NOTIFY_ICON;
  222. tnd.hIcon = NULL;
  223. tnd.szTip[0] = '\0';
  224. Shell_NotifyIcon(NIM_DELETE, &tnd);
  225. }
  226. BOOL
  227. UpdateTray(HWND hwnd)
  228. /*++
  229. Routine Description:
  230. Update the tray icon based on the time to live of the TGT
  231. Arguments:
  232. Return Value:
  233. --*/
  234. {
  235. HICON hicon;
  236. TCHAR buf[SHORTSTRING];
  237. BOOL expired = FALSE;
  238. NTSTATUS Status, SubStatus;
  239. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  240. PKERB_RETRIEVE_TKT_RESPONSE TicketEntry = NULL;
  241. PKERB_EXTERNAL_TICKET Ticket;
  242. ULONG ResponseSize;
  243. FILETIME CurrentFileTime;
  244. LARGE_INTEGER Quad;
  245. long dt = 0L;
  246. int days, hours, minutes, seconds;
  247. DWORD tt;
  248. TCHAR buf2[SHORTSTRING];
  249. StrNCpy(buf, progname, TSIZE(buf));
  250. //
  251. // Get the TGT from the ticket cache
  252. //
  253. CacheRequest.MessageType = KerbRetrieveTicketMessage;
  254. CacheRequest.LogonId.LowPart = 0;
  255. CacheRequest.LogonId.HighPart = 0;
  256. Status = LsaCallAuthenticationPackage(LogonHandle,
  257. PackageId,
  258. &CacheRequest,
  259. sizeof(CacheRequest),
  260. (PVOID *) &TicketEntry,
  261. &ResponseSize,
  262. &SubStatus);
  263. //
  264. // If no TGT, display the correct icon
  265. //
  266. if (!SEC_SUCCESS(Status) || !SEC_SUCCESS(SubStatus)) {
  267. hicon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_KDC));
  268. StrCatBuff(buf, GetStringRes(IDS_NO_CREDS), TSIZE(buf));
  269. }
  270. else {
  271. //
  272. // Select the correct icon based on the time left of the TGT
  273. //
  274. Ticket = &(TicketEntry->Ticket);
  275. GetSystemTimeAsFileTime(&CurrentFileTime);
  276. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  277. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  278. dt = (long)((Ticket->EndTime.QuadPart - Quad.QuadPart) / TPS);
  279. LsaFreeReturnBuffer(TicketEntry);
  280. hicon = kwin_icons[GetIconIndex(dt)];
  281. StrCatBuff(buf, TEXT(" - "), TSIZE(buf));
  282. if (dt <= 0) {
  283. StrCatBuff(buf, GetStringRes(IDS_EXPIRED), TSIZE(buf));
  284. expired = TRUE;
  285. }
  286. else {
  287. days = (int) (dt / (24*3600l));
  288. tt = dt % (24*3600l);
  289. hours = (int) (tt / 3600);
  290. tt %= 3600;
  291. minutes = (int) (tt / 60);
  292. seconds = (int) (tt % 60);
  293. if (days) {
  294. if (hours || minutes || seconds) {
  295. _snwprintf(buf2, TSIZE(buf2), dt_output_dhms, days,
  296. (days > 1) ? dt_day_plural : dt_day_singular,
  297. hours, minutes, seconds);
  298. }
  299. else {
  300. _snwprintf(buf2, TSIZE(buf2), dt_output_donly, days,
  301. (days > 1) ? dt_day_plural : dt_day_singular);
  302. }
  303. }
  304. else {
  305. _snwprintf(buf2, TSIZE(buf2), dt_output_hms,
  306. hours, minutes, seconds);
  307. }
  308. _snwprintf(buf, TSIZE(buf), TEXT("%s %s"), progname, buf2);
  309. }
  310. }
  311. SetTray(hwnd, hicon, buf);
  312. return(expired);
  313. }
  314. BOOL
  315. InitializeApp(
  316. HANDLE hInstance,
  317. int nCmdShow
  318. )
  319. /*++
  320. Routine Description:
  321. Arguments:
  322. Return Value:
  323. --*/
  324. {
  325. LSA_STRING Name;
  326. NTSTATUS Status;
  327. WNDCLASSEX wc;
  328. HWND hwnd;
  329. int i;
  330. //
  331. // Check for an existing instance
  332. //
  333. hwnd = FindWindow(TEXT("MainWindowClass"), TEXT("KerbTray"));
  334. if (hwnd) {
  335. //
  336. // Popup the tickets dialog, if one found
  337. // Run only one instance of kerbtray
  338. //
  339. SendMessage(hwnd, WM_NOTIFY_ICON, 0, WM_LBUTTONDBLCLK);
  340. ExitProcess(0);
  341. }
  342. hModule = GetModuleHandle(NULL);
  343. InitCommonControls();
  344. LoadString(hInstance, IDS_KRB5_NAME, progname, TSIZE(progname));
  345. //
  346. // Setup connection for LSA to Kerberos package
  347. //
  348. Status = LsaConnectUntrusted(&LogonHandle);
  349. if (!SEC_SUCCESS(Status)) {
  350. Error(TEXT("Failed to register as a logon process: 0x%x"), Status);
  351. return FALSE;
  352. }
  353. Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
  354. Name.Length = (USHORT) strlen(Name.Buffer);
  355. Name.MaximumLength = Name.Length + 1;
  356. Status = LsaLookupAuthenticationPackage(
  357. LogonHandle,
  358. &Name,
  359. &PackageId
  360. );
  361. if (!SEC_SUCCESS(Status)){
  362. printf("Failed to lookup package %Z: 0x%x\n",&Name, Status);
  363. return FALSE;
  364. }
  365. //
  366. // Create the image list.
  367. //
  368. if ((himl = ImageList_Create(CX_ICON, CY_ICON, ILC_COLOR, MAX_ICONS, 0)) == NULL)
  369. return FALSE;
  370. ImageList_SetBkColor(himl, CLR_NONE);
  371. for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) {
  372. #ifndef COLOR_ICONS
  373. kwin_icons[i - IDI_FIRST_CLOCK] = LoadIcon(hInstance,
  374. MAKEINTRESOURCE(i));
  375. #else
  376. kwin_icons[i - IDI_FIRST_CLOCK] = LoadImage(hInstance,
  377. MAKEINTRESOURCE(i),
  378. IMAGE_ICON, 0, 0,
  379. LR_DEFAULTCOLOR|LR_DEFAULTSIZE|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS);
  380. #endif
  381. (void) ImageList_AddIcon(himl, kwin_icons[i - IDI_FIRST_CLOCK]);
  382. }
  383. #ifndef COLOR_ICONS
  384. domain_icon = ImageList_AddIcon(himl,
  385. LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DOMAIN)));
  386. #else
  387. domain_icon = ImageList_AddIcon(himl,
  388. LoadImage(hInstance, MAKEINTRESOURCE(IDI_DOMAIN),
  389. IMAGE_ICON, 0, 0,
  390. LR_DEFAULTCOLOR|LR_DEFAULTSIZE|LR_LOADTRANSPARENT|LR_LOADMAP3DCOLORS));
  391. #endif
  392. //
  393. // Register a window class for the main window.
  394. //
  395. wc.cbSize = sizeof(WNDCLASSEX);
  396. wc.style = CS_HREDRAW|CS_VREDRAW;
  397. wc.lpfnWndProc = MainWndProc;
  398. wc.cbClsExtra = 0;
  399. wc.cbWndExtra = 0;
  400. wc.hInstance = hInstance;
  401. wc.hIcon = LoadIcon(hModule, MAKEINTRESOURCE(IDI_EXPIRED));
  402. wc.hIconSm = LoadIcon(hModule, MAKEINTRESOURCE(IDI_EXPIRED));
  403. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  404. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  405. wc.lpszMenuName = 0;
  406. wc.lpszClassName = TEXT("MainWindowClass");
  407. if (!RegisterClassEx(&wc)) {
  408. Error(TEXT("RegisterClassEx failed"));
  409. return FALSE;
  410. }
  411. //
  412. // Create the main window
  413. //
  414. hWnd = CreateWindowEx(WS_EX_APPWINDOW,
  415. TEXT("MainWindowClass"),
  416. TEXT("KerbTray"),
  417. WS_OVERLAPPEDWINDOW,
  418. 0, 0,
  419. 5, 5,
  420. NULL,
  421. NULL,
  422. hModule,
  423. NULL);
  424. if (hWnd == NULL) {
  425. Error(TEXT("CreateWindowEx failed"));
  426. return FALSE;
  427. }
  428. ShowWindow(hWnd, SW_HIDE);
  429. return TRUE;
  430. }
  431. int WINAPI
  432. WinMain(
  433. HINSTANCE hInst,
  434. HINSTANCE hPrevInst,
  435. LPSTR lpszCmdLn,
  436. int nShowCmd
  437. )
  438. /*++
  439. Routine Description:
  440. Arguments:
  441. Return Value:
  442. --*/
  443. {
  444. MSG msg;
  445. HANDLE hAccelTable, hCryptDll;
  446. hInstance = hInst;
  447. hModule = GetModuleHandle(NULL);
  448. osvers.dwOSVersionInfoSize = sizeof(osvers);
  449. GetVersionEx(&osvers);
  450. #ifndef NO_CRYPTDLL
  451. hCryptDll = LoadLibrary(TEXT("CRYPTDLL.DLL"));
  452. if (!hCryptDll)
  453. ErrorExit(TEXT("Unable to load cryptdll.dll"));
  454. pCDLocateCSystem = (CDLOCATECSYSTEM) GetProcAddress(hCryptDll, "CDLocateCSystem");
  455. if (!pCDLocateCSystem)
  456. ErrorExit(TEXT("Unable to link cryptdll.dll::CDLocateCSystem"));
  457. #endif
  458. if (! InitializeApp(hInst, nShowCmd))
  459. ErrorExit(TEXT("InitializeApp failure"));
  460. hAccelTable = LoadAccelerators(hInst, TEXT("KerbTray"));
  461. while (GetMessage(&msg, NULL, 0, 0)) {
  462. if (!IsDialogMessage(hDlgTickets, &msg)) {
  463. if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
  464. TranslateMessage(&msg);
  465. DispatchMessage(&msg);
  466. }
  467. }
  468. }
  469. return 1;
  470. UNREFERENCED_PARAMETER(hPrevInst);
  471. UNREFERENCED_PARAMETER(lpszCmdLn);
  472. }
  473. LRESULT CALLBACK
  474. MainWndProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
  475. /*++
  476. Routine Description:
  477. Arguments:
  478. Return Value:
  479. --*/
  480. {
  481. POINT pos;
  482. static HMENU hPopupMenu;
  483. switch (uiMessage) {
  484. //
  485. // Someone clicked the icon
  486. //
  487. case WM_NOTIFY_ICON:
  488. switch (lParam) {
  489. case WM_LBUTTONDBLCLK:
  490. Tickets();
  491. return 0L;
  492. case WM_RBUTTONDOWN:
  493. if (hPopupMenu) {
  494. if (GetCursorPos(&pos)) {
  495. if (TrackPopupMenu(hPopupMenu,
  496. TPM_RIGHTALIGN|TPM_LEFTBUTTON,
  497. pos.x, pos.y,
  498. 0, hwnd, NULL) == 0)
  499. Error(TEXT("TrackPopupMenuFailed: 0x%x"),
  500. GetLastError());
  501. }
  502. }
  503. return 0L;
  504. }
  505. break;
  506. //
  507. // Create a client windows
  508. //
  509. case WM_CREATE:
  510. hPopupMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU));
  511. if (!hPopupMenu)
  512. Error(TEXT("LoadMenu failed %d"), GetLastError());
  513. hPopupMenu = GetSubMenu(hPopupMenu, 0);
  514. if (!hPopupMenu)
  515. Error(TEXT("LoadMenu failed %d"), GetLastError());
  516. (void) UpdateTray(hwnd);
  517. //
  518. // Start timer for watching the TGT
  519. //
  520. if (!SetTimer(hwnd, 1, KWIN_UPDATE_PERIOD, NULL)) {
  521. ErrorExit(TEXT("SetTimer failed"));
  522. }
  523. return 0L;
  524. //
  525. // Update the tray icon
  526. //
  527. case WM_TIMER:
  528. (void) UpdateTray(hwnd);
  529. return(0L);
  530. case WM_ENDSESSION:
  531. return(0L);
  532. //
  533. // Close the main window. First set fKillAll to TRUE to
  534. // terminate all threads. Then wait for the threads to exit
  535. // before passing a close message to a default handler. If you
  536. // don't wait for threads to terminate, process terminates
  537. // with no chance for thread cleanup.
  538. //
  539. case WM_CLOSE:
  540. exit:;
  541. {
  542. DeleteTray(hWnd);
  543. KillTimer(hWnd, 1);
  544. PostQuitMessage(0);
  545. return 0L;
  546. }
  547. //
  548. // Terminate the process
  549. //
  550. case WM_DESTROY:
  551. PostQuitMessage(0);
  552. return 0L;
  553. //
  554. // Handle the menu commands
  555. //
  556. case WM_COMMAND:
  557. switch (LOWORD(wParam)) {
  558. case ID_ABOUT:
  559. About();
  560. return 0L;
  561. case ID_TICKETS:
  562. Tickets();
  563. return 0L;
  564. case ID_PURGE:
  565. PurgeCache();
  566. return 0L;
  567. case ID_EXIT:
  568. goto exit;
  569. }
  570. }
  571. return DefWindowProc(hwnd, uiMessage, wParam, lParam);
  572. }
  573. LPTSTR
  574. GetStringRes(int id)
  575. /*++
  576. Routine Description:
  577. Load a string from the resources
  578. Arguments:
  579. Return Value:
  580. --*/
  581. {
  582. static TCHAR buffer[MAX_PATH];
  583. buffer[0] = 0;
  584. LoadString(GetModuleHandle (NULL), id, buffer, MAX_PATH);
  585. return buffer;
  586. }
  587. LRESULT CALLBACK
  588. AboutProc(
  589. HWND hDlg,
  590. UINT message,
  591. WPARAM wParam,
  592. LPARAM lParam
  593. )
  594. /*++
  595. Routine Description:
  596. Arguments:
  597. Return Value:
  598. --*/
  599. {
  600. static HFONT hfontDlg; // Font for dialog text
  601. DWORD dwVerInfoSize; // Size of version information block
  602. LPTSTR lpVersion; // String pointer to 'version' text
  603. DWORD dwVerHnd = 0; // An 'ignored' parameter, always '0'
  604. UINT uVersionLen;
  605. DWORD wRootLen;
  606. BOOL bRetCode;
  607. int i;
  608. TCHAR szFullPath[LONGSTRING];
  609. TCHAR szResult[LONGSTRING];
  610. TCHAR szGetName[LONGSTRING];
  611. TCHAR szVersion[SHORTSTRING];
  612. DWORD dwResult;
  613. int resmap[6] = {
  614. IDC_COMPANY,
  615. IDC_FILEDESC,
  616. IDC_PRODVER,
  617. IDC_COPYRIGHT,
  618. IDC_OSVERSION,
  619. };
  620. LPSTR lpstrVffInfo;
  621. HANDLE hMem;
  622. switch (message) {
  623. case WM_INITDIALOG:
  624. ShowWindow(hDlg, SW_HIDE);
  625. hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  626. VARIABLE_PITCH | FF_SWISS, TEXT(""));
  627. GetModuleFileName(hInstance, szFullPath, TSIZE(szFullPath));
  628. szFullPath[TSIZE(szFullPath) - 1] = 0;
  629. //
  630. // Now lets dive in and pull out the version information:
  631. //
  632. dwVerInfoSize = GetFileVersionInfoSize(szFullPath, &dwVerHnd);
  633. if (dwVerInfoSize) {
  634. hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
  635. if (!hMem) {
  636. ErrorExit(TEXT("Unable to allocate memory"));
  637. }
  638. lpstrVffInfo = GlobalLock(hMem);
  639. if (!lpstrVffInfo) {
  640. ErrorExit(TEXT("Unable to lock memory"));
  641. }
  642. GetFileVersionInfo(szFullPath, dwVerHnd, dwVerInfoSize, lpstrVffInfo);
  643. //
  644. // The below 'hex' value looks a little confusing, but
  645. // essentially what it is, is the hexidecimal representation
  646. // of a couple different values that represent the language
  647. // and character set that we are wanting string values for.
  648. // 040904E4 is a very common one, because it means:
  649. // US English, Windows MultiLingual characterset
  650. // Or to pull it all apart:
  651. // 04------ = SUBLANG_ENGLISH_USA
  652. // --09---- = LANG_ENGLISH
  653. // ----04E4 = 1252 = Codepage for Windows:Multilingual
  654. //
  655. StrNCpy(szGetName, GetStringRes(IDS_VER_INFO_LANG), TSIZE(szGetName));
  656. wRootLen = lstrlen(szGetName); // Save this position
  657. //
  658. // Set the title of the dialog
  659. //
  660. StrCatBuff(szGetName, TEXT("ProductName"), TSIZE(szGetName));
  661. bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
  662. (LPTSTR)szGetName,
  663. (LPVOID)&lpVersion,
  664. (UINT *)&uVersionLen);
  665. StrNCpy(szResult, TEXT("About "), TSIZE(szResult));
  666. StrCatBuff(szResult, lpVersion, TSIZE(szResult));
  667. SetWindowText(hDlg, szResult);
  668. //
  669. // Walk through the dialog items that we want to replace
  670. //
  671. for (i = 0; i < 6; i++) {
  672. GetDlgItemText(hDlg, resmap[i], szResult, TSIZE(szResult));
  673. szGetName[wRootLen] = TEXT('\0');
  674. StrCatBuff(szGetName, szResult, TSIZE(szGetName));
  675. uVersionLen = 0;
  676. lpVersion = NULL;
  677. bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
  678. (LPTSTR)szGetName,
  679. (LPVOID)&lpVersion,
  680. (UINT *)&uVersionLen);
  681. if ( bRetCode && uVersionLen && lpVersion) {
  682. // Replace dialog item text with version info
  683. StrNCpy(szResult, lpVersion, TSIZE(szResult));
  684. SetDlgItemText(hDlg, resmap[i], szResult);
  685. } else {
  686. dwResult = GetLastError();
  687. _snwprintf(szResult, TSIZE(szResult),
  688. TEXT("Error %lu"), dwResult);
  689. SetDlgItemText (hDlg, resmap[i], szResult);
  690. }
  691. SendMessage(GetDlgItem(hDlg, resmap[i]), WM_SETFONT,
  692. (WPARAM)hfontDlg,
  693. TRUE);
  694. }
  695. GlobalUnlock(hMem);
  696. GlobalFree(hMem);
  697. }
  698. else {
  699. // No version information available
  700. }
  701. SendMessage(GetDlgItem (hDlg, IDC_LABEL), WM_SETFONT,
  702. (WPARAM)hfontDlg,(LPARAM)TRUE);
  703. _snwprintf(szVersion, TSIZE(szVersion),
  704. TEXT("Microsoft Windows %u.%u (Build: %u)"),
  705. osvers.dwMajorVersion,
  706. osvers.dwMinorVersion,
  707. osvers.dwBuildNumber);
  708. szVersion[SHORTSTRING - 1] = 0;
  709. SetWindowText(GetDlgItem(hDlg, IDC_OSVERSION), szVersion);
  710. ShowWindow(hDlg, SW_SHOW);
  711. return TRUE;
  712. case WM_COMMAND:
  713. switch (LOWORD(wParam)) {
  714. case IDOK:
  715. case IDCANCEL:
  716. EndDialog(hDlg, 0);
  717. break;
  718. }
  719. }
  720. return FALSE;
  721. }
  722. void
  723. About(void)
  724. /*++
  725. Routine Description:
  726. Arguments:
  727. Return Value:
  728. --*/
  729. {
  730. DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutProc);
  731. }
  732. #define CheckDlgButtonFlag(b, f) \
  733. CheckDlgButton(hDlg, b, (flags & f)?BST_CHECKED:BST_UNCHECKED)
  734. VOID
  735. ShowFlags(HWND hDlg, ULONG flags)
  736. /*++
  737. Routine Description:
  738. Arguments:
  739. Return Value:
  740. --*/
  741. {
  742. CheckDlgButtonFlag(IDC_FORWARDABLE, KERB_TICKET_FLAGS_forwardable);
  743. CheckDlgButtonFlag(IDC_FORWARDED, KERB_TICKET_FLAGS_forwarded);
  744. CheckDlgButtonFlag(IDC_PROXIABLE, KERB_TICKET_FLAGS_proxiable);
  745. CheckDlgButtonFlag(IDC_PROXY, KERB_TICKET_FLAGS_proxy);
  746. CheckDlgButtonFlag(IDC_MAY_POSTDATE, KERB_TICKET_FLAGS_may_postdate);
  747. CheckDlgButtonFlag(IDC_POSTDATED, KERB_TICKET_FLAGS_postdated);
  748. CheckDlgButtonFlag(IDC_INVALID, KERB_TICKET_FLAGS_invalid);
  749. CheckDlgButtonFlag(IDC_RENEWABLE, KERB_TICKET_FLAGS_renewable);
  750. CheckDlgButtonFlag(IDC_INITIAL, KERB_TICKET_FLAGS_initial);
  751. CheckDlgButtonFlag(IDC_HWAUTH, KERB_TICKET_FLAGS_hw_authent);
  752. CheckDlgButtonFlag(IDC_PREAUTH, KERB_TICKET_FLAGS_pre_authent);
  753. CheckDlgButtonFlag(IDC_OK_AS_DELEGATE, KERB_TICKET_FLAGS_ok_as_delegate);
  754. }
  755. LPTSTR
  756. ETypeString(
  757. int enctype
  758. )
  759. /*++
  760. Routine Description:
  761. Arguments:
  762. Return Value:
  763. --*/
  764. {
  765. #ifndef NO_CRYPTDLL
  766. static PCRYPTO_SYSTEM pcsSystem;
  767. static TCHAR buf[12] = {0};
  768. if (pCDLocateCSystem(enctype, &pcsSystem) == S_OK)
  769. return pcsSystem->Name;
  770. else {
  771. _snwprintf(buf, TSIZE(buf), TEXT("etype %d"), enctype);
  772. buf[11] = 0;
  773. return buf;
  774. }
  775. #else
  776. static TCHAR buf[12];
  777. switch (enctype) {
  778. case KERB_ETYPE_NULL:
  779. return TEXT("NULL");
  780. break;
  781. case KERB_ETYPE_DES_CBC_CRC:
  782. return TEXT("Kerberos DES-CBC-CRC");
  783. break;
  784. case KERB_ETYPE_DES_CBC_MD5:
  785. return TEXT("Kerberos DES-CBC-MD5");
  786. break;
  787. case KERB_ETYPE_RC4_MD4:
  788. return TEXT("RSADSI RC4-MD4");
  789. break;
  790. case KERB_ETYPE_RC4_PLAIN2:
  791. return TEXT("RSADSI RC4-PLAIN");
  792. break;
  793. case KERB_ETYPE_RC4_LM:
  794. return TEXT("RSADSI RC4-LM");
  795. break;
  796. case KERB_ETYPE_DES_PLAIN:
  797. return TEXT("Kerberos DES-Plain");
  798. break;
  799. #ifdef KERB_ETYPE_RC4_HMAC
  800. case KERB_ETYPE_RC4_HMAC:
  801. return TEXT("RSADSI RC4-HMAC");
  802. break;
  803. #endif
  804. case KERB_ETYPE_RC4_PLAIN:
  805. return TEXT("RSADSI RC4");
  806. break;
  807. #ifdef KERB_ETYPE_RC4_HMAC_EXP
  808. case KERB_ETYPE_RC4_HMAC_EXP:
  809. return TEXT("RSADSI RC4-HMAC(Export)");
  810. break;
  811. #endif
  812. case KERB_ETYPE_RC4_PLAIN_EXP:
  813. return TEXT("RSADSI RC4(Export)");
  814. break;
  815. case KERB_ETYPE_DES_CBC_MD5_EXP:
  816. return TEXT("Kerberos DES-CBC-MD5-EXP(Export)");
  817. break;
  818. case KERB_ETYPE_DES_PLAIN_EXP:
  819. return TEXT("Kerberos DES-Plain(Export)");
  820. break;
  821. default:
  822. _snwprintf(buf, TSIZE(buf), TEXT("etype %d"), enctype);
  823. buf[11] = 0;
  824. return buf;
  825. break;
  826. }
  827. #endif
  828. }
  829. LPTSTR
  830. TimeString(TimeStamp ConvertTime)
  831. /*++
  832. Routine Description:
  833. Convert a TimeStamp into something readable
  834. Arguments:
  835. Return Value:
  836. --*/
  837. {
  838. SYSTEMTIME SystemTime;
  839. FILETIME LocalFileTime;
  840. static TCHAR buf[LONGSTRING];
  841. if (ConvertTime.HighPart == 0x7FFFFFFF &&
  842. ConvertTime.LowPart == 0xFFFFFFFF) {
  843. return(GetStringRes(IDS_INFINITE));
  844. }
  845. if (FileTimeToLocalFileTime(
  846. (PFILETIME) &ConvertTime,
  847. &LocalFileTime) &&
  848. FileTimeToSystemTime(
  849. &LocalFileTime,
  850. &SystemTime)) {
  851. _snwprintf(buf, TSIZE(buf), ftime_default_fmt,
  852. SystemTime.wMonth,
  853. SystemTime.wDay,
  854. SystemTime.wYear,
  855. SystemTime.wHour,
  856. SystemTime.wMinute);
  857. buf[TSIZE(buf)-1] = 0;
  858. }
  859. else
  860. return(GetStringRes(IDS_INVALID));
  861. return(buf);
  862. }
  863. DLGTEMPLATE * WINAPI
  864. DoLockDlgRes(LPCTSTR lpszResName)
  865. /*++
  866. Routine Description:
  867. loads and locks a dialog template resource
  868. Arguments:
  869. lpszResName - name of the resource
  870. Return Value:
  871. Returns the address of the locked resource.
  872. --*/
  873. {
  874. HRSRC hrsrc;
  875. HGLOBAL hglb;
  876. DLGTEMPLATE *pDlg;
  877. hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
  878. if (!hrsrc) {
  879. Error(TEXT("Unable to locate resource '%s'"), lpszResName);
  880. ExitProcess(0);
  881. }
  882. hglb = LoadResource(hInstance, hrsrc);
  883. if (!hglb) {
  884. Error(TEXT("Unable to load resource '%s'"), lpszResName);
  885. ExitProcess(0);
  886. }
  887. pDlg = (DLGTEMPLATE *)LockResource(hglb);
  888. if (!pDlg) {
  889. Error(TEXT("Unable to lock resource '%s'"), lpszResName);
  890. ExitProcess(0);
  891. }
  892. return pDlg;
  893. }
  894. void
  895. PurgeCache(void)
  896. /*++
  897. Routine Description:
  898. Arguments:
  899. Return Value:
  900. --*/
  901. {
  902. KERB_PURGE_TKT_CACHE_REQUEST CacheRequest;
  903. PVOID Response;
  904. ULONG ResponseSize;
  905. NTSTATUS Status, SubStatus;
  906. memset(&CacheRequest, 0, sizeof(CacheRequest));
  907. //
  908. // Purge all tickets in the cache
  909. //
  910. CacheRequest.MessageType = KerbPurgeTicketCacheMessage;
  911. Status = LsaCallAuthenticationPackage(LogonHandle,
  912. PackageId,
  913. &CacheRequest,
  914. sizeof(CacheRequest),
  915. &Response,
  916. &ResponseSize,
  917. &SubStatus);
  918. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  919. ShowMessage(MB_ICONINFORMATION, GetStringRes(IDS_PURGED));
  920. }
  921. else {
  922. Error(TEXT("Failed to purge ticket cache - 0x%x"), Status);
  923. }
  924. if (Response != NULL) {
  925. LsaFreeReturnBuffer(Response);
  926. }
  927. }
  928. HTREEITEM
  929. AddOneItem(
  930. HTREEITEM hParent,
  931. LPTSTR szText,
  932. HTREEITEM hInsAfter,
  933. int iImage,
  934. HWND hwndTree,
  935. LPARAM lParam
  936. )
  937. /*++
  938. Routine Description:
  939. Add the item to the specified TreeView
  940. Arguments:
  941. Return Value:
  942. --*/
  943. {
  944. HTREEITEM hItem;
  945. TV_ITEM tvI;
  946. TV_INSERTSTRUCT tvIns;
  947. tvI.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
  948. tvI.pszText = szText;
  949. tvI.cchTextMax = lstrlen(szText);
  950. tvI.lParam = lParam;
  951. tvI.iImage = iImage;
  952. tvI.iSelectedImage = iImage;
  953. tvIns.item = tvI;
  954. tvIns.hInsertAfter = hInsAfter;
  955. tvIns.hParent = hParent;
  956. hItem = TreeView_InsertItem(hwndTree, &tvIns);
  957. return(hItem);
  958. }
  959. HTREEITEM
  960. FindDomainByName(LPTSTR name)
  961. /*++
  962. Routine Description:
  963. Find the tree for the specified Domain
  964. Arguments:
  965. Return Value:
  966. --*/
  967. {
  968. HTREEITEM dom = NULL;
  969. TVITEM item;
  970. TCHAR buf[LONGSTRING];
  971. dom = TreeView_GetRoot(hWndUsers);
  972. if (!dom)
  973. return NULL;
  974. do {
  975. item.mask = TVIF_TEXT;
  976. item.pszText = buf;
  977. item.cchTextMax = sizeof(buf);
  978. item.hItem = dom;
  979. if (TreeView_GetItem(hWndUsers, &item)) {
  980. if (wcscmp(name, buf) == 0) {
  981. return dom;
  982. }
  983. }
  984. } while (dom = TreeView_GetNextSibling(hWndUsers, dom));
  985. return NULL;
  986. }
  987. HTREEITEM
  988. AddDomain(
  989. LPTSTR name
  990. )
  991. /*++
  992. Routine Description:
  993. Add the named Domain to the tree
  994. Arguments:
  995. Return Value:
  996. --*/
  997. {
  998. HTREEITEM hItem;
  999. if (!(hItem = FindDomainByName(name))) {
  1000. hItem = AddOneItem(NULL, _wcsdup(name), TVI_ROOT,
  1001. domain_icon, hWndUsers, 0);
  1002. }
  1003. return(hItem);
  1004. }
  1005. HTREEITEM
  1006. FindTicketByName(HTREEITEM lip, LPTSTR name)
  1007. /*++
  1008. Routine Description:
  1009. Find a ticket by name in the tree
  1010. Arguments:
  1011. Return Value:
  1012. --*/
  1013. {
  1014. HTREEITEM tick = NULL;
  1015. TVITEM item;
  1016. TCHAR buf[LONGSTRING];
  1017. tick = TreeView_GetChild(hWndUsers, lip);
  1018. if (!tick)
  1019. return NULL;
  1020. do {
  1021. item.mask = TVIF_TEXT;
  1022. item.pszText = buf;
  1023. item.cchTextMax = sizeof(buf);
  1024. item.hItem = tick;
  1025. if (TreeView_GetItem(hWndUsers, &item)) {
  1026. if (wcscmp(name, buf) == 0) {
  1027. return tick;
  1028. }
  1029. }
  1030. } while (tick = TreeView_GetNextSibling(hWndUsers, tick));
  1031. return NULL;
  1032. }
  1033. HTREEITEM
  1034. AddTicket(
  1035. HTREEITEM dom,
  1036. LPTSTR name,
  1037. int idx,
  1038. LPARAM lParam
  1039. )
  1040. /*++
  1041. Routine Description:
  1042. Add a ticket to the domain branch.
  1043. Arguments:
  1044. Return Value:
  1045. --*/
  1046. {
  1047. HTREEITEM hItem;
  1048. hItem = AddOneItem(dom, name, TVI_SORT, idx, hWndUsers, lParam);
  1049. TreeView_Expand(hWndUsers, dom, TVE_EXPAND);
  1050. return(hItem);
  1051. }
  1052. void
  1053. ShowTicket(
  1054. HWND hDlg,
  1055. PKERB_TICKET_CACHE_INFO tix,
  1056. int i,
  1057. BOOL ShowExpiredTickets
  1058. )
  1059. /*++
  1060. Routine Description:
  1061. Updates a Ticket for display
  1062. Arguments:
  1063. Return Value:
  1064. --*/
  1065. {
  1066. TCHAR sname[LONGSTRING];
  1067. HTREEITEM dom, tick;
  1068. FILETIME CurrentFileTime;
  1069. LARGE_INTEGER Quad;
  1070. long dt = 0L;
  1071. memset(sname, 0, sizeof(sname));
  1072. //
  1073. // Calculate ticket lifetime
  1074. //
  1075. GetSystemTimeAsFileTime(&CurrentFileTime);
  1076. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  1077. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  1078. dt = (long)((tix->EndTime.QuadPart - Quad.QuadPart) / TPS);
  1079. //
  1080. // Only display valid tickets
  1081. //
  1082. if (dt > 0 || ShowExpiredTickets)
  1083. {
  1084. //
  1085. // Add realm to tree control
  1086. //
  1087. swprintf(sname, TEXT("%wZ"), &tix->RealmName);
  1088. dom = AddDomain(sname);
  1089. //
  1090. // Add ticket under realm
  1091. //
  1092. swprintf(sname, TEXT("%wZ"), &tix->ServerName);
  1093. tick = AddTicket(dom, sname, GetIconIndex(dt), (LPARAM)tix);
  1094. //
  1095. // Look for initial TGT
  1096. //
  1097. if (tix->TicketFlags & KERB_TICKET_FLAGS_initial)
  1098. tgt = tick;
  1099. }
  1100. }
  1101. void
  1102. DisplayCreds(
  1103. HWND hDlg
  1104. )
  1105. /*++
  1106. Routine Description:
  1107. Get the list of tickets to display
  1108. Arguments:
  1109. Return Value:
  1110. --*/
  1111. {
  1112. KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
  1113. PKERB_RETRIEVE_TKT_RESPONSE TicketEntry = NULL;
  1114. PKERB_EXTERNAL_TICKET Ticket;
  1115. NTSTATUS Status, SubStatus;
  1116. ULONG ResponseSize;
  1117. DWORD i;
  1118. DLGTABHDR *pHdr;
  1119. TCITEM tie;
  1120. DWORD dwDlgBase = GetDialogBaseUnits();
  1121. int cxMargin = LOWORD(dwDlgBase) / 4;
  1122. int cyMargin = HIWORD(dwDlgBase) / 8;
  1123. RECT rcTab;
  1124. static TCHAR princ[LONGSTRING];
  1125. pHdr = (DLGTABHDR *) LocalAlloc(LPTR|LMEM_ZEROINIT, sizeof(DLGTABHDR));
  1126. if (!pHdr)
  1127. ErrorExit(TEXT("Unable to allocate memory"));
  1128. //
  1129. // Save a pointer to the DLGHDR structure.
  1130. //
  1131. SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)pHdr);
  1132. pHdr->hwndTab = GetDlgItem(hDlg, IDC_TAB_ATTRIBUTES);
  1133. hWndUsers = GetDlgItem(hDlg, IDC_TICKETS);
  1134. //
  1135. // Associate the image list with the tree view control.
  1136. //
  1137. //TreeView_SetImageList(hWndUsers, himl, TVSIL_NORMAL);
  1138. //
  1139. // Add a tab for each of the three child dialog boxes.
  1140. //
  1141. tie.mask = TCIF_TEXT | TCIF_IMAGE;
  1142. tie.iImage = -1;
  1143. tie.pszText = GetStringRes(IDS_LNAMES);
  1144. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_NAMES, &tie);
  1145. tie.pszText = GetStringRes(IDS_LTIMES);
  1146. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_TIMES, &tie);
  1147. tie.pszText = GetStringRes(IDS_LFLAGS);
  1148. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_FLAGS, &tie);
  1149. tie.pszText = GetStringRes(IDS_LENCTYPE);
  1150. TabCtrl_InsertItem(pHdr->hwndTab, PPAGE_ETYPES, &tie);
  1151. //
  1152. // Lock the resources for the three child dialog boxes.
  1153. //
  1154. pHdr->apRes[PPAGE_NAMES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_NAMES));
  1155. pHdr->apRes[PPAGE_TIMES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_TIMES));
  1156. pHdr->apRes[PPAGE_FLAGS] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_TKT_FLAGS));
  1157. pHdr->apRes[PPAGE_ETYPES] = DoLockDlgRes(MAKEINTRESOURCE(IDD_PROP_ENCTYPES));
  1158. //
  1159. // Determine the bounding rectangle for all child dialog boxes.
  1160. //
  1161. SetRectEmpty(&rcTab);
  1162. for (i = 0; i < C_PAGES; i++) {
  1163. if (pHdr->apRes[i]->cx > rcTab.right)
  1164. rcTab.right = pHdr->apRes[i]->cx;
  1165. if (pHdr->apRes[i]->cy > rcTab.bottom)
  1166. rcTab.bottom = pHdr->apRes[i]->cy;
  1167. }
  1168. rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
  1169. rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
  1170. //
  1171. // Calculate how large to make the tab control, so
  1172. // the display area can accommodate all the child dialog boxes.
  1173. //
  1174. TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
  1175. OffsetRect(&rcTab, cxMargin - rcTab.left,
  1176. cyMargin - rcTab.top);
  1177. //
  1178. // Calculate the display rectangle.
  1179. //
  1180. CopyRect(&pHdr->rcDisplay, &rcTab);
  1181. TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
  1182. //
  1183. // Get the User's TGT for the client name
  1184. //
  1185. CacheRequest.MessageType = KerbRetrieveTicketMessage;
  1186. CacheRequest.LogonId.LowPart = 0;
  1187. CacheRequest.LogonId.HighPart = 0;
  1188. Status = LsaCallAuthenticationPackage(LogonHandle,
  1189. PackageId,
  1190. &CacheRequest,
  1191. sizeof(CacheRequest),
  1192. (PVOID *) &TicketEntry,
  1193. &ResponseSize,
  1194. &SubStatus);
  1195. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1196. //
  1197. // Got the cname/crealm format it and display
  1198. //
  1199. Ticket = &(TicketEntry->Ticket);
  1200. memset(princ, 0, sizeof(princ));
  1201. swprintf(princ, TEXT("%wZ@%wZ"),
  1202. &Ticket->ClientName->Names[0],
  1203. &Ticket->DomainName);
  1204. SetDlgItemText(hDlg, IDC_PRINC_LABEL, princ);
  1205. }
  1206. else {
  1207. //
  1208. // No TGT, clear out the client name
  1209. //
  1210. SetDlgItemText(hDlg, IDC_PRINC_LABEL,
  1211. GetStringRes(IDS_NO_NET_CREDS));
  1212. SetDlgItemText(hDlg, IDC_PRINC_START,
  1213. TEXT(""));
  1214. if (TicketEntry)
  1215. LsaFreeReturnBuffer(TicketEntry);
  1216. return;
  1217. }
  1218. //
  1219. // Done with the TGT
  1220. //
  1221. if (TicketEntry) {
  1222. LsaFreeReturnBuffer(TicketEntry);
  1223. TicketEntry = NULL;
  1224. }
  1225. //
  1226. // Get the list of cached tickets
  1227. //
  1228. CacheRequest.MessageType = KerbQueryTicketCacheMessage;
  1229. CacheRequest.LogonId.LowPart = 0;
  1230. CacheRequest.LogonId.HighPart = 0;
  1231. Status = LsaCallAuthenticationPackage(LogonHandle,
  1232. PackageId,
  1233. &CacheRequest,
  1234. sizeof(CacheRequest),
  1235. (PVOID *) &pHdr->Tickets,
  1236. &ResponseSize,
  1237. &SubStatus);
  1238. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1239. for (i = 0; i < pHdr->Tickets->CountOfTickets; i++) {
  1240. ShowTicket(hDlg, &pHdr->Tickets->Tickets[i], i, FALSE);
  1241. }
  1242. }
  1243. //
  1244. // Position the selection on the initial TGT
  1245. //
  1246. if (tgt)
  1247. TreeView_SelectItem(hWndUsers, tgt);
  1248. PropsheetDisplay(hDlg);
  1249. SelectTicket(hDlg);
  1250. }
  1251. LRESULT CALLBACK
  1252. PropSheetProc(
  1253. HWND hDlg,
  1254. UINT message,
  1255. WPARAM wParam,
  1256. LPARAM lParam
  1257. )
  1258. /*++
  1259. Routine Description:
  1260. Arguments:
  1261. Return Value:
  1262. --*/
  1263. {
  1264. DLGTABHDR *pHdr;
  1265. HWND hwndParent = GetParent(hDlg);
  1266. hwndParent = GetParent(hwndParent);
  1267. pHdr = (DLGTABHDR *) GetWindowLongPtr(hwndParent, GWLP_USERDATA);
  1268. switch (message) {
  1269. case WM_INITDIALOG:
  1270. SetWindowPos(hDlg, HWND_TOP,
  1271. pHdr->rcDisplay.left, pHdr->rcDisplay.top,
  1272. 0, 0, SWP_NOSIZE);
  1273. return TRUE;
  1274. }
  1275. return FALSE;
  1276. }
  1277. void
  1278. PropsheetDisplay(HWND hDlg)
  1279. /*++
  1280. Routine Description:
  1281. Arguments:
  1282. Return Value:
  1283. --*/
  1284. {
  1285. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1286. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1287. //
  1288. // Destroy the current child dialog box, if any.
  1289. //
  1290. if (pHdr->hwndDisplay != NULL)
  1291. DestroyWindow(pHdr->hwndDisplay);
  1292. //
  1293. // Create the new child dialog box.
  1294. //
  1295. pHdr->hwndDisplay = CreateDialogIndirect(hInstance, pHdr->apRes[iSel],
  1296. pHdr->hwndTab, PropSheetProc);
  1297. }
  1298. INT
  1299. UnparseExternalName(
  1300. PKERB_EXTERNAL_NAME iName,
  1301. PUNICODE_STRING *np
  1302. )
  1303. /*++
  1304. Routine Description:
  1305. Format the name list into a "/" seperated name for display.
  1306. Arguments:
  1307. Return Value:
  1308. --*/
  1309. {
  1310. int len, cnt;
  1311. PUNICODE_STRING name;
  1312. for (len = 0, cnt = 0; cnt < iName->NameCount; cnt++) {
  1313. len += iName->Names[cnt].Length;
  1314. if ((cnt + 1) < iName->NameCount)
  1315. len += 2;
  1316. }
  1317. name = malloc(sizeof(UNICODE_STRING));
  1318. if (!name)
  1319. return -1;
  1320. name->Buffer = malloc(len + 2);
  1321. if (!name->Buffer) {
  1322. free(name);
  1323. return -1;
  1324. }
  1325. name->Length = 0;
  1326. name->MaximumLength = len+2;
  1327. memset(name->Buffer, 0, len + 2);
  1328. for (cnt = 0; cnt < iName->NameCount; cnt++) {
  1329. wcsncat(name->Buffer, iName->Names[cnt].Buffer, iName->Names[cnt].Length/2);
  1330. name->Length += iName->Names[cnt].Length;
  1331. if ((cnt + 1) < iName->NameCount) {
  1332. wcsncat(name->Buffer, L"/", 1);
  1333. name->Length += 2;
  1334. }
  1335. }
  1336. *np = name;
  1337. return 0;
  1338. }
  1339. VOID
  1340. FreeUnicodeString(
  1341. PUNICODE_STRING ustr
  1342. )
  1343. /*++
  1344. Routine Description:
  1345. Arguments:
  1346. Return Value:
  1347. --*/
  1348. {
  1349. if (ustr) {
  1350. free(ustr->Buffer);
  1351. free(ustr);
  1352. }
  1353. }
  1354. void
  1355. SelectTicket(HWND hDlg)
  1356. /*++
  1357. Routine Description:
  1358. Respond to the user clicking on a ticket in the tree
  1359. Arguments:
  1360. Return Value:
  1361. --*/
  1362. {
  1363. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1364. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1365. HTREEITEM hItem = TreeView_GetSelection(hWndUsers);
  1366. TVITEM item;
  1367. TCHAR sname[LONGSTRING];
  1368. PKERB_TICKET_CACHE_INFO tix;
  1369. FILETIME CurrentFileTime;
  1370. LARGE_INTEGER Quad;
  1371. long dt = 0L;
  1372. //
  1373. // No selection
  1374. //
  1375. if (!hItem)
  1376. return;
  1377. item.hItem = hItem;
  1378. item.mask = TVIF_PARAM;
  1379. item.lParam = 0;
  1380. TreeView_GetItem(hWndUsers, &item);
  1381. //
  1382. // No info on the leaf
  1383. //
  1384. if (!item.lParam) {
  1385. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1386. GetStringRes(IDS_DOMAIN));
  1387. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, TEXT(""));
  1388. FillinTicket(hDlg);
  1389. return;
  1390. }
  1391. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1392. GetStringRes(IDS_SERVICE_PRINCIPAL));
  1393. tix = (PKERB_TICKET_CACHE_INFO)item.lParam;
  1394. //
  1395. // Calculate lifetime
  1396. //
  1397. GetSystemTimeAsFileTime(&CurrentFileTime);
  1398. Quad.LowPart = CurrentFileTime.dwLowDateTime;
  1399. Quad.HighPart = CurrentFileTime.dwHighDateTime;
  1400. dt = (long)((tix->EndTime.QuadPart - Quad.QuadPart) / TPS);
  1401. if (dt > 0) {
  1402. swprintf(sname, TEXT("%wZ@%wZ"),
  1403. &tix->ServerName,
  1404. &tix->RealmName);
  1405. SetDlgItemText(hDlg, IDC_SERVICE_PRINC, sname);
  1406. }
  1407. else {
  1408. SetDlgItemText(hDlg, IDC_SERVICE_PRINC_LABEL,
  1409. GetStringRes(IDS_EXPIRED));
  1410. SetDlgItemText(hDlg, IDC_SERVICE_PRINC,
  1411. TEXT(""));
  1412. }
  1413. FillinTicket(hDlg);
  1414. }
  1415. void
  1416. FillinTicket(HWND hDlg)
  1417. /*++
  1418. Routine Description:
  1419. Arguments:
  1420. Return Value:
  1421. --*/
  1422. {
  1423. PKERB_TICKET_CACHE_INFO tix;
  1424. DLGTABHDR *pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1425. int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
  1426. HTREEITEM hItem = TreeView_GetSelection(hWndUsers);
  1427. TVITEM item;
  1428. PKERB_RETRIEVE_TKT_REQUEST TicketRequest;
  1429. ULONG ResponseSize;
  1430. NTSTATUS Status, SubStatus;
  1431. PKERB_EXTERNAL_TICKET ticket;
  1432. int sz;
  1433. TCHAR sname[LONGSTRING];
  1434. PUNICODE_STRING svc;
  1435. if (!hItem)
  1436. return;
  1437. item.hItem = hItem;
  1438. item.mask = TVIF_PARAM;
  1439. item.lParam = 0;
  1440. TreeView_GetItem(hWndUsers, &item);
  1441. switch(iSel) {
  1442. case PPAGE_NAMES:
  1443. SetDlgItemText(pHdr->hwndDisplay, IDC_SERVICENAME,
  1444. TEXT(""));
  1445. SetDlgItemText(pHdr->hwndDisplay, IDC_TARGETNAME,
  1446. TEXT(""));
  1447. #if 0
  1448. SetDlgItemText(pHdr->hwndDisplay, IDC_CLIENTNAME,
  1449. TEXT(""));
  1450. #endif
  1451. break;
  1452. case PPAGE_TIMES:
  1453. SetDlgItemText(pHdr->hwndDisplay, IDC_STARTTIME,
  1454. TEXT(""));
  1455. SetDlgItemText(pHdr->hwndDisplay, IDC_ENDTIME,
  1456. TEXT(""));
  1457. SetDlgItemText(pHdr->hwndDisplay, IDC_RENEW_UNTIL,
  1458. TEXT(""));
  1459. break;
  1460. case PPAGE_ETYPES:
  1461. SetDlgItemText(pHdr->hwndDisplay, IDC_TKT_ENCTYPE,
  1462. TEXT(""));
  1463. SetDlgItemText(pHdr->hwndDisplay, IDC_KEY_ENCTYPE,
  1464. TEXT(""));
  1465. break;
  1466. case PPAGE_FLAGS:
  1467. ShowFlags(pHdr->hwndDisplay, 0);
  1468. break;
  1469. }
  1470. if (!item.lParam) {
  1471. return;
  1472. }
  1473. //
  1474. // Retrieve full ticket for properties
  1475. //
  1476. tix = (PKERB_TICKET_CACHE_INFO)item.lParam;
  1477. swprintf(sname, TEXT("%wZ@%wZ"),
  1478. &tix->ServerName,
  1479. &tix->RealmName);
  1480. sz = sizeof(WCHAR)*(wcslen(sname) + 1);
  1481. TicketRequest = LocalAlloc(LMEM_ZEROINIT,
  1482. sizeof(KERB_RETRIEVE_TKT_REQUEST) + sz);
  1483. if (!TicketRequest)
  1484. ErrorExit(TEXT("Unable to allocate memory"));
  1485. TicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
  1486. TicketRequest->LogonId.LowPart = 0;
  1487. TicketRequest->LogonId.HighPart = 0;
  1488. TicketRequest->TargetName.Length = wcslen(sname) * sizeof(WCHAR);
  1489. TicketRequest->TargetName.MaximumLength =
  1490. TicketRequest->TargetName.Length + sizeof(WCHAR);
  1491. TicketRequest->TargetName.Buffer = (LPWSTR) (TicketRequest + 1);
  1492. wcsncpy(TicketRequest->TargetName.Buffer, sname, wcslen(sname));
  1493. TicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_USE_CACHE_ONLY;
  1494. TicketRequest->EncryptionType = 0L;
  1495. TicketRequest->TicketFlags = 0L;
  1496. Status = LsaCallAuthenticationPackage(LogonHandle,
  1497. PackageId,
  1498. TicketRequest,
  1499. (sizeof(KERB_RETRIEVE_TKT_REQUEST) + sz),
  1500. (PVOID *)&ticket,
  1501. &ResponseSize,
  1502. &SubStatus);
  1503. //
  1504. // Don't need the request buffer anymore
  1505. //
  1506. LocalFree(TicketRequest);
  1507. if (SEC_SUCCESS(Status) && SEC_SUCCESS(SubStatus)) {
  1508. switch(iSel) {
  1509. case PPAGE_NAMES:
  1510. //
  1511. // Get the service name for the ticket
  1512. //
  1513. if (ticket->ServiceName && ticket->DomainName.Length &&
  1514. !UnparseExternalName(ticket->ServiceName, &svc)) {
  1515. swprintf(sname, TEXT("%wZ@%wZ"),
  1516. svc,
  1517. &ticket->DomainName);
  1518. SetDlgItemText(pHdr->hwndDisplay, IDC_SERVICENAME,
  1519. sname);
  1520. FreeUnicodeString(svc);
  1521. }
  1522. #if 0
  1523. //
  1524. // Get the client name from the buffer
  1525. //
  1526. // Bug - client name is wrong from the kerberos ssp. Use
  1527. // the TGT client name.
  1528. //
  1529. if (ticket->ClientName && ticket->DomainName.Length &&
  1530. !UnparseExternalName(ticket->ClientName, &svc)) {
  1531. swprintf(sname, TEXT("%wZ@%wZ"),
  1532. svc,
  1533. &ticket->DomainName);
  1534. SetDlgItemText(pHdr->hwndDisplay, IDC_CLIENTNAME,
  1535. sname);
  1536. FreeUnicodeString(svc);
  1537. }
  1538. #endif
  1539. //
  1540. // Get the requested target name for the ticket
  1541. //
  1542. if (ticket->TargetName && ticket->TargetDomainName.Length &&
  1543. !UnparseExternalName(ticket->TargetName, &svc)) {
  1544. swprintf(sname, TEXT("%wZ@%wZ"),
  1545. svc,
  1546. &ticket->TargetDomainName);
  1547. SetDlgItemText(pHdr->hwndDisplay, IDC_TARGETNAME,
  1548. sname);
  1549. FreeUnicodeString(svc);
  1550. }
  1551. break;
  1552. case PPAGE_TIMES:
  1553. //
  1554. // Display the ticket times
  1555. //
  1556. SetDlgItemText(pHdr->hwndDisplay, IDC_STARTTIME,
  1557. TimeString(tix->StartTime));
  1558. SetDlgItemText(pHdr->hwndDisplay, IDC_ENDTIME,
  1559. TimeString(tix->EndTime));
  1560. if (tix->TicketFlags & KERB_TICKET_FLAGS_renewable) {
  1561. SetDlgItemText(pHdr->hwndDisplay, IDC_RENEW_UNTIL,
  1562. TimeString(tix->RenewTime));
  1563. ShowWindow(GetDlgItem(pHdr->hwndDisplay, IDC_RENEW_UNTIL),
  1564. SW_SHOW);
  1565. }
  1566. else {
  1567. ShowWindow(GetDlgItem(pHdr->hwndDisplay, IDC_RENEW_UNTIL),
  1568. SW_HIDE);
  1569. }
  1570. break;
  1571. case PPAGE_ETYPES:
  1572. //
  1573. // Display ticket and session key enctype
  1574. //
  1575. SetDlgItemText(pHdr->hwndDisplay, IDC_TKT_ENCTYPE,
  1576. ETypeString(tix->EncryptionType));
  1577. SetDlgItemText(pHdr->hwndDisplay, IDC_KEY_ENCTYPE,
  1578. ETypeString(ticket->SessionKey.KeyType));
  1579. break;
  1580. case PPAGE_FLAGS:
  1581. //
  1582. // Display the ticket flags
  1583. //
  1584. ShowFlags(pHdr->hwndDisplay, tix->TicketFlags);
  1585. break;
  1586. }
  1587. LsaFreeReturnBuffer(ticket);
  1588. }
  1589. }
  1590. LRESULT CALLBACK
  1591. TicketsProc(
  1592. HWND hDlg,
  1593. UINT message,
  1594. WPARAM wParam,
  1595. LPARAM lParam
  1596. )
  1597. /*++
  1598. Routine Description:
  1599. Arguments:
  1600. Return Value:
  1601. --*/
  1602. {
  1603. LPNMHDR nm;
  1604. DLGTABHDR *pHdr;
  1605. switch (message) {
  1606. case WM_INITDIALOG:
  1607. DisplayCreds(hDlg);
  1608. ShowWindow(hDlg, SW_SHOW);
  1609. return TRUE;
  1610. case WM_NOTIFY: {
  1611. nm = (LPNMHDR)lParam;
  1612. switch (nm->code) {
  1613. case TCN_SELCHANGING:
  1614. return FALSE;
  1615. case TCN_SELCHANGE:
  1616. PropsheetDisplay(hDlg);
  1617. FillinTicket(hDlg);
  1618. return TRUE;
  1619. case TVN_SELCHANGED:
  1620. SelectTicket(hDlg);
  1621. break;
  1622. }
  1623. }
  1624. break;
  1625. case WM_SYSCOMMAND:
  1626. switch (wParam) {
  1627. case SC_CLOSE:
  1628. goto close_tix;
  1629. }
  1630. break;
  1631. case WM_COMMAND:
  1632. switch (LOWORD(wParam)) {
  1633. case IDC_CLOSE:
  1634. close_tix:
  1635. pHdr = (DLGTABHDR *) GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1636. if (pHdr->hwndDisplay != NULL)
  1637. DestroyWindow(pHdr->hwndDisplay);
  1638. DestroyWindow(hDlgTickets);
  1639. LsaFreeReturnBuffer(pHdr->Tickets);
  1640. LocalFree(pHdr);
  1641. hDlgTickets = NULL;
  1642. break;
  1643. }
  1644. break;
  1645. }
  1646. return FALSE;
  1647. }
  1648. void
  1649. Tickets(void)
  1650. /*++
  1651. Routine Description:
  1652. Arguments:
  1653. Return Value:
  1654. --*/
  1655. {
  1656. if (!hDlgTickets)
  1657. hDlgTickets = CreateDialog(hInstance,
  1658. MAKEINTRESOURCE(IDD_TICKETS),
  1659. hWnd,
  1660. TicketsProc);
  1661. else {
  1662. ShowWindow(hDlgTickets, SW_SHOW);
  1663. SetForegroundWindow(hDlgTickets);
  1664. }
  1665. }