[comp.os.vms] VMS PHONE - The Patch, bugfixed

WEIRAUCH%iravcl@germany.CSNET ("Stefan Weirauch, IRA, Uni Karlsruhe") (07/21/87)

Whoops !

I made a big, fat mistake... so sorry... shame on me...

Well, with the help of Kenneth Adelman (many thanks to him), I fixed a hole
in my own (sniif) patch.

If you already applied my patch, define the logical ORIGINAL_PHONE_X1
pointing to an original PHONE image file.
(For example: $ DEFINE ORIGINAL_PHONE_X1 SYS$COMMON:[SYSEXE]PHONE.EXE;1)
Define that logical with the full file-spec (including version number) !
Without this definition PHONEPAT.COM takes the actual PHONE, which results
in an error while trying to patch with ECO 100 (allready set in first patch).

I'm only human - and humanly this patch really makes phone more secure.

Stefan

-------------------------------- cut here -------------------------------
$!
$!      PHONEPAT.COM
$!
$! Command procedure to patch and install (replace) VMS PHONE
$! to make PHONE much more secure
$!
$! created on 15-JUL-1987 by
$!
$! Stefan Weirauch                 CSNET:    WEIRAUCH%iravcl@germany.csnet
$! Informatik-Rechner-Abteilung    UUCP:     WEIRAUCH%iravcl%uka.uucp@unido.uucp
$! Universitaet Karlsruhe          PSI:      PSI%026245721042100::WEIRAUCH
$! D-7500 Karlsruhe 1
$! West Germany
$!
$! Modifications:
$!
$! 20-JUL-1987  some modifications in phonepat.pat         (see there)
$!              added check for logical ORIGINAL_PHONE_X1  (Stefan Weirauch)
$!                 to support already patched machines
$!
$       say       := write sys$output
$       install   := $install/command
$!
$       old_privs = f$setprv("SYSPRV,CMKRNL")
$       cur_dir = f$environment("default")
$       on control_y then goto exit
$       on warning then goto exit
$       if f$priv("SYSPRV,CMKRNL") then goto privs_ok
$       say "%PHONEPAT-E-NOPRIV, insufficient privilege for attempted operation"
$       goto exit
$privs_ok:
$       set default sys$common:[sysupd]
$       if f$log("ORIGINAL_PHONE_X1") .nes. "" then goto log_defined
$       define ORIGINAL_PHONE_X1 sys$common:[sysexe]phone.exe
$log_defined:
$       copy ORIGINAL_PHONE_X1 ;
$       open/read imag phone.exe
$       read imag record
$       close imag
$       offset = f$cvui(6*8,16,record)
$       len = f$cvui(offset*8,8,record)
$       imag_nam = f$extr(offset+1,len,record)
$	offset = offset + 40
$       len = f$cvui(offset*8,8,record)
$       imag_fid = f$extr(offset+1,len,record)
$       if (imag_nam .eqs."PHONE") .and.(imag_fid .eqs."X-1") then goto imag_ok
$       say "%PHONEPAT-E-WRONGIMAG, wrong image - name not PHONE or fid not X-1"
$       goto exit
$imag_ok:
$       create phonepat.pat
!
!       PHONEPAT.PAT   protect phone mailboxes against user manipulation
!
!       patch - file for image: PHONE, identification: X-1
!       (usually VMS 4.4 and 4.5)
!
!       EC100   10-JUL-1987     (Stefan Weirauch)
!               MODULE:         PHONE
!               ROUTINE:        PHN$INIT_MAIN
!               set sysprv and cmkrnl, exit if it fails
!               create out permanent mailbox without world and group access
!               change owner uic of our mailbox to [1,4]
!
!               Modifications:
!               20-JUL-1987     (Stefan W., with hints from Kenneth Adelman)
!               clear cmkrnl after test it; set it only temporary
!               during execution of MODDEVORB
!
!       EC101   11-JUL-1987     (Stefan Weirauch)
!               MODULE:         INPUT
!               ROUTINE:        PHN$CMD_PARSE
!               clear sysprv (if it was not set) temporarily while executing
!               PHN$FACSIMILE_CMD (MODULE FILECMDS)
!
!       EC102   13-JUL-1987     (Stefan Weirauch)
!               MODULE:         LINKSUBS
!               ROUTINE:        PHN$ESTAB_LINK
!               create the permanent mailbox of the called person like ours
!               including owner uic change
!
!       EC103   20-JUL-1987     (Stefan W., with hints from Kenneth Adelman)
!               MODULE:         MISCCMDS
!               ROUTINE:        PHN$MAIL_CMD
!               add sysprv to list of temporary purged privs before
!               spawning mail command
!
PHONE.EXE

