You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
370 lines
10 KiB
370 lines
10 KiB
// ===========================================================================
|
|
// UAMPswdField.c © 2001 Microsoft Corp. All rights reserved.
|
|
// ===========================================================================
|
|
// Routines for managing a password field in Carbon. Carbon provides an edit
|
|
// control that acts as a great password entry box.
|
|
//
|
|
// Created by: Michael J. Conrad ([email protected])
|
|
//
|
|
// ===========================================================================
|
|
//
|
|
|
|
#include "UAMPswdField.h"
|
|
#include "UAMUtils.h"
|
|
#include "UAMEncrypt.h"
|
|
#include "UAMDialogs.h"
|
|
#include "UAMDLOGUtils.h"
|
|
#include "UAMDebug.h"
|
|
|
|
extern long gSupportedUAMs;
|
|
|
|
ControlKeyFilterUPP gKeyFilterUPP = NULL;
|
|
SInt16 gMaxPasswordLength = UAM_CLRTXTPWDLEN;
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_SetMaximumPasswordLength()
|
|
// ---------------------------------------------------------------------------
|
|
// Sets the maximum password length that the password key filter will
|
|
// allow. This function is only really necessary under carbon.
|
|
//
|
|
// Note that the allowed length is different for chaning password depending
|
|
// on the support the server offers.
|
|
//
|
|
|
|
void UAM_SetMaximumPasswordLength(
|
|
Boolean inChangingPassword
|
|
)
|
|
{
|
|
//
|
|
//If we're changing password, then the maximum password length changes
|
|
//depending on what level of support the server provides. MS2.0 auth
|
|
//is the only special case we need to check for.
|
|
//
|
|
if ((inChangingPassword) && (SUPPORTS_MS20_ONLY(gSupportedUAMs)))
|
|
{
|
|
gMaxPasswordLength = UAM_CLRTXTPWDLEN;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
//This is the default password length for all cases. Unless we're changing
|
|
//password, this will always return the correct value to use.
|
|
//
|
|
gMaxPasswordLength = (gSupportedUAMs & (kMSUAM_V2_Supported | kMSUAM_V3_Supported)) ?
|
|
UAM_MAX_LMv2_PASSWORD : UAM_CLRTXTPWDLEN;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_InitializeDialogPasswordItem()
|
|
// ---------------------------------------------------------------------------
|
|
// Initialize the dialog password edit control by setting its validation
|
|
// and key filter procs.
|
|
//
|
|
// Returns: TRUE if initialization was successful.
|
|
//
|
|
|
|
Boolean UAM_InitializeDialogPasswordItem(
|
|
DialogRef inDialog,
|
|
SInt16 inItem
|
|
)
|
|
{
|
|
OSErr theError = noErr;
|
|
|
|
#ifdef UAM_TARGET_CARBON
|
|
ControlRef theControl = NULL;
|
|
|
|
theError = GetDialogItemAsControl(inDialog, inItem, &theControl);
|
|
|
|
if ((theError != noErr) || (!IsValidControlHandle(theControl)))
|
|
{
|
|
//
|
|
//For some reason we couldn't get a handle to the control. Exit
|
|
//gracefully if possible.
|
|
//
|
|
Assert_(0);
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
//Create the universal proc ptr that will get called when validation
|
|
//is necessary. We only do this on the initial call to this func.
|
|
//
|
|
if (gKeyFilterUPP == NULL)
|
|
{
|
|
gKeyFilterUPP = NewControlKeyFilterUPP(
|
|
(ControlKeyFilterUPP)&UAM_PasswordKeyFilterProc);
|
|
|
|
if (gKeyFilterUPP == NULL)
|
|
{
|
|
DbgPrint_((DBGBUFF, "Initializing password key filter proc failed!"));
|
|
|
|
//
|
|
//Not enough memory?? Bail and tell the caller we're done.
|
|
//
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
//Now set the proc in the control by using the Set API.
|
|
//
|
|
theError = SetControlData(
|
|
theControl,
|
|
kControlNoPart,
|
|
kControlEditTextKeyFilterTag,
|
|
sizeof(ControlKeyFilterUPP),
|
|
&gKeyFilterUPP);
|
|
#else
|
|
|
|
UAM_SetBulletItem(inDialog, inItem, gMaxPasswordLength);
|
|
|
|
#endif
|
|
|
|
return(theError == noErr);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_CleanupPasswordFieldItems()
|
|
// ---------------------------------------------------------------------------
|
|
// Clean up allocated memory that we used dealing with the edit control
|
|
// passwords.
|
|
//
|
|
|
|
void UAM_CleanupPasswordFieldItems(void)
|
|
{
|
|
if (gKeyFilterUPP == NULL)
|
|
{
|
|
DisposeControlKeyFilterUPP(gKeyFilterUPP);
|
|
}
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_PasswordKeyFilterProc()
|
|
// ---------------------------------------------------------------------------
|
|
// Validate the password field whenever a key is pressed.
|
|
//
|
|
|
|
ControlKeyFilterResult
|
|
UAM_PasswordKeyFilterProc(
|
|
ControlRef inControl,
|
|
SInt16* inKeyCode,
|
|
SInt16* inCharCode,
|
|
EventModifiers* inModifiers)
|
|
{
|
|
#pragma unused(inKeyCode)
|
|
#pragma unused(inModifiers)
|
|
|
|
Size theActualLength = 0;
|
|
char theText[64];
|
|
OSErr theError;
|
|
ControlEditTextSelectionRec theSelection;
|
|
|
|
//
|
|
//Get the actual password text from the control. We don't care what the
|
|
//text is at this point, we only want it's size.
|
|
//
|
|
theError = GetControlData(
|
|
inControl,
|
|
kControlNoPart,
|
|
kControlEditTextPasswordTag,
|
|
sizeof(theText),
|
|
theText,
|
|
&theActualLength);
|
|
|
|
//
|
|
//If we got an error getting the string, then we're in big trouble.
|
|
//
|
|
if (theError != noErr)
|
|
{
|
|
Assert_(0);
|
|
return(kControlKeyFilterBlockKey);
|
|
}
|
|
|
|
//
|
|
//Here are the keystrokes that we just plain don't want to allow in
|
|
//the password edit field.
|
|
//
|
|
switch(*inCharCode)
|
|
{
|
|
case UAMKey_Escape:
|
|
case UAMKey_PageUp:
|
|
case UAMKey_PageDown:
|
|
case UAMKey_End:
|
|
case UAMKey_Home:
|
|
return(kControlKeyFilterBlockKey);
|
|
|
|
default:
|
|
//
|
|
//The key pressed is okay to pass onto the password edit field.
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
//Check and make sure the length of the password+1 is within the limits.
|
|
//
|
|
if ((theActualLength + 1) > gMaxPasswordLength)
|
|
{
|
|
//
|
|
//The additional character will make the password too long. Before we
|
|
//put up the warning, check to make sure that no text is selected that
|
|
//would be deleted upon accepting the key press.
|
|
//
|
|
|
|
theError = GetControlData(
|
|
inControl,
|
|
kControlNoPart,
|
|
kControlEditTextSelectionTag,
|
|
sizeof(theSelection),
|
|
(void*)&theSelection,
|
|
&theActualLength);
|
|
|
|
if (theError == noErr)
|
|
{
|
|
//
|
|
//If selStart != selEnd, then there is a selection and we should
|
|
//allow the key press.
|
|
//
|
|
if (theSelection.selStart != theSelection.selEnd)
|
|
{
|
|
return(kControlKeyFilterPassKey);
|
|
}
|
|
}
|
|
|
|
switch(*inCharCode)
|
|
{
|
|
case UAMKey_BackDel:
|
|
case UAMKey_FwdDel:
|
|
case UAMKey_Left:
|
|
case UAMKey_Right:
|
|
case UAMKey_Return:
|
|
case UAMKey_Enter:
|
|
break;
|
|
|
|
default:
|
|
Str32 theLengthStr;
|
|
|
|
NumToString(gMaxPasswordLength, theLengthStr);
|
|
ParamText(NULL, NULL, NULL, theLengthStr);
|
|
|
|
//
|
|
//The password is too long, so we warn the user.
|
|
//
|
|
UAM_StandardAlert(uamErr_PasswordMessage, uamErr_PasswordTooLongExplanation, NULL);
|
|
|
|
//
|
|
//Block the key from being accepted into the password buffer.
|
|
//
|
|
return(kControlKeyFilterBlockKey);
|
|
}
|
|
}
|
|
|
|
return(kControlKeyFilterPassKey);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_GetPasswordText()
|
|
// ---------------------------------------------------------------------------
|
|
// Get the text from the password edit control.
|
|
//
|
|
|
|
void UAM_GetPasswordText(DialogRef inDialog, short item, Str255 theText)
|
|
{
|
|
#ifdef UAM_TARGET_CARBON
|
|
|
|
OSErr theError;
|
|
Size theActualLength;
|
|
ControlRef theControl = NULL;
|
|
|
|
theError = GetDialogItemAsControl(inDialog, item, &theControl);
|
|
|
|
if (theError == noErr)
|
|
{
|
|
GetControlData(
|
|
theControl,
|
|
kControlNoPart,
|
|
kControlEditTextPasswordTag,
|
|
sizeof(Str255),
|
|
(char*)&theText[1],
|
|
&theActualLength);
|
|
|
|
theText[0] = (UInt8)theActualLength;
|
|
}
|
|
#else
|
|
|
|
UAM_GetBulletBuffer(inDialog, item, theText);
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_SetPasswordText()
|
|
// ---------------------------------------------------------------------------
|
|
// Set the text in a password edit control.
|
|
//
|
|
|
|
void UAM_SetPasswordText(DialogRef inDialog, short item, const Str255 theText)
|
|
{
|
|
#ifdef UAM_TARGET_CARBON
|
|
|
|
OSErr theError;
|
|
ControlRef theControl = NULL;
|
|
|
|
theError = GetDialogItemAsControl(inDialog, item, &theControl);
|
|
|
|
if (theError == noErr)
|
|
{
|
|
SetControlData(
|
|
theControl,
|
|
kControlEditTextPart,
|
|
kControlEditTextPasswordTag,
|
|
theText[0],
|
|
(void*)&theText[1]);
|
|
}
|
|
#else
|
|
|
|
UAM_SetBulletText(inDialog, item, (unsigned char*)theText);
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ¥ UAM_MakePasswordItemFocusItem()
|
|
// ---------------------------------------------------------------------------
|
|
// Makes a password item the keyboard focus item and select the text in it.
|
|
//
|
|
|
|
void UAM_MakePasswordItemFocusItem(DialogRef inDialog, SInt16 inPasswordItemID)
|
|
{
|
|
#ifdef UAM_TARGET_CARBON
|
|
OSErr theError;
|
|
ControlRef theControl = NULL;
|
|
|
|
theError = GetDialogItemAsControl(inDialog, inPasswordItemID, &theControl);
|
|
|
|
if (theError == noErr)
|
|
{
|
|
SetKeyboardFocus(GetDialogWindow(inDialog), theControl, kControlEditTextPart);
|
|
}
|
|
#else
|
|
|
|
SelectDialogItemText(inDialog, inPasswordItemID, 0, 0);
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|