.TITLE USER User subroutines .NLIST BEX .ENABL LC ; ; User subroutines ; ; External symbols ; .GLOBL BLDKS,ENCRYP ;des encryption routines .GLOBL TYPE ;determine char type .GLOBL ASG ;assign logical channel ; ; Entry symbols ; .GLOBL LOGIN ;log user on system .GLOBL LOGOUT ;log user off system .GLOBL CONECT ;connect to user directory ; ; System definitions ; .ASECT .MCALL .COM,.CHR,.PSA,.CLP,.IOD,.SMF,.LGD ;dcnlib definitions .MCALL .PSEM,.VSEM ;dcnlib macros .MCALL .GVAL,.PURGE,.LOOKU,.READW,.WRITW ;rt-11 macroni .MCALL .DATE,.GTIM .MCALL CALL ;netlib macroni .COM ;define common data .CHR ;define ascii character codes .PSA ;define psa and par areas .CLP ;define rt-11 monitor area extension .IOD ;emulator monitor area extension .SMF ;define semaphore ids .LGD ;define login file entry ; ; Module definitions ; ; Return codes ; ER.OK = 0 ;normal return ER.DIR = 1 ;directory not found ER.ERR = 2 ;login file error ER.USE = 3 ;login incorrect ER.NLI = 4 ;not logged in ; ; Assembly parameters ; CHN = 14. ;login file channel ; ; Stack frame area (us) ; . = 0 US.ARG: .BLKW 5 ;rt-11 argument block US.CON: .BLKW 1 ;configuration word US.BLK: .BLKW 1 ;login file block US.KEY: .BLKB 16.+8. ;login file search key US.FLG: .BLKB 1 ;temp .EVEN US.LEN: .BLKW 6 ;register save area US.USE: .BLKW 1 ;pointer to user id string US.PAS: .BLKW 1 ;pointer to password string US.PRO: .BLKW 1 ;pointer to profile string ; ; Procedure segment ; .PSECT $BOSI,RO,I ; ; LOGIN (log) log user on system ; ULP/C calling sequence: code = login( &userid, &passwd, &profil) ; code (see above) ; userid user id from login file ; passwd password from login file (or zero to ignore) ; profil profile (copied from login file) ; LOGIN: MOV R1,-(SP) ;ulp/c entry MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) SUB #US.LEN,SP MOV SP,R5 CALL LOGOUT,#0 ;log user out (just in case) JSR PC,USER ;find login file entry MOV US.PRO(R5),R1 ;is profile specified BEQ 2$ ;branch if no MOV R4,R0 ;yes. copy info fields MOV #LF.LEN,R2 1$: MOVB (R0)+,(R1)+ SOB R2,1$ 2$: MOVB LF.FLG(R4),US.FLG(R5) ;fiddle bits CLRB LF.FLG(R4) .DATE ;update timestamp MOV R0,LF.DAT(R4) MOV R4,R1 ADD #LF.TIM,R1 .GTIM R5,R1 .WRITW R5,#CHN,#FILBUF,#256.,US.BLK(R5) ;update login file BCC 3$ ;branch if ok MOV #ER.ERR,R0 ;login file error JMP USE20 ; 3$: .PURGE #CHN ;forget that channel MOV R4,R1 ;assign user directory ADD #LF.DIR,R1 .LOOKU R5,#CHN,R1 BCS 4$ ;branch if error CALL ASG,LOGNAM,#CHN ;assign directory TST R0 BEQ 5$ ;branch if ok 4$: MOV #ER.DIR,R0 ;directory not found JMP USE20 ; 5$: BIT #FUZZY$,US.CON(R5) ;is this a fuzzball BEQ 7$ ;branch if no MOV @#SYSPTR,R1 ;yes. insert capability keys MOVB US.FLG(R5),IOHCAP(R1) BISB #AF.LOG,IOHCAP(R1) ADD #IOHUSR,R1 ;insert userid MOV R4,R0 ADD #LF.USE,R0 MOV #16.,R2 6$: MOVB (R0)+,(R1)+ SOB R2,6$ 7$: CLR R0 ;normal exit JMP USE20 ; ; LOGOUT (log) log user off system ; ULP/C calling sequence: code = logout( &userid) ; code (see above) ; userid user id (if logged on) ; LOGOUT: MOV R1,-(SP) ;ulp/c entry MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) SUB #US.LEN,SP MOV SP,R5 .GVAL R5,#CONFIG ;get configuration word MOV R0,US.CON(R5) BIT #FUZZY$,US.CON(R5) ;is this a fuzzball BEQ 1$ ;branch if no MOV @#SYSPTR,R2 ;yes. is user logged on BITB #AF.LOG,IOHCAP(R2) BEQ 3$ ;branch if no CLRB IOHCAP(R2) ;yes. assign user directory MOV R2,R1 ADD #IOHUSR,R1 CALL CONECT,R1,#0,#AF.LGO TST R0 BNE 3$ ;branch if error MOV US.USE(R5),R0 ;is userid specified BEQ 1$ ;branch if no 2$: MOVB (R1)+,(R0)+ ;yes. copy that BNE 2$ CLRB IOHUSR(R2) 1$: CALL CONECT,#0,#0,#0 ;assign default directory JMP USE21 ; 3$: MOV #ER.NLI,R0 ;not logged in JMP USE21 ; ; CONECT (con) connect to user directory ; ULP/C calling sequence: code = conect( &userid, &passwd, &flags) ; code (see above) ; userid user id from login file ; passwd password from login file (or zero to ignore) ; flags flags to set in profile ; CONECT: MOV R1,-(SP) ;ulp/c entry MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) SUB #US.LEN,SP MOV SP,R5 TST US.USE(R5) ;is userid specified BEQ 1$ ;branch if no JSR PC,USER ;yes. find login file entry MOVB US.PRO(R5),R0 ;are flags waving BEQ 2$ ;branch if no BISB R0,LF.FLG(R4) ;yes. update login file entry .WRITW R5,#CHN,#FILBUF,#256.,US.BLK(R5) BCC 2$ ;branch if ok MOV #ER.ERR,R0 ;login file error BR USE20 ; 1$: .LOOKU R5,#CHN,#WRKDEV ;assign default directory CALL ASG,LOGNAM,#CHN TST R0 BEQ USE21 ;branch if ok MOV #ER.DIR,R0 ;directory not found BR USE21 ; 2$: .PURGE #CHN ;forget that channel MOV R4,R1 ;assign user directory ADD #LF.DIR,R1 .LOOKU R5,#CHN,R1 CALL ASG,LOGNAM,#CHN TST R0 BEQ USE20 ;branch if ok MOV #ER.DIR,R0 ;directory not found ; ; Common exit linkage ; USE20: MOV R0,R2 ;save return code .PURGE #CHN ;don't leave channel lying around BIT #FUZZY$,US.CON(R5) ;is this a fuzzball BEQ 1$ ;branch if no .VSEM #SF.PFL ;yes. unlock login file 1$: MOV R2,R0 ;fetch return code USE21: MOV R5,SP ;ulp/c exit ADD #US.LEN,SP MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RTS PC ; ; Subroutine to find entry in login file ; Returns r4 = entry pointer for c(cc) = 0, r0 = error code if c(cc) = 1 ; USER: .GVAL R5,#CONFIG ;get configuration word MOV R0,US.CON(R5) BIT #FUZZY$,US.CON(R5) ;is this a fuzzball BEQ 1$ ;branch if no .PSEM #SF.PFL ;yes. lock login file 1$: CALL BLDKS,#KEYSKD,#KEY ;build key schedule MOV R5,R1 ;initialize search key ADD #US.KEY,R1 MOV #16.+8.,R2 2$: CLRB (R1)+ SOB R2,2$ MOV US.USE(R5),R1 ;is userid argument present BEQ 4$ ;branch if no MOV R5,R2 ;yes. copy and edit userid ADD #US.KEY,R2 MOV #15.,R3 3$: MOVB (R1)+,R0 JSR PC,TYPE BEQ 4$ MOVB R0,(R2)+ SOB R3,3$ 4$: MOV US.PAS(R5),R1 ;is password argument present BEQ USE40 ;branch if no MOV R5,R2 ;yes. copy and edit password ADD #US.KEY+16.,R2 MOV #8.,R3 5$: MOVB (R1)+,R0 JSR PC,TYPE BEQ USE40 MOVB R0,(R2)+ SOB R3,5$ USE40: MOV R5,R2 ;encrypt password ADD #US.KEY+16.,R2 CALL ENCRYP,R2,#KEYSKD .PURGE #CHN ;open login file .LOOKU R5,#CHN,#LOGFIL BCS 2$ ;branch if error CLR US.BLK(R5) ;search login file 1$: .READW R5,#CHN,#FILBUF,#256.,US.BLK(R5) ;read next block BCC 5$ ;branch if ok TSTB @#ERRBYT ;error. is it eof BEQ 3$ ;branch if yes 2$: MOV #ER.ERR,R0 ;login file error JMP USE20 ; 3$: MOV #ER.USE,R0 ;login incorrect JMP USE20 ; 5$: MOV #FILBUF,R4 ;scan block for userid/password 6$: TSTB @R4 ;is file done BEQ 3$ ;branch if yes CMP R4,#FILBUF+512. ;is block done BLO 7$ ;branch if no INC US.BLK(R5) ;yes. go read next block BR 1$ ; 9$: ADD #LF.LEN,R4 ;advance to next entry BR 6$ ; 7$: MOV R4,R2 ;compare user id MOV R5,R1 ADD #US.KEY,R1 MOV #16.,R3 TST US.PAS(R5) ;is password required BEQ 8$ ;branch if no ADD #8.,R3 ;yes. compare entire string 8$: CMPB (R1)+,(R2)+ ;does entry match BNE 9$ ;branch if no SOB R3,8$ RTS PC ;yes. normal exit ; ; Data segments ; .PSECT $BOSD,RO,D ; LOGFIL: .RAD50 'SY LOGIN DAT' ;name of login file LOGNAM: .RAD50 'DK ' ;logical directory name WRKDEV: .RAD50 'SY ' ;default work device KEY: .ASCII 'FUZZBALL' ;des key .EVEN ; .PSECT $ERAS,RW,I ; FILBUF: .BLKW 256. ;login file buffer KEYSKD: .BLKB 16.*8. ;des key schedule .EVEN ; .END