xref: /freebsd/crypto/krb5/src/windows/leashdll/lsh_pwd.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 #define SCALE_FACTOR 31/20
2 
3 /* LSH_PWD.C
4 
5    Jason Hunter
6    8/2/94
7    DCNS/IS MIT
8 
9    Re-written for KFW 2.6 by Jeffrey Altman <jaltman@mit.edu>
10 
11    Contains the callback functions for the EnterPassword an
12    ChangePassword dialog boxes and well as the API function
13    calls:
14 
15    Lsh_Enter_Password_Dialog
16    Lsh_Change_Password_Dialog
17 
18    for calling the dialogs.
19 
20    Also contains the callback for the MITPasswordControl.
21 
22 */
23 
24 /* Standard Include files */
25 #include <windows.h>
26 #include <windowsx.h>
27 #include <stdio.h>
28 #include <string.h>
29 
30 /* Private Inlclude files */
31 #include "leashdll.h"
32 #include <leashwin.h>
33 #include "leash-int.h"
34 #include "leashids.h"
35 #include <leasherr.h>
36 #include <krb5.h>
37 #include <commctrl.h>
38 
39 extern void * Leash_pec_create(HWND hEditCtl);
40 extern void Leash_pec_destroy(void *pAutoComplete);
41 extern void Leash_pec_add_principal(char *principal);
42 extern void Leash_pec_clear_history(void *pec);
43 
44 /* Global Variables. */
45 static long lsh_errno;
46 static char *err_context;       /* error context */
47 extern HINSTANCE hLeashInst;
48 extern HINSTANCE hKrb5;
49 
50 
51 INT_PTR
52 CALLBACK
53 PasswordProc(
54     HWND hwndDlg,
55     UINT uMsg,
56     WPARAM wParam,
57     LPARAM lParam
58     );
59 
60 INT_PTR
61 CALLBACK
62 AuthenticateProc(
63     HWND hwndDlg,
64     UINT uMsg,
65     WPARAM wParam,
66     LPARAM lParam
67     );
68 
69 INT_PTR
70 CALLBACK
71 NewPasswordProc(
72     HWND hwndDlg,
73     UINT uMsg,
74     WPARAM wParam,
75     LPARAM lParam
76     );
77 
78 
Leash_get_lsh_errno(LONG * err_val)79 long Leash_get_lsh_errno(LONG *err_val)
80 {
81     return lsh_errno;
82 }
83 
84 /*/////// ******** API Calls follow here.   ******** /////////*/
85 
86 static int
NetId_dialog(LPLSH_DLGINFO lpdlginfo)87 NetId_dialog(LPLSH_DLGINFO lpdlginfo)
88 {
89     LRESULT             lrc;
90     HWND    	        hNetIdMgr;
91     HWND    		hForeground;
92 
93     hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
94     if (hNetIdMgr != NULL) {
95 	char desiredPrincipal[512];
96 	NETID_DLGINFO *dlginfo;
97 	char		*desiredName = 0;
98 	char            *desiredRealm = 0;
99 	HANDLE hMap;
100 	DWORD  tid = GetCurrentThreadId();
101 	char mapname[256];
102 
103 	strcpy(desiredPrincipal, lpdlginfo->principal);
104 
105 	/* do we want a specific client principal? */
106 	if (desiredPrincipal[0]) {
107 	    char * p;
108 	    desiredName = desiredPrincipal;
109 	    for (p = desiredName; *p && *p != '@'; p++);
110 	    if ( *p == '@' ) {
111 		*p = '\0';
112 		desiredRealm = ++p;
113 	    }
114 	}
115 
116 	sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
117 
118 	hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
119 				 0, 4096, mapname);
120 	if (hMap == NULL) {
121 	    return -1;
122 	} else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
123 	    CloseHandle(hMap);
124 	    return -1;
125 	}
126 
127 	dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
128 						 0, 0, 4096, NULL);
129 	if (dlginfo == NULL) {
130 	    CloseHandle(hMap);
131 	    return -1;
132 	}
133 
134 	hForeground = GetForegroundWindow();
135 
136 	memset(dlginfo, 0, sizeof(NETID_DLGINFO));
137 
138 	dlginfo->size = sizeof(NETID_DLGINFO);
139 	if (lpdlginfo->dlgtype == DLGTYPE_PASSWD)
140 	    dlginfo->dlgtype = NETID_DLGTYPE_TGT;
141 	else
142 	    dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD;
143 	dlginfo->in.use_defaults = 1;
144 
145 	if (lpdlginfo->title) {
146 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
147 				lpdlginfo->title, -1,
148 				dlginfo->in.title, NETID_TITLE_SZ);
149 	} else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
150 	    char mytitle[NETID_TITLE_SZ];
151 	    sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
152 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
153 				mytitle, -1,
154 				dlginfo->in.title, NETID_TITLE_SZ);
155 	} else {
156 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
157 				"Obtain Kerberos TGT", -1,
158 				dlginfo->in.title, NETID_TITLE_SZ);
159 	}
160 	if (desiredName)
161 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
162 				desiredName, -1,
163 				dlginfo->in.username, NETID_USERNAME_SZ);
164 	if (desiredRealm)
165 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
166 				desiredRealm, -1,
167 				dlginfo->in.realm, NETID_REALM_SZ);
168 	lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
169 
170 	UnmapViewOfFile(dlginfo);
171 	CloseHandle(hMap);
172 
173 	SetForegroundWindow(hForeground);
174 	return lrc;
175     }
176     return -1;
177 }
178 
179 static int
NetId_dialog_ex(LPLSH_DLGINFO_EX lpdlginfo)180 NetId_dialog_ex(LPLSH_DLGINFO_EX lpdlginfo)
181 {
182     HWND    	        hNetIdMgr;
183     HWND    		hForeground;
184 
185     hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon");
186     if (hNetIdMgr != NULL) {
187 	NETID_DLGINFO   *dlginfo;
188 	char		*desiredName = lpdlginfo->username;
189 	char            *desiredRealm = lpdlginfo->realm;
190 	LPSTR            title;
191 	char            *ccache;
192 	LRESULT         lrc;
193 	HANDLE hMap;
194 	DWORD  tid = GetCurrentThreadId();
195 	char mapname[256];
196 
197 	sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid);
198 
199 	hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
200 				 0, 4096, mapname);
201 	if (hMap == NULL) {
202 	    return -1;
203 	} else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
204 	    CloseHandle(hMap);
205 	    return -1;
206 	}
207 
208 	dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE,
209 						 0, 0, 4096, NULL);
210 	if (dlginfo == NULL) {
211 	    CloseHandle(hMap);
212 	    return -1;
213 	}
214 
215 	hForeground = GetForegroundWindow();
216 
217 	if (lpdlginfo->size == LSH_DLGINFO_EX_V1_SZ ||
218 	    lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ)
219 	{
220 	    title = lpdlginfo->title;
221 	    desiredName = lpdlginfo->username;
222 	    desiredRealm = lpdlginfo->realm;
223 	    ccache = NULL;
224 	} else {
225 	    title = lpdlginfo->in.title;
226 	    desiredName = lpdlginfo->in.username;
227 	    desiredRealm = lpdlginfo->in.realm;
228 	    ccache = lpdlginfo->in.ccache;
229 	}
230 
231 	memset(dlginfo, 0, sizeof(NETID_DLGINFO));
232 
233 	dlginfo->size = sizeof(NETID_DLGINFO);
234 	if (lpdlginfo->dlgtype == DLGTYPE_PASSWD)
235 	    dlginfo->dlgtype = NETID_DLGTYPE_TGT;
236 	else
237 	    dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD;
238 
239 	dlginfo->in.use_defaults = lpdlginfo->use_defaults;
240 	dlginfo->in.forwardable  = lpdlginfo->forwardable;
241 	dlginfo->in.noaddresses  = lpdlginfo->noaddresses;
242 	dlginfo->in.lifetime     = lpdlginfo->lifetime;
243 	dlginfo->in.renew_till   = lpdlginfo->renew_till;
244 	dlginfo->in.proxiable    = lpdlginfo->proxiable;
245 	dlginfo->in.publicip     = lpdlginfo->publicip;
246 
247 	if (title) {
248 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
249 				title, -1,
250 				dlginfo->in.title, NETID_TITLE_SZ);
251 	} else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) {
252 	    char mytitle[NETID_TITLE_SZ];
253 	    sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm);
254 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
255 				mytitle, -1,
256 				dlginfo->in.title, NETID_TITLE_SZ);
257 	} else {
258 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
259 				"Obtain Kerberos TGT", -1,
260 				dlginfo->in.title, NETID_TITLE_SZ);
261 	}
262 	if (desiredName)
263 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
264 				desiredName, -1,
265 				dlginfo->in.username, NETID_USERNAME_SZ);
266 	if (desiredRealm)
267 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
268 				desiredRealm, -1,
269 				dlginfo->in.realm, NETID_REALM_SZ);
270 	if (ccache)
271 	    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
272 				ccache, -1,
273 				dlginfo->in.ccache, NETID_CCACHE_NAME_SZ);
274 	lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid);
275 
276 	if (lrc > 0) {
277 	    if (lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ)
278 	    {
279 		WideCharToMultiByte(CP_ACP, 0, dlginfo->out.username, -1,
280 				     lpdlginfo->out.username, LEASH_USERNAME_SZ,
281 				     NULL, NULL);
282 		WideCharToMultiByte(CP_ACP, 0, dlginfo->out.realm, -1,
283 				     lpdlginfo->out.realm, LEASH_REALM_SZ,
284 				     NULL, NULL);
285 	    }
286 	    if (lpdlginfo->size == LSH_DLGINFO_EX_V3_SZ)
287 	    {
288 		WideCharToMultiByte(CP_ACP, 0, dlginfo->out.ccache, -1,
289 				     lpdlginfo->out.ccache, LEASH_CCACHE_NAME_SZ,
290 				     NULL, NULL);
291 	    }
292 	}
293 
294 	UnmapViewOfFile(dlginfo);
295 	CloseHandle(hMap);
296 
297 	SetForegroundWindow(hForeground);
298 	return lrc;
299     }
300     return -1;
301 }
302 
303 
304 #define LEASH_DLG_MUTEX_NAME  TEXT("Leash_Dialog_Mutex")
Leash_kinit_dlg(HWND hParent,LPLSH_DLGINFO lpdlginfo)305 int Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo)
306 {
307     int rc;
308     HANDLE hMutex;
309 
310     rc = NetId_dialog(lpdlginfo);
311     if (rc > -1)
312 	return rc;
313 
314     hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
315     if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
316         if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
317             return -1;
318         }
319         ReleaseMutex(hMutex);
320         CloseHandle(hMutex);
321         return 1;   /* pretend the dialog was displayed and succeeded */
322     }
323 
324     lpdlginfo->dlgtype = DLGTYPE_PASSWD;
325 
326     /* set the help file */
327     Leash_set_help_file(NULL);
328 
329     /* Call the Dialog box with the DLL's Password Callback and the
330        DLL's instance handle. */
331     rc =  DialogBoxParam(hLeashInst, "EnterPasswordDlg", hParent,
332                           PasswordProc, (LPARAM)lpdlginfo);
333 
334     ReleaseMutex(hMutex);
335     CloseHandle(hMutex);
336     return rc;
337 }
338 
339 
Leash_kinit_dlg_ex(HWND hParent,LPLSH_DLGINFO_EX lpdlginfo)340 int Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo)
341 {
342     int rc;
343     HANDLE hMutex;
344 
345     rc = NetId_dialog_ex(lpdlginfo);
346     if (rc > -1)
347 	return rc;
348 
349     hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
350     if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
351         if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
352             return -1;
353         }
354         ReleaseMutex(hMutex);
355         CloseHandle(hMutex);
356         return 1;   /* pretend the dialog was displayed and succeeded */
357     }
358 
359     /* set the help file */
360     Leash_set_help_file(NULL);
361 
362     /* Call the Dialog box with the DLL's Password Callback and the
363        DLL's instance handle. */
364     rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_AUTHENTICATE), hParent,
365                           AuthenticateProc, (LPARAM)lpdlginfo);
366     ReleaseMutex(hMutex);
367     CloseHandle(hMutex);
368     return rc;
369 }
370 
371 
Leash_changepwd_dlg(HWND hParent,LPLSH_DLGINFO lpdlginfo)372 int Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo)
373 {
374     int rc;
375     HANDLE hMutex;
376 
377     rc = NetId_dialog(lpdlginfo);
378     if (rc > -1)
379 	return rc;
380 
381     hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
382     if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
383         if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
384             return -1;
385         }
386         ReleaseMutex(hMutex);
387         CloseHandle(hMutex);
388         return 1;   /* pretend the dialog was displayed and succeeded */
389     }
390 
391     lpdlginfo->dlgtype = DLGTYPE_CHPASSWD;
392 
393     /* Call the Dialog box with the DLL's Password Callback and the
394        DLL's instance handle. */
395     rc = DialogBoxParam(hLeashInst, "CHANGEPASSWORDDLG", hParent,
396                           PasswordProc, (LPARAM)lpdlginfo);
397     ReleaseMutex(hMutex);
398     CloseHandle(hMutex);
399     return rc;
400 }
401 
Leash_changepwd_dlg_ex(HWND hParent,LPLSH_DLGINFO_EX lpdlginfo)402 int Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo)
403 {
404     int rc;
405     HANDLE hMutex;
406 
407     rc = NetId_dialog_ex(lpdlginfo);
408     if (rc > -1)
409 	return rc;
410 
411     hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME);
412     if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
413         if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) {
414             return -1;
415         }
416         ReleaseMutex(hMutex);
417         CloseHandle(hMutex);
418         return 1;   /* pretend the dialog was displayed and succeeded */
419     }
420 
421     lpdlginfo->dlgtype = DLGTYPE_CHPASSWD;
422 
423     /* Call the Dialog box with the DLL's Password Callback and the
424        DLL's instance handle. */
425     rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_PASSWORD), hParent,
426                           NewPasswordProc, (LPARAM)lpdlginfo);
427     ReleaseMutex(hMutex);
428     CloseHandle(hMutex);
429     return rc;
430 }
431 
432 
433 /*  These little utils are taken from lshutil.c
434     they are added here for the Call back function.
435 ****** beginning of added utils from lshutil.c  ******/
436 
IsDlgItem(HWND hWnd,WORD id)437 BOOL IsDlgItem(HWND hWnd, WORD id)
438 {
439     HWND hChild;
440 
441     hChild = GetDlgItem(hWnd, id);
442     return hChild ? IsWindow(hChild) : 0;
443 }
444 
lsh_getkeystate(WORD keyid)445 int lsh_getkeystate(WORD keyid)
446 {
447     static BYTE keys[256];
448 
449     GetKeyboardState((LPBYTE) &keys);
450     return (int) keys[keyid];
451 }
452 
krb_err_func(int offset,long code)453 LPSTR krb_err_func(int offset, long code)
454 {
455     return(NULL);
456 }
457 
458 /****** End of Added utils from leash.c  ******/
459 
460 
PaintLogoBitmap(HANDLE hPicFrame)461 int PaintLogoBitmap( HANDLE hPicFrame )
462 {
463     HBITMAP hBitmap;
464     HBITMAP hOldBitmap;
465     BITMAP Bitmap;
466     HDC hdc, hdcMem;
467     RECT rect;
468 
469     /* Invalidate the drawing space of the picframe. */
470     InvalidateRect( hPicFrame, NULL, TRUE);
471     UpdateWindow( hPicFrame );
472 
473     hdc = GetDC(hPicFrame);
474     hdcMem = CreateCompatibleDC(hdc);
475     GetClientRect(hPicFrame, &rect);
476     hBitmap = LoadBitmap(hLeashInst, "LOGOBITMAP");
477     hOldBitmap = SelectObject(hdcMem, hBitmap);
478     GetObject(hBitmap, sizeof(Bitmap), (LPSTR) &Bitmap);
479     StretchBlt(hdc, 0, 0, rect.right, rect.bottom, hdcMem, 0, 0,
480                Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);
481 
482     SelectObject(hdcMem, hOldBitmap); /* pbh 8-15-94 */
483     ReleaseDC(hPicFrame, hdc);
484     DeleteObject( hBitmap );  /* pbh 8-15-94 */
485     DeleteDC( hdcMem );       /* pbh 8-15-94 */
486 
487     return 0;
488 }
489 
490 
491 /* Callback function for the Password Dialog box that initilializes and
492    renews tickets. */
493 
494 INT_PTR
495 CALLBACK
PasswordProc(HWND hDialog,UINT message,WPARAM wParam,LPARAM lParam)496 PasswordProc(
497     HWND hDialog,
498     UINT message,
499     WPARAM wParam,
500     LPARAM lParam
501     )
502 {
503     static POINT Position = { -1, -1 };
504     static short state;
505     int lifetime;
506 #define ISCHPASSWD (lpdi->dlgtype == DLGTYPE_CHPASSWD)
507 #define STATE_INIT     0
508 #define STATE_PRINCIPAL 1
509 #define STATE_OLDPWD   2
510 #define STATE_NEWPWD1  3
511 #define STATE_NEWPWD2  4
512 #define STATE_CLOSED   5
513 #define NEXTSTATE(newstate) SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, newstate)
514     static int ids[STATE_NEWPWD2 + 1] = {
515         0,
516         ID_PRINCIPAL, ID_OLDPASSWORD, ID_CONFIRMPASSWORD1,
517         ID_CONFIRMPASSWORD2};
518     static char principal[255], oldpassword[255], newpassword[255],
519         newpassword2[255];
520     static char *strings[STATE_NEWPWD2 + 1] = {
521         NULL, principal, oldpassword, newpassword, newpassword2};
522     static LPLSH_DLGINFO lpdi;
523     char gbuf[200];                 /* global buffer for random stuff. */
524 
525 
526 #define checkfirst(id, stuff) IsDlgItem(hDialog, id) ? stuff : 0
527 #define CGetDlgItemText(hDlg, id, cp, len) checkfirst(id, GetDlgItemText(hDlg, id, cp, len))
528 #define CSetDlgItemText(hDlg, id, cp) checkfirst(id, SetDlgItemText(hDlg, id, cp))
529 #define CSetDlgItemInt(hDlg, id, i, b) checkfirst(id, SetDlgItemInt(hDlg, id, i, b))
530 #define CSendDlgItemMessage(hDlg, id, m, w, l) checkfirst(id, SendDlgItemMessage(hDlg, id, m, w, l))
531 #define CSendMessage(hwnd, m, w, l) IsWindow(hwnd) ? SendMessage(hwnd, m, w, l) : 0
532 #define CShowWindow(hwnd, state) IsWindow(hwnd) ? ShowWindow(hwnd, state) : 0
533 
534 #define GETITEMTEXT(id, cp, maxlen) \
535   GetDlgItemText(hDialog, id, (LPSTR)(cp), maxlen)
536 #define CloseMe(x) SendMessage(hDialog, WM_COMMAND, ID_CLOSEME, x)
537 
538 
539 #define EDITFRAMEIDOFFSET               500
540 
541     switch (message) {
542 
543     case WM_INITDIALOG:
544 
545         *( (LPLSH_DLGINFO far *)(&lpdi) ) = (LPLSH_DLGINFO)(LPSTR)lParam;
546         lpdi->dlgstatemax = ISCHPASSWD ? STATE_NEWPWD2
547             : STATE_OLDPWD;
548         SetWindowText(hDialog, lpdi->title);
549         /* stop at old password for normal password dlg */
550 
551         SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
552 
553         if (lpdi->principal)
554             lstrcpy(principal, lpdi->principal);
555         else
556 	{
557             principal[0] = '\0';
558             /* is there a principal already being used? if so, use it. */
559 	    }
560 
561         CSetDlgItemText(hDialog, ID_PRINCIPAL, principal);
562 
563         lifetime = Leash_get_default_lifetime();
564         if (lifetime <= 0)
565             lifetime = 600; /* 10 hours */
566 
567         CSetDlgItemInt(hDialog, ID_DURATION, lifetime, FALSE);
568 
569         /* setup text of stuff. */
570 
571         if (Position.x > 0 && Position.y > 0 &&
572             Position.x < GetSystemMetrics(SM_CXSCREEN) &&
573             Position.y < GetSystemMetrics(SM_CYSCREEN))
574             SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0,
575                          SWP_NOSIZE | SWP_NOZORDER);
576 
577         /* set window pos to last saved window pos */
578 
579 
580         /* replace standard edit control with our own password edit
581            control for password entry. */
582         {
583             RECT r;
584             POINT pxy, psz;
585             HWND hwnd;
586             int i;
587 
588             for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++)
589             {
590                 hwnd = GetDlgItem(hDialog, i);
591                 GetWindowRect(hwnd, &r);
592                 psz.x = r.right - r.left;
593                 psz.y = r.bottom - r.top;
594 
595                 pxy.x = r.left; pxy.y = r.top;
596                 ScreenToClient(hDialog, &pxy);
597 
598                 /* create a substitute window: */
599 
600                 DestroyWindow(hwnd);
601                 /* kill off old edit window. */
602 
603                 CreateWindow(MIT_PWD_DLL_CLASS,	/* our password window :o] */
604                              "",		/* no text */
605                              WS_CHILD | WS_VISIBLE | WS_TABSTOP, /* child window, visible,tabstop */
606                              pxy.x, pxy.y,	/* x, y coords */
607                              psz.x, psz.y,	/* width, height */
608                              hDialog,		/* the parent */
609                              (HMENU)i,		/* same id *//* id offset for the frames */
610                              (HANDLE)hLeashInst,/* instance handles */
611                              NULL);		/* createstruct */
612             }
613         }
614 
615         state = STATE_INIT;
616         NEXTSTATE(STATE_PRINCIPAL);
617         break;
618 
619     case WM_PAINT:
620         PaintLogoBitmap( GetDlgItem(hDialog, ID_PICFRAME) );
621         break;
622 
623     case WM_COMMAND:
624         switch (wParam) {
625         case ID_HELP:
626 	{
627             WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
628                     ISCHPASSWD ? ID_CHANGEPASSWORD : ID_INITTICKETS);
629 	}
630 	break;
631         case ID_CLOSEME:
632 	{
633             int i;
634 
635             for (i = STATE_PRINCIPAL; i <= lpdi->dlgstatemax; i++)
636 	    {
637                 memset(strings[i], '\0', 255);
638                 SetDlgItemText(hDialog, ids[i], "");
639 	    }
640             /* I claim these passwords in the name
641                of planet '\0'... */
642 
643             RemoveProp(hDialog, "HANDLES_HELP");
644             state = STATE_CLOSED;
645             EndDialog(hDialog, (int)lParam);
646         return TRUE;
647 	}
648 	break;
649         case ID_DURATION:
650             break;
651         case ID_PRINCIPAL:
652         case ID_OLDPASSWORD:
653         case ID_CONFIRMPASSWORD1:
654         case ID_CONFIRMPASSWORD2:
655             if (HIWORD(lParam) == EN_SETFOCUS)
656             {
657                 /* nothing, for now. */
658             }
659             break;
660         case ID_NEXTSTATE:
661 	{
662             RECT rbtn, redit;
663             POINT p;
664             int idfocus, i, s;
665             HWND hfocus, hbtn;
666             int oldstate = state;
667 
668             state = (int)lParam;
669             idfocus = ids[state];
670 
671 #ifdef ONE_NEWPWDBOX
672             if (state == STATE_NEWPWD2)
673                 SendDlgItemMessage(hDialog, ID_CONFIRMPASSWORD1, WM_SETTEXT,
674                                    0, (LONG)(LPSTR)"");
675 #endif
676 
677             for (s = STATE_PRINCIPAL; s <= lpdi->dlgstatemax; s++)
678 	    {
679                 i = ids[s];
680 
681                 if (s > state)
682                     SendDlgItemMessage(hDialog, i, WM_SETTEXT, 0,
683                                        (LONG)(LPSTR)"");
684                 EnableWindow(GetDlgItem(hDialog, i), i == idfocus);
685                 ShowWindow(GetDlgItem(hDialog, i),
686                            (i <= idfocus ? SW_SHOW : SW_HIDE));
687                 /* ShowWindow(GetDlgItem(hDialog, i + CAPTION_OFFSET),
688                    (i <= idfocus ? SW_SHOW : SW_HIDE));*/
689                 /* show caption? */
690 	    }
691 #ifdef ONE_NEWPWDBOX
692             CSetDlgItemText(hDialog, ID_CONFIRMCAPTION1,
693                             state < STATE_NEWPWD2 ?
694                             "Enter new password:" :
695                             "Enter new password again:");
696             if (state == STATE_NEWPWD2)
697 	    {
698                 HWND htext;
699                 htext = GetDlgItem(hDialog, ID_CONFIRMCAPTION1);
700                 FlashAnyWindow(htext);
701                 WinSleep(50);
702                 FlashAnyWindow(htext);
703 	    }
704 #endif
705 
706             hfocus = GetDlgItem(hDialog, idfocus);
707             if ( hfocus != (HWND)NULL ){
708                 SetFocus(hfocus); /* switch focus */
709                 if (idfocus >= ID_OLDPASSWORD)
710                     SendMessage(hfocus, WM_SETTEXT, 0, (LPARAM) (LPSTR) "");
711                 else
712                 {
713                     SendMessage(hfocus, EM_SETSEL, 0, MAKELONG(0, -1));
714                 }
715                 GetWindowRect(hfocus, &redit);
716             }
717 
718             hbtn   = GetDlgItem(hDialog, IDOK);
719             if( IsWindow(hbtn) ){
720                 GetWindowRect(hbtn, &rbtn);
721                 p.x = rbtn.left; p.y = redit.top;
722                 ScreenToClient(hDialog, &p);
723 
724                 SetWindowPos(hbtn, 0, p.x, p.y, 0, 0,
725                              SWP_NOSIZE | SWP_NOZORDER);
726             }
727 	}
728 	break;
729         case IDOK:
730 	{
731 	    char* p_Principal;
732             DWORD value = 0;
733 
734 	    GETITEMTEXT(ids[state], (LPSTR)strings[state], 255);
735 
736             switch(state)
737             {
738             case STATE_PRINCIPAL:
739             {
740                 if (!principal[0])
741                 {
742                     MessageBox(hDialog,
743                                 "You are not allowed to enter a blank principal.",
744                                "Invalid Principal",
745                                MB_OK | MB_ICONSTOP);
746                     NEXTSTATE(STATE_PRINCIPAL);
747                     return TRUE;
748                 }
749 
750 	        // Change 'principal' to upper case after checking
751 	        // "UpperCase" value in the Registry
752                 p_Principal = strchr(principal, '@');
753 
754                 if (p_Principal && Leash_get_default_uppercaserealm())
755                     strupr(p_Principal);
756                 break;
757             }
758 	    case STATE_OLDPWD:
759             {
760 		int duration;
761 
762 		if (!ISCHPASSWD)
763                     duration = GetDlgItemInt(hDialog, ID_DURATION, 0, FALSE);
764                 if (!oldpassword[0])
765                 {
766                     MessageBox(hDialog, "You are not allowed to enter a "
767                                "blank password.",
768                                "Invalid Password",
769                                MB_OK | MB_ICONSTOP);
770                     NEXTSTATE(STATE_OLDPWD);
771                     return TRUE;
772                 }
773                 if (lpdi->dlgtype == DLGTYPE_CHPASSWD)
774                     lsh_errno = Leash_int_checkpwd(principal, oldpassword, 1);
775                 else
776                 {
777                     lsh_errno = Leash_int_kinit_ex( 0,
778                                                     hDialog,
779                                                     principal,
780                                                     oldpassword,
781                                                     duration,
782                                                     Leash_get_default_forwardable(),
783                                                     Leash_get_default_proxiable(),
784                                                     Leash_get_default_renew_till(),
785                                                     Leash_get_default_noaddresses(),
786                                                     Leash_get_default_publicip(),
787                                                     1
788                                                     );
789                 }
790 		if (lsh_errno != 0)
791                 {
792 		    int next_state = state;
793 		    int capslock;
794 		    char *cp;
795 
796 		    err_context = "";
797 
798 		    switch(lsh_errno)
799                     {
800                     case LSH_INVPRINCIPAL:
801                     case LSH_INVINSTANCE:
802                     case LSH_INVREALM:
803 			next_state = STATE_PRINCIPAL;
804 			break;
805                     }
806 		    capslock = lsh_getkeystate(VK_CAPITAL);
807                     /* low-order bit means caps lock is
808                        toggled; if so, warn user since there's
809                        been an error. */
810 		    if (capslock & 1)
811                     {
812 			lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
813 			cp = gbuf + lstrlen((LPSTR)gbuf);
814 			if (cp != gbuf)
815                             *cp++ = ' ';
816 			lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
817 			err_context = gbuf;
818                     }
819 
820 // XXX		    DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
821 // XXX				       : "Ticket initialization failed.");
822 		    NEXTSTATE(next_state);
823 		    return TRUE;
824                 }
825 		if (ISCHPASSWD)
826                     break;
827 		CloseMe(TRUE); /* success */
828             }
829             break;
830 	    case STATE_NEWPWD1:
831             {
832                 int i = 0;
833                 int bit8 = 0;
834 
835                 for( i = 0; i < 255; i++ ){
836                     if( newpassword[i] == '\0' ){
837                         if ( bit8 ) {
838                             MessageBox(hDialog,
839                                         "Passwords should not contain non-ASCII characters.",
840                                         "Internationalization Warning",
841                                         MB_OK | MB_ICONINFORMATION);
842                         }
843                         i = 255;
844                         break;
845                     } else if( !isprint(newpassword[i]) ){
846                         memset(newpassword, '\0', 255);
847                         /* I claim these passwords in the name of planet '\0'... */
848                         MessageBox(hDialog,
849                                    "Passwords may not contain non-printable characters.",
850                                     "Invalid Password",
851                                     MB_OK | MB_ICONSTOP);
852                         NEXTSTATE(STATE_NEWPWD1);
853                         return TRUE;
854                     } else if ( newpassword[i] > 127 )
855                         bit8 = 1;
856                 }
857             }
858             break;
859 	    case STATE_NEWPWD2:
860                 if (lstrcmp(newpassword, newpassword2))
861                 {
862                     NEXTSTATE(STATE_NEWPWD1);
863                     MessageBox(hDialog,
864                                 "The new password was not entered the same way twice.",
865                                 "Password validation error",
866                                 MB_OK | MB_ICONSTOP);
867                     return TRUE;
868                 }
869                 else
870                 {
871                     /* make them type both pwds again if error */
872                     int next_state = STATE_NEWPWD1;
873                     int capslock;
874                     char *cp;
875 
876                     capslock = lsh_getkeystate(VK_CAPITAL);
877                     /* low-order bit means caps lock is
878                        toggled; if so, warn user since there's
879                        been an error. */
880                     if (capslock & 1)
881                     {
882                         lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
883                         cp = gbuf + lstrlen((LPSTR)gbuf);
884                         if (cp != gbuf)
885                             *cp++ = ' ';
886                         lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
887                         err_context = gbuf;
888                     }
889 
890                     if ((lsh_errno =
891                          Leash_int_changepwd(principal, oldpassword,
892                                          newpassword, 0, 1))
893                         == 0){
894                         CloseMe(TRUE);
895                     }
896                     else {
897                         // XXX - DoNiftyErrorReport(lsh_errno, "Error while changing password.");
898                         NEXTSTATE(next_state);
899                         return TRUE;
900 
901                     }
902 		}
903                 break;
904 	    }
905             /* increment state, but send the old state as a
906                parameter */
907             SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, state + 1);
908 	}
909 	break;
910         case IDCANCEL:
911             CloseMe(FALSE);
912             break;
913         case ID_RESTART:
914 	{
915             int i;
916 
917             for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++)
918                 SetDlgItemText(hDialog, i, "");
919             SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE,
920                         STATE_PRINCIPAL);
921 	}
922 	break;
923         }
924         break;
925 
926     case WM_MOVE:
927         if (state != STATE_CLOSED)
928 #ifdef _WIN32
929 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l),  \
930 			  (pt).y=(SHORT)HIWORD(l))
931             LONG2POINT(lParam,Position);
932 #else
933         Position = MAKEPOINT(lParam);
934 #endif
935         break;
936     }
937     return FALSE;
938 }
939 
940 
941 #define KRB_FILE                "KRB.CON"
942 #define KRBREALM_FILE           "KRBREALM.CON"
943 #define KRB5_FILE               "KRB5.INI"
944 
945 BOOL
GetProfileFile(LPSTR confname,UINT szConfname)946 GetProfileFile(
947     LPSTR confname,
948     UINT szConfname
949     )
950 {
951     char **configFile = NULL;
952     if (hKrb5 &&
953          pkrb5_get_default_config_files(&configFile))
954     {
955         GetWindowsDirectory(confname,szConfname);
956         confname[szConfname-1] = '\0';
957         strncat(confname, "\\",sizeof(confname)-strlen(confname));
958         confname[szConfname-1] = '\0';
959         strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname));
960         confname[szConfname-1] = '\0';
961         return FALSE;
962     }
963 
964     *confname = 0;
965 
966     if (hKrb5 && configFile)
967     {
968         strncpy(confname, *configFile, szConfname);
969         pkrb5_free_config_files(configFile);
970     }
971 
972     if (!*confname)
973     {
974         GetWindowsDirectory(confname,szConfname);
975         confname[szConfname-1] = '\0';
976         strncat(confname, "\\",sizeof(confname)-strlen(confname));
977         confname[szConfname-1] = '\0';
978         strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname));
979         confname[szConfname-1] = '\0';
980     }
981 
982     return FALSE;
983 }
984 
985 int
readstring(FILE * file,char * buf,int len)986 readstring(FILE * file, char * buf, int len)
987 {
988 	int  c,i;
989 	memset(buf, '\0', sizeof(buf));
990 	for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++)
991 	{
992 		if (i < sizeof(buf)) {
993 			if (c == '\n') {
994 				buf[i] = '\0';
995 				return i;
996 			} else {
997 				buf[i] = c;
998 			}
999 		} else {
1000 			if (c == '\n') {
1001 				buf[len-1] = '\0';
1002 				return(i);
1003 			}
1004 		}
1005 	}
1006 	if (c == EOF) {
1007 		if (i > 0 && i < len) {
1008 			buf[i] = '\0';
1009 			return(i);
1010 		} else {
1011 			buf[len-1] = '\0';
1012 			return(-1);
1013 		}
1014 	}
1015     return(-1);
1016 }
1017 
1018 typedef struct _slider_info {
1019 	int slider_id;
1020 	int text_id;
1021 	int min;
1022 	int max;
1023 	int increment;
1024 	struct _slider_info * next;
1025 } slider_info;
1026 static slider_info * sliders = NULL;
1027 
1028 static slider_info *
FreeSlider(slider_info * s)1029 FreeSlider(slider_info * s)
1030 {
1031 	slider_info * n = NULL;
1032 
1033 	if (s) {
1034 		n = s->next;
1035 		free(s);
1036 	}
1037 	return n;
1038 }
1039 
1040 static void
CleanupSliders(void)1041 CleanupSliders(void)
1042 {
1043 	while(sliders)
1044 		sliders = FreeSlider(sliders);
1045 }
1046 
1047 
1048 static unsigned short
NewSliderValue(HWND hDialog,int id)1049 NewSliderValue(HWND hDialog, int id)
1050 {
1051 	int value = 0;
1052 	slider_info * s = sliders;
1053 	while(s) {
1054 		if (s->slider_id == id) {
1055 			int pos = CSendDlgItemMessage( hDialog, id,
1056 										 TBM_GETPOS,
1057 										 (WPARAM) 0, (LPARAM) 0);
1058 			value = s->min + (pos * s->increment);
1059 			break;
1060 		}
1061 		s = s->next;
1062 	}
1063 	return(value);
1064 }
1065 
1066 static const char *
NewSliderString(int id,int pos)1067 NewSliderString(int id, int pos)
1068 {
1069 	static char buf[64]="";
1070 	char * p = buf;
1071 	int value = 0;
1072 	int must_hours = 0;
1073 	slider_info * s = sliders;
1074 	while(s) {
1075 		if (s->slider_id == id) {
1076 			value = s->min + pos * s->increment;
1077 			*p = 0;
1078 			if (value >= 60 * 24) {
1079 				sprintf(p,"%d day(s) ",value / (60 * 24));
1080 				value %= (60 * 24);
1081 				p += strlen(p);
1082 				must_hours = 1;
1083 			}
1084 			if (must_hours || value >= 60) {
1085 				sprintf(p,"%d hour(s) ",value / 60);
1086 				value %= 60;
1087 				p += strlen(p);
1088 			}
1089 			sprintf(p,"%d minute(s) ",value);
1090 			break;
1091 		}
1092 		s = s->next;
1093 	}
1094 	return(buf);
1095 }
1096 
1097 static void
SetupSlider(HWND hDialog,int sliderID,int textFieldID,int minimum,int maximum,int value)1098 SetupSlider( HWND hDialog,
1099 			 int sliderID,
1100 			 int textFieldID,
1101 			 int minimum,
1102 			 int maximum,
1103 			 int value)
1104 {
1105     int min = minimum;
1106     int max = maximum;
1107     int increment = 0;
1108     int range;
1109 	int roundedMinimum;
1110 	int roundedMaximum;
1111 	int roundedValue;
1112 	slider_info * new_info;
1113 
1114     if (max < min) {
1115         // swap values
1116         int temp = max;
1117         max = min;
1118         min = temp;
1119     }
1120 	range = max - min;
1121 
1122     if (range < 5*60)             { increment = 1;       //  1 s if under   5 m
1123     } else if (range < 30*60)     { increment = 5;       //  5 s if under  30 m
1124     } else if (range < 60*60)     { increment = 15;      // 15 s if under   1 h
1125     } else if (range < 2*60*60)   { increment = 30;      // 30 s if under   2 h
1126     } else if (range < 5*60*60)   { increment = 60;      //  1 m if under   5 h
1127     } else if (range < 50*60*60)  { increment = 5*60;    //  5 m if under  50 h
1128     } else if (range < 200*60*60) { increment = 15*60;   // 15 m if under 200 h
1129     } else if (range < 500*60*60) { increment = 30*60;   // 30 m if under 500 h
1130     } else                        { increment = 60*60; } //  1 h otherwise
1131 
1132     roundedMinimum = (min / increment) * increment;
1133     if (roundedMinimum > min) { roundedMinimum -= increment; }
1134     if (roundedMinimum <= 0)  { roundedMinimum += increment; } // make positive
1135 
1136     roundedMaximum = (max / increment) * increment;
1137     if (roundedMaximum < max) { roundedMaximum += increment; }
1138 
1139     roundedValue = (value / increment) * increment;
1140     if (roundedValue < roundedMinimum) { roundedValue = roundedMinimum; }
1141     if (roundedValue > roundedMaximum) { roundedValue = roundedMaximum; }
1142 
1143     if (roundedMinimum == roundedMaximum) {
1144         // [textField setTextColor: [NSColor grayColor]];
1145 		EnableWindow(GetDlgItem(hDialog,sliderID),FALSE);
1146     } else {
1147         // [textField setTextColor: [NSColor blackColor]];
1148 		EnableWindow(GetDlgItem(hDialog,sliderID),TRUE);
1149     }
1150 
1151 	CSendDlgItemMessage( hDialog, sliderID,
1152 						 TBM_SETRANGEMIN,
1153 						 (WPARAM) FALSE,
1154 						 (LPARAM) 0 );
1155 	CSendDlgItemMessage( hDialog, sliderID,
1156 						 TBM_SETRANGEMAX,
1157 						 (WPARAM) FALSE,
1158 						 (LPARAM) (roundedMaximum - roundedMinimum) / increment );
1159 	CSendDlgItemMessage( hDialog, sliderID,
1160 						 TBM_SETPOS,
1161 						 (WPARAM) TRUE,
1162 						 (LPARAM) (roundedValue - roundedMinimum) / increment);
1163 
1164 	new_info = (slider_info *) malloc(sizeof(slider_info));
1165 	new_info->slider_id = sliderID;
1166 	new_info->text_id = textFieldID;
1167 	new_info->min = roundedMinimum;
1168 	new_info->max = roundedMaximum;
1169 	new_info->increment = increment;
1170 	new_info->next = sliders;
1171 	sliders = new_info;
1172 
1173 	SetWindowText(GetDlgItem(hDialog, textFieldID),
1174 				   NewSliderString(sliderID,(roundedValue - roundedMinimum) / increment));
1175 }
1176 
1177 
1178 static void
AdjustOptions(HWND hDialog,int show,int hideDiff)1179 AdjustOptions(HWND hDialog, int show, int hideDiff)
1180 {
1181     RECT rect;
1182     RECT dlgRect;
1183     HWND hwnd;
1184     int diff;
1185 
1186     Leash_set_hide_kinit_options(!show);
1187 
1188     ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),show);
1189     ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME_VALUE),show);
1190     ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_LIFETIME),show);
1191     ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),show);
1192     ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW),show);
1193     ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW_TILL_VALUE),show);
1194     ShowWindow(GetDlgItem(hDialog,IDC_CHECK_FORWARDABLE),show);
1195     ShowWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),show);
1196     ShowWindow(GetDlgItem(hDialog,IDC_CHECK_RENEWABLE),show);
1197     ShowWindow(GetDlgItem(hDialog,IDC_STATIC_KRB5),show);
1198     ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_CLEAR_HISTORY),show);
1199 
1200     GetWindowRect( hDialog, &dlgRect );
1201     diff = dlgRect.top + GetSystemMetrics(SM_CYCAPTION)
1202          + GetSystemMetrics(SM_CYDLGFRAME) + (show ? -1 : 1) * hideDiff;
1203 
1204     hwnd = GetDlgItem(hDialog,IDOK);
1205     GetWindowRect(hwnd,&rect);
1206     SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
1207     hwnd = GetDlgItem(hDialog,IDCANCEL);
1208     GetWindowRect(hwnd,&rect);
1209     SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
1210     hwnd = GetDlgItem(hDialog,IDC_BUTTON_OPTIONS);
1211     GetWindowRect(hwnd,&rect);
1212     SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
1213     hwnd = GetDlgItem(hDialog,IDC_STATIC_VERSION);
1214     GetWindowRect(hwnd,&rect);
1215     SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
1216     hwnd = GetDlgItem(hDialog,IDC_STATIC_COPYRIGHT);
1217     GetWindowRect(hwnd,&rect);
1218     SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE);
1219     SetWindowPos(hDialog,0,0,0,
1220                  dlgRect.right-dlgRect.left,
1221                  dlgRect.bottom-dlgRect.top+(show ? 1 : - 1) * hideDiff,
1222                  SWP_NOZORDER|SWP_NOMOVE);
1223 
1224     CSetDlgItemText(hDialog, IDC_BUTTON_OPTIONS,
1225                     show ? "Hide Advanced" : "Show Advanced");
1226 
1227 }
1228 
1229 /* Callback function for the Authentication Dialog box that initializes and
1230    renews tickets. */
1231 
1232 INT_PTR
1233 CALLBACK
AuthenticateProc(HWND hDialog,UINT message,WPARAM wParam,LPARAM lParam)1234 AuthenticateProc(
1235     HWND hDialog,
1236     UINT message,
1237     WPARAM wParam,
1238     LPARAM lParam
1239     )
1240 {
1241     static POINT Position = { -1, -1 };
1242     static char principal[256]="";
1243     static char password[256]="";
1244     static int  lifetime=0;
1245     static int  renew_till=0;
1246     static int  forwardable=0;
1247     static int  noaddresses=0;
1248     static int  proxiable=0;
1249     static int  publicip=0;
1250     static LPLSH_DLGINFO_EX lpdi;
1251     static HWND hDlg=0;
1252     static HWND hSliderLifetime=0;
1253     static HWND hSliderRenew=0;
1254     static RECT dlgRect;
1255     static int  hideDiff = 0;
1256     static void *pAutoComplete = 0;
1257     long realm_count = 0;
1258     int disable_noaddresses = 0;
1259     HWND hEditCtrl=0;
1260     HWND hFocusCtrl=0;
1261     BOOL bReadOnlyPrinc=0;
1262 
1263     switch (message) {
1264 
1265     case WM_INITDIALOG:
1266 	hDlg = hDialog;
1267 
1268         hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL);
1269         if (hEditCtrl)
1270             pAutoComplete = Leash_pec_create(hEditCtrl);
1271 	hSliderLifetime = GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE);
1272 	hSliderRenew = GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE);
1273 
1274         *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam;
1275 
1276 	if ((lpdi->size != LSH_DLGINFO_EX_V1_SZ &&
1277 	     lpdi->size != LSH_DLGINFO_EX_V2_SZ &&
1278 	      lpdi->size < LSH_DLGINFO_EX_V3_SZ) ||
1279 	     (lpdi->dlgtype & DLGTYPE_MASK) != DLGTYPE_PASSWD) {
1280 
1281 	    MessageBox(hDialog, "An incorrect initialization data structure was provided.",
1282 			"AuthenticateProc()",
1283 			MB_OK | MB_ICONSTOP);
1284 	    return FALSE;
1285 	}
1286         bReadOnlyPrinc = (lpdi->dlgtype & DLGFLAG_READONLYPRINC) ?
1287                          TRUE : FALSE;
1288 
1289         if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
1290             lpdi->out.username[0] = 0;
1291             lpdi->out.realm[0] = 0;
1292         }
1293         if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) {
1294             lpdi->out.ccache[0] = 0;
1295         }
1296 
1297         if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
1298 	    SetWindowText(hDialog, lpdi->in.title);
1299 	else
1300 	    SetWindowText(hDialog, lpdi->title);
1301 
1302         SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
1303 	if (lpdi->use_defaults) {
1304 	    lifetime = Leash_get_default_lifetime();
1305 	    if (lifetime <= 0)
1306 		lifetime = 600; /* 10 hours */
1307 	    if (Leash_get_default_renewable()) {
1308                 renew_till = Leash_get_default_renew_till();
1309                 if (renew_till < 0)
1310                     renew_till = 10800; /* 7 days */
1311             } else
1312                 renew_till = 0;
1313 	    forwardable = Leash_get_default_forwardable();
1314 	    if (forwardable < 0)
1315 		forwardable = 0;
1316 	    noaddresses = Leash_get_default_noaddresses();
1317 	    if (noaddresses < 0)
1318 		noaddresses = 0;
1319 	    proxiable = Leash_get_default_proxiable();
1320 	    if (proxiable < 0)
1321 		proxiable = 0;
1322 	    publicip = Leash_get_default_publicip();
1323 	    if (publicip < 0)
1324 		publicip = 0;
1325 	} else {
1326 	    forwardable = lpdi->forwardable;
1327 	    noaddresses = lpdi->noaddresses;
1328 	    lifetime = lpdi->lifetime;
1329 	    renew_till = lpdi->renew_till;
1330 	    proxiable = lpdi->proxiable;
1331 	    publicip = lpdi->publicip;
1332 	}
1333         if (lpdi->username && (strlen(lpdi->username) > 0) &&
1334             lpdi->realm && (strlen(lpdi->realm) > 0)) {
1335             sprintf_s(principal, sizeof(principal), "%s@%s", lpdi->username,
1336                       lpdi->realm);
1337         } else {
1338             principal[0] = 0;
1339         }
1340         Edit_SetReadOnly(hEditCtrl, bReadOnlyPrinc);
1341         CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal);
1342         CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, "");
1343 
1344 	/* Set Lifetime Slider
1345 	*   min value = 5
1346 	*   max value = 1440
1347 	*   current value
1348 	*/
1349 
1350 	SetupSlider( hDialog,
1351 		     IDC_SLIDER_LIFETIME,
1352 		     IDC_STATIC_LIFETIME_VALUE,
1353 		     Leash_get_default_life_min(),
1354 		     Leash_get_default_life_max(),
1355 		     lifetime );
1356 
1357         CheckDlgButton(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL, TRUE);
1358 	/* Set Forwardable checkbox */
1359 	CheckDlgButton(hDialog, IDC_CHECK_FORWARDABLE, forwardable);
1360 	/* Set NoAddress checkbox */
1361 	CheckDlgButton(hDialog, IDC_CHECK_NOADDRESS, noaddresses);
1362         if ( disable_noaddresses )
1363             EnableWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),FALSE);
1364 	/* Set Renewable checkbox */
1365 	CheckDlgButton(hDialog, IDC_CHECK_RENEWABLE, renew_till);
1366 	/* if not renewable, disable Renew Till slider */
1367 	/* if renewable, set Renew Till slider
1368 	*     min value
1369 	*     max value
1370 	*     current value
1371 	*/
1372 	SetupSlider( hDialog,
1373 		     IDC_SLIDER_RENEWLIFE,
1374 		     IDC_STATIC_RENEW_TILL_VALUE,
1375 		     Leash_get_default_renew_min(),
1376 		     Leash_get_default_renew_max(),
1377 		     renew_till);
1378 	if (renew_till) {
1379 	    EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),TRUE);
1380 	} else {
1381 	    EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),FALSE);
1382 	}
1383 
1384         // Compute sizes of items necessary to show/hide the advanced options
1385         GetWindowRect( hDialog, &dlgRect );
1386         {
1387             RECT okRect, staticRect;
1388             GetWindowRect(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),&staticRect);
1389             GetWindowRect(GetDlgItem(hDialog,IDOK),&okRect);
1390             hideDiff = okRect.top - staticRect.top;
1391         }
1392 
1393         if ( hKrb5 ) {
1394             if (Leash_get_hide_kinit_options())
1395                 AdjustOptions(hDialog,0,hideDiff);
1396         } else {
1397             AdjustOptions(hDialog,0,hideDiff);
1398             EnableWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),FALSE);
1399             ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),SW_HIDE);
1400         }
1401 
1402         /* setup text of stuff. */
1403 
1404         if (Position.x > 0 && Position.y > 0 &&
1405             Position.x < GetSystemMetrics(SM_CXSCREEN) &&
1406             Position.y < GetSystemMetrics(SM_CYSCREEN))
1407             SetWindowPos(hDialog, HWND_TOP, Position.x, Position.y, 0, 0, SWP_NOSIZE);
1408         else /* Center the window on the desktop */
1409             SetWindowPos(hDialog, HWND_TOP,
1410                          (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2,
1411                          (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2,
1412                          0, 0,
1413                          SWP_NOSIZE);
1414 
1415         /* Take keyboard focus */
1416         SetActiveWindow(hDialog);
1417         SetForegroundWindow(hDialog);
1418         /* put focus on password if princ is read-only */
1419         hFocusCtrl = (bReadOnlyPrinc || principal[0] != '\0') ?
1420             GetDlgItem(hDialog, IDC_EDIT_PASSWORD) : hEditCtrl;
1421         if (((HWND)wParam) != hFocusCtrl) {
1422             SetFocus(hFocusCtrl);
1423         }
1424         break;
1425 
1426 	case WM_HSCROLL:
1427 	switch (LOWORD(wParam)) {
1428 	case TB_THUMBTRACK:
1429 	case TB_THUMBPOSITION:
1430 	    {
1431 		long pos = HIWORD(wParam); // the position of the slider
1432 		int  ctrlID = GetDlgCtrlID((HWND)lParam);
1433 
1434 		if (ctrlID == IDC_SLIDER_RENEWLIFE) {
1435 		    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE),
1436 				   NewSliderString(IDC_SLIDER_RENEWLIFE,pos));
1437 		}
1438 		if (ctrlID == IDC_SLIDER_LIFETIME) {
1439 		    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE),
1440 				   NewSliderString(IDC_SLIDER_LIFETIME,pos));
1441 		}
1442 	    }
1443 	    break;
1444         case TB_BOTTOM:
1445         case TB_TOP:
1446         case TB_ENDTRACK:
1447         case TB_LINEDOWN:
1448         case TB_LINEUP:
1449         case TB_PAGEDOWN:
1450         case TB_PAGEUP:
1451 	default:
1452 	    {
1453 		int  ctrlID = GetDlgCtrlID((HWND)lParam);
1454 		long pos = SendMessage(GetDlgItem(hDialog,ctrlID), TBM_GETPOS, 0, 0); // the position of the slider
1455 
1456 		if (ctrlID == IDC_SLIDER_RENEWLIFE) {
1457 		    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE),
1458 				   NewSliderString(IDC_SLIDER_RENEWLIFE,pos));
1459 		}
1460 		if (ctrlID == IDC_SLIDER_LIFETIME) {
1461 		    SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE),
1462 				   NewSliderString(IDC_SLIDER_LIFETIME,pos));
1463 		}
1464 	    }
1465 	}
1466         break;
1467 
1468     case WM_COMMAND:
1469         switch (wParam) {
1470 	case IDC_BUTTON_OPTIONS:
1471 	    {
1472                 AdjustOptions(hDialog,Leash_get_hide_kinit_options(),hideDiff);
1473                 GetWindowRect(hDialog,&dlgRect);
1474                 if ( dlgRect.bottom > GetSystemMetrics(SM_CYSCREEN))
1475                     SetWindowPos( hDialog,0,
1476                                   dlgRect.left,
1477                                   GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top,
1478                                   0,0,
1479                                   SWP_NOZORDER|SWP_NOSIZE);
1480 
1481 	    }
1482 	    break;
1483     case IDC_BUTTON_CLEAR_HISTORY:
1484         Leash_pec_clear_history(pAutoComplete);
1485         break;
1486 	case IDC_CHECK_RENEWABLE:
1487 	    {
1488 		if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) {
1489 		    EnableWindow(hSliderRenew,TRUE);
1490 		} else {
1491 		    EnableWindow(hSliderRenew,FALSE);
1492 		}
1493 	    }
1494 	    break;
1495         case ID_HELP:
1496 	    {
1497 		WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
1498 			 ID_INITTICKETS);
1499 	    }
1500 	    break;
1501         case ID_CLOSEME:
1502 	    {
1503 		CleanupSliders();
1504 		memset(password,0,sizeof(password));
1505 		RemoveProp(hDialog, "HANDLES_HELP");
1506         if (pAutoComplete) {
1507             Leash_pec_destroy(pAutoComplete);
1508             pAutoComplete = NULL;
1509         }
1510 		EndDialog(hDialog, (int)lParam);
1511                 return TRUE;
1512 	    }
1513 	    break;
1514         case IDOK:
1515 	    {
1516 		DWORD value = 0;
1517 
1518 		CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal));
1519 		CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password));
1520 
1521 		if (!principal[0]) {
1522 		    MessageBox(hDialog,
1523                        "You are not allowed to enter a blank principal.",
1524                        "Invalid Principal",
1525                        MB_OK | MB_ICONSTOP);
1526 		    return TRUE;
1527 		}
1528         // @TODO: parse realm portion and auto-uppercase
1529 /*
1530 		if (Leash_get_default_uppercaserealm())
1531 		{
1532 		    // found
1533 		    strupr(realm);
1534 		}
1535 */
1536 
1537 		if (!password[0])
1538 		{
1539 		    MessageBox(hDialog,
1540                                 "You are not allowed to enter a blank password.",
1541 				"Invalid Password",
1542 				MB_OK | MB_ICONSTOP);
1543 		    return TRUE;
1544 		}
1545 
1546 		lifetime = NewSliderValue(hDialog, IDC_SLIDER_LIFETIME);
1547 
1548 		forwardable = proxiable =
1549                     IsDlgButtonChecked(hDialog, IDC_CHECK_FORWARDABLE);
1550 		noaddresses = IsDlgButtonChecked(hDialog, IDC_CHECK_NOADDRESS);
1551 		if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) {
1552 		    renew_till = NewSliderValue(hDialog, IDC_SLIDER_RENEWLIFE);
1553 		} else {
1554 		    renew_till= 0;
1555 		}
1556 
1557 		lsh_errno = Leash_int_kinit_ex( 0,
1558 						hDialog,
1559 						principal, password, lifetime,
1560 						forwardable,
1561 						proxiable,
1562 						renew_till,
1563 						noaddresses,
1564 						publicip,
1565 						1
1566 						);
1567 		if (lsh_errno != 0)
1568 		{
1569 #ifdef COMMENT
1570 		    char gbuf[256];
1571 		    int capslock;
1572 		    char *cp;
1573 #endif
1574 		    err_context = "";
1575 		    switch(lsh_errno)
1576 		    {
1577 		    case LSH_INVPRINCIPAL:
1578 		    case LSH_INVINSTANCE:
1579                         CSendDlgItemMessage(hDialog, IDC_EDIT_PRINCIPAL, EM_SETSEL, 0, 256);
1580                         SetFocus(GetDlgItem(hDialog,IDC_EDIT_PRINCIPAL));
1581                         break;
1582 		    case LSH_INVREALM:
1583                         CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, EM_SETSEL, 0, 256);
1584                         SetFocus(GetDlgItem(hDialog,IDC_COMBO_REALM));
1585 			break;
1586                     default:
1587                         CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETSEL, 0, 256);
1588                         SetFocus(GetDlgItem(hDialog,IDC_EDIT_PASSWORD));
1589 			return(TRUE);
1590 		    }
1591 #ifdef COMMENT
1592 		    capslock = lsh_getkeystate(VK_CAPITAL);
1593 		    /* low-order bit means caps lock is
1594 		    toggled; if so, warn user since there's
1595 		    been an error. */
1596 		    if (capslock & 1)
1597 		    {
1598 			lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
1599 			cp = gbuf + lstrlen((LPSTR)gbuf);
1600 			if (cp != gbuf)
1601 			    *cp++ = ' ';
1602 			lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
1603 			err_context = gbuf;
1604 		    }
1605 
1606 		    // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
1607 		    // XXX : "Ticket initialization failed.");
1608 #endif /* COMMENT */
1609 		    return TRUE;
1610 		}
1611 
1612                 if ( Leash_get_default_preserve_kinit_settings() )
1613                 {
1614                     Leash_set_default_lifetime(lifetime);
1615                     if ( renew_till > 0 ) {
1616                         Leash_set_default_renew_till(renew_till);
1617                         Leash_set_default_renewable(1);
1618                     } else {
1619                         Leash_set_default_renewable(0);
1620                     }
1621                     Leash_set_default_forwardable(forwardable);
1622                     Leash_set_default_noaddresses(noaddresses);
1623                 }
1624 /* @TODO: out username/realm
1625                 if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
1626                     strncpy(lpdi->out.username, username, LEASH_USERNAME_SZ);
1627                     lpdi->out.username[LEASH_USERNAME_SZ-1] = 0;
1628                     strncpy(lpdi->out.realm, realm, LEASH_REALM_SZ);
1629                     lpdi->out.realm[LEASH_REALM_SZ-1] = 0;
1630                 }
1631 */
1632                 if (IsDlgButtonChecked(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL))
1633                     Leash_pec_add_principal(principal);
1634 
1635                 CloseMe(TRUE); /* success */
1636                 return FALSE;
1637 	    }
1638 	    break;
1639         case IDCANCEL:
1640             CloseMe(FALSE);
1641             break;
1642         }
1643         break;
1644 
1645     case WM_MOVE:
1646 #ifdef _WIN32
1647 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l),  \
1648 			 (pt).y=(SHORT)HIWORD(l))
1649     LONG2POINT(lParam,Position);
1650 #else
1651 	Position = MAKEPOINT(lParam);
1652 #endif
1653         break;
1654     }
1655     return FALSE;
1656 }
1657 
1658 /* Callback function for the Change Password Dialog box */
1659 
1660 INT_PTR
1661 CALLBACK
NewPasswordProc(HWND hDialog,UINT message,WPARAM wParam,LPARAM lParam)1662 NewPasswordProc(
1663     HWND hDialog,
1664     UINT message,
1665     WPARAM wParam,
1666     LPARAM lParam
1667     )
1668 {
1669     static POINT Position = { -1, -1 };
1670     static char password[256]="";
1671     static char password2[256]="";
1672     static char password3[256]="";
1673     static LPLSH_DLGINFO_EX lpdi;
1674     static HWND hDlg=0;
1675     static void *pAutoComplete = NULL;
1676     char principal[256];
1677     long realm_count = 0;
1678     HWND hEditCtrl = NULL;
1679 
1680     switch (message) {
1681 
1682     case WM_INITDIALOG:
1683 	hDlg = hDialog;
1684 
1685         *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam;
1686 
1687 	if ((lpdi->size < LSH_DLGINFO_EX_V3_SZ &&
1688 	      lpdi->size != LSH_DLGINFO_EX_V1_SZ &&
1689 	      lpdi->size != LSH_DLGINFO_EX_V2_SZ) ||
1690 	     lpdi->dlgtype != DLGTYPE_CHPASSWD) {
1691 
1692 	    MessageBox(hDialog, "An incorrect initialization data structure was provided.",
1693 			"PasswordProc()",
1694 			MB_OK | MB_ICONSTOP);
1695 	    return FALSE;
1696 	}
1697 
1698         if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) {
1699             lpdi->out.username[0] = 0;
1700             lpdi->out.realm[0] = 0;
1701         }
1702         if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) {
1703             lpdi->out.ccache[0] = 0;
1704         }
1705 
1706         if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ )
1707 	    SetWindowText(hDialog, lpdi->in.title);
1708 	else
1709 	    SetWindowText(hDialog, lpdi->title);
1710 
1711         SetProp(hDialog, "HANDLES_HELP", (HANDLE)1);
1712 
1713         if (lpdi->username != NULL && (strlen(lpdi->username) > 0) &&
1714             lpdi->realm != NULL && (strlen(lpdi->realm) > 0)) {
1715             sprintf_s(principal,
1716                       sizeof(principal), "%s@%s", lpdi->username, lpdi->realm);
1717         } else {
1718             principal[0] = 0;
1719         }
1720 
1721         CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal);
1722         CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, "");
1723         CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, "");
1724         CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, "");
1725 
1726         hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL);
1727         if (hEditCtrl)
1728             pAutoComplete = Leash_pec_create(hEditCtrl);
1729 
1730         /* setup text of stuff. */
1731 
1732         if (Position.x > 0 && Position.y > 0 &&
1733             Position.x < GetSystemMetrics(SM_CXSCREEN) &&
1734             Position.y < GetSystemMetrics(SM_CYSCREEN))
1735             SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0,
1736                          SWP_NOSIZE | SWP_NOZORDER);
1737         else { /* Center the window on the desktop */
1738             RECT dlgRect;
1739             GetWindowRect( hDialog, &dlgRect );
1740             SetWindowPos(hDialog, 0,
1741                          (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2,
1742                          (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2,
1743                          0, 0,
1744                          SWP_NOSIZE | SWP_NOZORDER);
1745         }
1746         /* set window pos to last saved window pos */
1747         break;
1748 
1749     case WM_COMMAND:
1750         switch (wParam) {
1751         case ID_HELP:
1752 	    {
1753 		WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT,
1754 			 ID_INITTICKETS);
1755 	    }
1756 	    break;
1757         case ID_CLOSEME:
1758 	    {
1759 		CleanupSliders();
1760 		memset(password,0,sizeof(password));
1761 		memset(password2,0,sizeof(password2));
1762 		memset(password3,0,sizeof(password3));
1763 		RemoveProp(hDialog, "HANDLES_HELP");
1764 		EndDialog(hDialog, (int)lParam);
1765                 if (pAutoComplete != NULL) {
1766                     Leash_pec_destroy(pAutoComplete);
1767                     pAutoComplete = NULL;
1768                 }
1769                 return TRUE;
1770 	    }
1771 	    break;
1772         case IDOK:
1773 	    {
1774 		DWORD value = 0;
1775 		int i = 0;
1776                 int bit8 = 0;
1777 
1778 		CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal));
1779 		CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password));
1780 		CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, password2, sizeof(password2));
1781 		CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, password3, sizeof(password3));
1782 
1783 		if (!principal[0])
1784 		{
1785 		    MessageBox(hDialog, "You are not allowed to enter a "
1786 				"blank username.",
1787 				"Invalid Principal",
1788 				MB_OK | MB_ICONSTOP);
1789 		    return TRUE;
1790 		}
1791 
1792 		if (!password[0] || !password2[0] || !password3[0])
1793 		{
1794 		    MessageBox(hDialog, "You are not allowed to enter a "
1795 				"blank password.",
1796 				"Invalid Password",
1797 				MB_OK | MB_ICONSTOP);
1798 		    return TRUE;
1799 		}
1800 
1801 		for( i = 0; i < 255; i++ ){
1802                     if( password2[i] == '\0' ){
1803                         if ( bit8 ) {
1804                             MessageBox(hDialog,
1805                                         "Passwords should not contain non-ASCII characters.",
1806                                         "Internationalization Warning",
1807                                         MB_OK | MB_ICONINFORMATION);
1808                         }
1809                         i = 255;
1810                         break;
1811                     } else if( !isprint(password2[i]) ){
1812                         memset(password2, '\0', sizeof(password2));
1813                         memset(password3, '\0', sizeof(password3));
1814                         /* I claim these passwords in the name of planet '\0'... */
1815                         MessageBox(hDialog,
1816                                    "Passwords may not contain non-printable characters.",
1817                                     "Invalid Password",
1818                                     MB_OK | MB_ICONSTOP);
1819                         return TRUE;
1820                     } else if ( password2[i] > 127 )
1821                         bit8 = 1;
1822 		}
1823 
1824 		if (lstrcmp(password2, password3))
1825 		{
1826                     MessageBox(hDialog,
1827                                 "The new password was not entered the same way twice.",
1828                                 "Password validation error",
1829                                 MB_OK | MB_ICONSTOP);
1830                     return TRUE;
1831 		}
1832 
1833                 lsh_errno = Leash_int_changepwd(principal, password, password2, 0, 1);
1834 		if (lsh_errno != 0)
1835 		{
1836 #ifdef COMMENT
1837 		    char gbuf[256];
1838 		    int capslock;
1839 		    char *cp;
1840 #endif /* COMMENT */
1841 
1842 		    err_context = "";
1843 		    switch(lsh_errno)
1844 		    {
1845 		    case LSH_INVPRINCIPAL:
1846 		    case LSH_INVINSTANCE:
1847 		    case LSH_INVREALM:
1848 			break;
1849 		    default:
1850 			return(TRUE);
1851 		    }
1852 #ifdef COMMENT
1853 		    capslock = lsh_getkeystate(VK_CAPITAL);
1854 		    /* low-order bit means caps lock is
1855 		    toggled; if so, warn user since there's
1856 		    been an error. */
1857 		    if (capslock & 1)
1858 		    {
1859 			lstrcpy((LPSTR)gbuf, (LPSTR)err_context);
1860 			cp = gbuf + lstrlen((LPSTR)gbuf);
1861 			if (cp != gbuf)
1862 			    *cp++ = ' ';
1863 			lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)");
1864 			err_context = gbuf;
1865 		    }
1866 
1867 		    // XXX   DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? ""
1868 		    // XXX   : "Ticket initialization failed.");
1869 #endif /* COMMENT */
1870                     return TRUE;
1871 		}
1872                 Leash_pec_add_principal(principal);
1873                 MessageBox(NULL, "Password successfully changed.",
1874                            "Password change", MB_OK);
1875                 CloseMe(TRUE); /* success */
1876 	    }
1877 	    break;
1878         case IDCANCEL:
1879             CloseMe(FALSE);
1880             break;
1881         }
1882         break;
1883 
1884     case WM_MOVE:
1885 #ifdef _WIN32
1886 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l),  \
1887 		   (pt).y=(SHORT)HIWORD(l))
1888     LONG2POINT(lParam,Position);
1889 #else
1890 	Position = MAKEPOINT(lParam);
1891 #endif
1892         break;
1893     }
1894     return FALSE;
1895 }
1896