#define SCALE_FACTOR 31/20 /* LSH_PWD.C Jason Hunter 8/2/94 DCNS/IS MIT Re-written for KFW 2.6 by Jeffrey Altman Contains the callback functions for the EnterPassword an ChangePassword dialog boxes and well as the API function calls: Lsh_Enter_Password_Dialog Lsh_Change_Password_Dialog for calling the dialogs. Also contains the callback for the MITPasswordControl. */ /* Standard Include files */ #include #include #include /* Private Inlclude files */ #include "leashdll.h" #include #include #include "leash-int.h" #include "leashids.h" #include #ifndef NO_KRB5 #include #endif /* NO_KRB5 */ #include extern void * Leash_pec_create(HWND hEditCtl); extern void Leash_pec_destroy(void *pAutoComplete); extern void Leash_pec_add_principal(char *principal); extern void Leash_pec_clear_history(void *pec); /* Global Variables. */ static long lsh_errno; static char *err_context; /* error context */ extern HINSTANCE hLeashInst; extern HINSTANCE hKrb4; extern HINSTANCE hKrb5; INT_PTR CALLBACK PasswordProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK AuthenticateProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); INT_PTR CALLBACK NewPasswordProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ); long Leash_get_lsh_errno(LONG *err_val) { return lsh_errno; } /*/////// ******** API Calls follow here. ******** /////////*/ static int NetId_dialog(LPLSH_DLGINFO lpdlginfo) { LRESULT lrc; HWND hNetIdMgr; HWND hForeground; hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); if (hNetIdMgr != NULL) { char desiredPrincipal[512]; NETID_DLGINFO *dlginfo; char *desiredName = 0; char *desiredRealm = 0; HANDLE hMap; DWORD tid = GetCurrentThreadId(); char mapname[256]; strcpy(desiredPrincipal, lpdlginfo->principal); /* do we want a specific client principal? */ if (desiredPrincipal[0]) { char * p; desiredName = desiredPrincipal; for (p = desiredName; *p && *p != '@'; p++); if ( *p == '@' ) { *p = '\0'; desiredRealm = ++p; } } sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, mapname); if (hMap == NULL) { return -1; } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hMap); return -1; } dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096, NULL); if (dlginfo == NULL) { CloseHandle(hMap); return -1; } hForeground = GetForegroundWindow(); memset(dlginfo, 0, sizeof(NETID_DLGINFO)); dlginfo->size = sizeof(NETID_DLGINFO); if (lpdlginfo->dlgtype == DLGTYPE_PASSWD) dlginfo->dlgtype = NETID_DLGTYPE_TGT; else dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD; dlginfo->in.use_defaults = 1; if (lpdlginfo->title) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, lpdlginfo->title, -1, dlginfo->in.title, NETID_TITLE_SZ); } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { char mytitle[NETID_TITLE_SZ]; sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mytitle, -1, dlginfo->in.title, NETID_TITLE_SZ); } else { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, "Obtain Kerberos TGT", -1, dlginfo->in.title, NETID_TITLE_SZ); } if (desiredName) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredName, -1, dlginfo->in.username, NETID_USERNAME_SZ); if (desiredRealm) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredRealm, -1, dlginfo->in.realm, NETID_REALM_SZ); lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); UnmapViewOfFile(dlginfo); CloseHandle(hMap); SetForegroundWindow(hForeground); return lrc; } return -1; } static int NetId_dialog_ex(LPLSH_DLGINFO_EX lpdlginfo) { HWND hNetIdMgr; HWND hForeground; hNetIdMgr = FindWindow("IDMgrRequestDaemonCls", "IDMgrRequestDaemon"); if (hNetIdMgr != NULL) { NETID_DLGINFO *dlginfo; char *desiredName = lpdlginfo->username; char *desiredRealm = lpdlginfo->realm; LPSTR title; char *ccache; LRESULT lrc; HANDLE hMap; DWORD tid = GetCurrentThreadId(); char mapname[256]; sprintf(mapname,"Local\\NetIDMgr_DlgInfo_%lu",tid); hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, mapname); if (hMap == NULL) { return -1; } else if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hMap); return -1; } dlginfo = (NETID_DLGINFO *)MapViewOfFileEx(hMap, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 4096, NULL); if (dlginfo == NULL) { CloseHandle(hMap); return -1; } hForeground = GetForegroundWindow(); if (lpdlginfo->size == LSH_DLGINFO_EX_V1_SZ || lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ) { title = lpdlginfo->title; desiredName = lpdlginfo->username; desiredRealm = lpdlginfo->realm; ccache = NULL; } else { title = lpdlginfo->in.title; desiredName = lpdlginfo->in.username; desiredRealm = lpdlginfo->in.realm; ccache = lpdlginfo->in.ccache; } memset(dlginfo, 0, sizeof(NETID_DLGINFO)); dlginfo->size = sizeof(NETID_DLGINFO); if (lpdlginfo->dlgtype == DLGTYPE_PASSWD) dlginfo->dlgtype = NETID_DLGTYPE_TGT; else dlginfo->dlgtype = NETID_DLGTYPE_CHPASSWD; dlginfo->in.use_defaults = lpdlginfo->use_defaults; dlginfo->in.forwardable = lpdlginfo->forwardable; dlginfo->in.noaddresses = lpdlginfo->noaddresses; dlginfo->in.lifetime = lpdlginfo->lifetime; dlginfo->in.renew_till = lpdlginfo->renew_till; dlginfo->in.proxiable = lpdlginfo->proxiable; dlginfo->in.publicip = lpdlginfo->publicip; if (title) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, title, -1, dlginfo->in.title, NETID_TITLE_SZ); } else if (desiredName && (strlen(desiredName) + strlen(desiredRealm) + 32 < NETID_TITLE_SZ)) { char mytitle[NETID_TITLE_SZ]; sprintf(mytitle, "Obtain Kerberos TGT for %s@%s",desiredName,desiredRealm); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mytitle, -1, dlginfo->in.title, NETID_TITLE_SZ); } else { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, "Obtain Kerberos TGT", -1, dlginfo->in.title, NETID_TITLE_SZ); } if (desiredName) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredName, -1, dlginfo->in.username, NETID_USERNAME_SZ); if (desiredRealm) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, desiredRealm, -1, dlginfo->in.realm, NETID_REALM_SZ); if (ccache) MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, ccache, -1, dlginfo->in.ccache, NETID_CCACHE_NAME_SZ); lrc = SendMessage(hNetIdMgr, 32810, 0, (LPARAM) tid); if (lrc > 0) { if (lpdlginfo->size == LSH_DLGINFO_EX_V2_SZ) { WideCharToMultiByte(CP_ACP, 0, dlginfo->out.username, -1, lpdlginfo->out.username, LEASH_USERNAME_SZ, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, dlginfo->out.realm, -1, lpdlginfo->out.realm, LEASH_REALM_SZ, NULL, NULL); } if (lpdlginfo->size == LSH_DLGINFO_EX_V3_SZ) { WideCharToMultiByte(CP_ACP, 0, dlginfo->out.ccache, -1, lpdlginfo->out.ccache, LEASH_CCACHE_NAME_SZ, NULL, NULL); } } UnmapViewOfFile(dlginfo); CloseHandle(hMap); SetForegroundWindow(hForeground); return lrc; } return -1; } #define LEASH_DLG_MUTEX_NAME TEXT("Leash_Dialog_Mutex") int Leash_kinit_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_PASSWD; /* set the help file */ Leash_set_help_file(NULL); /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, "EnterPasswordDlg", hParent, PasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_kinit_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog_ex(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } /* set the help file */ Leash_set_help_file(NULL); /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_AUTHENTICATE), hParent, AuthenticateProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_changepwd_dlg(HWND hParent, LPLSH_DLGINFO lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_CHPASSWD; /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, "CHANGEPASSWORDDLG", hParent, PasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } int Leash_changepwd_dlg_ex(HWND hParent, LPLSH_DLGINFO_EX lpdlginfo) { int rc; HANDLE hMutex; rc = NetId_dialog_ex(lpdlginfo); if (rc > -1) return rc; hMutex = CreateMutex(NULL, TRUE, LEASH_DLG_MUTEX_NAME); if ( GetLastError() == ERROR_ALREADY_EXISTS ) { if ( WaitForSingleObject( hMutex, INFINITE ) != WAIT_OBJECT_0 ) { return -1; } ReleaseMutex(hMutex); CloseHandle(hMutex); return 1; /* pretend the dialog was displayed and succeeded */ } lpdlginfo->dlgtype = DLGTYPE_CHPASSWD; /* Call the Dialog box with the DLL's Password Callback and the DLL's instance handle. */ rc = DialogBoxParam(hLeashInst, MAKEINTRESOURCE(IDD_PASSWORD), hParent, NewPasswordProc, (LPARAM)lpdlginfo); ReleaseMutex(hMutex); CloseHandle(hMutex); return rc; } /* These little utils are taken from lshutil.c they are added here for the Call back funtion. ****** beginning of added utils from lshutil.c ******/ BOOL IsDlgItem(HWND hWnd, WORD id) { HWND hChild; hChild = GetDlgItem(hWnd, id); return hChild ? IsWindow(hChild) : 0; } int lsh_getkeystate(WORD keyid) { static BYTE keys[256]; GetKeyboardState((LPBYTE) &keys); return (int) keys[keyid]; } LPSTR krb_err_func(int offset, long code) { return(NULL); } /****** End of Added utils from leash.c ******/ int PaintLogoBitmap( HANDLE hPicFrame ) { HBITMAP hBitmap; HBITMAP hOldBitmap; BITMAP Bitmap; HDC hdc, hdcMem; RECT rect; /* Invalidate the drawing space of the picframe. */ InvalidateRect( hPicFrame, NULL, TRUE); UpdateWindow( hPicFrame ); hdc = GetDC(hPicFrame); hdcMem = CreateCompatibleDC(hdc); GetClientRect(hPicFrame, &rect); hBitmap = LoadBitmap(hLeashInst, "LOGOBITMAP"); hOldBitmap = SelectObject(hdcMem, hBitmap); GetObject(hBitmap, sizeof(Bitmap), (LPSTR) &Bitmap); StretchBlt(hdc, 0, 0, rect.right, rect.bottom, hdcMem, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY); SelectObject(hdcMem, hOldBitmap); /* pbh 8-15-94 */ ReleaseDC(hPicFrame, hdc); DeleteObject( hBitmap ); /* pbh 8-15-94 */ DeleteDC( hdcMem ); /* pbh 8-15-94 */ return 0; } /* Callback function for the Password Dialog box that initilializes and renews tickets. */ INT_PTR CALLBACK PasswordProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static short state; int lifetime; #define ISCHPASSWD (lpdi->dlgtype == DLGTYPE_CHPASSWD) #define STATE_INIT 0 #define STATE_PRINCIPAL 1 #define STATE_OLDPWD 2 #define STATE_NEWPWD1 3 #define STATE_NEWPWD2 4 #define STATE_CLOSED 5 #define NEXTSTATE(newstate) SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, newstate) static int ids[STATE_NEWPWD2 + 1] = { 0, ID_PRINCIPAL, ID_OLDPASSWORD, ID_CONFIRMPASSWORD1, ID_CONFIRMPASSWORD2}; static char principal[255], oldpassword[255], newpassword[255], newpassword2[255]; static char *strings[STATE_NEWPWD2 + 1] = { NULL, principal, oldpassword, newpassword, newpassword2}; static LPLSH_DLGINFO lpdi; char gbuf[200]; /* global buffer for random stuff. */ #define checkfirst(id, stuff) IsDlgItem(hDialog, id) ? stuff : 0 #define CGetDlgItemText(hDlg, id, cp, len) checkfirst(id, GetDlgItemText(hDlg, id, cp, len)) #define CSetDlgItemText(hDlg, id, cp) checkfirst(id, SetDlgItemText(hDlg, id, cp)) #define CSetDlgItemInt(hDlg, id, i, b) checkfirst(id, SetDlgItemInt(hDlg, id, i, b)) #define CSendDlgItemMessage(hDlg, id, m, w, l) checkfirst(id, SendDlgItemMessage(hDlg, id, m, w, l)) #define CSendMessage(hwnd, m, w, l) IsWindow(hwnd) ? SendMessage(hwnd, m, w, l) : 0 #define CShowWindow(hwnd, state) IsWindow(hwnd) ? ShowWindow(hwnd, state) : 0 #define GETITEMTEXT(id, cp, maxlen) \ GetDlgItemText(hDialog, id, (LPSTR)(cp), maxlen) #define CloseMe(x) SendMessage(hDialog, WM_COMMAND, ID_CLOSEME, x) #define EDITFRAMEIDOFFSET 500 switch (message) { case WM_INITDIALOG: *( (LPLSH_DLGINFO far *)(&lpdi) ) = (LPLSH_DLGINFO)(LPSTR)lParam; lpdi->dlgstatemax = ISCHPASSWD ? STATE_NEWPWD2 : STATE_OLDPWD; SetWindowText(hDialog, lpdi->title); /* stop at old password for normal password dlg */ SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->principal) lstrcpy(principal, lpdi->principal); else { principal[0] = '\0'; /* is there a principal already being used? if so, use it. */ } CSetDlgItemText(hDialog, ID_PRINCIPAL, principal); lifetime = Leash_get_default_lifetime(); if (lifetime <= 0) lifetime = 600; /* 10 hours */ CSetDlgItemInt(hDialog, ID_DURATION, lifetime, FALSE); /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); /* set window pos to last saved window pos */ /* replace standard edit control with our own password edit control for password entry. */ { RECT r; POINT pxy, psz; HWND hwnd; int i; for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++) { hwnd = GetDlgItem(hDialog, i); GetWindowRect(hwnd, &r); psz.x = r.right - r.left; psz.y = r.bottom - r.top; pxy.x = r.left; pxy.y = r.top; ScreenToClient(hDialog, &pxy); /* create a substitute window: */ DestroyWindow(hwnd); /* kill off old edit window. */ CreateWindow(MIT_PWD_DLL_CLASS, /* our password window :o] */ "", /* no text */ WS_CHILD | WS_VISIBLE | WS_TABSTOP, /* child window, visible,tabstop */ pxy.x, pxy.y, /* x, y coords */ psz.x, psz.y, /* width, height */ hDialog, /* the parent */ (HMENU)i, /* same id *//* id offset for the frames */ (HANDLE)hLeashInst,/* instance handles */ NULL); /* createstruct */ } } state = STATE_INIT; NEXTSTATE(STATE_PRINCIPAL); break; case WM_PAINT: PaintLogoBitmap( GetDlgItem(hDialog, ID_PICFRAME) ); break; case WM_COMMAND: switch (wParam) { case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ISCHPASSWD ? ID_CHANGEPASSWORD : ID_INITTICKETS); } break; case ID_CLOSEME: { int i; for (i = STATE_PRINCIPAL; i <= lpdi->dlgstatemax; i++) { memset(strings[i], '\0', 255); SetDlgItemText(hDialog, ids[i], ""); } /* I claim these passwords in the name of planet '\0'... */ RemoveProp(hDialog, "HANDLES_HELP"); state = STATE_CLOSED; EndDialog(hDialog, (int)lParam); return TRUE; } break; case ID_DURATION: break; case ID_PRINCIPAL: case ID_OLDPASSWORD: case ID_CONFIRMPASSWORD1: case ID_CONFIRMPASSWORD2: if (HIWORD(lParam) == EN_SETFOCUS) { /* nothing, for now. */ } break; case ID_NEXTSTATE: { RECT rbtn, redit; POINT p; int idfocus, i, s; HWND hfocus, hbtn; int oldstate = state; state = (int)lParam; idfocus = ids[state]; #ifdef ONE_NEWPWDBOX if (state == STATE_NEWPWD2) SendDlgItemMessage(hDialog, ID_CONFIRMPASSWORD1, WM_SETTEXT, 0, (LONG)(LPSTR)""); #endif for (s = STATE_PRINCIPAL; s <= lpdi->dlgstatemax; s++) { i = ids[s]; if (s > state) SendDlgItemMessage(hDialog, i, WM_SETTEXT, 0, (LONG)(LPSTR)""); EnableWindow(GetDlgItem(hDialog, i), i == idfocus); ShowWindow(GetDlgItem(hDialog, i), (i <= idfocus ? SW_SHOW : SW_HIDE)); /* ShowWindow(GetDlgItem(hDialog, i + CAPTION_OFFSET), (i <= idfocus ? SW_SHOW : SW_HIDE));*/ /* show caption? */ } #ifdef ONE_NEWPWDBOX CSetDlgItemText(hDialog, ID_CONFIRMCAPTION1, state < STATE_NEWPWD2 ? "Enter new password:" : "Enter new password again:"); if (state == STATE_NEWPWD2) { HWND htext; htext = GetDlgItem(hDialog, ID_CONFIRMCAPTION1); FlashAnyWindow(htext); WinSleep(50); FlashAnyWindow(htext); } #endif hfocus = GetDlgItem(hDialog, idfocus); if ( hfocus != (HWND)NULL ){ SetFocus(hfocus); /* switch focus */ if (idfocus >= ID_OLDPASSWORD) SendMessage(hfocus, WM_SETTEXT, 0, (LPARAM) (LPSTR) ""); else { SendMessage(hfocus, EM_SETSEL, 0, MAKELONG(0, -1)); } GetWindowRect(hfocus, &redit); } hbtn = GetDlgItem(hDialog, IDOK); if( IsWindow(hbtn) ){ GetWindowRect(hbtn, &rbtn); p.x = rbtn.left; p.y = redit.top; ScreenToClient(hDialog, &p); SetWindowPos(hbtn, 0, p.x, p.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } break; case IDOK: { char* p_Principal; DWORD value = 0; GETITEMTEXT(ids[state], (LPSTR)strings[state], 255); switch(state) { case STATE_PRINCIPAL: { if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a blank principal.", "Invalid Principal", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_PRINCIPAL); return TRUE; } // Change 'principal' to upper case after checking // "UpperCase" value in the Registry p_Principal = strchr(principal, '@'); if (p_Principal && Leash_get_default_uppercaserealm()) strupr(p_Principal); break; } case STATE_OLDPWD: { int duration; if (!ISCHPASSWD) duration = GetDlgItemInt(hDialog, ID_DURATION, 0, FALSE); if (!oldpassword[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_OLDPWD); return TRUE; } if (lpdi->dlgtype == DLGTYPE_CHPASSWD) lsh_errno = Leash_int_checkpwd(principal, oldpassword, 1); else { lsh_errno = Leash_int_kinit_ex( 0, hDialog, principal, oldpassword, duration, Leash_get_default_forwardable(), Leash_get_default_proxiable(), Leash_get_default_renew_till(), Leash_get_default_noaddresses(), Leash_get_default_publicip(), 1 ); } if (lsh_errno != 0) { int next_state = state; int capslock; char *cp; err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: case LSH_INVREALM: next_state = STATE_PRINCIPAL; break; } capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); NEXTSTATE(next_state); return TRUE; } if (ISCHPASSWD) break; CloseMe(TRUE); /* success */ } break; case STATE_NEWPWD1: { int i = 0; int bit8 = 0; for( i = 0; i < 255; i++ ){ if( newpassword[i] == '\0' ){ if ( bit8 ) { MessageBox(hDialog, "Passwords should not contain non-ASCII characters.", "Internationalization Warning", MB_OK | MB_ICONINFORMATION); } i = 255; break; } else if( !isprint(newpassword[i]) ){ memset(newpassword, '\0', 255); /* I claim these passwords in the name of planet '\0'... */ MessageBox(hDialog, "Passwords may not contain non-printable characters.", "Invalid Password", MB_OK | MB_ICONSTOP); NEXTSTATE(STATE_NEWPWD1); return TRUE; } else if ( newpassword[i] > 127 ) bit8 = 1; } } break; case STATE_NEWPWD2: if (lstrcmp(newpassword, newpassword2)) { NEXTSTATE(STATE_NEWPWD1); MessageBox(hDialog, "The new password was not entered the same way twice.", "Password validation error", MB_OK | MB_ICONSTOP); return TRUE; } else { /* make them type both pwds again if error */ int next_state = STATE_NEWPWD1; int capslock; char *cp; capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } if ((lsh_errno = Leash_int_changepwd(principal, oldpassword, newpassword, 0, 1)) == 0){ CloseMe(TRUE); } else { // XXX - DoNiftyErrorReport(lsh_errno, "Error while changing password."); NEXTSTATE(next_state); return TRUE; } } break; } /* increment state, but send the old state as a parameter */ SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, state + 1); } break; case IDCANCEL: CloseMe(FALSE); break; case ID_RESTART: { int i; for (i = ID_OLDPASSWORD; i <= ids[lpdi->dlgstatemax]; i++) SetDlgItemText(hDialog, i, ""); SendMessage(hDialog, WM_COMMAND, ID_NEXTSTATE, STATE_PRINCIPAL); } break; } break; case WM_MOVE: if (state != STATE_CLOSED) #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; } #define KRB_FILE "KRB.CON" #define KRBREALM_FILE "KRBREALM.CON" #define KRB5_FILE "KRB5.INI" BOOL GetProfileFile( LPSTR confname, UINT szConfname ) { char **configFile = NULL; if (hKrb5 && pkrb5_get_default_config_files(&configFile)) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; return FALSE; } *confname = 0; if (hKrb5 && configFile) { strncpy(confname, *configFile, szConfname); pkrb5_free_config_files(configFile); } if (!*confname) { GetWindowsDirectory(confname,szConfname); confname[szConfname-1] = '\0'; strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; } return FALSE; } BOOL GetKrb4ConFile( LPSTR confname, UINT szConfname ) { if (hKrb5 ) { // hold krb.con where krb5.ini is located CHAR krbConFile[MAX_PATH]=""; LPSTR pFind; //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename); if (GetProfileFile(krbConFile, sizeof(krbConFile))) { GetWindowsDirectory(krbConFile,sizeof(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, KRB5_FILE,sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; } pFind = strrchr(krbConFile, '\\'); if (pFind) { *pFind = 0; strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, KRB_FILE,sizeof(krbConFile)-strlen(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; } else krbConFile[0] = 0; strncpy(confname, krbConFile, szConfname); confname[szConfname-1] = '\0'; } return FALSE; } BOOL GetKrb4RealmFile( LPSTR confname, UINT szConfname ) { if (hKrb5 ) { // hold krb.con where krb5.ini is located CHAR krbRealmConFile[MAX_PATH]; LPSTR pFind; //strcpy(krbRealmConFile, CLeashApp::m_krbv5_profile->first_file->filename); if (GetProfileFile(krbRealmConFile, sizeof(krbRealmConFile))) { GetWindowsDirectory(krbRealmConFile,sizeof(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, "\\",sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, KRB5_FILE,sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; } pFind = strrchr(krbRealmConFile, '\\'); if (pFind) { *pFind = 0; strncat(krbRealmConFile, "\\", sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; strncat(krbRealmConFile, KRBREALM_FILE, sizeof(krbRealmConFile)-strlen(krbRealmConFile)); krbRealmConFile[MAX_PATH-1] = '\0'; } else krbRealmConFile[0] = 0; strncpy(confname, krbRealmConFile, szConfname); confname[szConfname-1] = '\0'; } return FALSE; } int readstring(FILE * file, char * buf, int len) { int c,i; memset(buf, '\0', sizeof(buf)); for (i=0, c=fgetc(file); c != EOF ; c=fgetc(file), i++) { if (i < sizeof(buf)) { if (c == '\n') { buf[i] = '\0'; return i; } else { buf[i] = c; } } else { if (c == '\n') { buf[len-1] = '\0'; return(i); } } } if (c == EOF) { if (i > 0 && i < len) { buf[i] = '\0'; return(i); } else { buf[len-1] = '\0'; return(-1); } } return(-1); } typedef struct _slider_info { int slider_id; int text_id; int min; int max; int increment; struct _slider_info * next; } slider_info; static slider_info * sliders = NULL; static slider_info * FreeSlider(slider_info * s) { slider_info * n = NULL; if (s) { n = s->next; free(s); } return n; } static void CleanupSliders(void) { while(sliders) sliders = FreeSlider(sliders); } static unsigned short NewSliderValue(HWND hDialog, int id) { int value = 0; slider_info * s = sliders; while(s) { if (s->slider_id == id) { int pos = CSendDlgItemMessage( hDialog, id, TBM_GETPOS, (WPARAM) 0, (LPARAM) 0); value = s->min + (pos * s->increment); break; } s = s->next; } return(value); } static const char * NewSliderString(int id, int pos) { static char buf[64]=""; char * p = buf; int value = 0; int must_hours = 0; slider_info * s = sliders; while(s) { if (s->slider_id == id) { value = s->min + pos * s->increment; *p = 0; if (value >= 60 * 24) { sprintf(p,"%d day(s) ",value / (60 * 24)); value %= (60 * 24); p += strlen(p); must_hours = 1; } if (must_hours || value >= 60) { sprintf(p,"%d hour(s) ",value / 60); value %= 60; p += strlen(p); } sprintf(p,"%d minute(s) ",value); break; } s = s->next; } return(buf); } static void SetupSlider( HWND hDialog, int sliderID, int textFieldID, int minimum, int maximum, int value) { int min = minimum; int max = maximum; int increment = 0; int range; int roundedMinimum; int roundedMaximum; int roundedValue; slider_info * new_info; if (max < min) { // swap values int temp = max; max = min; min = temp; } range = max - min; if (range < 5*60) { increment = 1; // 1 s if under 5 m } else if (range < 30*60) { increment = 5; // 5 s if under 30 m } else if (range < 60*60) { increment = 15; // 15 s if under 1 h } else if (range < 2*60*60) { increment = 30; // 30 s if under 2 h } else if (range < 5*60*60) { increment = 60; // 1 m if under 5 h } else if (range < 50*60*60) { increment = 5*60; // 5 m if under 50 h } else if (range < 200*60*60) { increment = 15*60; // 15 m if under 200 h } else if (range < 500*60*60) { increment = 30*60; // 30 m if under 500 h } else { increment = 60*60; } // 1 h otherwise roundedMinimum = (min / increment) * increment; if (roundedMinimum > min) { roundedMinimum -= increment; } if (roundedMinimum <= 0) { roundedMinimum += increment; } // make positive roundedMaximum = (max / increment) * increment; if (roundedMaximum < max) { roundedMaximum += increment; } roundedValue = (value / increment) * increment; if (roundedValue < roundedMinimum) { roundedValue = roundedMinimum; } if (roundedValue > roundedMaximum) { roundedValue = roundedMaximum; } if (roundedMinimum == roundedMaximum) { // [textField setTextColor: [NSColor grayColor]]; EnableWindow(GetDlgItem(hDialog,sliderID),FALSE); } else { // [textField setTextColor: [NSColor blackColor]]; EnableWindow(GetDlgItem(hDialog,sliderID),TRUE); } CSendDlgItemMessage( hDialog, sliderID, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 0 ); CSendDlgItemMessage( hDialog, sliderID, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) (roundedMaximum - roundedMinimum) / increment ); CSendDlgItemMessage( hDialog, sliderID, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) (roundedValue - roundedMinimum) / increment); new_info = (slider_info *) malloc(sizeof(slider_info)); new_info->slider_id = sliderID; new_info->text_id = textFieldID; new_info->min = roundedMinimum; new_info->max = roundedMaximum; new_info->increment = increment; new_info->next = sliders; sliders = new_info; SetWindowText(GetDlgItem(hDialog, textFieldID), NewSliderString(sliderID,(roundedValue - roundedMinimum) / increment)); } static void AdjustOptions(HWND hDialog, int show, int hideDiff) { RECT rect; RECT dlgRect; HWND hwnd; int diff; Leash_set_hide_kinit_options(!show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_LIFETIME_VALUE),show); ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_LIFETIME),show); ShowWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_RENEW_TILL_VALUE),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_FORWARDABLE),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),show); ShowWindow(GetDlgItem(hDialog,IDC_CHECK_RENEWABLE),show); ShowWindow(GetDlgItem(hDialog,IDC_STATIC_KRB5),show); ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_CLEAR_HISTORY),show); GetWindowRect( hDialog, &dlgRect ); diff = dlgRect.top + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYDLGFRAME) + (show ? -1 : 1) * hideDiff; hwnd = GetDlgItem(hDialog,IDOK); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDCANCEL); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_BUTTON_OPTIONS); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_STATIC_VERSION); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); hwnd = GetDlgItem(hDialog,IDC_STATIC_COPYRIGHT); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd,0,rect.left-dlgRect.left-GetSystemMetrics(SM_CXDLGFRAME),rect.top-diff,0,0,SWP_NOZORDER|SWP_NOSIZE); SetWindowPos(hDialog,0,0,0, dlgRect.right-dlgRect.left, dlgRect.bottom-dlgRect.top+(show ? 1 : - 1) * hideDiff, SWP_NOZORDER|SWP_NOMOVE); CSetDlgItemText(hDialog, IDC_BUTTON_OPTIONS, show ? "Hide Advanced" : "Show Advanced"); } /* Callback function for the Authentication Dialog box that initializes and renews tickets. */ INT_PTR CALLBACK AuthenticateProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static char principal[256]=""; static char password[256]=""; static int lifetime=0; static int renew_till=0; static int forwardable=0; static int noaddresses=0; static int proxiable=0; static int publicip=0; static LPLSH_DLGINFO_EX lpdi; static HWND hDlg=0; static HWND hSliderLifetime=0; static HWND hSliderRenew=0; static RECT dlgRect; static int hideDiff = 0; static void *pAutoComplete = 0; long realm_count = 0; int disable_noaddresses = 0; HWND hEditCtrl=0; HWND hFocusCtrl=0; BOOL bReadOnlyPrinc=0; switch (message) { case WM_INITDIALOG: hDlg = hDialog; hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL); if (hEditCtrl) pAutoComplete = Leash_pec_create(hEditCtrl); hSliderLifetime = GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE); hSliderRenew = GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE); *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam; if ((lpdi->size != LSH_DLGINFO_EX_V1_SZ && lpdi->size != LSH_DLGINFO_EX_V2_SZ && lpdi->size < LSH_DLGINFO_EX_V3_SZ) || (lpdi->dlgtype & DLGTYPE_MASK) != DLGTYPE_PASSWD) { MessageBox(hDialog, "An incorrect initialization data structure was provided.", "AuthenticateProc()", MB_OK | MB_ICONSTOP); return FALSE; } bReadOnlyPrinc = (lpdi->dlgtype & DLGFLAG_READONLYPRINC) ? TRUE : FALSE; if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { lpdi->out.username[0] = 0; lpdi->out.realm[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) { lpdi->out.ccache[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) SetWindowText(hDialog, lpdi->in.title); else SetWindowText(hDialog, lpdi->title); SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->use_defaults) { lifetime = Leash_get_default_lifetime(); if (lifetime <= 0) lifetime = 600; /* 10 hours */ if (Leash_get_default_renewable()) { renew_till = Leash_get_default_renew_till(); if (renew_till < 0) renew_till = 10800; /* 7 days */ } else renew_till = 0; forwardable = Leash_get_default_forwardable(); if (forwardable < 0) forwardable = 0; noaddresses = Leash_get_default_noaddresses(); if (noaddresses < 0) noaddresses = 0; proxiable = Leash_get_default_proxiable(); if (proxiable < 0) proxiable = 0; publicip = Leash_get_default_publicip(); if (publicip < 0) publicip = 0; } else { forwardable = lpdi->forwardable; noaddresses = lpdi->noaddresses; lifetime = lpdi->lifetime; renew_till = lpdi->renew_till; proxiable = lpdi->proxiable; publicip = lpdi->publicip; } if (lpdi->username && (strlen(lpdi->username) > 0) && lpdi->realm && (strlen(lpdi->realm) > 0)) { sprintf_s(principal, sizeof(principal), "%s@%s", lpdi->username, lpdi->realm); } else { principal[0] = 0; } Edit_SetReadOnly(hEditCtrl, bReadOnlyPrinc); CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, ""); #if 0 /* 20030619 - mjv wishes to return to the default character */ /* echo spaces */ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0); #endif /* Set Lifetime Slider * min value = 5 * max value = 1440 * current value */ SetupSlider( hDialog, IDC_SLIDER_LIFETIME, IDC_STATIC_LIFETIME_VALUE, Leash_get_default_life_min(), Leash_get_default_life_max(), lifetime ); CheckDlgButton(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL, TRUE); /* Set Forwardable checkbox */ CheckDlgButton(hDialog, IDC_CHECK_FORWARDABLE, forwardable); /* Set NoAddress checkbox */ CheckDlgButton(hDialog, IDC_CHECK_NOADDRESS, noaddresses); if ( disable_noaddresses ) EnableWindow(GetDlgItem(hDialog,IDC_CHECK_NOADDRESS),FALSE); /* Set Renewable checkbox */ CheckDlgButton(hDialog, IDC_CHECK_RENEWABLE, renew_till); /* if not renewable, disable Renew Till slider */ /* if renewable, set Renew Till slider * min value * max value * current value */ SetupSlider( hDialog, IDC_SLIDER_RENEWLIFE, IDC_STATIC_RENEW_TILL_VALUE, Leash_get_default_renew_min(), Leash_get_default_renew_max(), renew_till); if (renew_till) { EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),TRUE); } else { EnableWindow(GetDlgItem(hDialog,IDC_SLIDER_RENEWLIFE),FALSE); } // Compute sizes of items necessary to show/hide the advanced options GetWindowRect( hDialog, &dlgRect ); { RECT okRect, staticRect; GetWindowRect(GetDlgItem(hDialog,IDC_STATIC_LIFETIME),&staticRect); GetWindowRect(GetDlgItem(hDialog,IDOK),&okRect); hideDiff = okRect.top - staticRect.top; } if ( hKrb5 ) { if (Leash_get_hide_kinit_options()) AdjustOptions(hDialog,0,hideDiff); } else { AdjustOptions(hDialog,0,hideDiff); EnableWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),FALSE); ShowWindow(GetDlgItem(hDialog,IDC_BUTTON_OPTIONS),SW_HIDE); } /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, HWND_TOP, Position.x, Position.y, 0, 0, SWP_NOSIZE); else /* Center the window on the desktop */ SetWindowPos(hDialog, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2, (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2, 0, 0, SWP_NOSIZE); /* Take keyboard focus */ SetActiveWindow(hDialog); SetForegroundWindow(hDialog); /* put focus on password if princ is read-only */ hFocusCtrl = bReadOnlyPrinc ? GetDlgItem(hDialog, IDC_EDIT_PASSWORD) : hEditCtrl; if (((HWND)wParam) != hFocusCtrl) { SetFocus(hFocusCtrl); } break; case WM_HSCROLL: switch (LOWORD(wParam)) { case TB_THUMBTRACK: case TB_THUMBPOSITION: { long pos = HIWORD(wParam); // the position of the slider int ctrlID = GetDlgCtrlID((HWND)lParam); if (ctrlID == IDC_SLIDER_RENEWLIFE) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE), NewSliderString(IDC_SLIDER_RENEWLIFE,pos)); } if (ctrlID == IDC_SLIDER_LIFETIME) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE), NewSliderString(IDC_SLIDER_LIFETIME,pos)); } } break; case TB_BOTTOM: case TB_TOP: case TB_ENDTRACK: case TB_LINEDOWN: case TB_LINEUP: case TB_PAGEDOWN: case TB_PAGEUP: default: { int ctrlID = GetDlgCtrlID((HWND)lParam); long pos = SendMessage(GetDlgItem(hDialog,ctrlID), TBM_GETPOS, 0, 0); // the position of the slider if (ctrlID == IDC_SLIDER_RENEWLIFE) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_RENEW_TILL_VALUE), NewSliderString(IDC_SLIDER_RENEWLIFE,pos)); } if (ctrlID == IDC_SLIDER_LIFETIME) { SetWindowText(GetDlgItem(hDialog, IDC_STATIC_LIFETIME_VALUE), NewSliderString(IDC_SLIDER_LIFETIME,pos)); } } } break; case WM_COMMAND: switch (wParam) { case IDC_BUTTON_OPTIONS: { AdjustOptions(hDialog,Leash_get_hide_kinit_options(),hideDiff); GetWindowRect(hDialog,&dlgRect); if ( dlgRect.bottom > GetSystemMetrics(SM_CYSCREEN)) SetWindowPos( hDialog,0, dlgRect.left, GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top, 0,0, SWP_NOZORDER|SWP_NOSIZE); } break; case IDC_BUTTON_CLEAR_HISTORY: Leash_pec_clear_history(pAutoComplete); break; case IDC_CHECK_RENEWABLE: { if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) { EnableWindow(hSliderRenew,TRUE); } else { EnableWindow(hSliderRenew,FALSE); } } break; case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ID_INITTICKETS); } break; case ID_CLOSEME: { CleanupSliders(); memset(password,0,sizeof(password)); RemoveProp(hDialog, "HANDLES_HELP"); if (pAutoComplete) { Leash_pec_destroy(pAutoComplete); pAutoComplete = NULL; } EndDialog(hDialog, (int)lParam); return TRUE; } break; case IDOK: { DWORD value = 0; CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password)); if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a blank principal.", "Invalid Principal", MB_OK | MB_ICONSTOP); return TRUE; } // @TODO: parse realm portion and auto-uppercase /* if (Leash_get_default_uppercaserealm()) { // found strupr(realm); } */ if (!password[0]) { MessageBox(hDialog, "You are not allowed to enter a blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } lifetime = NewSliderValue(hDialog, IDC_SLIDER_LIFETIME); forwardable = proxiable = IsDlgButtonChecked(hDialog, IDC_CHECK_FORWARDABLE); noaddresses = IsDlgButtonChecked(hDialog, IDC_CHECK_NOADDRESS); if (IsDlgButtonChecked(hDialog, IDC_CHECK_RENEWABLE)) { renew_till = NewSliderValue(hDialog, IDC_SLIDER_RENEWLIFE); } else { renew_till= 0; } lsh_errno = Leash_int_kinit_ex( 0, hDialog, principal, password, lifetime, forwardable, proxiable, renew_till, noaddresses, publicip, 1 ); if (lsh_errno != 0) { #ifdef COMMENT char gbuf[256]; int capslock; char *cp; #endif err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: CSendDlgItemMessage(hDialog, IDC_EDIT_PRINCIPAL, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_EDIT_PRINCIPAL)); break; case LSH_INVREALM: CSendDlgItemMessage(hDialog, IDC_COMBO_REALM, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_COMBO_REALM)); break; default: CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETSEL, 0, 256); SetFocus(GetDlgItem(hDialog,IDC_EDIT_PASSWORD)); return(TRUE); } #ifdef COMMENT capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); #endif /* COMMENT */ return TRUE; } if ( Leash_get_default_preserve_kinit_settings() ) { Leash_set_default_lifetime(lifetime); if ( renew_till > 0 ) { Leash_set_default_renew_till(renew_till); Leash_set_default_renewable(1); } else { Leash_set_default_renewable(0); } Leash_set_default_forwardable(forwardable); Leash_set_default_noaddresses(noaddresses); } /* @TODO: out username/realm if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { strncpy(lpdi->out.username, username, LEASH_USERNAME_SZ); lpdi->out.username[LEASH_USERNAME_SZ-1] = 0; strncpy(lpdi->out.realm, realm, LEASH_REALM_SZ); lpdi->out.realm[LEASH_REALM_SZ-1] = 0; } */ if (IsDlgButtonChecked(hDialog, IDC_CHECK_REMEMBER_PRINCIPAL)) Leash_pec_add_principal(principal); CloseMe(TRUE); /* success */ return FALSE; } break; case IDCANCEL: CloseMe(FALSE); break; } break; case WM_MOVE: #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; } /* Callback function for the Change Password Dialog box */ INT_PTR CALLBACK NewPasswordProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam ) { static POINT Position = { -1, -1 }; static char password[256]=""; static char password2[256]=""; static char password3[256]=""; static LPLSH_DLGINFO_EX lpdi; static HWND hDlg=0; static void *pAutoComplete = NULL; char principal[256]; long realm_count = 0; HWND hEditCtrl = NULL; switch (message) { case WM_INITDIALOG: hDlg = hDialog; *( (LPLSH_DLGINFO_EX far *)(&lpdi) ) = (LPLSH_DLGINFO_EX)(LPSTR)lParam; if ((lpdi->size < LSH_DLGINFO_EX_V3_SZ && lpdi->size != LSH_DLGINFO_EX_V1_SZ && lpdi->size != LSH_DLGINFO_EX_V2_SZ) || lpdi->dlgtype != DLGTYPE_CHPASSWD) { MessageBox(hDialog, "An incorrect initialization data structure was provided.", "PasswordProc()", MB_OK | MB_ICONSTOP); return FALSE; } if ( lpdi->size >= LSH_DLGINFO_EX_V2_SZ ) { lpdi->out.username[0] = 0; lpdi->out.realm[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) { lpdi->out.ccache[0] = 0; } if ( lpdi->size >= LSH_DLGINFO_EX_V3_SZ ) SetWindowText(hDialog, lpdi->in.title); else SetWindowText(hDialog, lpdi->title); SetProp(hDialog, "HANDLES_HELP", (HANDLE)1); if (lpdi->username != NULL && (strlen(lpdi->username) > 0) && lpdi->realm != NULL && (strlen(lpdi->realm) > 0)) { sprintf_s(principal, sizeof(principal), "%s@%s", lpdi->username, lpdi->realm); } else { principal[0] = 0; } CSetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD, ""); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, ""); CSetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, ""); hEditCtrl = GetDlgItem(hDialog, IDC_EDIT_PRINCIPAL); if (hEditCtrl) pAutoComplete = Leash_pec_create(hEditCtrl); #if 0 /* 20030619 - mjv wishes to return to the default character */ /* echo spaces */ CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD, EM_SETPASSWORDCHAR, 32, 0); CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD2, EM_SETPASSWORDCHAR, 32, 0); CSendDlgItemMessage(hDialog, IDC_EDIT_PASSWORD3, EM_SETPASSWORDCHAR, 32, 0); #endif /* setup text of stuff. */ if (Position.x > 0 && Position.y > 0 && Position.x < GetSystemMetrics(SM_CXSCREEN) && Position.y < GetSystemMetrics(SM_CYSCREEN)) SetWindowPos(hDialog, 0, Position.x, Position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); else { /* Center the window on the desktop */ RECT dlgRect; GetWindowRect( hDialog, &dlgRect ); SetWindowPos(hDialog, 0, (GetSystemMetrics(SM_CXSCREEN) - dlgRect.right + dlgRect.left)/2, (GetSystemMetrics(SM_CYSCREEN) - dlgRect.bottom + dlgRect.top)/2, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } /* set window pos to last saved window pos */ break; case WM_COMMAND: switch (wParam) { case ID_HELP: { WinHelp(GetWindow(hDialog,GW_OWNER), KRB_HelpFile, HELP_CONTEXT, ID_INITTICKETS); } break; case ID_CLOSEME: { CleanupSliders(); memset(password,0,sizeof(password)); memset(password2,0,sizeof(password2)); memset(password3,0,sizeof(password3)); RemoveProp(hDialog, "HANDLES_HELP"); EndDialog(hDialog, (int)lParam); if (pAutoComplete != NULL) { Leash_pec_destroy(pAutoComplete); pAutoComplete = NULL; } return TRUE; } break; case IDOK: { DWORD value = 0; int i = 0; int bit8 = 0; CGetDlgItemText(hDialog, IDC_EDIT_PRINCIPAL, principal, sizeof(principal)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD, password, sizeof(password)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD2, password2, sizeof(password2)); CGetDlgItemText(hDialog, IDC_EDIT_PASSWORD3, password3, sizeof(password3)); if (!principal[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank username.", "Invalid Principal", MB_OK | MB_ICONSTOP); return TRUE; } if (!password[0] || !password2[0] || !password3[0]) { MessageBox(hDialog, "You are not allowed to enter a " "blank password.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } for( i = 0; i < 255; i++ ){ if( password2[i] == '\0' ){ if ( bit8 ) { MessageBox(hDialog, "Passwords should not contain non-ASCII characters.", "Internationalization Warning", MB_OK | MB_ICONINFORMATION); } i = 255; break; } else if( !isprint(password2[i]) ){ memset(password2, '\0', sizeof(password2)); memset(password3, '\0', sizeof(password3)); /* I claim these passwords in the name of planet '\0'... */ MessageBox(hDialog, "Passwords may not contain non-printable characters.", "Invalid Password", MB_OK | MB_ICONSTOP); return TRUE; } else if ( password2[i] > 127 ) bit8 = 1; } if (lstrcmp(password2, password3)) { MessageBox(hDialog, "The new password was not entered the same way twice.", "Password validation error", MB_OK | MB_ICONSTOP); return TRUE; } lsh_errno = Leash_int_changepwd(principal, password, password2, 0, 1); if (lsh_errno != 0) { #ifdef COMMENT char gbuf[256]; int capslock; char *cp; #endif /* COMMENT */ err_context = ""; switch(lsh_errno) { case LSH_INVPRINCIPAL: case LSH_INVINSTANCE: case LSH_INVREALM: break; default: return(TRUE); } #ifdef COMMENT capslock = lsh_getkeystate(VK_CAPITAL); /* low-order bit means caps lock is toggled; if so, warn user since there's been an error. */ if (capslock & 1) { lstrcpy((LPSTR)gbuf, (LPSTR)err_context); cp = gbuf + lstrlen((LPSTR)gbuf); if (cp != gbuf) *cp++ = ' '; lstrcpy(cp, "(This may be because your CAPS LOCK key is down.)"); err_context = gbuf; } // XXX DoNiftyErrorReport(lsh_errno, ISCHPASSWD ? "" // XXX : "Ticket initialization failed."); #endif /* COMMENT */ return TRUE; } Leash_pec_add_principal(principal); MessageBox(NULL, "Password successfully changed.", "Password change", MB_OK); CloseMe(TRUE); /* success */ } break; case IDCANCEL: CloseMe(FALSE); break; } break; case WM_MOVE: #ifdef _WIN32 #define LONG2POINT(l,pt) ((pt).x=(SHORT)LOWORD(l), \ (pt).y=(SHORT)HIWORD(l)) LONG2POINT(lParam,Position); #else Position = MAKEPOINT(lParam); #endif break; } return FALSE; }