DEFINE  PHONE           = 0A00
DEFINE  PHN$INIT_MAIN   = PHONE + 0DB
DEFINE  INPUT           = 1DB0
DEFINE  PHN$CMD_PARSE   = INPUT + 13F
DEFINE  FILECMDS        = 288C
DEFINE  PHN$FACSIMILE_CMD = FILECMDS
DEFINE  LINKSUBS        = 1610
DEFINE  PHN$ESTAB_LINK  = LINKSUBS + 97
DEFINE  MISCCMDS        = 2368
DEFINE  PHN$MAIL_CMD    = MISCCMDS + 408

DEFINE  SYS$CMKRNL      = 7FFEDE90
DEFINE  SYS$EXIT        = 7FFEDF40
DEFINE  SYS$SETPRV      = 7FFEE100
DEFINE  CTL$GL_CCBBASE  = 7FFEFF38

DEFINE  SS$_NORMAL      = 01
DEFINE  SS$_NOPRIV      = 24
DEFINE  PRV$M_CMKRNL    = 00000001
DEFINE  PRV$M_SYSPRV    = 10000000

DEFINE  UCB$L_ORB       = 1C
DEFINE  ORB$W_PROT      = 18

SET ECO 100

! some data we need for sys$setprv

ALIGN/QUAD DATA

DEPO/PATCH_AREA/INSTR DATA
'PROC_PRIVS:    .LONG 0,0'
'NO_PRIVS:      .LONG 0,0'
'CMKRNL_MASK:   .LONG PRV$M_CMKRNL,0'
'SYSPRV_MASK:   .LONG PRV$M_SYSPRV,0'
'SYSPCMKR_MASK: .LONG PRV$M_SYSPRV+PRV$M_CMKRNL,0'
EXIT

! now some routines we need more then once

ALIGN/WORD SETPRIV

DEPO/PATCH_AREA/INSTR SETPRIV
! routines to set/clear current privs
! call sequence:
!       PUSHAQ  priv_mask
!       CALLS   #1,SETPRIV resp. CLRPRIV
!
'       .WORD   0'
'       CLRQ    -(SP)'
'       PUSHL   B^4(AP)'
'       PUSHL   #1'
'       CALLS   #4,@#SYS$SETPRV'
'       RET'
'CLRPRIV: .WORD 0'
'       CLRQ    -(SP)'
'       PUSHL   B^4(AP)'
'       CLRL    -(SP)'
'       CALLS   #4,@#SYS$SETPRV'
'       RET'
EXIT

ALIGN/BYTE MODDEVORB

