Trailing-Edge
-
PDP-10 Archives
-
decuslib10-13
-
pswchk.mac
There is 1 other file named pswchk.mac in the archive. Click here to see a list.
title pswchk
;Program to analyze a TOPS-10 accounting file
;in order to find badly chosen passwords
;for additional information about this program contact:
; Dr. Edmund West
; Computing Services (MP331)
; 255 Huron St.
; University of Toronto
; Toronto, Ontario, Canada M5S 1A1
; (telephone: 416-978-4085)
;the author would also appreciate receiving additional ideas
;which could be included in later versions of the program.
search glxmac,ornmac
prolog (pswchk)
parset
;version information
pswver==1
pswmin==0
pswwho==0
pswedt==0
loc 137
vrsn. (psw)
reloc 0
;assembly options
nd a$rc.l,16 ;accounting file record length
;default switch values
nd d%encrypt,-1 ;passwords are encrypted
nd d%accname,-1 ;check accounting name formats
nd d%logname,-1 ;check login name formats
nd d%ppn,-1 ;check ppn formats
nd d%words,-1 ;check selected passwords
subttl macro definitions
;list of possible passwords to be tested by routine "words"
define pswlst<
X <> ;blank (ie, no password)
X ABC
X ABCD
X ABCDE
X ABCDEF
X FEDCBA
X EDCBA
X DCBA
X CBA
X UVW
X UVWX
X UVWXY
X UVWXYZ
X VWXYZ
X WXYZ
X XYZ
X ZYX
X ZYXW
X ZYXWV
X ZYXWVU
X YXWVU
X XWVU
X WVU
X 123
X 1234
X 12345
X 123456
X 654321
X 54321
X 4321
X 321
X LGN
X LOG
X LOGI
X LOGIN
X PASS
X PASSW
X PASSWO
X PASSWD
X PASWRD
X PSW
X PSWD
X PSWRD
X PSWORD
X WORD
X WRD
X SYS
X SYST
X SYSTE
X SYSTEM
X TEST
X TESTS
X TESTER
X EXAMPL
X EXAMP
X EXAM
X LOCK
X SECRET
X FAILSA
X MAINT
X DAEMON
X DEMON
X DEMONS
X DEC
X DEC10
X DEC-10
X 1090
X DECSWS
X SWS
>;end of pswlst macro
;special macros
define $trett<jumpt .rett> ;if true, return true
define $fretf<jumpf .retf> ;if false, return false
;constants
nd pdll,100 ;push down list length
nd a.byt,^d36 ;byte size of accounting file
nd r.byt,7 ;byte size of report file
nd slash,ascii\/\ ;slash (left justified)
subttl data structures
prompt: asciz\PSWCHK>\ ;command prompt
eqlstr: asciz\= \ ;equal is delimiter
iflspc: asciz\STD:ACCT.SYS\ ;input (accounting) file specification
oflspc: asciz\DSK:PSWCHK.RPT\ ;output (report) file specification
ifd%df: xwd fdmsiz,5 ;default input file descriptor
sixbit \STD\
sixbit \ACCT\
sixbit \SYS\
exp 0
ofd%df: xwd fdmsiz,5 ;default output file descriptor
sixbit \DSK\
sixbit \PSWCHK\
sixbit \RPT\
exp 0
$data pdl,pdll ;push down list
$data ib,ib.sz ;initialization buffer
$data pab,par.sz ;parser argument block
$data a$ifn ;accounting file index
$data r$ifn ;report file index
$data reccnt ;record counter
$data mchcnt ;count of matched passwords
$data prj6bt ;project number in sixbit
$data prg6bt ;programmer number in sixbit
$data ppn6bt ;ppn in sixbit
$data nam6bt ;accounting name in sixbit
$data pswold ;previous password candidate
$data outpnt ;points to output routine for glxlib
;data set up by command parser
$data fl$encrypt ;flag for encryption
$data fl$word ;flag for special word test
$data fl$ppn ;flag for ppn test
$data fl$accname ;flag for accounting name test
$data fl$logname ;flag for login name test
;data read from accounting file
$data a$rec,a$rc.l ;accounting file record
nd ppn,a$rec ;project programmer number
nd psw,a$rec+1 ;password (encrypted)
nd nm6bt1,a$rec+3 ;name, chars 1-6
nd nm6bt2,a$rec+4 ;name, chars 7-12
a$fob: exp a$fd ;acct.sys file open block
exp a.byt ;byte size
nd a$fo.l,.-a$fob
a$fd: block fdxsiz ;accounting file descriptor
nd a$fd.l,.-a$fd
r$fob: exp r$fd ;report file open block
exp r.byt ;byte size
nd r$fo.l,.-r$fob
r$fd: block fdxsiz ;report file descriptor
nd r$fd.l,.-r$fd
pswmsk: ;table of password masks
maskb(0,3*6-1) ;3 characters
maskb(0,4*6-1) ;4 characters
maskb(0,5*6-1) ;5 characters
maskb(0,6*6-1) ;6 characters
nd msk.l,.-pswmsk ;length of password mask table
subttl text fields
initxt: itext < Password check beginning at ^H/[-1]/
Report file is ^F/r$fd/
Examining file ^F/a$fd/
Switches are: ^A>
fintxt: itext < Password check finished at ^H/[-1]/^M^J ^D/mchcnt/ matches found in ^D/reccnt/ accounts^M^J>
hdrtxt: itext <
PPN User Name Type Password
>
fndtxt: itext < ^P15L/ppn/ ^W6L/nm6bt1/^W6L/nm6bt2/ ^T10L/@t1/^W6L/p1/>
subttl parsing tables
confrm: $crlf
cmdpdb: $init(rptpdb)
rptpdb: $ofile(eqlpdb,<report file specification>,<$pdefault(oflspc),$alternate(eqlpdb)>)
eqlpdb: $token(accpdb,<=>,<$pdefault(eqlstr),$alternate(swtpdb)>)
accpdb: $ifile(swtpdb,<accounting file specification>,<$pdefault(iflspc),$alternate(swtpdb)>)
swtpdb: $switch(,swttbl,<$action(shrswt),$alternate(confrm)>)
swttbl: $stab
dsptab(next(swtpdb),w$accname,<accname>)
dsptab(next(swtpdb),w$all,<all>)
dsptab(next(swtpdb),w$encrypt,<encrypt>)
dsptab(next(swtpdb),w$logname,<logname>)
dsptab(next(swtpdb),w$noaccname,<noaccname>)
dsptab(next(swtpdb),w$noencrypt,<noencrypt>)
dsptab(next(swtpdb),w$nologname,<nologname>)
dsptab(next(swtpdb),w$none,<none>)
dsptab(next(swtpdb),w$noppn,<noppn>)
dsptab(next(swtpdb),w$nowords,<nowords>)
dsptab(next(swtpdb),w$ppn,<ppn>)
dsptab(next(swtpdb),w$words,<words>)
$etab
subttl pswchk - main program
;initialization section
pswchk:
jfcl ;no ccl
reset ;reset the world
move p,[iowd pdll,pdl] ;set up stack pointer
movx s1,it.oct ;open command terminal for parser
movem s1,ib+ib.flg
move s1,[sixbit\pswchk\] ;name of program
movem s1,ib+ib.prg ;into init block
movx s1,ib.sz ;size of initialization block
movx s2,ib ;address of initialization block
$call i%init ;initialize glxlib
jumpf [outstr [asciz\? PSWCHK Cannot initialize GLXLIB\]
$call i%exit] ;quit on init failure
setzb s1,s2 ;clear args
$call p$init ;initialize parser
jumpf [$fatal(cannot initialize parser)]
cmd: ;here to process commands
$call getcmd ;get input command
jumpf pswchk ;try again
setzm reccnt ;clear record counter
setzm mchcnt ;clear match counter
$call ttyhead ;output header on tty
;open report file for output
movx s1,r$fo.l ;length of block
movx s2,r$fob ;address of block
$call f%oopn ;open file for output
jumpf [$warn(Cannot open report file ^F/r$fd/)
jumpa pswchk] ;quit on open error
movem s1,r$ifn ;save ifn for file
$call rpthead ;output report header
$text (rptout,<^M^J^I/hdrtxt/>)
move s1,r$ifn ;select report file
$call f%chkp ;checkpoint it
jumpf [$warn(Cannot checkpoint report file header)
jumpa pswchk] ;quit on error
;open accounting file for input
movx s1,a$fo.l ;length of block
movx s2,a$fob ;address of block
$call f%iopn ;open file for input
jumpf [$warn(Cannot open accounting file ^F/a$fd/)
jumpa pswchk] ;quit on error
movem s1,a$ifn ;save ifn for file
;read first word of accounting file to confirm record size
move s1,a$ifn ;get ifn for accounting file
$call f%ibyt ;read first byte
jumpf [$warn(Cannot read accounting file record)
jumpa pswchk] ;quit on error
hrrzs s2 ;extract record size from file
caxe s2,a$rc.l ;is it correct?
jumpa [$warn(Accounting record size does not match)
jumpa pswchk] ;quit on error
;this is the main loop of program
loop: ;main io loop
$call rdrec ;read record from accounting file
jumpf rderr ;if error, process it
skipn ppn ;is this ppn=0,,0?
jumpa loop ;yes, ignore it
aos reccnt ;increment record counter
$call check ;check this account
jumpf loop ;if no match, get the next one
$call found ;found a match, report it
jumpf pswchk ;if error, give up
jumpa loop ;get the next ppn
rderr: ;here if error reading the file
caxe s1,ereof$ ;is it an eof?
jumpa [$warn(Cannot read accounting file)
jumpa pswchk] ;no, a real error
;here to proceed with normal termination
$text (rptout,<^M^J^I/fintxt/>)
move s1,r$ifn ;report file index
$call f%rel ;close and release the file
jumpf [$warn(Error closing report file)
jumpa pswchk] ;quit on error
move s1,a$ifn ;account file index
$call f%rel ;close and release the file
jumpf [$warn(Error closing accounting file)
jumpa] ;quit on error
$text (t%tty,<^M^J^I/fintxt/>)
jumpa pswchk ;try again
subttl header output routines
ttyhead:
movei s1,t%tty ;address of terminal output routine
movem s1,outpnt ;point to it
jumpa outhead ;output the header
rpthead:
movei s1,rptout ;address of terminal output routine
movem s1,outpnt ;point to it
jumpa outhead ;output the header
outhead:
$text (@outpnt,<^M^J^I/initxt/>)
move s1,[asciz\/NO\]
skipe fl$encrypt
movsi s1,(slash)
$text (@outpnt,< ^T/s1/ENCRYPT^A>)
move s1,[asciz\/NO\]
skipe fl$words
movsi s1,(slash)
$text (@outpnt,< ^T/s1/WORDS^A>)
move s1,[asciz\/NO\]
skipe fl$accname
movsi s1,(slash)
$text (@outpnt,< ^T/s1/ACCNAME^A>)
move s1,[asciz\/NO\]
skipe fl$logname
movsi s1,(slash)
$text (@outpnt,< ^T/s1/LOGNAME^A>)
move s1,[asciz\/NO\]
skipe fl$ppn
movsi s1,(slash)
$text (@outpnt,< ^T/s1/PPN^A>)
$text (@outpnt,<^M^J>)
$ret
subttl getcmd - prompt user and process the command
getcmd:
move s1,[xwd ofd%df,r$fd] ;copy default output file spec
blt s1,r$fd+fdmsiz-1
move s1,[xwd ifd%df,a$fd] ;copy default input file spec
blt s1,a$fd+fdmsiz-1
ifn d%encrypt,< setom fl$encrypt ;set encrypt flag>
ife d%encrypt,< setzm fl$encrypt ;clear encrypt flag>
ifn d%words,< setom fl$words ;set words flag>
ife d%words,< setzm fl$words ;clear words flag>
ifn d%ppn,< setom fl$ppn ;set ppn flag>
ife d%ppn,< setzm fl$ppn ;clear ppn flag>
ifn d%accname,< setom fl$accname ;set accounting name flag>
ife d%accname,< setzm fl$accname ;clear accounting name flag>
ifn d%logname,< setom fl$logname ;set login name flag>
ife d%logname,< setzm fl$logname ;clear login name flag>
movei s1,cmdpdb ;top of command tree
movem s1,pab+par.tb
movei s1,prompt ;address of prompt string
movem s1,pab+par.pm
setzm pab+par.sr ;clear to read from tty
movx s1,par.sz ;parser argument block pointers
movei s2,pab
$call parser## ;parse the command
move t1,s2 ;save parser return block pointer
jumpf [move s1,prt.fl(t1) ;in case of error
txnn s1,p.erro ;was it bad syntax?
$fatal(unexpected error return from PARSER) ;no, bad trouble
$warn(^T/@prt.em(t1)/) ;yes, tell him
jumpa getcmd] ;and try again
move s1,prt.cm(t1) ;address of parsed data
addi s1,com.sz ;address of parser block
$call p$setu ;set up for scanning the input
getpbk:
$call p$curr ;get current parser block
jumpe s1,[$warn(error return from P$CURR) ;legal address?
$retf] ;no, quit
hrrz s1,pfd.hd(s1) ;get data type
cain s1,.cmswi ;is it a switch?
jumpa getswt ;yes
cain s1,.cmifi ;no, is it an input file?
jumpa getifl ;yes
cain s1,.cmofi ;no, is it an output file?
jumpa getofl ;yes
cain s1,.cmtok ;no, is it a token?
jumpa gettok ;yes
cain s1,.cmcfm ;no, is it a confirm?
jumpa getcfm ;yes
$warn(unexpected data type (^O/s1/) returned from P$CURR)
$retf
gettok: ;process a token
$call p$tok ;read the token
jumpf [$warn(data type error ^O/s1/ in P$TOK)
$retf]
jumpa getpbk
getswt: ;process a switch
$call p$swit ;read the switch
jumpf [$warn(data type error ^O/s1/ in P$SWIT)
jumpa getpbk]
jumpa (s1) ;process the switch
getifl: ;process input file spec
$call p$ifil ;get input file descriptor
jumpf [$warn(data type error ^O/s1/ in P$IFIL)
$retf]
movss s1 ;source address in left half
hrri s1,a$fd ;destination address in right half
movei t1,a$fd+a$fd.l-1 ;final destination address
blt s1,@t1 ;save the file descriptor
jumpa getpbk ;get next input field
getofl: ;process output file spec
$call p$ofil ;get output file descriptor
jumpf [$warn(data type error ^O/s1/ in P$IFIL)
$retf]
movss s1 ;source address in left half
hrri s1,r$fd ;destination address in right half
movei t1,r$fd+r$fd.l-1 ;final destination address
blt s1,@t1 ;save the file descriptor
jumpa getpbk ;get next input field
getcfm: ;here to confirm the command
$call p$cfm ;get confirmation
jumpf [$warn(data type error ^O/s1/ in P$CFM)
$retf]
$rett
w$encrypt:
setom fl$encrypt ;set encryption flag
jumpa getpbk
w$noencrypt:
setzm fl$encrypt ;clear encryption flag
jumpa getpbk
w$all:
setom fl$words ;set words flag
setom fl$ppn ;set ppn flag
setom fl$accname ;set accounting name flag
setom fl$logname ;set login name flag
jumpa getpbk
w$none:
setzm fl$words ;clear words flag
setzm fl$ppn ;clear ppn flag
setzm fl$accname ;clear accounting name flag
setzm fl$logname ;clear login name flag
jumpa getpbk
w$accnam:
setom fl$accname ;set accounting name flag
jumpa getpbk
w$noaccname:
setzm fl$accname ;clear accounting name flag
jumpa getpbk
w$lognam:
setom fl$logname ;set login name flag
jumpa getpbk
w$nolognam:
setzm fl$logname ;clear login name flag
jumpa getpbk
w$ppn:
setom fl$ppn ;set ppn flag
jumpa getpbk
w$noppn:
setzm fl$ppn ;clear ppn flag
jumpa getpbk
w$words:
setom fl$words ;set words flag
jumpa getpbk
w$nowords:
setzm fl$words ;clear words flag
jumpa getpbk
subttl routine to read a record from the input file
rdrec: ;read accounting file record
move s1,a$ifn ;get index
movsi t1,-a$rc.l ;accounting record length,,loop index
rdrec1:
$call f%ibyt ;read next word
$fretf ;if error, return error
movem s2,a$rec(t1) ;save this word
aobjn t1,rdrec1 ;if count still negative, get next
$rett ;done, return true
;routine to process a password match
; p1 = (not encoded) password
found: ;here to report a match
aos mchcnt ;count number of matches
$text (rptout,<^I/fndtxt/>)
move s1,r$ifn ;select report file
$call f%chkp ;checkpoint it
jumpf [$warn(Cannot checkpoint report file)
$retf] ;quit on error
$rett ;return to caller
;routine to pass characters to the report file
rptout:
move s2,s1 ;put character into s2
move s1,r$ifn ;report file index
$call f%obyt ;output byte in s2
jumpf [$fatal(Cannot write report file)] ;quit if error
$rett
subttl routine to check password
check: ;check this ppn for bad password
skipn fl$word ;word check selected?
jumpa chk010 ;no, skip this
setzm pswold ;yes, clear previous password attempt
$call wrdchk ;check password list
jumpt [movei t1,[asciz\word\] ;if found a match, set type
$rett] ;and return true
chk010:
skipn fl$ppn ;ppn check selected?
jumpa chk020 ;no, skip this
$call ppnchk ;yes, check user's PPN (various forms)
jumpt [movei t1,[asciz\ppn\] ;if found a match, set type
$rett] ;and return true
chk020:
skipn fl$accname ;accounting name check selected?
jumpa chk030 ;no, skip this
$call accnam ;yes, check accounting name
jumpt [movei t1,[asciz\accnam\] ;if found a match, set type
$rett] ;and return true
chk030:
skipn fl$logname ;login name check selected?
jumpa chk040 ;no, skip this
$call lgnnam ;login name
jumpt [movei t1,[asciz\lgnnam\] ;if found a match, set type
$rett] ;and return true
chk040:
$retf ;no match, return false
subttl routine to test possible passwords
wrdchk:
movx p4,list.l ;length of password list
word1:
sojl p4,.retf ;if list is exhausted, return false
move p1,list(p4) ;get possible password
$call compar ;test this candidate
$trett ;if true, return true
jumpa word1 ;not true, try next candidate
;table of password candidates
define x(a),<sixbit \a\>
list:
lall
pswlst
sall
nd list.l,.-list
subttl routine to check various forms of the PPN
ppnchk:
hlrz t1,ppn ;get project number
$call oct6bt ;convert octal to sixbit
movem p1,prj6bt ;save it for later
movx s1,msk.l ;index for password mask table
ppn0a:
sojl s1,ppn1 ;if done, try next format
move p1,prj6bt ;get sixbit project
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa ppn0a ;no match, try next fragment
ppn1:
hrrz t1,ppn ;get programmer number
$call oct6bt ;convert to sixbit
movem p1,prg6bt ;save it for later
movx s1,msk.l ;index for password mask table
ppn1a:
sojl s1,ppn2 ;if done, try next format
move p1,prg6bt ;get sixbit programmer
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa ppn1a ;no match, try next fragment
ppn2: ;combine project and programmer
setzm ppn6bt ;clear ppn test word
movx t4,^d6 ;maximum number of sixbit bytes
move p4,[point 6,ppn6bt] ;pointer to ppn in sixbit (deposit)
move p3,[point 6,prj6bt] ;pointer to project in sixbit (load)
ppn2a:
ildb t1,p3 ;get project byte
jumpe t1,ppn2b ;if null, done with prj6bt
sojl t4,ppn2d ;if no more room, test it
idpb t1,p4 ;store byte
jumpa ppn2a ;get the next one
ppn2b:
move p3,[point 6,prg6bt] ;pointer to programmer in sixbit (load)
ppn2c:
ildb t1,p3 ;get programmer byte
jumpe t1,ppn2d ;if null input, test it
sojl t4,ppn2d ;if no more room, test it
idpb t1,p4 ;store byte
jumpa ppn2c ;get the next one
ppn2d:
movx s1,msk.l ;index for password mask table
ppn2e:
sojl s1,ppn3 ;if done, try next format
move p1,ppn6bt ;get sixbit ppn
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa ppn2e ;no match, try next fragment
ppn3:
;here when all the formats fail
$retf
subttl routine to convert the octal number (in t1) to sixbit (in p1)
oct6bt:
setz p1, ;clear password ac
movx t3,^d12 ;maximum number of octal digits
move p3,[point 3,t1] ;pointer to octal byte
movx t4,^d6 ;maximum number of sixbit byte
move p4,[point 6,p1] ;pointer to sixbit bytes
;discard leading zeros
oct1:
sojl t3,[$fatal(tried to convert 0 to sixbit)] ;quit if all bytes zero
ildb t2,p3 ;get next octal byte
jumpe t2,oct1 ;if zero, get next byte
jumpa oct3 ;non-zero, start processing
;here to get octal bytes (after discarding leading zeros)
oct2:
sojl t3,.popj ;if all octal bytes used, return
ildb t2,p3 ;more to come, get next octal byte
oct3: ;enter here with first good octal byte
iori t2,'0' ;convert octal to sixbit
idpb t2,p4 ;stick into test word
sojg t4,oct2 ;if room for another sixbit byte, get it
$ret ;if not, return
subttl routine to test various forms of the accounting name
accnam:
move t1,nm6bt1 ;get accounting name
movem t1,nam6bt ;set up test word for processing
movx s1,msk.l ;index for password mask table
acc0:
sojl s1,acc1 ;if done, try next format
move p1,nam6bt ;get accounting name
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa acc0 ;no, try next fragment
subttl make copy of accounting name with only letters and digits
acc1:
setzm nam6bt ;clear test word
movx t3,^d12 ;maximum characters in input
move p3,[point 6,nm6bt1] ;pointer to accounting name
movx t4,^d6 ;maximum characters in output
move p4,[point 6,nam6bt] ;pointer to sixbit accounting name
acc1a:
sojl t3,acc1c ;if input exhausted, test word
ildb t1,p3 ;get next byte
jumpe t1,acc1c ;if input empty, test word now
caige t1,'0' ;is character below '0'?
jumpa acc1a ;yes, count it and ignore it
caile t1,'9' ;is character in range 0-9?
jumpa acc1b ;yes, include it
caige t1,'a' ;is character below 'a'?
jumpa acc1a ;yes, ignore it
caile t1,'z' ;is character in range a-z?
jumpa acc1b ;yes, include it
jumpa acc1a ;no, ignore it
acc1b:
idpb t1,p4 ;store next byte
sojg t4,acc1a ;if more space, get next byte
;test the modified accounting name
acc1c:
move p1,nam6bt ;get modified accounting name
camn p1,nm6bt1 ;is it same as original?
jumpa acc2 ;yes, try next format
movx s1,msk.l ;length of password mask table
acc1d:
sojl s1,acc2 ;if done, try next format
move p1,nam6bt ;get accounting name
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa acc1d ;no, try next fragment
subttl test part of name following a period (if any)
acc2:
setzb s1,nam6bt ;clear flag and test word
movx t3,^d12 ;maximum characters in input
move p3,[point 6,nm6bt1] ;pointer to accounting name
movx t4,^d6 ;maximum characters in output
move p4,[point 6,nam6bt] ;pointer to sixbit accounting name
acc2a:
sojl t3,acc2c ;if input exhausted, test word
ildb t1,p3 ;get next byte
jumpe t1,acc2c ;if input empty, test word now
cain t1,'.' ;is this a period?
aoja s1,acc2a ;yes, count it and get next byte
jumpe s1,acc2a ;no, if no period yet, get next byte
acc2b: idpb t1,p4 ;store this byte
sojg t4,acc2a ;if more space, get next byte
;test the modified accounting name
acc2c:
jumpe s1,acc3 ;if no period seen, skip test
movx s1,msk.l ;length of password mask table
acc2d:
sojl s1,acc3 ;if done, try next format
move p1,nam6bt ;get accounting name
and p1,pswmsk(s1) ;convert to fragment
$call compar ;test this candidate
$trett ;if matches, return true
jumpa acc2d ;no, try next fragment
acc3:
$retf ;return false
subttl routine to test user's login (ie, SWITCH.INI) name
nd s.byt,7 ;byte size of user's switch.ini file
$data inpsav ;word to save last input character
$data qqf ;double quote flag
$data s$ifn ;switch.ini file index
s$fob: exp s$fd ;user's SWITCH.INI file open block
exp s.byt ;byte size
nd s$fo.l,.-s$fob
s$fd: xwd s$fd.l,.fdnat ;length of fd,,native format
sixbit \all\ ;device
sixbit \switch\ ;filename
sixbit \ini\ ;extension
s$ppn: exp 0 ;ppn
nd s$fd.l,.-s$fd
lgnnam:
move t1,ppn ;get this ppn
movem t1,s$ppn ;set up ppn for this user
movx s1,s$fo.l ;length of file open block
movx s2,s$fob ;address of file open block
$call f%iopn ;open file for input
$fretf ;if cannot open file, return false
movem s1,s$ifn ;save ifn for file
;fall through to process the user's switch.ini file
subttl read lines in file to find login line
lgn1:
$call f%ibyte ;read first byte in line
jumpf nofile ;if error, release file
caie s2,"L" ;upper case ok?
cain s2,"l" ;no, lower case ok?
skipa ;yes, check next character
jumpa lgnlin ;no, process rest of input line
$call f%ibyte ;read second byte in line
jumpf nofile ;if error, release file
caie s2,"O" ;upper case ok?
cain s2,"o" ;no, lower case ok?
skipa ;yes, check next character
jumpa lgnlin ;no, process rest of input line
$call f%ibyte ;read third byte in line
jumpf nofile ;if error, release file
caie s2,"G" ;upper case ok?
cain s2,"g" ;no, lower case ok?
skipa ;yes, check next character
jumpa lgnlin ;no, process rest of input line
$call f%ibyte ;read fourth byte in line
jumpf nofile ;if error, release file
caie s2,"I" ;upper case ok?
cain s2,"i" ;no, lower case ok?
skipa ;yes, check next character
jumpa lgnlin ;no, process rest of input line
$call f%ibyte ;read fifth byte in line
jumpf nofile ;if error, release file
caie s2,"N" ;upper case ok?
cain s2,"n" ;no, lower case ok?
skipa ;yes, check next character
jumpa lgnlin ;no, process rest of input line
;here to scan the login line for the /name switch
lgn2:
$call f%ibyt ;read a character
jumpf nofile ;if error, return false
lgn2a:
caie s2,.chcrt ;carraige return?
cain s2,.chlfd ;or line feed?
jumpa lgnlin ;yes, read to end of line
caie s2,"/" ;no, is this a slash?
jumpa lgn2 ;no, read the next character
;here if found "/"
setzm qqf ;clear the double quote flag
$call f%ibyt ;read a character
jumpf nofile ;if error, return false
caie s2,"N" ;upper case ok?
cain s2,"n" ;no, lower case ok?
skipa ;yes, read next character
jumpa lgn2a ;no, search for next switch
;here if found "/N"
$call f%ibyt ;read a character
jumpf nofile ;if error, return false
caie s2,"A" ;upper case ok?
cain s2,"a" ;no, lower case ok?
skipa ;yes, read next character
jumpa lgn2a ;no, search for next switch
;here if found "/NA"; now search for the colon
lgn3:
$call f%ibyt ;read a byte
jumpf nofile ;if error, return false
lgn3a:
caie s2,.chcrt ;carraige return?
cain s2,.chlfd ;or line feed?
jumpa lgnlin ;yes, read to end of line
caie s2,":" ;no, is this a colon?
jumpa lgn3 ;no, read the next byte
;here to read the switch value (ie, login name)
lgn3b:
setzm nam6bt ;clear test word
$call f%ibyt ;read a byte
jumpf nofile ;if error, return false
caie s2,.chcrt ;carraige return?
cain s2,.chlfd ;or line feed?
jumpa lgnlin ;yes, read to end of line
caie s2,42 ;no, is this a double quote?
jumpa lgn4 ;no , read the login name
setom qqf ;yes, set the double quote flag
$call f%ibyt ;and read the next byte
jumpf nofile ;if error, return false
;here to process the login name itself
lgn4:
movx t4,^d6 ;maximum bytes in password
move p4,[point 6,nam6bt] ;pointer to test word
lgn4a:
movem s2,inpsav ;save this character
sojl t4,lgn5 ;if input done, process the word
skipn qqf ;is quoted input in effect?
jumpa lgn4b ;no, process normally
cain s2,42 ;yes, is it a double quote?
jumpa lgn5 ;yes, process the word
jumpa lgn4c ;no, accept anything except end of line
lgn4b:
cain s2,"/" ;is it a slash?
jumpa lgn5 ;yes, process the word
lgn4c:
caie s2,.chcrt ;is it a carraige return?
cain s2,.chlfd ;or line feed?
jumpa lgn5 ;yes, process the word
caige s2,140 ;no, convert to sixbit. upper case?
addi s2,40 ;yes, change range
andi s2,77 ;retain only six bits
idpb s2,p4 ;no, use this byte
$call f%ibyt ;read a byte
jumpf nofile ;if error, return false
jumpa lgn4a ;and get the next one
;here to process this password candidate
lgn5:
move s2,inpsav ;restore the last character
movx p4,msk.l ;length of password mask table
lgn5a:
sojl p4,lgn2a ;if done, continue parsing this line
move p1,nam6bt ;get the word
and p1,pswmsk(p4) ;convert to fragment
$call compar ;test this candidate
jumpt [move s1,s$ifn ;if a match,
$call f%rel ;release file
$rett] ;and return true
jumpa lgn5a ;not a match, try next fragment
;here to read to the end of the present line
lgnlin:
cain s2,.chlfd ;is this a line feed?
jumpa lgn1 ;yes, process the next line
$call f%ibyte ;no, read next byte
jumpf nofile ;if error, release file
jumpa lgnlin ;process this character
nofile: ;here for any failure after file opened
move s1,s$ifn ;get index
$call f%rel ;release file
$retf ;and return false
subttl routine to compare test password with the real one
;call with test password in p1
;
; $call compar
;
;return: true: password matched
; false: no match
;
; p1 = original contents
compar:
skipe fl$encrypt ;processing encrypted passwords?
jumpa comencrypt ;yes, go do it
came p1,psw ;no, are they the same?
$retf ;no, return false
$rett ;yes, return true
comencrypt: ;here if passwords are encrypted
camn p1,pswold ;is this same as last try?
$retf ;yes, return false
movem p1,pswold ;no, save it for later
$call encode ;hash it
came p1,psw ;does it match the true hashed password?
jumpa [move p1,pswold ;no, restore previous candidate
$retf] ;and return false
move p1,pswold ;yes, restore the password
$rett ;and return true
subttl encode - routine to encrypt potential passwords
;this routine is copied from LOGIN
;ACs used: T1,T2,T3,T4,P1
;ROUTINE TO HASH-CODE THE PASSWORD FOR GREATER SECURITY
;HASHING FUNCTION IS NON-INVERTIBLE
;CALL: MOVE P1,[PASSWORD]
; PUSHJ P,ENCODE##
; RETURN HERE WITH HASHED PASSWORD IN P1
ENCODE::MOVE T2,P1 ;GET PSWD IN T2
MOVE T1,T2 ;AND T2
HRRZ T4,PPN ;GET PROGRAMMER NUMBER
IDIVI T2,(T4) ;DIVIDE INTO PASSWORD
MOVM T3,T3 ;GET ABS(REMAINDER)
MOVE T4,T3 ;COPY FOR A LOOP COUNTER
FOO: MUL T1,T1 ;SQUARE THE PASSWORD
ROTC T1,^D18 ;GET MIDDLE 36 BITS OF RESULT
JUMPN T1,.+2 ;MAKE SURE NON-ZERO
MOVE T1,T2 ;IF ZERO, PICK UP PSWD AGAIN
SOJG T4,FOO ;DO THIS A LARGE (RANDOM) NO. OF TIMES
XOR T1,P1 ;MUNGE IT STILL MORE
IDIVI T3,^D35 ;DIVIDE LOOP COUNTER
ROT T1,1(T4) ;ROTATE T1 BY REMAINDER
MOVE P1,T1 ;COPY FINAL RESULT BACK TO P1
POPJ P, ;ALL DONE!
end pswchk