.title SSXTLOCK ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ; Program: SSXTLOCK ; Author: Lynn Tedder ; Date Written: 04/22/91 ; Synopsis: This program will accept a password from the terminal ; and verify it against what is in the SYSUAF. If a ; retry limit is exceded, the process will either be ; logged off, or the calling image will be run down ; ; INPUTS: None ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .library /sys$library:lib.mlb/ .library /sys$library:starlet.mlb/ .link /sys$system:sys.stb/ $iodef ;Define Section Table Entry offsets for I/O $qiodef ;Define Section Table Entry offsets for QIO masks $ssdef ;Define Section Table Entry offsets for System Services $trmdef ;Define Section Table Entry offsets for Terminal masks $ttdef ;Define Section Table Entry offsets for TT masks $prvdef ;Define Section Table Entry offsets for priv masks .macro check ?l cmpl #ss$_normal,r0 beql l pushl r0 calls #1,g^lib$stop l: .endm check username_descriptor: username_length: .word 12 .word .address username username: .ascii / / terminator_mask: ;Define the QIO Read terminator mask first_terminator_longword: ;The first longword must be 0 .long 0 second_terminator_longword: ;The second longword allows only .long 8192 ; as a terminator control_mask: ;Will contain lib$m_cli_ctrly to .long 0 ;disallow the use of old_control_mask: ;Longword to contain the saved .long 0 ;control character mask spaces: .ascii / / master_pid: .long master_pid_len: .word getjpi_iosb: ;IOSB of GETJPI call .long getjpi_rest_iosb: .long getjpi_item_list: ;GETJPI item list to return the ;username and the master pid .word 12 ;Length of returned item .word jpi$_username ;Item code to return the USERNAME .address username ;Address of return buffer .address username_length ;Length written to return buffer .word 4 ;Length of returned item .word jpi$_master_pid ;Item code to return the master pid .address master_pid ;Address of return buffer .address master_pid_len ;Length written to return buffer .long 0 ;Item List ending Longword getuai_item_list: ;GETUAI item list .word 1 ;Length of returned item .word uai$_encrypt ;Item code to return the algorithm .address algorithm ;Address of return buffer .address algorithm_length;Length written to return buffer .word 2 ;Length of returned item .word uai$_salt ;Item code to return the password salt .address password_seed ;Address of return buffer .address seed_length ;Length written to return buffer .word 8 ;Length of returned item .word uai$_pwd ;Item code to return the hashed password .address hashed_password ;Address of return buffer .address password_length ;Length written to return buffer .word 4 ;Length of returned item .word uai$_uic ;Item code to return the hUIC .address longword_uic ;Address of return buffer .address uic_length ;Length written to return buffer .long 0 ;Item List ending Longword getsyi_iosb: ;I/O Status block for GETSYI call .long .long getsyi_item_list: ;GETSYI item list to return the Breakin Limit .word 1 ;Length of returned item .word syi$_lgi_brk_lim;Item code to return the breakin limit .address max_loop_counter;Address of return buffer .address algorithm_length;Length written to return buffer .long 0 max_loop_counter: ;Storage for LGI_BRK_LIM .long loop_counter: .long 0 algorithm: .byte algorithm_length: .word password_seed: .word seed_length: .word hashed_password: .quad password_length: .word longword_uic: .long uic_length: .word control_string: .ascid /!%U/ new_hashed_password: .quad tt_chan: .blkw 1 tt_descriptor: .ascid /SYS$INPUT:/ password_prompt: .ascii /Password: / password_prompt_length: .long 10 second_password_prompt: .ascii /Password: / pass_buffer_length: .word 32 entered_password_descriptor: entered_password_length: .word 0 .word .address entered_password entered_password: .blkb 32 read_qio_iosb: ;I/O Status block for the QIO .word read_qio_length: ;Length of entered data .word read_qio_terminator: ;Terminator used .word read_qio_terminator_length: ;Length of Terminator .word read_qio_function: ;Convert input to upcase, do not echo, ;and purge the type ahead buffer .word io$_readprompt!io$m_cvtlow!io$m_noecho!io$m_purge invalid_message: .ascii /INVALID/ lf = 10 ;Line Feed cr = 13 ;Carriage Return ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ; ; ;Code start ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; .entry ssxtlock,^m ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ; ; ;Disable processing ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; bisl2 #lib$m_cli_ctrly,control_mask ;Mask out pushal old_control_mask ;Save current Control Mask pushal control_mask calls #2,g^lib$disable_ctrl ;Disable check ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ; ; ;Call $GETJPI to get a username. ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; 20$: pushl #0 ;No AST Params pushl #0 ;No AST Procedure pushaq getjpi_iosb ;IO Status Block pushal getjpi_item_list ;Item List pushl #0 ;No Process Name - this process pushl #0 ;No PID - use this process pushl #0 ;No Event flag to set calls #7,g^sys$getjpiw ;Go get the current username check ;Everything OK with the call? movl getjpi_iosb,r0 ;Now, lets check the IOSB check ;Hope we're OK 30$: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;Get the Password algorithm, the hashed password, and the seed from the UAF. ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pushl #0 ;Null Argument pushl #0 ;Null Argument pushl #0 ;Null Argument pushal getuai_item_list ;Item List pushal username_descriptor ;Username pushl #0 ;Null Argument pushl #0 ;Null Argument calls #7,g^sys$getuai check ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;Get the SYSGEN parameter LGI_BRK_LIM to see how many chances to give to get ; ;the password right. ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pushl #0 ;No AST Parameter pushl #0 ;No AST Routine address pushal getsyi_iosb ;I/O Status Block pushal getsyi_item_list ;Item List pushl #0 ;Use this Node, no Node name pushl #0 ;Use this node, no CSID pushl #0 ;No Event flag, do it Sync-ly calls #7,g^sys$getsyiw check movl getsyi_iosb,r0 ;Check the status in IOSB check $assign_s devnam=tt_descriptor,- ;Assign I/O Channel to Terminal chan=tt_chan check movl #0,loop_counter ;Initialize the Loop Counter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;Get the Password from the user. Wait until they enter it ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; qio_call: addl #1,loop_counter ;Increment the loop counter pushl password_prompt_length ;Get the length of the prompt pushal password_prompt ;Get the address of the prompt pushal terminator_mask ;Get the terminator mask pushl #0 ;No p3 pushl pass_buffer_length ;Get the password buffer length pushal entered_password ;Get the password buffer pushl #0 ;No AST parameter pushl #0 ;No AST pushaq read_qio_iosb ;Read I/O Status Block pushl read_qio_function ;Function = upcase,purge,noecho, ;Read with prompt pushl tt_chan ;Terminal Channel pushl #0 ;No Event Flag calls #12,g^sys$qiow ;Check success of the call blbs r0,40$ ret 40$: movl read_qio_iosb,r0 ;Check the status in IOSB blbs r0,check_control_y ret check_control_y: cmpw #ss$_controly,read_qio_iosb ;Check to see if they hit beql control_c_y ;They did! check_control_c: cmpw #ss$_controlc,read_qio_iosb ;Check to see if they hit bneq got_a_password ;They did not control_c_y: subl2 #1,loop_counter ;They did. Subtract 1 from loop ;counter brw bad_password ;Go to BAD_PASSWORD ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ; ; ;We have a password entered. We need to hash it and then compare it to what ; ;we got from the UAF. ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; got_a_password: movw read_qio_length,entered_password_length ;Get the number of characters pushaq new_hashed_password ;Destination pushal username_descriptor ;Username pushl password_seed ;Password Salt pushl algorithm ;Name of the algorithm pushal entered_password_descriptor ;Password entered at the prompt calls #5,g^sys$hash_password ;Hash it check movaq new_hashed_password,r7 ;Get address of new hash movaq hashed_password,r8 ;Get address of old hash cmpl (r7)+,(r8)+ ;Compare them and auto increment ;the address for the second ;longword. bneq bad_password ;They didn't match cmpl (r7),(r8) ;Compare the second longword bneq bad_password ;They didn't match brw finished ;They matched! ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; ; ; ;The password entered did not match what was stored. Compare the loop counter ; ;to the masimum number of tries. If we excede this number, log them out. ; ; ; ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; bad_password: cmpl max_loop_counter,loop_counter ;Exceded maximum # of tries? bleq go_away ;Yes we have movc3 #12,second_password_prompt,password_prompt ;Move in the second prompt. ;This has CR and LF in it. movw #12,password_prompt_length ;Change to the new length brw qio_call ;Go back and prompt them go_away: $dassgn_s chan=tt_chan ;Deassign the terminal channel check $delprc_s pidadr=master_pid ;If not, delete the process $exit_s ;else, run down the image finished: $dassgn_s chan=tt_chan ;Deassigh the terminal channel check pushal control_mask ;Restore the original control pushal old_control_mask ;mask. calls #2,g^lib$enable_ctrl ;Set it now. check movl #1,r0 ret ;Let's go home! .end ssxtlock