[comp.sys.mac.programmer] Password a'la AppleShare

newsuser@LTH.Se (LTH network news server) (05/16/89)

Hello!

I want to make a login dialog with username and a password.
The password should be protected by exchanging characters to 
"*" or similar, like the AppleShare login. How should this be
done? 

o  Changing the DialogRecord.textH.txFont when the user
   enters the password field does not work when the dialog needs
   an update.

o  Exchanging characters with * in a filterproc and handling the 
   string updates myself?

o  Useritem which consists of a textrecord on its own?

Or is there any easier way?

/Thanks Joakim 

-- 
Joakim Bengtson                      Internet: joakim_b@ldc.lu.se
Lund University Computing Center     Bitnet:   joakim_b@seldc52
Box 783                              Telefax:  +46 46 138225
S - 220 07 Lund  Sweden              Telex:    33533 LUNIVER S

blob@apple.com (Brian Bechtel) (05/17/89)

I kept this code from the last time that this question was asked.
>From: matthews@eleazar.dartmouth.edu (Jim Matthews)
>Subject: Re: suppress display of password entry

In article <536@sdacs.ucsd.EDU> wade@sdacs.ucsd.EDU (Wade Blomgren) writes:
>
>What is the best (easiest) way to allow entry of a password on the screen
>while suppressing the display of the actual characters in the 
>edittext item? 

It actually isn't very difficult to intercept the key events and keep 
a hidden copy of the password string.  It isn't necessary to remember
any context since you have access to the TextEdit record, and it tells
you what the current selection is.  The following routine is a filter
for a name/password dialog box.  It displays bullets (ala AppleShare)
and stores the real password in a global string, pwStr.  It also handles
hitting return or enter.

{ signonFilter -- dialog filter for doSignon, hides password }
FUNCTION signonFilter (dp : DialogPtr;
            VAR theEvent : EventRecord;
            VAR itemHit : integer) : boolean;
    CONST
        nameItem = 3;
        passwordItem = 4;
        bs = $08;
        tab = $09;
        cr = $0D;
        enter = $03;
        larrow = $1C;
        rarrow = $1D;
        uparrow = $1E;
        downarrow = $1F;
    VAR
        dpeek : DialogPeek;
        theChar : char;
        theStr : Str255;
        selStart, selEnd : integer;
        h : Handle;
        itemType : integer;
        box : Rect;
BEGIN
    signonFilter := false;
    dpeek := DialogPeek(dp);
    IF ((theEvent.what = keydown) OR (theEvent.what = autoKey)) THEN
        IF (dpeek^.editField = passwordItem - 1) THEN
        BEGIN
            theChar := char(BitAnd(theEvent.message, charCodeMask));
            selStart := dpeek^.textH^^.selStart;
            selEnd := dpeek^.textH^^.selEnd;
            CASE ord(theChar) OF
                bs :                { Backspace }
                    BEGIN
                        IF selEnd = selStart THEN  { back over a character 
}
                        BEGIN
                            IF selStart > 0 THEN
                                pwStr := concat(copy(pwStr,1, selStart - 
1),
                                                  copy(pwStr, selStart + 1,
                                                   length(pwStr) - 
selStart));
                        END
                        ELSE            { delete the selection }
                            pwStr := concat(copy(pwStr, 1, selStart),
                             copy(pwStr, selEnd + 1,
                                   length(pwStr) - selEnd));
                    END;
                cr, enter :     { Return or Enter -- treat as "OK }
                    BEGIN
                        itemHit := ok;
                        signonFilter := true;
                    END; { cr, enter }
                tab, uparrow, downarrow, rarrow, larrow :
                    ;     { just pass on tabs & arrows }
                OTHERWISE   { "normal" character }
                    BEGIN        { remember character, insert a bullet }
                        pwStr := concat(copy(pwStr, 1, selStart),
                         theChar,
                         copy(pwStr, selEnd + 1, length(pwStr) - selEnd));
                        theEvent.message :=
                         BitAnd(theEvent.message, $FFFFFF00) + ord('%');
                    END; { normal character }
            END; { case ord(theChar) of }
        END { in password field }
        ELSE     { not in password field -- still check for cr, enter }
            CASE BitAnd(theEvent.message, charCodeMask) OF
                cr, enter :
                    BEGIN
                        itemHit := ok;
                        signonFilter := true;
                    END; { cr, enter }
                OTHERWISE
                    ;
            END; { case BitAnd }
END; { signonFilter }


--Brian Bechtel     blob@apple.com     "My opinion, not Apple's"