Annotation of Examples/AppKit/Backspace/Password.m, revision 1.1.1.1

1.1       root        1: //  Password.m
                      2: //
                      3: // implements a simple password protocol for a small amount of security
                      4: // as a screen locker.  Can be passed in a view to animate while
                      5: // waiting for events to verify a password.  This class isn't as stand-alone
                      6: // as it might be, because it sucks its UI stuff out of a nib and relies
                      7: // on the nib for a couple of connections, but that could be fixed.
                      8: //
                      9: //  You may freely copy, distribute, and reuse the code in this example.
                     10: //  NeXT disclaims any warranty of any kind, expressed or  implied, as to its
                     11: //  fitness for any particular use.
                     12: 
                     13: 
                     14: #import "Password.h"
                     15: #import "SpaceView.h"
                     16: #import "psfuncts.h"
                     17: 
                     18: 
                     19: #import <appkit/appkit.h>
                     20: #import <pwd.h>
                     21: #import <objc/NXBundle.h>
                     22: 
                     23: 
                     24: @interface TileView:View
                     25: @end
                     26: @implementation TileView
                     27: - drawSelf:(const NXRect *)rects :(int)rectCount
                     28: {
                     29:        if (!rects || !rectCount) return self;
                     30:        NXDrawButton(&bounds, &bounds);
                     31:        return self;
                     32: }
                     33: @end
                     34: 
                     35: @implementation Password
                     36: 
                     37: static const char mess[] = "                   ";      
                     38: static const char unMess[] = "";       
                     39: static const char salt[] = "Uh";       
                     40: 
                     41: - init
                     42: {
                     43:        const char *ptr;
                     44: 
                     45:        lockEnabled = NO;
                     46: 
                     47:        ptr = NXGetDefaultValue([NXApp appName], "encryptedPassword");
                     48:        if (ptr) safe_strcpy(password, ptr);
                     49:        
                     50:        return self;
                     51: }
                     52: 
                     53: - setPassword:sender
                     54: {
                     55:        id ret;
                     56:        
                     57:        if (![self checkPassword : NXLocalString("Setting password.  Enter old password:",0,0)
                     58:                        randomPos:NO checkLock:NO withView:nil])
                     59:                return nil;
                     60: 
                     61: 
                     62:        [self attemptToSetPassword:
                     63:                NXLocalString("Enter new password:\n(NOT your account password!)",0,0)];
                     64:        safe_strcpy(attempt2, attempt1);
                     65:        [self attemptToSetPassword: NXLocalString("Reenter new password:",0,0)];
                     66: 
                     67:        if (!strcmp(attempt1, attempt2)) 
                     68:        {
                     69:                safe_strcpy(password, attempt1);
                     70:                NXWriteDefault([NXApp appName], "encryptedPassword", password);
                     71:                ret = self;
                     72:        }
                     73:        else
                     74:        {
                     75:                [[infoText cell] setStringValue:
                     76:                        NXLocalString("Error: Passwords didn't match.",0,0)];
                     77:                ret = nil;
                     78:                [self activePauseWithView:nil];
                     79:        }
                     80: 
                     81:        [window orderOut:self];
                     82:     return ret;
                     83: }
                     84: 
                     85: - attemptToSetPassword:(const char *)text
                     86: {
                     87:        if (!window) [self createWindow];
                     88:        
                     89:        [[infoText cell] setStringValue:text];
                     90:        [self orderWindowToFront];
                     91: 
                     92:        [NXApp runModalFor:window];
                     93: 
                     94:        //hey!  I didn't want runmodal to put my window away!
                     95:        [self orderWindowToFront];
                     96: 
                     97:        safe_strcpy(attempt1, 
                     98:                (const char *)(crypt((char *)[[clearText cell] stringValue],
                     99:                (char *)salt)));
                    100:        [[clearText cell] setStringValue: mess];
                    101:        [[clearText cell] setStringValue: unMess];
                    102: 
                    103:     return self;
                    104: }
                    105: 
                    106: - userTypedReturn:sender
                    107: {
                    108:        [NXApp stopModal];
                    109:     return self;
                    110: }
                    111: 
                    112: - (BOOL) checkPassword:(const char *)text randomPos:(BOOL)random 
                    113:        checkLock:(BOOL)check withView:aView
                    114: {
                    115:        BOOL ret;
                    116:     NXModalSession session;
                    117:        BStimeval timeout = currentTimeInMs() + 6000;
                    118:        
                    119:        // we check lock to pass if the screen is locked
                    120:        // otherwise we always want to verify password
                    121:        if ((!lockEnabled && check) || !password[0]) return YES;
                    122:        
                    123:        // here I allow passage if password has been typed in last 6 seconds
                    124:        // NOT! I seem to have had some problems with time wrapping, I nixed this for security
                    125:        // if (currentTimeInMs() < (lastPasswordTime + 6000)) return YES;
                    126:        
                    127:        if (!window) [self createWindow];
                    128: 
                    129:     [NXApp beginModalSession:&session for:window];
                    130: 
                    131:        [[infoText cell] setStringValue:text];
                    132:        
                    133:        if (random) [self randomWindowPosition];
                    134:        else [window center];
                    135:        [self orderWindowToFront];
                    136: 
                    137:     for (;;) {
                    138:         if ([NXApp runModalSession:&session] != NX_RUNCONTINUES)
                    139:             break;
                    140:                        
                    141:                if (currentTimeInMs() > timeout) break;
                    142: 
                    143:                if (aView)
                    144:                {
                    145:                        [aView lockFocus];
                    146:                        if ([aView respondsTo:@selector(didLockFocus)]) 
                    147:                                [aView didLockFocus];
                    148:                        [aView oneStep];
                    149:                        [[aView window] flushWindow];
                    150:                        NXPing ();      // Synchronize postscript for smoother animation
                    151:                        [aView unlockFocus];
                    152:                }
                    153:     }
                    154: 
                    155:        ret = (!strcmp(password, 
                    156:                (crypt((char *)[[clearText cell] stringValue], (char *)salt))));
                    157: 
                    158:        // on BackSpace password failure, try user password
                    159:        if (!ret)
                    160:        {
                    161:                struct passwd *pwen = getpwuid( getuid() );
                    162:                ret = (!strcmp(pwen->pw_passwd,
                    163:                        (crypt((char *)[[clearText cell] stringValue], pwen->pw_passwd))));
                    164:        }
                    165: 
                    166:        // on user password failure, try root password (only if there is one)
                    167:        if (!ret)
                    168:        {
                    169:                struct passwd *pwen = getpwuid(0);
                    170:                if (strlen(pwen->pw_passwd) == 0) ret = 0;
                    171:                else ret = (!strcmp(pwen->pw_passwd,
                    172:                        (crypt((char *)[[clearText cell] stringValue], pwen->pw_passwd))));
                    173:        }
                    174: 
                    175:        [[clearText cell] setStringValue: mess];
                    176:        [[clearText cell] setStringValue: unMess];
                    177: 
                    178: 
                    179: 
                    180:        // did we get a valid password?
                    181:        if (!ret)
                    182:        {
                    183:                [[infoText cell] setStringValue:
                    184:                        NXLocalString("Error: Incorrect password.",0,0)];
                    185:                [self activePauseWithView:aView];
                    186:        }
                    187:        else
                    188:        {
                    189:                lastPasswordTime = currentTimeInMs();
                    190:        }
                    191:        
                    192:        [window orderOut:self];
                    193:        [window center];
                    194:        
                    195:     [NXApp endModalSession:&session];
                    196: 
                    197:        // this display shouldn't be necessary, but is to ensure timely
                    198:        // redraw of a nonretained window.  It looks yucky, though.
                    199:        // really should just display area uncovered by panel
                    200:        [aView display];
                    201:        return ret;
                    202: }
                    203: 
                    204: - orderWindowToFront
                    205: {
                    206:        [clearText selectText:self];
                    207:        [window display];
                    208: 
                    209:        // make password window float over everything
                    210:        PSsetwindowlevel((SAVERTIER+1), [window windowNum]);
                    211: 
                    212:        [window makeKeyAndOrderFront:self];
                    213:        return self;
                    214: }
                    215: 
                    216: - randomWindowPosition
                    217: {
                    218:        NXRect r;
                    219:        NXSize s;
                    220:        NXPoint p;
                    221:        [NXApp getScreenSize:&s];
                    222:        [window getFrame:&r];
                    223:        p.x = floor(randBetween(0, s.width - r.size.width));
                    224:        p.y = floor(randBetween(0, s.height - r.size.height));
                    225:        
                    226:        [window moveTo: p.x :p.y];
                    227: 
                    228:        return self;
                    229: }
                    230: 
                    231: 
                    232: - createWindow
                    233: {
                    234:        NXRect r;
                    235:        id tileView;
                    236:        
                    237:        [contentBox getFrame:&r];
                    238:        r.origin.x = r.origin.y = 8;
                    239:        [contentBox setFrame:&r];
                    240:        r.size.width += 16;
                    241:        r.size.height += 16;
                    242:        
                    243:        window = [[Window alloc]
                    244:                        initContent:&r style:NX_PLAINSTYLE
                    245:                        backing:NX_BUFFERED buttonMask:0 defer:NO];
                    246: 
                    247:        [window center];
                    248:        tileView = [[TileView alloc] init];
                    249:        
                    250:        [contentBox removeFromSuperview];               //not really necessary
                    251:        [[window setContentView:tileView] free];
                    252:        [tileView addSubview:contentBox];
                    253: 
                    254:        [window useOptimizedDrawing:YES];
                    255:        [window display];
                    256:        
                    257:        return self;
                    258: }
                    259: 
                    260: - activePauseWithView:aView
                    261: {
                    262:        BStimeval done;
                    263:        
                    264:        [window display];
                    265:        NXPing();
                    266:        done = currentTimeInMs() + 1500;
                    267:        if (aView)
                    268:        {
                    269:                [aView lockFocus];
                    270:                if ([aView respondsTo:@selector(didLockFocus)]) [aView didLockFocus];
                    271: 
                    272:                do {
                    273:                        [aView oneStep];
                    274:                        [[aView window] flushWindow];
                    275:                        NXPing ();      // Synchronize postscript for smoother animation
                    276:                   } while (currentTimeInMs() < done);
                    277:                   
                    278:                [aView unlockFocus];
                    279:        }
                    280:        else usleep(1500000);
                    281:        return self;
                    282: }
                    283: 
                    284: - setLock:(BOOL)flag;
                    285: {
                    286:        lockEnabled = flag;
                    287:        return self;
                    288: }
                    289: 
                    290: - (BOOL) isLocked
                    291: {
                    292:        return lockEnabled;
                    293: }
                    294: 
                    295: - (BOOL) validPassword
                    296: {
                    297:        if (password[0]) return YES;
                    298:        return NO;
                    299: }
                    300: 
                    301: // this function just protects me from overrunning to, which 
                    302: // is assumed to always be of length LEN
                    303: void safe_strcpy(char *to, const char *from)
                    304: {
                    305:        if (strlen((char *)from) < LEN) strcpy(to,(char *)from);
                    306:        else strncpy(to,(char *)from,(LEN-1));
                    307: }
                    308: 
                    309: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.