DEPO/PATCH_AREA/INSTR MODDEVORB
! modify the ORB of a device specied by its channel
! (set system [1,4] as owner, set dev-prot to (S:RWLP,O:RWLP,G:,W:)
!
! input:   R2 : address of channel number
!
! call:  JSB MODDEVORB
!
! CCB = Channel Control Block
! UCB = Unit Control Block
! ORB = Object Rights Block
!
'       PUSHR   #3'                     ! save R0, R1 - they might be important
'       MOVZWL  (R2),R1'                ! extend chan-no to long
'       SUBL3   R1,@#CTL$GL_CCBBASE,R1' ! get address of CCB of that channel
'       PUSHL   (R1)'                   ! push address of UCB as par in KERN
'       PUSHAB  CMKRNL_MASK'            ! set cmkrnl-priv
'       CALLS   #1,SETPRIV'
'       PUSHAB  B^KERN'                 ! to work with the I/O database
'       CALLS   #2,@#SYS$CMKRNL'        !    we must change to kernel mode
'       BLBS    R0,KERNOK'
'       PUSHL   R0'                     ! something wrong with sys$cmkrnl call
'       CALLS   #1,@#SYS$EXIT'          !    exit with error message
'KERNOK:PUSHAB  CMKRNL_MASK'            ! clear cmkrnl priv, we dont need it
'       CALLS   #1,CLRPRIV'             !    elsewhere
'       POPR    #3'                     ! restore R0, R1
'       RSB'
'KERN:  .WORD   0'
'       MOVL    B^UCB$L_ORB(AP),R1'     ! get address of ORB
'       MOVL    #10004,(R1)'            ! set system uic into the ORB
'       MOVW    #0FF00,B^ORB$W_PROT(R1)'! set prot-mask as described above
'       MOVL    #SS$_NORMAL,R0'         ! return success
'       RET'
EXIT

! modifications of the original code

INSERT/INSTR    PHN$INIT_MAIN + 18
'       CLRQ    -(SP)'                  ! original code

'       PUSHAB  PROC_PRIVS'             ! get current proc-privs
'       PUSHL   #1'
'       PUSHAB  NO_PRIVS'
'       PUSHL   #1'
'       CALLS   #4,@#SYS$SETPRV'
'       PUSHAB  SYSPCMKR_MASK'          ! try to set sysprv and cmkrnl
'       CALLS   #1,SETPRIV'
'       CMPL    R0,#SS$_NORMAL'
'       BEQL    PRVOK'
'       PUSHL   #SS$_NOPRIV'            ! not installed with sysprv or cmkrnl
'       CALLS   #1,@#SYS$EXIT'          !    exit with error msg
'PRVOK: PUSHAB  CMKRNL_MASK'            ! clear cmkrnl-priv, will be set if
'       CALLS   #1,CLRPRIV'             !    it is needed
'       NOP'
EXIT

REPLACE/INSTR   PHN$INIT_MAIN + 0D4
'       CALLS   #1,@#7FFEDF00'
'       BRB     0BCB'
EXIT
'       CALLS   #1,@#7FFEDF00'          ! 7FFEDF00 = SYS$DELMBX
'       MOVL    R0,R3'                  ! correctly created mailbox
'       BLBC    R3,ERR1'                !    successfully marked for deletion ?
'       JSB     MODDEVORB'              ! yes : modify ORB in the named manner
'       BRW     PHN$INIT_MAIN + 0FB'    !       continue at the right place
'ERR1:  BRW     PHN$INIT_MAIN + 0F6'    ! no  : continue to signal error
EXIT

UPDATE

SET ECO 101

REPLACE/INSTR   PHN$CMD_PARSE + 0F5
'       MOVL    B^28(R4),R0'
'       BEQL    1FF0'
'       PUSHAB  B^0C(R4)'
'       CALLS   #1,(R0)'
EXIT
'       MOVL    B^28(R4),R2'
'       BEQL    NOSET'
'       MOVAB   PHN$FACSIMILE_CMD,R3'
'       CMPL    R2,R3'                  ! facsimile command parsed ?
'       BNEQ    NOCLR'                  ! no: leave sysprv on
'       BITL    #PRV$M_SYSPRV,PROC_PRIVS' ! yes: sysprv set in proc-privs ?
'       BNEQ    NOCLR'                  ! yes: dont clear it
'       PUSHAB  SYSPRV_MASK'            ! no: clear it for security reasons
'       CALLS   #1,CLRPRIV'
'NOCLR: PUSHAB  B^0C(R4)'               ! call command routine
'       CALLS   #1,(R2)'
'       CMPL    R2,R3'                  ! was it facsimile ?
'       BNEQ    NOSET'
'       PUSHAB  SYSPRV_MASK'            ! yes: reenable sysprv
'       CALLS   #1,SETPRIV'
'NOSET: NOP'
EXIT

UPDATE

SET ECO 102

REPLACE/INSTR PHN$ESTAB_LINK + 1AC
'       MOVL    R0,(SP)'
'       BLBS    (SP),1862'
EXIT
'       MOVL    R0,(SP)'                ! here the mbx is successfully created
'       BLBC    (SP),ERR2'              ! successfully marked for deletion ?
'       JSB     MODDEVORB'              ! yes: modify ORB as above
'       BRW     1862'
'ERR2:  NOP'                            ! no: continue to signal error
EXIT

UPDATE

SET ECO 103

REPLACE/INSTR PHN$MAIL_CMD + 0B9
'       MOVL    #150804,B^0F8(FP)'      ! list of temporary purged cur. privs
EXIT
'       MOVL    #<150804+PRV$M_SYSPRV>,B^0F8(FP)'       ! ...added by SYSPRV
EXIT

UPDATE

EXIT
$       checksum phonepat.pat
$       if checksum$checksum .eqs. "1129729746" then goto chksum_ok
$       say "%PHONEPAT-E-CHKSUMERR, checksum error in patch command file"
$       goto exit
$chksum_ok:
$       say "%PHONEPAT-I-PATCH, patching original phone.exe"
$       define/user sys$output nl:
$       patch @phonepat.pat
$       if $status then goto patch_ok
$       say "%PHONEPAT-E-PATCHERR, error occured during execution of PATCH"
$       goto exit
$patch_ok:
$       copy phone.exe sys$common:[sysexe]
$       say "%PHONEPAT-I-INSTALL, installing new phone.exe"
$       install replace -
                phone/priv=(cmkrnl,sysnam,prmmbx,world,oper,netmbx,sysprv)
$       type sys$input

Now, all work is done, and its up to you to:

1.:     insert the following lines into your systartup.com:
        $ install := $install/command
        $ install replace -
                  phone/priv=(cmkrnl,sysnam,prmmbx,world,oper,netmbx,sysprv)

2.:     manually reinstall phone in the same manner on each other node
        (using the same sys$common:[sysexe] directory) of your cluster,
        if you have one

$exit:
$       dummy = f$setprv(old_privs)
$       set default 'cur_dir
$       exit