[comp.os.vms] VMS PHONE - aspects of security

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

Hi there in VMS land,

recently I noticed some clever students, playing around with other users
phone mailboxes, and I wondered whether PHONE comes up to the aspects
of security in VMS.
On the assumption that sometimes users communicating via PHONE exchange some
important (may be system-security relevant) or very private information, I
think it is very strange to find the following possibilities to manipulate
phone mailboxes (the manipulator does not need any privileges !) :

- everyone can disturb the phone-dialog of two or more users
- everyone can send commands to anyones phone command line (exit, facsimile...)
- everyone can trace a whole dialog, without to be noticed by the phoning users
- everyone can phone with a username different to his/herselves

I think, the last two points are the most remarkable ones; on the assumption
I made above, every (clever) user is able to get information, which he not
ought to get and is able to hurt someones reputation by misusing his/her
username.
The reason for all that is quiet simple:
PHONE creates those mailboxes with the uic of their creator and with a
protection mask, allowing the whole world to access those mailboxes reading
and writing, which is possible because of the required shareableness of those
devices. Besides, PHONE assigns a logical name to each of the phone mailboxes,
that is not required but eases those manipulations.
Example: user MILLER calls user SMITH, who is not currently running PHONE;
now PHONE creates two mailboxes, both with the UIC of MILLER, assigns the
logical names PHN$MILLER to the first (the callers one) and PHN$SMITH to the
second (the called one), these logicals normally reside in LNM$SYSTEM_TBALE.

However such a behaviour of PHONE affects the integrity of VMS in real life,
I think it does not fit the aspects of system security in VMS.
At my site I drew the conclusions and wrote a patch, which might be (I hope so)
of general interest.
Below, you'll find a command procedure managing the necessary things.
It checks for a proper environment (privileges, work-directory: sys$update,
correct image (this patch supports only PHONE X-1, usually to find on VMS 4.4
and 4.5)), creates the patch command file (uses checksum for verification),
patches and install (replace) phone. It can be started from anywhere by anyhow.

Finally, I hope you'll understand, that I cant send any demonstration programs,
there might be sites which reveive them, but not the patch...

p.s.: Greetings to Paul C. Angnostopoulos (the original creator of PHONE),
      L. Mark Pilant (the creator of those funny $setuai/$getuai routines),
      and all of the actual DEC-VMS-Group.


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

-------------------------------- 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
$!
$       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]
$       copy sys$common:[sysexe]phone.exe *.*
$       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]
!
!       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
!
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  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'
'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/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 parameter
'       PUSHAB  B^KERN'                 !    inside the KERN routine (in AP)
'       CALLS   #2,@#SYS$CMKRNL'        ! to work with the I/O database
'       BLBS    R0,KERNOK'              !    we must change to kernel mode
'       PUSHL   R0'                     ! something wrong with sys$cmkrnl call
'       CALLS   #1,@#SYS$EXIT'          !    exit with error message
'KERNOK: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

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

! 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: 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

EXIT
$       checksum phonepat.pat
$       if checksum$checksum .eqs. "1813945649" 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