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