Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/windows/leash/Leash.cpp
34907 views
1
//**************************************************************************
2
// File: Leash.cpp
3
// By: Arthur David Leather
4
// Created: 12/02/98
5
// Copyright: 1998 Massachusetts Institute of Technology - All rights
6
// reserved.
7
//
8
// Description: CPP file for Leash.h. Contains variables and functions
9
// for Leash
10
//
11
// History:
12
//
13
// MM/DD/YY Inits Description of Change
14
// 12/02/98 ADL Original
15
//**************************************************************************
16
17
#include "stdafx.h"
18
#include "Leash.h"
19
20
#include "MainFrm.h"
21
#include "LeashDoc.h"
22
#include "LeashView.h"
23
#include "LeashAboutBox.h"
24
25
#include "reminder.h"
26
#include <leasherr.h>
27
#include "lglobals.h"
28
#include <krb5.h>
29
#include <com_err.h>
30
31
#include <errno.h>
32
33
#include <afxwin.h>
34
35
#ifdef _DEBUG
36
#define new DEBUG_NEW
37
#undef THIS_FILE
38
static char THIS_FILE[] = __FILE__;
39
#endif
40
41
TicketInfoWrapper ticketinfo;
42
43
HWND CLeashApp::m_hProgram = 0;
44
HINSTANCE CLeashApp::m_hLeashDLL = 0;
45
HINSTANCE CLeashApp::m_hComErr = 0;
46
HINSTANCE CLeashApp::m_hKrb5DLL = 0;
47
HINSTANCE CLeashApp::m_hKrb5ProfileDLL= 0;
48
HINSTANCE CLeashApp::m_hPsapi = 0;
49
HINSTANCE CLeashApp::m_hToolHelp32 = 0;
50
krb5_context CLeashApp::m_krbv5_context = 0;
51
profile_t CLeashApp::m_krbv5_profile = 0;
52
HINSTANCE CLeashApp::m_hKrbLSA = 0;
53
int CLeashApp::m_useRibbon = TRUE;
54
BOOL CLeashApp::m_bUpdateDisplay = FALSE;
55
56
/////////////////////////////////////////////////////////////////////////////
57
// CLeashApp
58
59
60
BEGIN_MESSAGE_MAP(CLeashApp, CWinApp)
61
//{{AFX_MSG_MAP(CLeashApp)
62
//}}AFX_MSG_MAP
63
// Standard file based document commands
64
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
65
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
66
END_MESSAGE_MAP()
67
68
/////////////////////////////////////////////////////////////////////////////
69
// CLeashApp construction
70
CLeashApp::CLeashApp()
71
{
72
m_krbv5_context = NULL;
73
m_krbv5_profile = NULL;
74
// TODO: add construction code here,
75
// Place all significant initialization in InitInstance
76
77
// Memory may not be initialized to zeros (in debug)
78
memset(&ticketinfo, 0, sizeof(ticketinfo));
79
80
ticketinfo.lockObj = CreateMutex(NULL, FALSE, NULL);
81
82
#ifdef USE_HTMLHELP
83
#if _MSC_VER >= 1300
84
EnableHtmlHelp();
85
#endif
86
#endif
87
}
88
89
CLeashApp::~CLeashApp()
90
{
91
if ( m_krbv5_context ) {
92
pkrb5_free_context(m_krbv5_context);
93
m_krbv5_context = NULL;
94
}
95
96
if ( m_krbv5_profile ) {
97
pprofile_release(m_krbv5_profile);
98
m_krbv5_profile = NULL;
99
}
100
101
#ifdef COMMENT
102
/* Do not free the locking objects. Doing so causes an invalid handle access */
103
CloseHandle(ticketinfo.lockObj);
104
#endif
105
AfxFreeLibrary(m_hLeashDLL);
106
AfxFreeLibrary(m_hKrb5DLL);
107
AfxFreeLibrary(m_hKrb5ProfileDLL);
108
AfxFreeLibrary(m_hPsapi);
109
AfxFreeLibrary(m_hToolHelp32);
110
AfxFreeLibrary(m_hKrbLSA);
111
#ifdef DEBUG
112
_CrtDumpMemoryLeaks();
113
#endif
114
}
115
116
/////////////////////////////////////////////////////////////////////////////
117
// The one and only CLeashApp object
118
119
CLeashApp theApp;
120
121
/////////////////////////////////////////////////////////////////////////////
122
// CLeashApp initialization
123
124
void CLeashApp::ParseParam (LPCTSTR lpszParam,BOOL bFlag,BOOL bLast)
125
{
126
//CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast) ;
127
}
128
129
extern "C" {
130
LRESULT WINAPI LeashWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
131
{
132
switch ( Msg ) {
133
case WM_SYSCOMMAND:
134
if (SC_CLOSE == (wParam & 0xfff0)) {
135
wParam = (wParam & ~0xfff0) | SC_MINIMIZE;
136
}
137
break;
138
}
139
return ::DefWindowProc(hWnd, Msg, wParam, lParam);
140
}
141
}
142
143
BOOL CLeashApp::InitInstance()
144
{
145
#ifdef DEBUG
146
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
147
_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
148
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
149
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
150
151
int tmp = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG);
152
_CrtSetDbgFlag( tmp | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
153
#endif
154
AfxOleInit();
155
// NOTE: Not used at this time
156
/// Set LEASH_DLL to the path where the Leash.exe is
157
char modulePath[MAX_PATH];
158
krb5_error_code code;
159
DWORD result = GetModuleFileName(AfxGetInstanceHandle(), modulePath, MAX_PATH);
160
ASSERT(result);
161
162
char* pPath = modulePath + strlen(modulePath) - 1;
163
while (*pPath != '\\')
164
{
165
*pPath = 0;
166
pPath--;
167
}
168
strcat(modulePath, LEASH_HELP_FILE);
169
m_helpFile = modulePath;
170
171
///strcat(dllFile, LEASH_DLL);
172
///m_leashDLL = dllFile;
173
174
BOOL autoInit = FALSE;
175
HWND hMsg = GetForegroundWindow();
176
if (!InitDLLs())
177
return FALSE; //exit program, can't load LEASHDLL
178
code = pkrb5_init_context(&m_krbv5_context);
179
if (code) {
180
// @TODO: report error
181
return FALSE;
182
}
183
184
// Check for args (switches)
185
LPCTSTR exeFile = __targv[0];
186
for (int argi = 1; argi < __argc; argi++) {
187
LPCTSTR optionParam = __targv[argi];
188
189
if (!optionParam)
190
continue;
191
192
if (*optionParam == '-' || *optionParam == '/')
193
{
194
if (0 == stricmp(optionParam+1, "kinit") ||
195
0 == stricmp(optionParam+1, "i"))
196
{
197
LSH_DLGINFO_EX ldi;
198
char username[64]="";
199
char realm[192]="";
200
int i=0, j=0;
201
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
202
throw("Unable to lock ticketinfo");
203
204
LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
205
206
if ( ticketinfo.Krb5.btickets && ticketinfo.Krb5.principal ) {
207
for (; ticketinfo.Krb5.principal[i] && ticketinfo.Krb5.principal[i] != '@'; i++)
208
{
209
username[i] = ticketinfo.Krb5.principal[i];
210
}
211
username[i] = '\0';
212
if (ticketinfo.Krb5.principal[i]) {
213
for (i++ ; ticketinfo.Krb5.principal[i] ; i++, j++)
214
{
215
realm[j] = ticketinfo.Krb5.principal[i];
216
}
217
}
218
realm[j] = '\0';
219
}
220
221
LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
222
223
ReleaseMutex(ticketinfo.lockObj);
224
225
ldi.size = LSH_DLGINFO_EX_V1_SZ;
226
ldi.dlgtype = DLGTYPE_PASSWD;
227
ldi.title = "MIT Kerberos: Get Ticket";
228
ldi.username = username;
229
ldi.realm = realm;
230
ldi.dlgtype = DLGTYPE_PASSWD;
231
ldi.use_defaults = 1;
232
233
if (!pLeash_kinit_dlg_ex(hMsg, &ldi))
234
{
235
MessageBox(hMsg, "There was an error getting tickets!",
236
"Error", MB_OK);
237
return FALSE;
238
}
239
return TRUE;
240
}
241
else if (0 == stricmp(optionParam+1, "destroy") ||
242
0 == stricmp(optionParam+1, "d"))
243
{
244
if (pLeash_kdestroy())
245
{
246
MessageBox(hMsg,
247
"There was an error destroying tickets!",
248
"Error", MB_OK);
249
return FALSE;
250
}
251
return TRUE;
252
}
253
else if (0 == stricmp(optionParam+1, "renew") ||
254
0 == stricmp(optionParam+1, "r"))
255
{
256
if (!pLeash_renew())
257
{
258
MessageBox(hMsg,
259
"There was an error renewing tickets!",
260
"Error", MB_OK);
261
return FALSE;
262
}
263
return TRUE;
264
}
265
else if (0 == stricmp(optionParam+1, "autoinit") ||
266
0 == stricmp(optionParam+1, "a"))
267
{
268
autoInit = TRUE;
269
}
270
else if (0 == stricmp(optionParam+1, "console") ||
271
0 == stricmp(optionParam+1, "c"))
272
{
273
FILE *dummy;
274
AllocConsole();
275
freopen_s(&dummy, "CONOUT$", "w", stderr);
276
freopen_s(&dummy, "CONOUT$", "w", stdout);
277
}
278
else if (0 == stricmp(optionParam+1, "noribbon"))
279
{
280
m_useRibbon = FALSE;
281
}
282
else
283
{
284
MessageBox(hMsg,
285
"'-kinit' or '-i' to perform ticket initialization (and exit)\n"
286
"'-renew' or '-r' to perform ticket renewal (and exit)\n"
287
"'-destroy' or '-d' to perform ticket destruction (and exit)\n"
288
"'-autoinit' or '-a' to perform automatic ticket initialization\n"
289
"'-console' or '-c' to attach a console for debugging\n",
290
"MIT Kerberos Error", MB_OK);
291
return FALSE;
292
}
293
}
294
else
295
{
296
MessageBox(hMsg,
297
"'-kinit' or '-i' to perform ticket initialization (and exit)\n"
298
"'-renew' or '-r' to perform ticket renewal (and exit)\n"
299
"'-destroy' or '-d' to perform ticket destruction (and exit)\n"
300
"'-autoinit' or '-a' to perform automatic ticket initialization\n",
301
"MIT Kerberos Error", MB_OK);
302
return FALSE;
303
}
304
}
305
306
// Insure only one instance of Leash
307
if (!FirstInstance())
308
return FALSE;
309
310
if (!CWinAppEx::InitInstance())
311
return FALSE;
312
313
//register our unique wnd class name to find it later
314
WNDCLASS wndcls;
315
memset(&wndcls, 0, sizeof(WNDCLASS));
316
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
317
wndcls.lpfnWndProc = ::LeashWindowProc;
318
wndcls.hInstance = AfxGetInstanceHandle();
319
wndcls.hIcon = LoadIcon(IDR_MAINFRAME);
320
wndcls.hCursor = LoadCursor(IDC_ARROW);
321
wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
322
wndcls.lpszMenuName = NULL;
323
//now the wnd class name to find it
324
wndcls.lpszClassName = _T("LEASH.0WNDCLASS");
325
326
//register the new class
327
if(!AfxRegisterClass(&wndcls))
328
{
329
TRACE("Class registration failed\n");
330
return FALSE;
331
}
332
333
AfxEnableControlContainer();
334
335
// Standard initialization
336
// If you are not using these features and wish to reduce the size
337
// of your final executable, you should remove from the following
338
// the specific initialization routines you do not need.
339
340
#if _MSC_VER < 1300
341
#ifdef _AFXDLL
342
Enable3dControls(); // Call this when using MFC in a shared DLL
343
#else
344
Enable3dControlsStatic(); // Call this when linking to MFC statically
345
#endif
346
#endif
347
348
// Registry key under which our settings are stored.
349
if (m_pszAppName)
350
free((void*)m_pszAppName);
351
m_pszAppName = _tcsdup("MIT Kerberos");
352
SetRegistryKey(_T("MIT"));
353
354
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
355
356
// Register the application's document templates. Document templates
357
// serve as the connection between documents, frame windows and views.
358
359
CSingleDocTemplate* pDocTemplate;
360
pDocTemplate = new CSingleDocTemplate(
361
IDR_MAINFRAME,
362
RUNTIME_CLASS(LeashDoc),
363
RUNTIME_CLASS(CMainFrame), // main SDI frame window
364
RUNTIME_CLASS(CLeashView));
365
AddDocTemplate(pDocTemplate);
366
367
// Parse command line for standard shell commands, DDE, file open
368
CCommandLineInfo cmdInfo;
369
ParseCommandLine(cmdInfo);
370
371
// Dispatch commands specified on the command line
372
if (!ProcessShellCommand(cmdInfo))
373
return FALSE;
374
375
// Check to see if there are any tickets in the cache. If not and
376
// autoinitialization is enabled, display the initial tickets dialog.
377
{
378
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
379
throw("Unable to lock ticketinfo");
380
LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
381
BOOL b_autoinit = !ticketinfo.Krb5.btickets;
382
LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
383
ReleaseMutex(ticketinfo.lockObj);
384
385
if (autoInit) {
386
if ( b_autoinit )
387
AfxBeginThread(InitWorker, m_pMainWnd->m_hWnd);
388
389
IpAddrChangeMonitorInit(m_pMainWnd->m_hWnd);
390
}
391
}
392
393
// The one and only window has been initialized, so show and update it.
394
m_pMainWnd->SetWindowText("MIT Kerberos");
395
m_pMainWnd->UpdateWindow();
396
m_pMainWnd->ShowWindow(SW_SHOW);
397
m_pMainWnd->SetForegroundWindow();
398
399
ValidateConfigFiles();
400
401
return TRUE;
402
}
403
404
405
/////////////////////////////////////////////////////////////////////////////
406
// CLeashApp commands
407
408
// leash functions
409
DECL_FUNC_PTR(Leash_kdestroy);
410
DECL_FUNC_PTR(Leash_changepwd_dlg);
411
DECL_FUNC_PTR(Leash_changepwd_dlg_ex);
412
DECL_FUNC_PTR(Leash_kinit_dlg);
413
DECL_FUNC_PTR(Leash_kinit_dlg_ex);
414
DECL_FUNC_PTR(Leash_timesync);
415
DECL_FUNC_PTR(Leash_get_default_uppercaserealm);
416
DECL_FUNC_PTR(Leash_set_default_uppercaserealm);
417
DECL_FUNC_PTR(Leash_renew);
418
419
FUNC_INFO leash_fi[] = {
420
MAKE_FUNC_INFO(Leash_kdestroy),
421
MAKE_FUNC_INFO(Leash_changepwd_dlg),
422
MAKE_FUNC_INFO(Leash_changepwd_dlg_ex),
423
MAKE_FUNC_INFO(Leash_kinit_dlg),
424
MAKE_FUNC_INFO(Leash_kinit_dlg_ex),
425
MAKE_FUNC_INFO(Leash_timesync),
426
MAKE_FUNC_INFO(Leash_get_default_uppercaserealm),
427
MAKE_FUNC_INFO(Leash_set_default_uppercaserealm),
428
MAKE_FUNC_INFO(Leash_renew),
429
END_FUNC_INFO
430
};
431
432
// com_err functions
433
DECL_FUNC_PTR(error_message);
434
FUNC_INFO ce_fi[] = {
435
MAKE_FUNC_INFO(error_message),
436
END_FUNC_INFO
437
};
438
439
// psapi functions
440
DECL_FUNC_PTR(GetModuleFileNameExA);
441
DECL_FUNC_PTR(EnumProcessModules);
442
443
FUNC_INFO psapi_fi[] = {
444
MAKE_FUNC_INFO(GetModuleFileNameExA),
445
MAKE_FUNC_INFO(EnumProcessModules),
446
END_FUNC_INFO
447
};
448
449
// toolhelp functions
450
DECL_FUNC_PTR(CreateToolhelp32Snapshot);
451
DECL_FUNC_PTR(Module32First);
452
DECL_FUNC_PTR(Module32Next);
453
454
FUNC_INFO toolhelp_fi[] = {
455
MAKE_FUNC_INFO(CreateToolhelp32Snapshot),
456
MAKE_FUNC_INFO(Module32First),
457
MAKE_FUNC_INFO(Module32Next),
458
END_FUNC_INFO
459
};
460
461
// krb5 functions
462
DECL_FUNC_PTR(krb5_cc_default_name);
463
DECL_FUNC_PTR(krb5_cc_set_default_name);
464
DECL_FUNC_PTR(krb5_get_default_config_files);
465
DECL_FUNC_PTR(krb5_free_config_files);
466
DECL_FUNC_PTR(krb5_free_context);
467
DECL_FUNC_PTR(krb5_get_default_realm);
468
DECL_FUNC_PTR(krb5_free_default_realm);
469
DECL_FUNC_PTR(krb5_init_context);
470
DECL_FUNC_PTR(krb5_cc_default);
471
DECL_FUNC_PTR(krb5_parse_name);
472
DECL_FUNC_PTR(krb5_free_principal);
473
DECL_FUNC_PTR(krb5_cc_close);
474
DECL_FUNC_PTR(krb5_cc_get_principal);
475
DECL_FUNC_PTR(krb5_build_principal);
476
DECL_FUNC_PTR(krb5_c_random_make_octets);
477
DECL_FUNC_PTR(krb5_get_init_creds_password);
478
DECL_FUNC_PTR(krb5_free_cred_contents);
479
DECL_FUNC_PTR(krb5_cc_resolve);
480
DECL_FUNC_PTR(krb5_unparse_name);
481
DECL_FUNC_PTR(krb5_free_unparsed_name);
482
DECL_FUNC_PTR(krb5_cc_destroy);
483
DECL_FUNC_PTR(krb5_cccol_cursor_new);
484
DECL_FUNC_PTR(krb5_cccol_cursor_free);
485
DECL_FUNC_PTR(krb5_cccol_cursor_next);
486
DECL_FUNC_PTR(krb5_cc_start_seq_get);
487
DECL_FUNC_PTR(krb5_cc_next_cred);
488
DECL_FUNC_PTR(krb5_cc_end_seq_get);
489
DECL_FUNC_PTR(krb5_cc_get_name);
490
DECL_FUNC_PTR(krb5_cc_set_flags);
491
DECL_FUNC_PTR(krb5_is_config_principal);
492
DECL_FUNC_PTR(krb5_free_ticket);
493
DECL_FUNC_PTR(krb5_decode_ticket);
494
DECL_FUNC_PTR(krb5_cc_switch);
495
DECL_FUNC_PTR(krb5_build_principal_ext);
496
DECL_FUNC_PTR(krb5_get_renewed_creds);
497
DECL_FUNC_PTR(krb5_cc_initialize);
498
DECL_FUNC_PTR(krb5_cc_store_cred);
499
DECL_FUNC_PTR(krb5_cc_get_full_name);
500
DECL_FUNC_PTR(krb5_free_string);
501
DECL_FUNC_PTR(krb5_enctype_to_name);
502
DECL_FUNC_PTR(krb5_cc_get_type);
503
DECL_FUNC_PTR(krb5int_cc_user_set_default_name);
504
505
FUNC_INFO krb5_fi[] = {
506
MAKE_FUNC_INFO(krb5_cc_default_name),
507
MAKE_FUNC_INFO(krb5_cc_set_default_name),
508
MAKE_FUNC_INFO(krb5_get_default_config_files),
509
MAKE_FUNC_INFO(krb5_free_config_files),
510
MAKE_FUNC_INFO(krb5_free_context),
511
MAKE_FUNC_INFO(krb5_get_default_realm),
512
MAKE_FUNC_INFO(krb5_free_default_realm),
513
MAKE_FUNC_INFO(krb5_init_context),
514
MAKE_FUNC_INFO(krb5_cc_default),
515
MAKE_FUNC_INFO(krb5_parse_name),
516
MAKE_FUNC_INFO(krb5_free_principal),
517
MAKE_FUNC_INFO(krb5_cc_close),
518
MAKE_FUNC_INFO(krb5_cc_get_principal),
519
MAKE_FUNC_INFO(krb5_build_principal),
520
MAKE_FUNC_INFO(krb5_c_random_make_octets),
521
MAKE_FUNC_INFO(krb5_get_init_creds_password),
522
MAKE_FUNC_INFO(krb5_free_cred_contents),
523
MAKE_FUNC_INFO(krb5_cc_resolve),
524
MAKE_FUNC_INFO(krb5_unparse_name),
525
MAKE_FUNC_INFO(krb5_free_unparsed_name),
526
MAKE_FUNC_INFO(krb5_cc_destroy),
527
MAKE_FUNC_INFO(krb5_cccol_cursor_new),
528
MAKE_FUNC_INFO(krb5_cccol_cursor_next),
529
MAKE_FUNC_INFO(krb5_cccol_cursor_free),
530
MAKE_FUNC_INFO(krb5_cc_start_seq_get),
531
MAKE_FUNC_INFO(krb5_cc_next_cred),
532
MAKE_FUNC_INFO(krb5_cc_end_seq_get),
533
MAKE_FUNC_INFO(krb5_cc_get_name),
534
MAKE_FUNC_INFO(krb5_cc_set_flags),
535
MAKE_FUNC_INFO(krb5_is_config_principal),
536
MAKE_FUNC_INFO(krb5_free_ticket),
537
MAKE_FUNC_INFO(krb5_decode_ticket),
538
MAKE_FUNC_INFO(krb5_cc_switch),
539
MAKE_FUNC_INFO(krb5_build_principal_ext),
540
MAKE_FUNC_INFO(krb5_get_renewed_creds),
541
MAKE_FUNC_INFO(krb5_cc_initialize),
542
MAKE_FUNC_INFO(krb5_cc_store_cred),
543
MAKE_FUNC_INFO(krb5_cc_get_full_name),
544
MAKE_FUNC_INFO(krb5_free_string),
545
MAKE_FUNC_INFO(krb5_enctype_to_name),
546
MAKE_FUNC_INFO(krb5_cc_get_type),
547
MAKE_FUNC_INFO(krb5int_cc_user_set_default_name),
548
END_FUNC_INFO
549
};
550
551
// profile functions
552
DECL_FUNC_PTR(profile_release);
553
DECL_FUNC_PTR(profile_init);
554
DECL_FUNC_PTR(profile_flush);
555
DECL_FUNC_PTR(profile_rename_section);
556
DECL_FUNC_PTR(profile_update_relation);
557
DECL_FUNC_PTR(profile_clear_relation);
558
DECL_FUNC_PTR(profile_add_relation);
559
DECL_FUNC_PTR(profile_get_relation_names);
560
DECL_FUNC_PTR(profile_get_subsection_names);
561
DECL_FUNC_PTR(profile_get_values);
562
DECL_FUNC_PTR(profile_free_list);
563
DECL_FUNC_PTR(profile_abandon);
564
DECL_FUNC_PTR(profile_get_string);
565
DECL_FUNC_PTR(profile_release_string);
566
567
FUNC_INFO profile_fi[] = {
568
MAKE_FUNC_INFO(profile_release),
569
MAKE_FUNC_INFO(profile_init),
570
MAKE_FUNC_INFO(profile_flush),
571
MAKE_FUNC_INFO(profile_rename_section),
572
MAKE_FUNC_INFO(profile_update_relation),
573
MAKE_FUNC_INFO(profile_clear_relation),
574
MAKE_FUNC_INFO(profile_add_relation),
575
MAKE_FUNC_INFO(profile_get_relation_names),
576
MAKE_FUNC_INFO(profile_get_subsection_names),
577
MAKE_FUNC_INFO(profile_get_values),
578
MAKE_FUNC_INFO(profile_free_list),
579
MAKE_FUNC_INFO(profile_abandon),
580
MAKE_FUNC_INFO(profile_get_string),
581
MAKE_FUNC_INFO(profile_release_string),
582
END_FUNC_INFO
583
};
584
585
// Tries to load the .DLL files. If it works, we get some functions from them
586
// and return a TRUE. If it doesn't work, we return a FALSE.
587
BOOL CLeashApp::InitDLLs()
588
{
589
m_hLeashDLL = AfxLoadLibrary(LEASHDLL);
590
m_hKrb5DLL = AfxLoadLibrary(KERB5DLL);
591
m_hKrb5ProfileDLL = AfxLoadLibrary(KERB5_PPROFILE_DLL);
592
m_hComErr = AfxLoadLibrary(COMERR_DLL);
593
594
#define PSAPIDLL "psapi.dll"
595
#define TOOLHELPDLL "kernel32.dll"
596
597
m_hPsapi = AfxLoadLibrary(PSAPIDLL);
598
m_hToolHelp32 = AfxLoadLibrary(TOOLHELPDLL);
599
600
HWND hwnd = GetForegroundWindow();
601
if (!m_hLeashDLL)
602
{
603
// We couldn't load the m_hLeashDLL.
604
m_msgError = "Couldn't load the Leash DLL or one of its dependents.";
605
MessageBox(hwnd, m_msgError, "Error", MB_OK);
606
return FALSE;
607
}
608
609
if (!LoadFuncs(LEASHDLL, leash_fi, 0, 0, 1, 0, 0))
610
{
611
MessageBox(hwnd,
612
"Functions within the Leash DLL didn't load properly!",
613
"Error", MB_OK);
614
return FALSE;
615
}
616
617
if (!LoadFuncs(COMERR_DLL, ce_fi, &m_hComErr, 0, 0, 1, 0)) {
618
MessageBox(hwnd,
619
"Functions within " COMERR_DLL "didn't load properly!",
620
"Error", MB_OK);
621
return FALSE;
622
}
623
624
if (m_hKrb5DLL)
625
{
626
if (!LoadFuncs(KERB5DLL, krb5_fi, 0, 0, 1, 0, 0))
627
{
628
MessageBox(hwnd,
629
"Unexpected error while loading " KERB5DLL ".\n"
630
"Kerberos 5 functionality will be disabled.\n",
631
"Error", MB_OK);
632
AfxFreeLibrary(m_hKrb5DLL);
633
m_hKrb5DLL = 0;
634
}
635
else if (!m_hKrb5ProfileDLL ||
636
!LoadFuncs(KERB5_PPROFILE_DLL, profile_fi, 0, 0, 1, 0, 0))
637
{
638
MessageBox(hwnd,
639
"Unexpected error while loading " KERB5_PPROFILE_DLL "."
640
"\nKerberos 5 functionality will be disabled.\n",
641
"Error", MB_OK);
642
AfxFreeLibrary(m_hKrb5ProfileDLL);
643
m_hKrb5ProfileDLL = 0;
644
// Use m_hKrb5DLL to undo LoadLibrary in loadfuncs...
645
UnloadFuncs(krb5_fi, m_hKrb5DLL);
646
AfxFreeLibrary(m_hKrb5DLL);
647
m_hKrb5DLL = 0;
648
}
649
650
}
651
652
OSVERSIONINFO osvi;
653
memset(&osvi, 0, sizeof(OSVERSIONINFO));
654
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
655
GetVersionEx(&osvi);
656
657
// XXX: We should really use feature testing, first
658
// checking for CreateToolhelp32Snapshot. If that's
659
// not around, we try the psapi stuff.
660
//
661
// Only load LSA functions if on NT/2000/XP
662
if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
663
{
664
// Windows 9x
665
AfxFreeLibrary(m_hPsapi);
666
m_hPsapi = NULL;
667
if (!m_hToolHelp32 ||
668
!LoadFuncs(TOOLHELPDLL, toolhelp_fi, 0, 0, 1, 0, 0))
669
{
670
MessageBox(hwnd, "Could not load " TOOLHELPDLL "!", "Error",
671
MB_OK);
672
return FALSE;
673
}
674
}
675
else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
676
{
677
// Windows NT
678
AfxFreeLibrary(m_hToolHelp32);
679
m_hToolHelp32 = NULL;
680
if (!m_hPsapi ||
681
!LoadFuncs(PSAPIDLL, psapi_fi, 0, 0, 1, 0, 0))
682
{
683
MessageBox(hwnd, "Could not load " PSAPIDLL "!", "Error", MB_OK);
684
return FALSE;
685
}
686
687
m_hKrbLSA = AfxLoadLibrary(SECUR32DLL);
688
}
689
else
690
{
691
MessageBox(hwnd,
692
"Unrecognized Operating System!",
693
"Error", MB_OK);
694
return FALSE;
695
}
696
697
return TRUE;
698
}
699
700
701
BOOL CLeashApp::FirstInstance()
702
{
703
CWnd* pWndprev;
704
CWnd* pWndchild;
705
706
//find if it exists
707
pWndprev = CWnd::FindWindow(_T("LEASH.0WNDCLASS"), NULL);
708
if (pWndprev)
709
{
710
//if it has popups
711
pWndchild = pWndprev->GetLastActivePopup();
712
//if iconic restore
713
if (pWndprev->IsIconic())
714
pWndprev->ShowWindow(SW_RESTORE);
715
716
//bring the wnd to foreground
717
pWndchild->SetForegroundWindow();
718
719
return FALSE;
720
}
721
//we could not find prev instance
722
else
723
return TRUE;
724
}
725
726
void
727
CLeashApp::ValidateConfigFiles()
728
{
729
char confname[257];
730
char realm[256]="";
731
732
CWinApp * pApp = AfxGetApp();
733
if (pApp)
734
if (!pApp->GetProfileInt("Settings", "CreateMissingConfig", FALSE_FLAG))
735
return;
736
737
if ( m_hKrb5DLL ) {
738
// Create the empty KRB5.INI file
739
if (!GetProfileFile(confname,sizeof(confname))) {
740
const char *filenames[2];
741
filenames[0] = confname;
742
filenames[1] = NULL;
743
long retval = pprofile_init(filenames, &m_krbv5_profile);
744
if (!retval)
745
return;
746
else if (retval == ENOENT) {
747
FILE * f = fopen(confname,"w");
748
if (f != NULL) {
749
fclose(f);
750
retval = pprofile_init(filenames, &m_krbv5_profile);
751
}
752
}
753
754
755
const char* lookupKdc[] = {"libdefaults", "dns_lookup_kdc", NULL};
756
const char* lookupRealm[] = {"libdefaults", "dns_lookup_realm", NULL};
757
const char* defRealm[] = {"libdefaults", "default_realm", NULL};
758
const char* noAddresses[] = {"libdefaults", "noaddresses", NULL};
759
760
// activate DNS KDC Lookups
761
const char** names = lookupKdc;
762
retval = pprofile_add_relation(m_krbv5_profile,
763
names,
764
"true");
765
766
// activate No Addresses
767
names = noAddresses;
768
retval = pprofile_add_relation(m_krbv5_profile,
769
names,
770
"true");
771
772
// Get Windows 2000/XP/2003 Kerberos config
773
if ( m_hKrbLSA && m_hKrb5DLL )
774
{
775
char domain[256]="";
776
HKEY hk=0;
777
DWORD dwType, dwSize, dwIndex;
778
779
if ( !RegOpenKeyEx(HKEY_CURRENT_USER,
780
"Volatile Environment", 0,
781
KEY_READ, &hk) )
782
{
783
dwSize = sizeof(domain);
784
RegQueryValueEx(hk, "USERDNSDOMAIN", 0, 0, (LPBYTE)domain, &dwSize);
785
RegCloseKey(hk);
786
}
787
else if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE,
788
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
789
0, KEY_READ, &hk))
790
{
791
792
dwSize = sizeof(domain);
793
RegQueryValueEx( hk, "DefaultDomainName",
794
NULL, &dwType, (unsigned char *)&domain, &dwSize);
795
RegCloseKey(hk);
796
}
797
798
char realmkey[256]="SYSTEM\\CurrentControlSet\\Control\\Lsa\\Kerberos\\Domains\\";
799
size_t keylen = strlen(realmkey)-1;
800
801
if ( domain[0] ) {
802
strncpy(realm,domain,256);
803
realm[255] = '\0';
804
strncat(realmkey,domain,256-strlen(realmkey));
805
realmkey[255] = '\0';
806
}
807
808
if ( domain[0] &&
809
!RegOpenKeyEx(HKEY_LOCAL_MACHINE,
810
realmkey,
811
0,
812
KEY_READ,
813
&hk)
814
)
815
{
816
RegCloseKey(hk);
817
818
realmkey[keylen] = '\0';
819
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
820
realmkey,
821
0,
822
KEY_READ|KEY_ENUMERATE_SUB_KEYS,
823
&hk);
824
825
dwIndex = 0;
826
unsigned char subkey[256];
827
FILETIME ft;
828
dwSize = 256;
829
while ( ERROR_SUCCESS == RegEnumKeyEx(hk,dwIndex++,
830
(char *)subkey,
831
&dwSize,
832
0,
833
0,
834
0,
835
&ft) )
836
{
837
HKEY hksub;
838
839
if ( !RegOpenKeyEx(hk,
840
(char *)subkey,
841
0,
842
KEY_READ,
843
&hksub) )
844
{
845
unsigned char * lpszValue = NULL, *p;
846
dwSize = 0;
847
dwType = 0;
848
RegQueryValueEx( hksub, "KdcNames",
849
NULL, &dwType, lpszValue, &dwSize);
850
if ( dwSize > 0 ) {
851
lpszValue = (unsigned char *)malloc(dwSize+1);
852
dwSize += 1;
853
RegQueryValueEx( hksub, "KdcNames",
854
NULL, &dwType, lpszValue, &dwSize);
855
856
p = lpszValue;
857
while ( *p ) {
858
const char* realmKdc[] = {"realms", (const char *)subkey, "kdc", NULL};
859
names = realmKdc;
860
retval = pprofile_add_relation(m_krbv5_profile,
861
names,
862
(const char *)p);
863
864
p += strlen((char*)p) + 1;
865
}
866
free(lpszValue);
867
}
868
RegCloseKey(hksub);
869
}
870
}
871
RegCloseKey(hk);
872
}
873
} else {
874
// activate DNS Realm Lookups (temporarily)
875
names = lookupRealm;
876
retval = pprofile_add_relation(m_krbv5_profile,
877
names,
878
"true");
879
}
880
881
// Save to Kerberos Five config. file "Krb5.ini"
882
retval = pprofile_flush(m_krbv5_profile);
883
884
885
// Use DNS to retrieve the realm (if possible)
886
if (!realm[0]) {
887
krb5_context ctx = 0;
888
krb5_principal me = 0;
889
krb5_error_code code = 0;
890
891
code = pkrb5_init_context(&ctx);
892
if (code) goto no_k5_realm;
893
894
code = pkrb5_parse_name(ctx, "foo", &me);
895
if (code) goto no_k5_realm;
896
897
if ( krb5_princ_realm(ctx,me)->length < sizeof(realm) - 1) {
898
memcpy(realm, krb5_princ_realm(ctx,me)->data,
899
krb5_princ_realm(ctx,me)->length);
900
realm[krb5_princ_realm(ctx,me)->length] = '\0';
901
}
902
903
no_k5_realm:
904
if ( me )
905
pkrb5_free_principal(ctx,me);
906
if ( ctx )
907
pkrb5_free_context(ctx);
908
}
909
910
// disable DNS Realm Lookups
911
retval = pprofile_update_relation(m_krbv5_profile,
912
names,
913
"true", "false");
914
915
// save the default realm if it was discovered
916
if ( realm[0] ) {
917
names = defRealm;
918
retval = pprofile_add_relation(m_krbv5_profile,
919
names,
920
realm);
921
922
// It would be nice to be able to generate a list of KDCs
923
// but to do so based upon the contents of DNS would be
924
// wrong for several reasons:
925
// . it would make static the values inserted into DNS SRV
926
// records
927
// . DNS cannot necessarily be trusted
928
}
929
930
// Save to Kerberos Five config. file "Krb5.ini"
931
retval = pprofile_flush(m_krbv5_profile);
932
933
pprofile_release(m_krbv5_profile);
934
m_krbv5_profile = NULL;
935
936
}
937
}
938
}
939
940
BOOL
941
CLeashApp::GetProfileFile(
942
LPSTR confname,
943
UINT szConfname
944
)
945
{
946
char **configFile = NULL;
947
if (!m_hKrb5DLL)
948
return NULL;
949
950
if (pkrb5_get_default_config_files(&configFile))
951
{
952
GetWindowsDirectory(confname,szConfname);
953
confname[szConfname-1] = '\0';
954
strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
955
confname[szConfname-1] = '\0';
956
return FALSE;
957
}
958
959
*confname = 0;
960
961
if (configFile)
962
{
963
strncpy(confname, *configFile, szConfname);
964
confname[szConfname-1] = '\0';
965
pkrb5_free_config_files(configFile);
966
}
967
968
if (!*confname)
969
{
970
GetWindowsDirectory(confname,szConfname);
971
confname[szConfname-1] = '\0';
972
strncat(confname,"\\KRB5.INI",szConfname-strlen(confname));
973
confname[szConfname-1] = '\0';
974
}
975
976
return FALSE;
977
}
978
979
#define PROBE_USERNAME "KERBEROS-KDC-PROBE"
980
#define PROBE_PASSWORD_LEN 16
981
982
BOOL
983
CLeashApp::ProbeKDC(void)
984
{
985
krb5_context ctx=0;
986
krb5_ccache cc=0;
987
krb5_principal principal = 0;
988
krb5_principal probeprinc = 0;
989
krb5_creds creds;
990
krb5_error_code code;
991
krb5_data pwdata;
992
char password[PROBE_PASSWORD_LEN+1];
993
long success = FALSE;
994
995
if (!pkrb5_init_context)
996
return success;
997
998
memset(&creds, 0, sizeof(creds));
999
1000
code = pkrb5_init_context(&ctx);
1001
if (code)
1002
goto cleanup;
1003
1004
code = pkrb5_cc_default(ctx, &cc);
1005
if (code)
1006
goto cleanup;
1007
1008
code = pkrb5_cc_get_principal(ctx, cc, &principal);
1009
if ( code )
1010
code = pkrb5_parse_name(ctx, "foo", &principal);
1011
if ( code )
1012
goto cleanup;
1013
1014
code = pkrb5_build_principal( ctx, &probeprinc,
1015
krb5_princ_realm(ctx,principal)->length,
1016
krb5_princ_realm(ctx,principal)->data,
1017
PROBE_USERNAME, NULL, NULL);
1018
if ( code )
1019
goto cleanup;
1020
1021
pwdata.data = password;
1022
pwdata.length = PROBE_PASSWORD_LEN;
1023
code = pkrb5_c_random_make_octets(ctx, &pwdata);
1024
if (code) {
1025
int i;
1026
for ( i=0 ; i<PROBE_PASSWORD_LEN ; i )
1027
password[i] = 'x';
1028
}
1029
password[PROBE_PASSWORD_LEN] = '\0';
1030
1031
code = pkrb5_get_init_creds_password(ctx,
1032
&creds,
1033
probeprinc,
1034
password, // password
1035
NULL, // prompter
1036
0, // prompter data
1037
0, // start time
1038
0, // service name
1039
0 // no options
1040
);
1041
1042
switch ( code ) {
1043
case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
1044
case KRB5KDC_ERR_CLIENT_REVOKED:
1045
case KRB5KDC_ERR_CLIENT_NOTYET:
1046
case KRB5KDC_ERR_PREAUTH_FAILED:
1047
case KRB5KDC_ERR_PREAUTH_REQUIRED:
1048
case KRB5KDC_ERR_PADATA_TYPE_NOSUPP:
1049
success = TRUE;
1050
break;
1051
}
1052
cleanup:
1053
if (creds.client == probeprinc)
1054
creds.client = 0;
1055
pkrb5_free_cred_contents(ctx, &creds);
1056
if (principal)
1057
pkrb5_free_principal(ctx,principal);
1058
if (probeprinc)
1059
pkrb5_free_principal(ctx,probeprinc);
1060
if (cc)
1061
pkrb5_cc_close(ctx,cc);
1062
if (ctx)
1063
pkrb5_free_context(ctx);
1064
return success;
1065
}
1066
1067
VOID
1068
CLeashApp::ObtainTicketsViaUserIfNeeded(HWND hWnd)
1069
{
1070
if (WaitForSingleObject( ticketinfo.lockObj, INFINITE ) != WAIT_OBJECT_0)
1071
throw("Unable to lock ticketinfo");
1072
LeashKRB5ListDefaultTickets(&ticketinfo.Krb5);
1073
int btickets = ticketinfo.Krb5.btickets;
1074
LeashKRB5FreeTicketInfo(&ticketinfo.Krb5);
1075
ReleaseMutex(ticketinfo.lockObj);
1076
1077
if (ProbeKDC() && (!btickets || !pLeash_renew())) {
1078
LSH_DLGINFO_EX ldi;
1079
ldi.size = LSH_DLGINFO_EX_V1_SZ;
1080
ldi.dlgtype = DLGTYPE_PASSWD;
1081
ldi.title = "MIT Kerberos: Get Ticket";
1082
ldi.username = NULL;
1083
ldi.realm = NULL;
1084
ldi.dlgtype = DLGTYPE_PASSWD;
1085
ldi.use_defaults = 1;
1086
1087
pLeash_kinit_dlg_ex(hWnd, &ldi);
1088
}
1089
return;
1090
}
1091
1092
// IP Change Monitoring Functions
1093
#include <Iphlpapi.h>
1094
1095
1096
DWORD
1097
CLeashApp::GetNumOfIpAddrs(void)
1098
{
1099
PMIB_IPADDRTABLE pIpAddrTable = 0;
1100
ULONG dwSize;
1101
DWORD code;
1102
DWORD index;
1103
DWORD validAddrs = 0;
1104
1105
dwSize = 0;
1106
code = GetIpAddrTable(NULL, &dwSize, 0);
1107
if (code == ERROR_INSUFFICIENT_BUFFER) {
1108
pIpAddrTable = (PMIB_IPADDRTABLE) malloc(dwSize);
1109
code = GetIpAddrTable(pIpAddrTable, &dwSize, 0);
1110
if ( code == NO_ERROR ) {
1111
for ( index=0; index < pIpAddrTable->dwNumEntries; index++ ) {
1112
if (pIpAddrTable->table[index].dwAddr != 0)
1113
validAddrs++;
1114
}
1115
}
1116
free(pIpAddrTable);
1117
}
1118
return validAddrs;
1119
}
1120
1121
UINT
1122
CLeashApp::IpAddrChangeMonitor(void * hWnd)
1123
{
1124
DWORD Result;
1125
DWORD prevNumOfAddrs = GetNumOfIpAddrs();
1126
DWORD NumOfAddrs;
1127
1128
if ( !hWnd )
1129
return 0;
1130
1131
while ( TRUE ) {
1132
Result = NotifyAddrChange(NULL,NULL);
1133
if ( Result != NO_ERROR ) {
1134
// We do not have permission to open the device
1135
return 0;
1136
}
1137
1138
NumOfAddrs = GetNumOfIpAddrs();
1139
if ( NumOfAddrs != prevNumOfAddrs ) {
1140
// wait for the network state to stabilize
1141
Sleep(2000);
1142
// this call should probably be mutex protected
1143
ObtainTicketsViaUserIfNeeded((HWND)hWnd);
1144
}
1145
prevNumOfAddrs = NumOfAddrs;
1146
}
1147
1148
return 0;
1149
}
1150
1151
1152
DWORD
1153
CLeashApp::IpAddrChangeMonitorInit(HWND hWnd)
1154
{
1155
AfxBeginThread(IpAddrChangeMonitor, hWnd);
1156
return 0;
1157
}
1158
1159
UINT
1160
CLeashApp::InitWorker(void * hWnd)
1161
{
1162
if ( ProbeKDC() ) {
1163
LSH_DLGINFO_EX ldi;
1164
ldi.size = LSH_DLGINFO_EX_V1_SZ;
1165
ldi.dlgtype = DLGTYPE_PASSWD;
1166
ldi.title = "Initialize Ticket";
1167
ldi.username = NULL;
1168
ldi.realm = NULL;
1169
ldi.use_defaults = 1;
1170
1171
pLeash_kinit_dlg_ex((HWND)hWnd, &ldi);
1172
::SendMessage((HWND)hWnd, WM_COMMAND, ID_UPDATE_DISPLAY, 0);
1173
}
1174
return 0;
1175
}
1176
1177
#ifdef USE_HTMLHELP
1178
#if _MSC_VER < 1300
1179
void
1180
CLeashApp::WinHelp(DWORD dwData, UINT nCmd)
1181
{
1182
switch (nCmd)
1183
{
1184
case HELP_CONTEXT:
1185
::HtmlHelp(GetDesktopWindow(), m_helpFile, HH_HELP_CONTEXT, dwData );
1186
break;
1187
case HELP_FINDER:
1188
::HtmlHelp(GetDesktopWindow(), m_helpFile, HH_DISPLAY_TOPIC, 0);
1189
break;
1190
}
1191
}
1192
#endif
1193
#endif
1194
1195
1196
BOOL CLeashApp::OnIdle(LONG lCount)
1197
{
1198
// TODO: Add your specialized code here and/or call the base class
1199
BOOL retval = CWinAppEx::OnIdle(lCount);
1200
if ((lCount == 0) && m_bUpdateDisplay) {
1201
m_bUpdateDisplay = FALSE;
1202
m_pMainWnd->SendMessage(WM_COMMAND, ID_UPDATE_DISPLAY, 0);
1203
}
1204
return retval;
1205
}
1206
1207