Macro 32 Ramblings

Mind Archive

A Practical Exercise in Securing an OpenVMS System v2

A Practical Exercise in

Securing an OpenVMS System

Rob McMillan
Prentice Centre
The University Of Queensland

Now at Griffith University
E-Mail: R.McMillan@itc.gu.edu.au
Phone: 07 875 6557
Postal: Information Technology Services
Griffith University
Nathan Qld 4111

A Practical Exercise In Securing An OpenVMS System

Abstract

_________________________________________________________

OpenVMS machines have many features that can be used to
defend them from attack. To properly defend your
machine, you need to make use of these features from the
moment of delivery.

In this paper, I present the series of steps taken by a
typical systems programmer (namely the author) in tuning
the defense mechanisms of an OpenVMS machine, and
outline some non-standard mechanisms employed in the
defence of this machine.

All too often, emphasis is placed on particular accents,
such as access prevention, or reactive examination and
monitoring after attack. This paper attempts a more
holistic approach to the host-based mechanisms that
could be employed to defend a machine. Access control
mechanisms (such as passwords, user authorisation
parameters, and access control wrappers) and activity
logging mechanisms (such as audit trails, terminal
monitors and FAL logging) are considered.
_________________________________________________________

The information contained in this paper is given freely
as an account of my own experience, and may be used by
the reader as the reader sees fit.

No responsibility or liability will be accepted by the
author for any damages caused by direct or indirect use
of the information or functionality described in this
paper.

Introduction

1.1 Assumptions

This paper will discuss some of the features that can be
used to defend an OpenVMS machine from outside attack.
The ideas presented in this paper are the result of an
exercise in configuring a machine in a university
department used for a sensitive research project.

All of the mechanisms I consider in this paper can be
classed as host based mechanisms. However, the defence
of an computer system is not limited to these measures
only.

Measures that should be used, but that I don’t discuss
in this paper are:

* network based security,
* backups, and
* physical security.

This paper is not intended to present an “expert’s view”
of securing an OpenVMS machine. The reason for this is
simple – whilst my knowledge of OpenVMS security is
quite solid, I would not put myself in the “expert”
category. Therefore this paper should not be seen as the
canonical guide to OpenVMS security – rather, it should
be seen as the series of measures that programmers
should typically consider in defending their machine.
There is absolutely no substitute for reading the Guide
to VAX/VMS System Security manual.

Finally, this paper is concerned with the defence of a
machine. I do not personally make any attempt to crack
machines. I will not present any information on how to
crack an OpenVMS machine.

1.2 What This Paper Contains

The following topics are those considered during the
configuration of the machine referred to above. This
list is not exhaustive.

* System Mechanisms For Configuring The Machine To
Control Access :

* SYS$MANAGER Command Files
* Welcome Messages
* Accounts To Disable, Passwords To Change, And
Objects To Modify
* System Logicals And Logical Definitions
* System Passwords
* The UAF File
* File Protections
* ACLs
* Tailoring UCX
* Proxies

* System Mechanisms For Configuring The Machine To Log
Activity :

* Accounting
* Auditing
* FAL and Poor Man’s Routing

* Using Homegrown Or Publicly Available Software :

* Wrappers
* Single Use PINs
* Terminal Monitors

* Monitoring The Use of The Machine :

* The SHOW INTRUSION Command
* Daily Activities
* Having a Live Console

System Mechanisms For Configuring
The Machine To Control Access

2.1 SYS$MANAGER Command Files

There are three files in SYS$MANAGER: that are of
importance in terms of this paper. They are
SYSTARTUP_V5.COM, SYLOGIN.COM and SYLOGICALS.COM. I have
left comments about SYLOGICALS.COM for Section 2.4,
System Logicals And Logical Definitions.

2.1.1 SYSTARTUP_V5.COM

There are several different things to be done here.

As discussed in Section 2.5, System Passwords, a system
password should be installed. A system password means
that the user must enter a password before the login
prompt appears. The procedure for doing this is
discussed in Section 2.5. However, this is the change
you could make in SYSTARTUP_V5.COM to ensure that a
console user does not need to enter the password. (The
console should be located in a physically secure area.)

$! No system password required for console.
$ write sys$output “[Modifying console settings]”
$ SET TERMINAL OPA0: /PERMANENT /NOSYSPASSWORD

This ensures that should the user log in from the
console, a system password will not be required. This
prevents situations where you are locked out from the
machine should the password be changed or forgotten.

$! The following commands turn off account logging and
$! delete the account log.
$! To keep an account log on your system, delete the
$! following 5 command lines.
$!
$! IF (.NOT. MICROVAX) THEN GOTO SKIP_ACCOUNTING
$! SET ACCOUNTING/DISABLE
$! IF F$SEARCH(“SYS$MANAGER:ACCOUNTNG.DAT”) .NES. “” THEN –
$! DELETE SYS$MANAGER:ACCOUNTNG.DAT;*
$!SKIP_ACCOUNTING:

When the operating system is installed, this code is not
commented out. That is, account logging is not enabled
by default. It is good practice to use all logging
facilities available to you, and system accounting is
one of those facilities that is strongly recommended.

You need accounting to provide an extra audit trail on
the system. To enable accounting, comment out these
lines, as shown on the following page.

$! The following commands purge the operator and network
$! logs to two versions.
$!
$! IF (.NOT. MICROVAX) THEN GOTO SKIP_PURGING
$! IF F$SEARCH(“SYS$MANAGER:OPERATOR.LOG;-1”) .NES. “” THEN –
$! PURGE SYS$MANAGER:OPERATOR.LOG
$! IF F$SEARCH(“SYS$MANAGER:EVL.LOG;-1”) .NES. “” THEN –
$! PURGE SYS$MANAGER:EVL.LOG
$!SKIP_PURGING:

Here the machine is trying to make a guess about how
much information should be saved as current information
(the tradeoff being information currency and usefulness
against disk space). A more reasonable figure is 10
versions (working on the basis of a new file per day).
To implement this, do the following:

* Comment out the lines above.

* Create artificial OPERATOR.LOG and EVL.LOG files,
each 1 version higher than the logs currently open
and in use by the system.

* Issue SET FILE OPERATOR.LOG /VERSION_LIMIT=10 and
SET FILE EVL.LOG /VERSION_LIMIT=10. This is done
against the files just created, as the SET FILE
command will fail against the logs open and in use
by the system. When new files are opened for use
by the system, they will be created with a version
number of one higher than the logs created
artificially, but will inherit the version limit.

$! This command defines a message to be displayed before
$! each user logs in.
$!
$! DEFINE /SYSTEM SYS$ANNOUNCE ” Welcome to VAX/VMS ”F$GETSYI(“VERSION”)'”
$ DEFINE /SYSTEM SYS$ANNOUNCE “@SYS$MANAGER:ANNOUNCE.TXT”
$!
$! This command defines a message or file to be
$! displayed after each user logs in.
$!
$ DEFINE /SYSTEM SYS$WELCOME “@SYS$MANAGER:WELCOME.TXT”
$!

For legal reasons, as set out in SERT Advisory SA-93.03
(See Appendix 1, SERT Advisory SA-93.03, Suggested Login
Banner) give people fair warning of the consequences of
misuse. The contents of the files ANNOUNCE.TXT and
WELCOME.TXT are discussed in Section 2.2, Welcome
Messages. To make these files appear, the definitions
above are used.

2.1.2 SYLOGIN.COM

SYLOGIN.COM is a command file executed when any user
logs in. This is the ideal place to install mechanisms
to universally check a user’s credentials (such as
username, source of login, time, terminal or knowledge-
based authenticators).

The first three lines of SYLOGIN.COM should be as
follows (but aren’t in the supplied file).

$ SET NOON
$ SET NOCONTROL_Y
$ SET NOVERIFY

This prevents a user (and hence crackers in the first
instance) from seeing what mechanisms you have
installed, and also interrupting the execution of this
file to avoid these mechanisms.

$! Place your site-specific LOGIN commands below
$!
$! If they get this far, then there may have been a breakin,
$! but at least we can stop them at this point.
$! Call the wrapper.
$!
$ @LOCAL$WRAP:INTERACTIVE.COM
$ IF ($Status .NE. %x10000001)
$ THEN
$ STOP/ID=0
$ ENDIF

As the comments outline, we use a command procedure at
this point to check credentials. This may or may not
involve interactive exchanges. If the person logging in
fails to pass the tests, then they are logged out. (You
will need to define LOCAL$WRAP, for example, in
SYLOGICALS.COM.)

2.2 Welcome Messages

For legal reasons, as set out in SERT Advisory SA-93.03
(See Appendix 1, SERT Advisory SA-93.03, Suggested Login
Banner) give people fair warning of the consequences of
misuse. By default, there is no SYS$WELCOME issued, and
SYS$ANNOUNCE welcomes the person logging in. SYS$WELCOME
needs to be enabled, and point to a file, and
SYS$ANNOUNCE should also point to a file (as shown in
Section 2.1.1, SYSTARTUP_V5.COM). These files should
outline to people conditions of use, and legal
consequences of misuse.

SYS$ANNOUNCE is the message or banner that appears
immediately before the login prompt (but after the
system password has been entered). SYS$WELCOME is the
message or banner that appears immediately after the
person has logged in. In this way, users should normally
see this warning before and after logging in.

This message should appear in SYS$MANAGER:ANNOUNCE.TXT:

—– Warning Message —–

***** This service is for authorised staff only *****

*************************************************************************
* *
* WARNING: It is a criminal offence to: *
* i. Obtain access to data without authority *
* (Penalty 2 years imprisonment) *
* ii Damage, delete, alter or insert data without authority *
* (Penalty 10 years imprisonment) *
* *
*************************************************************************

The following message should appear in
SYS$MANAGER:WELCOME.TXT.

This is {nodename} (VAX/VMS V5.5-2) – Unauthorised access prohibited!

***** This service is for authorised staff only *****

*************************************************************************
* *
* WARNING: It is a criminal offence to: *
* i. Obtain access to data without authority *
* (Penalty 2 years imprisonment) *
* ii Damage, delete, alter or insert data without authority *
* (Penalty 10 years imprisonment) *
* *
*************************************************************************

2.3 Accounts To Disable, Passwords To Change, And Objects
To Modify

2.3.1 Accounts

VMS is supplied with a number of default accounts. It
should be assumed that crackers will attempt to
compromise a machine using default account names and
passwords. This principle applies to any operating
system.

The following default accounts should have their
passwords changed, and the accounts disabled: DEFAULT,
FIELD, MIRRO$SERVER, SYSTEST, SYSTEST_CLIG.

The accounts can be disabled thus:

$ MCR AUTHORIZE
UAF> MODIFY DEFAULT /FLAGS=DISUSER
UAF> MODIFY FIELD /FLAGS=DISUSER
UAF> MODIFY MIRRO$SERVER /FLAGS=DISUSER
UAF> MODIFY SYSTEST /FLAGS=DISUSER
UAF> MODIFY SYSTEST_CLIG /FLAGS=DISUSER
UAF> EXIT
$

Depending upon how you wish to execute batch jobs and
carry out general system administration, you may also
wish to either similarly treat the SYSTEM account, or
alternative apply strict access controls on this account
on the UAF file (See Section 2.6, The UAF File).

2.3.2 Objects

There are several objects that needed tailoring. Some of
the tailoring is to prevent simple security breaches,
whereas others (like the modifications to PHONE, TASK
and FAL) are to prevent breaches that could occur in
whole or in part to Poor Man’s Routing (See Section 3.3,
FAL and Poor Man’s Routing).

In the first stage, the PHONE and TASK objects are
disabled.

In the PHONE application, the directory command can be
used to obtain a directory listing of users on remote
DECNet nodes. It is essentially a default “finger”.
Whilst security through obscurity is no security at all,
any access to system details should be suppressed where
possible.

The TASK object is used to execute jobs on your node
from remote nodes. Since this is not a desired feature
on the machine used in the preparation of this paper,
this object was disabled. Alternatively, the object
could have been loaded with false information into the
permanent database.

These objects are created at boot time using default
information if there is no information about them in the
NCP permanent database. Therefore, a job can be run
immediately after booting to remove these objects.

The objects can be removed thus:

$ MCR NCP CLEAR OBJECT PHONE ALL
$ MCR NCP PURGE OBJECT PHONE ALL
$ MCR NCP CLEAR OBJECT TASK ALL
$ MCR NCP PURGE OBJECT TASK ALL

They could alternatively be modified thus:

$ MCR NCP SET OBJECT TASK USER ILLEGAL PASSWORD DISABLED
$ MCR NCP SET OBJECT TASK PROXY NONE
$ MCR NCP SET OBJECT TASK ALIAS INCOMING DISABLED
$ MCR NCP SET OBJECT TASK ALIAS OUTGOING DISABLED
$ MCR NCP DEFINE OBJECT TASK USER ILLEGAL PASSWORD DISABLED
$ MCR NCP DEFINE OBJECT TASK PROXY NONE
$ MCR NCP DEFINE OBJECT TASK ALIAS INCOMING DISABLED
$ MCR NCP DEFINE OBJECT TASK ALIAS OUTGOING DISABLED
$ MCR NCP SET OBJECT PHONE USER ILLEGAL PASSWORD DISABLED
$ MCR NCP SET OBJECT PHONE PROXY NONE
$ MCR NCP SET OBJECT PHONE ALIAS INCOMING DISABLED
$ MCR NCP SET OBJECT PHONE ALIAS OUTGOING DISABLED
$ MCR NCP DEFINE OBJECT PHONE USER ILLEGAL PASSWORD DISABLED
$ MCR NCP DEFINE OBJECT PHONE PROXY NONE
$ MCR NCP DEFINE OBJECT PHONE ALIAS INCOMING DISABLED
$ MCR NCP DEFINE OBJECT PHONE ALIAS OUTGOING DISABLED

In the second stage below, objects are modified so that
they are still usable, but subject to tighter controls
than the default.

The simplest change is made to the MIRROR object by
disabling the MIRRO$SERVER account in the User
Authorisation File. The MIRROR object should be kept to
allow loopback testing should it become necessary. The
account is disabled since it serves no useful purpose
(other than for loopback testing), and should be
disabled unless in use.

The MAIL object should be modified thus according to the
VMS v5.5-2 release notes, Section 2.8.7, to restrict
outgoing access on the mail server. In v5.5-2, MAIL
enables system privileges when it opens a DECnet
connection to a remote mail server. By restricting
outgoing access on the mail server object (as below),
unauthorised users are prevented from placing
connections on the mail server object.

$ MCR NCP SET OBJECT MAIL OUTGOING CONNECT PRIVILEGE SYSPRV
$ MCR NCP DEFINE OBJECT MAIL OUTGOING CONNECT PRIVILEGE SYSPRV

This can be undone by executing the same commands with
“NOSYSPRV”. MAIL_SERVER.EXE (the executable associated
with the MAIL object) is installed as a privileged
image.

Wrappers should also be installed for the FAL and NML
objects. The executable images for these are, by
default, normally FAL.EXE and NML.EXE respectively.
Modify the object database as shown below.

$ MCR NCP SET OBJECT FAL FILE LOCAL$WRAP:FAL.COM
$ MCR NCP DEFINE OBJECT FAL FILE LOCAL$WRAP:FAL.COM
$ MCR NCP SET OBJECT NML FILE LOCAL$WRAP:NML.COM
$ MCR NCP DEFINE OBJECT NML FILE LOCAL$WRAP:NML.COM

The contents of the wrappers are discussed in Section
4.1, Wrappers.

2.4 System Logicals And Logical Definitions

SYS$MANAGER:SYLOGICALS.COM is used to establish
important site-specific logical names across the entire
system. You can put meaningful local definitions in here
as well as the definitions already supplied with the
delivered system.

$! Undocumented feature to disable poor man’s routing
$ DEFINE /SYSTEM /EXEC FAL$LOG “03/DISABLE=8”

Poor Man’s Routing is explained in Section 3.3, FAL and
Poor Man’s Routing.

That section also explains the significance of this
definition. It’s relevance to this section is merely
that it is centrally defined in SYLOGICALS.COM.

$! Make network server processes die after 10 seconds
$! (to give separate NETSERVER.LOG files for
$! each distinct operation)
$ DEFINE /SYSTEM /EXEC NETSERVER$TIMEOUT “0000 00:00:10”

This forces network server processes to die after 10
seconds of lying idle, thus creating separate
NETSERVER.LOG files for each essentially distinct
operation. The tradeoff for these distinct files is the
price that must be paid in terms of process creation on
each network connection.

$! System databases
$ DEFINE /SYSTEM /EXEC LMF$LICENSE SYS$SYSTEM:LMF$LICENSE.LDB
$ DEFINE /SYSTEM /EXEC NETNODE_REMOTE SYS$SYSTEM:NETNODE_REMOTE.DAT
$ DEFINE /SYSTEM /EXEC NETPROXY SYS$SYSTEM:NETPROXY.DAT
$ DEFINE /SYSTEM /EXEC NETUAF SYS$SYSTEM:NETUAF.DAT
$ DEFINE /SYSTEM /EXEC RIGHTSLIST SYS$SYSTEM:RIGHTSLIST.DAT
$ DEFINE /SYSTEM /EXEC SYSUAF SYS$SYSTEM:SYSUAF.DAT
$ DEFINE /SYSTEM /EXEC VMSMAIL SYS$SYSTEM:VMSMAIL_PROFILE.DAT

If these aren’t defined, and a user attempts operations
on them, new ones can be created by that user. These
definitions prevent this. Note file protections for
these files in Section 2.7, File Protections.

Other system-wide logical symbols (such as LOCAL$WRAP)
would also be defined in this file.

2.5 System Passwords

VMS systems can have what is called a “system password”.
This is a password that must be typed BEFORE the host
prompts you for login information. So when you initially
connect to a system with a “system password”, you don’t
get any prompting on the screen. Once you have typed in
the password, the normal prompt message appears.

The system password will appear or not depending on the
value of the sysgen parameter TTY_DEFCHAR2. A value of
%X80000 (i.e. Hex) enables system password. This
parameter is not dynamic.

The SYSGEN parameter TTY_DEFCHAR2 (bit represented by
%X80000) enables system password by default for all
terminals (including LAT, X.25 and telnet terminals).

The default value for TTY_DEFCHAR2 is 4098 (decimal):

$ RUN SYS$SYSTEM:SYSGEN
SYSGEN> USE DEFAULT
SYSGEN> SHO TTY_DEFCHAR2
Parameter Name Current Default Min. Max. Unit Dynamic
————– ——- ——- —— —— —- ——-
TTY_DEFCHAR2 4098 4098 0 -1 Bit-Encode

The correct value can be set by modifying
SYS$SYSTEM:MODPARAMS.DAT, and AUTOGENing the system. The
required value in MODPARAMS.DAT is set by adding the
following lines (amongst other values):

TTY_DEFCHAR2 = %X80000 + %X1000 + %X2 ! = 528386
! %X80000 (bit 19) TT2$M_SYSPWD System password
! %X1000 (bit 12) TT2$M_EDITING Cmd line editing
! %X2 (bit 1) TT2$M_AUTOBAUD Autobaud

The actual system password can be set either by DCL or
by AUTHORIZE.

$ SET PASSWORD /SYSTEM

or else by

$ RUN SYS$SYSTEM:AUTHORIZE
UAF> MODIFY /SYSTEM_PASSWORD={password}

Terminals can be set /NOSYSPWD /PERM or /SYSPWD. See
Section 2.1.1 SYSTARTUP_V5.COM for an example.

2.6 The UAF File

This is an extremely useful file for tuning security on
an OpenVMS machine. The UAF file (and associated files)
allow you to control access to the system and allocate
resources to users.

For the purposes of this paper, there are several fields
worth considering. Specifically, the ones that can be
used include (but are not restricted to) access control
fields, password control fields and the rights list.

On the particular machine used in the preparation of
this paper, there are several accounts that are used for
specific purposes, and should be used only within
specific time frames. For instance, consider an account
(the “USER1” account for the purposes of this example)
which should only be used interactively during the hours
of 8am to 7pm on primary days (Monday to Friday), but
can run batch jobs at any time on any day. All other
access is to be denied.

This is achieved by the following commands:

$ RUN SYS$SYSTEM:AUTHORIZE
UAF> MODIFY USER1 /NONETWORK /NODIALUP –
/LOCAL=(PRIMARY:8-18) /REMOTE=(PRIMARY:8-18)

This results in an access control matrix like the one
below.

Primary days: Mon Tue Wed Thu Fri
Secondary days: Sat Sun
Primary 000000000011111111112222 Secondary 00000000001111111111222
Day Hours 012345678901234567890123 Day Hours 012345678901234567890123
Network: —– No access —— —– No access ——
Batch: ##### Full access ###### ##### Full access######
Local: ——–###########—– —– No access ——
Dialup: —– No access —— —– No access ——
Remote: ——–###########—– —– No access ——

Full access can be restored using:

$ RUN SYS$SYSTEM:AUTHORIZE
UAF> MODIFY USER1 /ACCESS=(PRIMARY:0-24,SECONDARY:0-24)

Passwords are historically a weak point in computer
systems. A weak password on a single account leaves the
entire system vulnerable to attack. (See Appendix 2,
SERT Advisory SA-93.04, Guidelines For Developing A
Sensible Password Policy.)

You must therefore ensure that all accounts have a
minimum password length of 8 characters, and that they
expire at regular intervals. In addition, privileged
accounts should have password lengths greater than that,
and passwords should be set using the MODIFY
{accountname} /GENERATE_PASSWORD command.

The other important use of the AUTHORIZE utility is
creating rights list identifiers and using these in
conjunction with ACLs to control access to files and
devices at individual levels.

For instance, on the machine used while preparing this
paper, there is a particular device and a directory that
should only ever be accessed by a small group of people.
This device is used for a research project, and the
results are kept in the directory. The entire group of
people involved with the experiment needed to read the
results (kept in the DISKE:[EXPERIMENT1] directory),
whereas only a few people needed write access to this
directory. Furthermore, because they were all in the
same project team, they were all allocated the same
group number. Finally, there was a restricted number of
people in this group who were authorised to access the
device used in the experiment in question.

The first step in controlling this is to create various
rights list identifiers, and granting them to people who
should access them. The rights list identifiers are
created as follows:

$ RUN SYS$SYSTEM:AUTHORIZE
UAF> ADD /IDENTIFIER EXP1_READ
UAF> ADD /IDENTIFIER EXP1_WRITE
UAF> ADD /IDENTIFIER EXP1_CONTROL
UAF> EXIT

Users 1..10 are allowed read access to the results;
users 5, 6 and 7 are allowed write access and users 6
and 7 are allowed to control the transducer.

$ RUN SYS$SYSTEM:AUTHORIZE
UAF> GRANT /IDENTIFIER EXP1_READ USER1
UAF> GRANT /IDENTIFIER EXP1_READ USER2
UAF> GRANT /IDENTIFIER EXP1_READ USER3
UAF> GRANT /IDENTIFIER EXP1_READ USER4
UAF> GRANT /IDENTIFIER EXP1_READ USER8
UAF> GRANT /IDENTIFIER EXP1_READ USER9
UAF> GRANT /IDENTIFIER EXP1_READ USER10
UAF> GRANT /IDENTIFIER EXP1_WRITE USER5
UAF> GRANT /IDENTIFIER EXP1_WRITE USER6
UAF> GRANT /IDENTIFIER EXP1_WRITE USER7
UAF> GRANT /IDENTIFIER EXP1_CONTROL USER6
UAF> GRANT /IDENTIFIER EXP1_CONTROL USER7
UAF> EXIT
$

ACLs and protection are then set on the device and
directory as set out in Section 2.8, ACLs.

Finally, great care has been taken in the allocation of
privileges to individual user accounts. In particular,
the default privileges must be kept to the minimum
required.

2.7 File Protections

File protection is an important aspect in preventative
security. Checks should be periodically carried out for
world-writeable files and directories, and appropriate
action taken.

In addition, various sensitive files should be confirmed
as having the following protection.

:[000000]000000.DIR (S:RWE,O:RWE,G:RE,W:E)
:[000000]INDEXF.SYS (S:RWE,O:RWE,G:RE,W)

* This prevents unauthorised users from finding
directory and file names.

SYS$SYSTEM:AUTHORIZE.EXE (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NCP.EXE (S:RWE,O:RWE,G:RWE,W)

* This ensures that unauthorised users cannot change
the NCP and authorisation databases through the use
of these programs. Note that merely protecting
these programs does not prevent modification of the
data files – it is imperative that the data files
themselves are protected.

SYS$SYSTEM:NETCIRC.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETCONF.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETLINE.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETLOGING.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETNODE_LOCAL.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETNODE_REMOTE.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETOBJECT.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETPROXY.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETUAF.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETX25.DAT (S:RWE,O:RWE,G:RWE,W)
SYS$SYSTEM:NETX29.DAT (S:RWE,O:RWE,G:RWE,W)

* This ensures that unauthorised users cannot change
information in these databases, nor gain
information about other users or system
configuration from these files.

SYS$SYSTEM:RIGHTSLIST.DAT (S:RWE,O:RWE,G:RE,W:RE)

SYS$SYSTEM:SYSUAF.DAT (S:RWE,O:RWE,G:RWE,W)
ACL=(NETWORK,ACCESS=EXECUTE)

SYS$SYSTEM:VMSMAIL.DAT (S:RWE,O:RWE,G:RWE,W)

SYS$SYSTEM:VMSMAIL_PROFILE.DATA (S:RWE,O:RWE,G:RWE,W)

* This ensures that unauthorised users cannot change
information in these databases, nor gain
information about other users from these files.

For more details on File Protections, see Managing
Security in a Multi-Vendor Network by Ron Tencati, and
also the Guide to VAX/VMS System Security manual.

2.8 ACLs

This section, is a continuation of the example supplied
in Section 2.6, The UAF File, about access control using
rights list identifiers.

In a particular experiment, experimental results are
being kept in the DISKE:[EXPERIMENT1] directory. The
results are obtained using a transducer controlled on
device RCD0:.

Various rights list identifiers to read results
(EXP1_READ), write a file to the results directory
(EXP1_WRITE) and control the transducer (EXP1_CONTROL)
have been created. These rights identifiers are used in
the the creation of access control lists to enforce
these access control principles.

The transducer is the first object so modified:

$ SET ACL /OBJECT=DEVICE /ACL=( –
(IDENTIFIER=SYSTEM,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL), –
(IDENTIFIER=EXP1_CONTROL,ACCESS=READ+WRITE+DELETE+CONTROL), –
(IDENTIFIER=[*,*],ACCESS=NONE)) RCD0:

$ SHOW DEVICE RCD0: /FULL
:
{Device details on NODE1$RCD0: deleted}
:
device, error logging is enabled.
Error count 0 Operations completed 26
Owner process “” Owner UIC [0,0]
Owner process ID 00000000 Dev Prot S:RWED,O:RWED,G:RWED,W:RWED
Reference count 0 Default buffer size 2048
Density unknown Format {deleted}
Volume status: {deleted}

Device access control list:
(IDENTIFIER=[SYSTEM],ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL)
(IDENTIFIER=EXP1_CONTROL,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL)
(IDENTIFIER=[*,*],ACCESS=NONE)

On the machine used for preparing this paper, the nature
of the device prevented us from changing the protection
using the SET PROTECTION/DEVICE command. However, the
ACL is sufficient to control access to this device.

The next step is to protect the directory (and files
under it). An ACL is applied to the directory file
usinfg the commands on the next page.

$ SET ACL /OBJECT=FILE /ACL=( –
(IDENTIFIER=EXP1_WRITE,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL), –
(IDENTIFIER=EXP1_READ, ACCESS=READ+EXECUTE), –
(IDENTIFIER=SYSTEM, ACCESS=READ+EXECUTE), –
(IDENTIFIER=[*,*], ACCESS=NONE)) DISKE:[000000]EXPERIMENT1.DIR
$
$ SET PROTECTION DISKE:[000000]EXPERIMENT1.DIR /PROTECTION=(S,O,G,W)
$

$ DIR DISKE:[000000]EXPERIMENT1.DIR /SECURITY
Directory DISKE:[000000]

EXPERIMENT1.DIR;1 4 17-JUN-1992 11:19:27.01 [SYSTEM] (,,,)
(IDENTIFIER=EXP1_WRITE,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL)
(IDENTIFIER=EXP1_READ,ACCESS=READ+EXECUTE)
(IDENTIFIER=[SYSTEM],ACCESS=READ+EXECUTE)
(IDENTIFIER=[*,*],ACCESS=NONE)
Total of 1 file, 4 blocks.

This means that only people who specifically possess the
EXP1_WRITE rights list identifier can write to this
directory. Users who possess the EXP1_READ identifier
can read the contents of the directory as can the SYSTEM
account (but not system privileged accounts or system
UIC group members). All other access is denied.

Note that action is taken on the first match of the ACL.
So, for example, if the SYSTEM account is being used to
access data in DISKE:[EXPERIMENT1], and the system
account has the EXP1_READ right, then SYSTEM can read
the data by virtue of this right as opposed to being the
system account. The reason for this is that the
EXP1_READ identifier occurs before [SYSTEM] in the ACL.

Any directories created in this directory after the
creation of this ACL will inherit this ACL.

2.9 SYSGEN Parameters

There are various SYSGEN parameters that must be
considered and/or changed during configuration. Many of
these are related to system performance and are not
within the scope of this paper. Parameters that must be
considered from a security point of view are listed
below, with extracts from the SYSGEN HELP facility on
their use. (See SYSGEN> HELP PARAMETERS for more
details.)

TTY_DEFCHAR2: Bit 19 (TT2$M_SYSPWD) is set to allow the
use of system passwords. The password was set using the
AUTHORIZE utility (see Section 2.5, System Passwords),
and the console is modified such that the password is
not required when logging on from that source (using SET
TERMINAL OPA0: /PERMANENT /NOSYSPASSWORD). (See Section
2.1.1, SYSTARTUP_V5.COM.) All other terminals must enter
the system password before the login prompt is issued.

This parameter (TTY_DEFCHAR2). amongst others, can be
set in SYS$SYSTEM:MODPARAMS.DAT with a single line:

TTY_DEFCHAR2 = %X80000 + %X1000 + %X2 ! = 528386
! %X80000 (bit 19) TT2$M_SYSPWD System password
! %X1000 (bit 12) TT2$M_EDITING Cmd line editing
! %X2 (bit 1) TT2$M_AUTOBAUD Autobaud

LGI_PWD_TMO: Period of time, in seconds, a user has to
correctly enter the system password on a terminal on
which the system password is in effect.

LGI_BRK_TMO: Specifies the number of seconds that a
user, terminal, or node is permitted to attempt a login
before the system assumes that a breakin attempt is
occurring and evasive action is required.

LGI_BRK_LIM: Specifies the number of failures that may
occur at login time before the system will take action
against a possible breakin.

LGI_RETRY_TMO: Specifies the number of seconds allowed
between login retry attempts after a login failure.

LGI_RETRY_LIM: Specifies the number of retry attempts
allowed for users attempting to login over dialup lines.

LGI_HID_TIM: Specifies the number of seconds that
evasive action will persist following the detection of a
possible breakin attempt. The evasive action consists of
refusing to allow any logins during this period,
regardless of whether a valid user name and password are
specified.

LGI_BRK_DISUSER: When set, turns on the DISUSER flag in
the UAF record when an attempted breakin is detected,
thus permanently locking out that account.

LGI_BRK_TERM: Causes the terminal name to be part of the
association string for the terminal mode of breakin
detection.

Note that if parameters are changed using SYSGEN, modify
both the CURRENT image and the ACTIVE, running system.
Leave DEFAULT as it is.

2.10 Tailoring UCX

The machine being configured required only incoming
telnet access, and outgoing telnet and ftp. SMTP is
handled by a dedicated mail package (MX). Other services
like SNMP, NFS and Berkeley “r” commands are not
required (or, in fact, desirable).

Services not required are shutdown thus:

$! — Shutdown what we don’t need
$!
$ @SYS$MANAGER:RPC$UCX_SHUTDOWN.COM
$ @SYS$MANAGER:UCX$LPD_SHUTDOWN.COM
$ @SYS$MANAGER:UCX$NFS_SHUTDOWN.COM
$ @SYS$MANAGER:UCX$SMTP_SHUTDOWN.COM
$ @SYS$MANAGER:UCX$SNMP_SHUTDOWN.COM
$!
$! — Disable incoming connections on other services
$!
$ UCX DISABLE SERVICE FTP
$ UCX DISABLE SERVICE REXEC
$ UCX DISABLE SERVICE RLOGIN
$ UCX DISABLE SERVICE RSH

In addition, the relevant UCX accounts are disabled in
the User Authorization File (using UAF> MODIFY
/flag=DisUser): UCX$FTP, UCX$NFS, UCX$REXEC, UCX$RSH,
UCX$SNMP, UCX_LPD, UCX_SMTP. Telnet (interactive) access
should be monitored using a wrapper (as discussed in
Section 4.1, Wrappers).

2.11 Proxies

Proxies should not be allowed if they are not required!
If a net proxy is required for file transfer, the proxy
must be created on the remote machine, and the required
command issued on the local machine. The theory here is
that the local machine is less likely to be compromised
than an outside machine, and the use of proxies will
reduce the instances of access information being
transmitted over a network connection.

Only allow proxy access to a non-privileged account on
the target system.

System Mechanisms For Configuring
The Machine To Log Activity

There are several facilities available to the system
administrator to achieve effective logging. Specifically
these are accounting and auditing. There is also scope
for development of local tools. In this section, I will
outline the use of the standard facilities, while
homegrown mechanisms will be considered in the next
section.

Firstly, it will be useful to have a brief look at
accounting and auditing. System accounting is a facility
for recording information about the use of the machine
from a normal system accounting perspective, whereas the
system audit logger records similar information, but
from a system security perspective. Both of these can be
used to construct audit trails of activity. Information
from the system audit logger can be gleaned not only
from the audit journal, but also from the operator log,
as the auditor also sends it’s messages to OPCOM.

Consider, for example, a situation in which a user
(USER1) has made a modification to USER2’s entry in the
User Authorization File.

The audit logger returns the following information:

Security alarm (SECURITY) and security audit (SECURITY) on NODE1,
system id: 1072 / System UAF record modification
Event time: 27-JUL-1993 12:15:17.47
PID: 0000005F
Username: USER1
Image name: NODE1$DKA0:[SYS0.SYSCOMMON.][SYSEXE]AUTHORIZE.EXE
Object name: SYS$COMMON:[SYSEXE]SYSUAF.DAT;1
Object type: file
User record modified: USER2
Fields modified: FLAGS,PRIVILEGES

The accounting facility contains this:

AUTHORIZE Image Termination
—————————
Username: USER1 UIC: [STAFF,USER1]
Account: STAFF Finish time: 27-JUL-1993 12:15:27.79
Process ID: 0000005F Start time: 27-JUL-1993 12:14:51.23
Owner ID: Elapsed time: 0 00:00:36.56
Terminal name: RTA1: Processor time: 0 00:00:00.22
Remote node addr: 1038 Priority: 4
Remote node name: NODE2 Privilege <31-00>: 10148001
Remote ID: USER2 Privilege <63-32>: 00000040
Queue entry: Final status code: 00000001
Queue name:
Job name:
Final status text: %SYSTEM-S-NORMAL, normal successful completion

Page faults: 238 Direct IO: 32
Page fault reads: 9 Buffered IO: 58
Peak working set: 631 Volumes mounted: 0
Peak page file: 1166 Images executed: 244
Image name: NODE1$DKA0:[SYS0.SYSCOMMON.][SYSEXE]AUTHORIZE.EXE

Both facilities tell us that USER1 ran the AUTHORIZE
utility successfully under PID 5F at 12:15 pm on 27-Jul-
1993. From the accounting, we can see at a glance where
USER1 logged in from. The audit logger tells us exactly
what USER1 did whilst running this utility.

Consider another example, in which a computer cracker
has logged in from an X.25 network address in an attempt
to maintain anonymity. The audit server has recorded the
following information in the operator log:

%%%%%%%%%%% OPCOM 27-Jul-1993 19:38:23.60 %%%%%%%%%%%
Message from user AUDIT$SERVER on NODE1
Security alarm (SECURITY) and security audit (SECURITY) on NODE1,
system id: 1038
Auditable event: Dialup interactive login
Event time: 27-Jul-1993 19:38:23.59
PID: 20205316
Username: USER1
Terminal name: _VTA1514 ({X.25 address deleted})

The system accounting record from the same user logging
out returns the following information:

LOGINOUT Image Termination
————————–
Username: USER1 UIC: [STAFF,USER1]
Account: STAFF Finish time: 27-Jul-1993 03:36:17.69
Process ID: 20205316 Start time: 27-Jul-1993 19:38:07.19
Owner ID: Elapsed time: 0 07:58:10.50
Terminal name: VTA1514 Processor time: 0 00:00:46.14
Remote node addr: Priority: 4
Remote node name: Privilege <31-00>: 00108000
Remote ID: Privilege <63-32>: 00000000
Queue entry: Final status code: 00000001
Queue name:
Job name:
Final status text: %SYSTEM-S-NORMAL, normal successful completion

Page faults: 4716 Direct IO: 20927
Page fault reads: 208 Buffered IO: 85056
Peak working set: 970 Volumes mounted: 0
Peak page file: 4813 Images executed: 28
Image name: NODE1$DKA0:[SYS0.SYSCOMMON.][SYSEXE]LOGINOUT.EXE

The two records act as a useful cross check for each
other. The audit logger shows the X.25 address from
which the user logged in from (which is not available in
this accounting record). The accounting facility shows
the length of time that the user was on the system. When
this information is collated with the network accounting
information, then the cost of the connection can be
calculated. Furthermore the accounting records and audit
records can be examined to aid in determining the extent
of the damage caused by the attacker.

3.1 Accounting

Confirm that required system accounting is enabled thus:

$ SET ACCOUNTING /ENABLE[=(Keyword…)]

The command above enables logging of all activities on
the system in the accounting file. Accounting can be
enabled to log the following activities.

PROCESS any process termination
IMAGE image execution
INTERACTIVE interactive job termination
LOGIN_FAILURE login failures
SUBPROCESS subprocess termination
DETACHED detached job termination
BATCH batch job termination
NETWORK network job termination
PRINT all print jobs
MESSAGE user messages

Each day, a new accounting file should be created in
order to keep the accounting files of a manageable size,
using the command –

$ SET ACCOUNTING /NEW_FILE

3.2 Auditing

The auditor can be configured to log the following
events:

ACL Event requested by an Access Control List Item
AUTHORIZATION Modification of the system user authorization file
BREAKIN Occurrence of a breakin attempt
(from various sources)
FILE_ACCESS File or global section access
(by various methods)
INSTALL Occurrence of any INSTALL operation
LOGFAILURE Occurrence of a login failure
(from various sources)
LOGIN A login attempt (from various sources)
LOGOUT Occurrence of a logout
MOUNT Issuance of a mount or dismount request

This is done using SET AUDIT /ENABLE=(keyword[,…]).
The /ALARM qualifier is also used to raise an alarm to
all terminals enabled as security operators.

You can examine the configuration of your system audit
server using SHOW AUDIT /ALL. The categories that should
be carefully considered are the auditing server
characteristics, the alarm failure mode, and the enabled
security alarms.

Note that within the auditing server characteristics,
the default final resource action is to crash the system
if the system runs out of virtual memory. This means
that if the disk containing the audit journal log is
full, the system will crash, thus exposing the system to
denial of service attacks. When configuring the audit
server, you should carefully consider the final resource
action parameter. It can be set using the SET AUDIT
command.

$ SET AUDIT /SERVER=FINAL_ACTION=action

(where action can be one of CRASH, IGNORE_NEW or
PURGE_OLD)

As with system accounting, a new audit journal should be
created each day:

$ SET AUDIT /SERVER=NEW_LOG

3.3 FAL and Poor Man’s Routing

In order to properly explain the step taken in this
phase, it is necessary to understand what Poor Man’s
Routing is, and how it is linked with the File Access
Listener (FAL) object and the logical FAL$LOG.

The FAL object (File Access Listener) is the DECnet
object that allows a remote user to access files on your
node. It can be used to browse your node, or perform
file transfers. For legitimate users, this is extremely
useful – unfortunately, people with malintent also find
it useful if your system is not protected.

In the context of DECnet networking operations (and
specifically FAL), “Poor Man’s Routing (PMR) refers to
the technique of supplying an explicit path to the
required target, rather than letting assigned DECnet
routers pick the most optimal path” [Tencati]. When PMR
is used, a process is created on each node in the path
to forward the connection to the next node in the path.
Each of these nodes (including the destination node)
only sees the connection from it’s path predecessor. It
is therefore very difficult to ascertain from the
destination node where the connection originated from.

The legitimate use of this is in cases where the source
node may not know anything about the remote note.
Unfortunately, people with malintent can use the
properties described above to create a convoluted path
to the node they wish to attack (possibly via several
timezones and countries) to hide themselves effectively.

PMR can also be used to defeat the hiding of DECnet
subnets. There is a parameter in the NCP database called
the maximum area (see NCP> HELP SET EXECUTOR MAXIMUM
AREA). This parameter specifies the largest area number
known to an executor’s routing layer. If used carefully,
this parameter can be used to hide subnets. PMR can be
used to circumvent this technique if the attacker has
appropriate information about your network design. (The
lesson here is to never trust security through obscurity
– always rely on robust, proactive methods rather than
ignorance.) Ron Tencati’s Managing Security in a Multi-
Vendor Network gives a good explanation of PMR, and the
use of Area Routing.

You can configure FAL by use of the logical symbol
FAL$LOG. In the machine used in the preparation of this
paper, this logical was configured to do two things:

* refuse connections made by PMR
* supply audit trail information in NETSERVER.LOG
files in the case of successful FAL connections.

The logical name FAL$LOG translates to a string of the
form xx_yy where:

* xx is a hexadecimal number representing a longword
string value
* yy is a hexadecimal number specifying how many bytes
of each DAP message are to be displayed in the log
file (SYS$OUTPUT:).

The hexadecimal flags are:

0001 – log filename/function requests
0002 – log throughput statistics
0004 – log individual DAP messages
0008 – log DAP message packet AST requests (logged at AST level)
0010 – log DAP message packet QIO requests
0020 – reserved
0040 – disable DAP message blocking
0080 – disable DAP CRC error checking

In SYS$MANAGER:SYLOGICALS.COM, FAL$LOG should be defined
to be the character string “03/DISABLE=8” (See Section
2.4, System Logicals And Logical Definitions). By
setting this logical to this value, the following is
achieved:

* PMR is disabled (“/DISABLE=8”)
* filename/function requests and throughput statistics
are logged (the setting “03” being the addition of
“01” and “02”

Consider an example where NODE1::USER1 is executing a
directory on NODE2::USER2’s home directory. In the file
NETSERVER.LOG in USER2’s directory, we would see the
following results.

With no definition for FAL$LOG:

——————————————————–
Connect request received at 28-JUL-1993 15:36:45.78
from remote process NODE1::”0=USER1″
for object “SYS$COMMON:[SYSEXE]FAL.EXE”
——————————————————–

With FAL$LOG defined to be “03/DISABLE=8″, extra
information is appended:

——————————————————–
Connect request received at 28-JUL-1993 15:55:40.28
from remote process NODE1::”0=USER1”
for object “SYS$COMMON:[SYSEXE]FAL.EXE”
——————————————————–

========================================================
FAL V5.1-D3 started execution on 28-JUL-1993 15:55:41.12
with SYS$NET = NODE1::”0=USER1″ and with FAL$LOG = 03

Logical link was established on 28-JUL-1993 15:55:41.13

Requested file access operation: Directory List
Specified file: DISKE:[USER2]L*.*;*
Resultant file: DISKE:[USER2]LOGIN.COM;3
Resultant file: DISKE:[USER2]LWK_PERSONAL.LINKBASE;1

Logical link was terminated on 28-JUL-1993 15:55:41.18

Total connect time for logical link was 0 00:00:00.05
Total CPU time used for connection was 0 00:00:00.02

File Access Statistics for RECV-Side XMIT-Side Composite
————————– ——— ——— ——–
# DAP Message QIO Calls 2 2 4
# DAP Messages Exchanged 2 14 16
# User Records/Blocks 0 0 0
NETSERVER.LOG (continued)

# Bytes of User Data 0 0 0
# Bytes in DAP Layer 49 310 359
User Data Throughput (bps) 0 0 0
DAP Layer Throughput (bps) 7840 49600 57440
Average Record/Block Size 0 0 0
% User Data in DAP Layer 0.0% 0.0% 0.0%
————————– ——— ——— ———

Negotiated DAP buffer size = 1060 bytes
Buffered I/O count during connection = 13
Direct I/O count during connection = 0
Peak working set size for process = 470 pages

Successful Start Transaction Branch = 0
Start Transaction Branch loops = 0

FAL terminated execution on 28-JUL-1993 15:55:41.21
========================================================

Using Homegrown Or Publicly Available Software

4.1 Wrappers

A “wrapper” is a piece of software that monitors an
attempt to use a service, and based on the details about
the source of the attempt (such as remote host and user,
time, and connection type), determine whether to allow
the use of the service or not. This is the feature that
a wrapper has available to it over and above standard
system logging software: the use of the wrapper gives
the system manager freedom to make decisions whether to
allow the use of the machine from a remote site in
addition to simply logging that use.

Wrappers should be constructed for the NML and FAL
objects, and also for interactive logins. Section 2.1.2,
SYLOGIN.COM and Section 2.3.2, Objects gives the details
on how to install these wrappers.

Because the NML and FAL wrappers need to handle DECnet
connections only, they are more simple than the
interactive login wrapper.

The DECnet object wrappers evaluate the connection by
comparing the remote node and user combination against a
set of rules. The set of rules is described in two
files:
AllowFile which describes which combinations may make
the connection, and
DenyFile which describes which combinations may not
make the connection.

Wildcards are allowed. The general algorithm is:

Main ()
{
RemoteUser = f$trnlnm(“SYS$REM_ID”)
RemoteNode = f$trnlnm(“SYS$REM_NODE”)
ConnectionOkay = CheckRules(RemoteNode, RemoteUser)
if (ConnectionOkay = Allow) /* ConnectionOkay = Allow|Deny */
then
write successful connection record to wrapper log
request/to=(network,security) “
run SYS$SYSTEM:FAL.EXE
else
write failed connection record to wrapper log
request/to=(network,security) “
logout
endif
} end Main
CheckRules (RemoteNode, RemoteUser)
{
if ((result = CheckCombination(RemoteNode, RemoteUser)) != Unknown)
then return result
if ((result = CheckCombination(RemoteNode, “*”)) != Unknown)
then return result
if ((result = CheckCombination(“*”, “*”)) != Unknown)
then return result
return Deny
} end CheckRules
CheckCombination (RemoteNode, RemoteUser)
{
Search AllowFile for RemoteNode::RemoteUser
if found then return Allow
Search DenyFile for RemoteNode::RemoteUser
if found then return Deny
return Unknown
} end CheckCombination

The search commands used above should be such that a
wildcard search matches the literal “*” in a file, not
any string (in a similar manner to the VMS “SEARCH”
command). Hence the wildcard value of “*” is placed in
the file by the system manager. The general philosophy
that should be adopted is to use a blanket denial (a
single line of “*::*” in the deny file) with specific
allowed node::user combinations in the allow file.

The interactive connection wrapper is similar, with only
a slightly more complicated top level algorithm:

Main ()
{
| Establish RemoteUser
| Establish RemoteNode
ConnectionOkay = CheckRules(RemoteNode, RemoteUser)
if (ConnectionOkay = Allow) /* ConnectionOkay = Allow|Deny */
then
write successful connection record to wrapper log
request/to=(network,security) “
| exit(Success)
else
write failed connection record to wrapper log
request/to=(network,security) “
| exit(Failure)
endif
} end Main

The main problem here is to establish remote user and
node identities. Interactive access may take place using
DECnet, LAT, TCP/IP and so on. System values used to
find this information are:

* F$TRNLNM(“SYS$REM_ID”)
* F$TRNLNM(“SYS$REM_NODE”)
* F$GETDVI(“SYS$COMMAND”,”TT_ACCPORNAM”)
* the DECnet database
* the local terminal type of the connection
* information from F$TRNLNM(“DECW$DISPLAY”)

Connections are then evaluated not only on remote node
and user (if provided by the protocol), but also by the
protocol used for the connection and local
characteristics (such as the time).

It is important to note that any reading from AllowFile
or DenyFile, and writing to the wrapper log should be
carried out by installed, protected images, and that the
command file(s) and executable(s) used are writeable
only by system privileged accounts. This prevents
modification of behaviour and recorded results by
potential attackers.

Example code and configuration files appear in Appendix
3, Wrapper Example.

4.2 Single Use PINs

A Personal Identification Number (PIN) is simply the
numerical equivalent of a text-based password. Unlike a
normal password system, though, a single use PIN relies
on algorithmic knowledge rather than static value
knowledge.

The system works thus: when a user logs in, system and
user passwords must be supplied as described in previous
sections. A numerical challenge is then issued. The user
must supply the correct reply to this challenge, or the
login will be denied. The correct reply is some
permutation of the original challenge. The challenge
must be randomly generated, so that every time the user
logs in, a different numerical challenge is supplied,
requiring a unique reply – only the algorithm used to
deduce the reply from the challenge is static.
Furthermore, this algorithm is different for each user.
The software which issues the challenge and receives the
reply must be robust, so that an attacker cannot simply
“crash” the software and hence bypass this mechanism.

Such systems are available commercially. A smart-card is
usually supplied with such systems. The user keys the
challenge supplied by the host into the smartcard using
the keypad. The smartcard then displays the response,
and the user enters this as the reply to the host.

A cheaper alternative is to write such a system locally,
fulfilling all of these criteria. A usage policy must be
in place to effectively manage this system.

4.3 Terminal Monitors

Terminal monitors are useful utilities for providing
help to users who may be working remotely, or may not be
reachable by telephone and require some type of help in
real-time (i.e. electronic mail would not suffice).

Where such utilities are available on the system, they
must be adequately protected to ensure that unauthorised
users can neither use them nor copy them. Care must be
taken to ensure that explicit permission is sought by
the legitimate users concerned or a relevant authority
when such a utility is used.

Similar principles apply when using system software for
capturing a process’s recall buffer in order to examine
the commands issued by that process.

Monitoring The Use Of The Machine

It is essential to carry out monitoring on any machine
in order to evaluate the health of the system. In
addition to checks that should be carried out on a
regular basis, steps should be taken to be allow for
investigation of unusual security related events as soon
as possible.

5.1 The SHOW INTRUSION Command

Use the command SHOW INTRUSION regularly. This command
displays the contents of the break-in database,
providing a quick technique for checking if there have
been attempts to break into your system in the immediate
past.

When using the SHOW INTRUSION command, you must first
get some idea if the host has detected any potential
breakins:

$ SET PROC/PRIV=(CMKRNL,SYSPRV)
$ SHOW INTRUSION
Intrusion Type Count Expiration Source
NETWORK SUSPECT 6 16:32:23.03 NODE2::USER2
TERM_USER SUSPECT 3 16:18:14.16 USER1

In this case, there are two suspect incidents. The
records below show that the first was an attempt by
USER2 on node NODE2 to login as USER1 on the local host
(NODE1) via DECnet. The second is an attempt to login as
USER1 on the local host using telnet from NODE3 (which
in this case was actually the localhost – 127.0.0.1).

The accounting records show the following:

LOGIN FAILURE
————-
Username: USER1 UIC: [SYSTEM]
Account: Finish time: 3-AUG-1993 16:02:28.80
Process ID: 2080D073 Start time: 3-AUG-1993 16:02:19.59
Owner ID: Elapsed time: 0 00:00:09.21
Terminal name: RTA3: Processor time: 0 00:00:00.23
Remote node addr: 1038 Priority: 4
Remote node name: NODE2 Privilege <31-00>: 0010C000
Remote ID: USER2 Privilege <63-32>: 00000000
Queue entry: Final status code: 10D380FC
Queue name:
Job name:
Final status text: %LOGIN-F-INVPWD, invalid password

Page faults: 234 Direct IO: 24
Page fault reads: 5 Buffered IO: 40
Peak working set: 287 Volumes mounted: 0
Peak page file: 1474 Images executed: 1

LOGIN FAILURE
————-
Username: USER1 UIC: [SYSTEM]
Account: Finish time: 3-AUG-1993 16:03:20.85
Process ID: 2080D878 Start time: 3-AUG-1993 16:03:11.77
Owner ID: Elapsed time: 0 00:00:09.08
Terminal name: VTA3959 Processor time: 0 00:00:00.21
Remote node addr: Priority 4
Remote node name: Privilege <31-00>: FFFFFFFF
Remote ID: Privilege <63-32>: FFFFFFFF
Queue entry: Final status code: 10D380FC
Queue name:
Job name:
Final status text: %LOGIN-F-INVPWD, invalid password

Page faults: 235 Direct IO: 18
Page fault reads: 5 Buffered IO: 41
Peak working set: 284 Volumes mounted: 0
Peak page file: 1474 Images executed: 1

The audit records show the following:

Security alarm (SECURITY) and security audit (SECURITY) on NODE1,
system id: 1072 / Remote interactive login failure
Event time: 3-AUG-1993 16:02:19.59
PID: 00000D33
Username: USER1
Terminal name: _RTA1:
Remote nodename: NODE2 Remote node id: 1184
Remote username: USER2
Status: %LOGIN-F-INVPWD, invalid password

Security alarm (SECURITY) and security audit (SECURITY) on NODE1,
system id: 1072 / Remote interactive login failure
Event time: 3-AUG-1993 16:03:11.77
PID: 00000CB4
Username: USER1
Terminal name: _TNA7:
Remote nodename: 127.0. Remote node id: 2130706433
Remote username: TELNET_7F000001
Status: %LOGIN-F-INVPWD, invalid password

Note that the remote nodename is always truncated to six
characters. The remote node id is a numerical
representation of the remote address.

Notice from the failed telnet login above that the
remote username is given as TELNET_7F000001. This
equates to the IP address 127.0.0.1 thus:

7 * 16 + F = 127
0 * 16 + 0 = 0
0 * 16 + 0 = 0
0 * 16 + 1 = 1

Hence if this attempt had come from the Network
Information Centre (nic.ddn.mil, Internet address
192.112.36.5), the remote username would have appeared
TELNET_C0702405.

5.2 Daily Activities

A batch file must be written in order to carry out
regular activities on a daily basis. Amongst these
activities should be various checks on log files. These
are listed below.

$ SEARCH/OUTPUT=BREAKIN_CHECK.TMP SYS$MANAGER:OPERATOR.LOG;-1 –
“Security alarm”/WINDOW=(3,8)
$ ANALYZE/AUDIT/BRIEF/SUMMARY/NOINTERACTIVE/OUTPUT=BREAKIN_CHECK.TMP –
SYS$MANAGER:SECURITY_AUDIT.AUDIT$JOURNAL;-1
$ ACCOUNT/LOG/SORT=(TYPE,STARTED)/OUTPUT=BREAKIN_CHECK.TMP ACCOUNTNG;-1

Any one of these can be used for obtaining information
about the life of the system. The amount and type of
information required should be used to determine which.
When any record from the output of these files reveals
an incident that appears unusual, then further checking
is required. The daily summary returned by any one of
the commands above should only be used to indicate that
this action is required – you should not rely on just
the summary information returned by these commands.

$ SHOW AUDIT/ALL/OUTPUT=AUDIT_CHECK.TMP

Check daily that the security auditing characteristics
you require are in place, and have not been changed.

$ ANALYZE/ERROR/SINCE=”-1 0:0:0.0″/OUTPUT=ERROR_CHECK.TMP

Examine the error log daily as well. This will not
necessarily alert you to a security incident, but it
will draw your attention to any system problems that
could potentially hinder your efforts to recover from
disaster. (You could also put the “SHOW ERROR” command
in your LOGIN.COM file.)

$ MAIL/NOSELF/NOEDIT LOCAL$WRAP:INTERACTIVE.LOG –
“@SYS$SYSROOT:[SYSMGR.MAIL]DAILY_BATCH.DIS” –
/SUBJECT:”Logged interactive logins”

Wrappers were discussed in Section 4.1, Wrappers. As
part of your daily checking, you should mail to
yourself, and other relevant users, the output from
these wrappers on a daily basis. The example above
mentions only output from the interactive wrapper log –
the implication is that all logs should be checked.

5.3 Having a Live Console

Don’t rely simply on on-line sinks (such as
OPERATOR.LOG) for your security oriented output. In the
event of a system compromise, it is quite likely that an
attacker will attempt to delete or modify information in
system files.

A good idea is to enable a security operator’s terminal.
In addition to (or even instead of) the normal system
console (usually OPA0:), you should consider using a
security operator’s terminal one that provides hardcopy
output and is located in a secure location.

(A word of caution: even an unsuccessful attack could
seriously disrupt your system if the hardcopy printer
runs out of paper.)

Using the example from the Guide to VMS System Security
manual, consider an example where such a terminal
(TTA3:) has been designated, and security messages are
to be disabled on the console. This can be achieved
thus:

$ DEFINE/USER SYS$COMMAND OPA0:
$ REPLY/DISABLE=SECURITY
$ DEFINE/USER SYS$COMMAND TTA3:
$ REPLY/ENABLE=SECURITY

You can, of course, enable other message classes to this
terminal as well.

Acknowledgements

Most of the undocumented material in this paper is a
mixture of my own work and other material that has been
passed on to me by various colleagues at The University
Of Queensland. The original idea for the wrapper was
inspired by Ron Tencati, and Wietse Venema’s public
domain tcp_wrapper for UNIX systems.

References

VAX/VMS Documentation manuals:

DEC TCP/IP Services for VMS System Management
Guide to VAX/VMS System Security
Access Control List Editor Utility
Accounting Utility
Audit Analysis Utility
Authorize Utility
Guide to Maintaining a VMS System
Network Control Program Manual
Networking Manual

Ron Tencati, Ken Coar and E Eugene Schultz

Managing Security in a Multi-Vendor Network, 1992

Appendix 1

SERT Advisory SA-93.03, Suggested Login Banner

=============================================================================
SA-93:03A SERT Advisory
31-May-1993
Suggested Login Banner
—————————————————————————–

On 7-May-1993, the Security Emergency Response Team released Advisory
SA-93:03. Since then, it has been brought to our attention that the word
“permission” could be considered ambiguous as Unix file systems use
“permission” bits to specify if access is granted to a file or not.

Further advice from the Commonwealth Director of Public Prosecutions
indicates:

“‘Permit’ does seem to include a meaning of ‘allow or let happen even by
accident or carelessness’.”

“‘Authority’ or ‘authorisation’ suggest that someone has deliberately
turned their mind to an action and formally approved that action.”

“In light of the fact that there does appear to be a difference in meaning
between words ‘permit or permission’ and ‘authority or authorisation’ and
the fact that computer scientists refer to ‘permission’ bits on Unix files,
it does appear desirable that the words ‘authority’ or ‘authorisation’ be
used instead of the word ‘permission’.”

Therefore, the Security Emergency Response Team has reissued SA-93:03 as
SA-93:03A taking into account the new recommendations. The new Advisory is
included below.

—————————————————————————-
The SERT team wishes to thank Kate Lance at the University of Newcastle for
bringing this problem to our attention.
—————————————————————————-

—————————————————————————-
Body of SERT Advisory SA-93:03A
—————————————————————————-

The Security Emergency Response Team has received information that a
successful prosecution of a computer cracker has taken place in New South
Wales. The prosecution was aided by the use of an appropriate login
banner. The following is an extract from a letter by the Australian
Federal Police:

“A major factor, commented upon by the magistrate, was the repeated warning
message displayed at logon to your system. Your agreement to implement this
feature has certainly started to pay dividends and demonstrates a certain
willingness to accept [that] tertiary institutions are not fair game.”

A recommended login banner is:

—– Warning Message —–

***** This service is for authorised clients only *****

****************************************************************************
* WARNING: It is a criminal offence to: *
* i. Obtain access to data without authority *
* (Penalty 2 years imprisonment) *
* ii Damage, delete, alter or insert data without authority *
* (Penalty 10 years imprisonment) *
****************************************************************************

This example login banner was supplied to the Australian Federal Police by
the office of the Commonwealth Director of Public Prosecutions. Legal
opinion from the Commonwealth Director of Public Prosecutions indicates
that this warning will assist in prosecutions of computer crackers for two
reasons:

“The prosecution in a criminal case must show that the computer hacker’s
actions are intentional. It would be extremely difficult for a hacker to
argue that his actions were by accident or inadvertent when he has to go
past such a warning on the system.”

“A hacker may admit that his actions were intentional. However, upon his
sentence, he may argue that he was ignorant of the law or that he was
unaware that his actions were unauthorised, thereby inducing the court to
mitigate the penalty that it imposes. If the above warning is used, it
will be extremely difficult for a hacker to present such arguments.”

SERT recommends the use of this, or similar banners on ALL systems and
access points into the network (such as a modem pool and ftp access). This
not only provides forewarning to any crackers that may intrude your system
that certain types of activity are illegal, but also advises any legitimate
users of their obligations relating to acceptable use of the computer
system.

The warning is deliberately general in nature as it has not yet been
established what type of (if any) crime has been committed. Subsequent
prosecution may be performed under Federal or State law, or handled by
local institution disciplinary procedures.

SERT recommends that any login banner or system initial message should not
imply consent to use the computer services (E.g., words such as “greeting”
or “welcome”), unless it is the express intention that any user is free to
use the system, whether they are authorised or not.

You may wish to include some identification information (such as the
hostname) so that genuine users know that they have connected to the
correct system. For example,
“You have connected to node FRED at The University of Wooloomooloo”
and follow this with an appropriate warning message.

Examples methods for login messages are:

VMS: Edit the file SYS$MANAGER:SYSTARTUP_V5.COM and include the line:
$DEFINE/SYSTEM SYS$ANNOUNCE “@SYS$MANAGER:ANNOUNCE.TXT”
then create the file SYS$MANAGER:ANNOUNCE.TXT with the text that you wish
displayed when a user connects to your system.

Note that this has implications for LAT as the default service
identification is the logical SYS$ANNOUNCE (which will translate to
@SYS$MANAGER:ANNOUNCE.TXT). In this case, you should edit the LAT startup
procedures to explicitly define a LAT service identification.

Unix: Edit the “message of the day” file, (e.g., /etc/motd) and include
the text that you wish displayed when a user logs in to your system.

This does not cover all ways to connect to a computer (e.g., rlogin,
telnet, SET HOST, ftp), but serves as one point of warning in a number of
cases. Warnings such as this are a positive step towards providing
adequate notice of the obligations and responsibilities relating to the use
of the computer equipment. If a person is known to have seen the warning,
they cannot subsequently claim ignorance of their responsibilities.

—————————————————————————-
The SERT team wishes to thank The University of Sydney, the University of
South Australia, the Australian Federal Police, and the Commonwealth
Director of Public Prosecutions for their advice and cooperation in this
matter.
—————————————————————————-

If you believe that your system has been compromised, contact SERT or your
representative in FIRST (Forum of Incident Response and Security Teams).

Internet Email: sert@sert.edu.au
Facsimile: (07) 365 4477
Telephone: (07) 365 4417
SERT personnel answer during business hours (AEST).

Security Emergency Response Team
Prentice Centre
The University Of Queensland
Qld. 4072.

Appendix 2

SERT Advisory SA-93.04, Guidelines For Developing A Sensible Password Policy

=============================================================================
SA-93:04 SERT Advisory
1-Jun-1993
Guidelines For Developing A Sensible Password Policy
—————————————————————————–

This advisory contains guidelines for developing a sensible password policy.
Please feel free to extract the contents of this advisory, modify to suit local
conditions, and then distribute to end users, as it is end users who are
responsible in the first instance for individual account security.

Without doubt, one of the most popular methods used by computer crackers to
compromise a system is password stealing.

By stealing your username and password an intruder can, with reduced
likelihood of detection, gain access to your system, modify it for his or
her own purposes and use that system as a launchpad for attacks on other
systems throughout the world – and all in your name. Password protection is
one of the most (if not the single most) important principles of system
security. It is uniformly important for ALL users, regardless of system
privileges or computer literacy. It is up to each and every individual to
ensure that their password is safe – a single unsafe password can (and
probably will) lead to a computer cracker violating YOUR system.

Your best line of defence against attack is a secure password. A password
is like a key, and any entry point that allows access by default is not
secure. A bad password is like leaving your front door unlocked.

Do not underestimate the ease with which your password can be stolen. There
are many techniques available to do this. A simple and amazingly successful
password theft technique for the cracker is password guessing (i.e. entering
your username, and simply guessing what your password might be). The aim of
this advisory is to thwart these attempts.

How To Select A Safe Password
—————————–

Some systems automatically (and autocratically) allocate passwords to
users. Many systems, however, give the user the option of selecting his
or her own password. The following guidelines should help in selecting a
password which will be sufficiently robust to prevent a cracker from
guessing your password in the majority of cases.

There are several principles involved in selecting a safe password. These
are covered below.

The DO-NOTs

DO NOT use simple passwords that are easy to remember and are typically
not safe. Examples of such passwords are:

– your userid (a common, but extremely dangerous practice);

– a word which can be associated with you. For example:
– your car make, model or registration number
– your child’s name
– your street name, postcode or other address details
– your medicare number
– your tax file number
– any of your bank account numbers;

– a word which someone watching could easily spot (qwertyuiop);

– any dictionary word (which a cracker with a PC and an on-line
dictionary could discover by exhaustive trial);

– words from other guessable word sets such as famous names,
proper names, colloquial terms (in various spheres of
life) and so on.

It is not sufficient to include a single number in the word, or
change all O’s to 0’s and I’s or L’s to 1’s in the word, or to spell
the word backwards.

DO NOT leave your account without a password.

DO NOT use your userid as your password.

DO NOT use any word from a dictionary (of any language) as most forms of
password attack use dictionaries as a basis for password guessing.

DO NOT use birthdays, car registration numbers, room numbers, department names,
machine names, locations, wife/husband’s names, pet’s names,
children’s names and so on. These may be determined as most of this
information is not confidential.

DO NOT use keyboard patterns, or duplicating characters such as qwerty or
aabbccdd.

DO NOT use the same password on multiple accounts. If you have many accounts,
then do not use the same password on each account. If one is broken,
then all are broken. Also, do not just change one character in the
password as this may be easily spotted if one of the passwords is
compromised.

DO NOT allow anyone to watch while you type your password.

DO NOT record your password either on-line. DO NOT write down your
passwords.

DO NOT tell anyone what your password is. Do not share your password with
your partner, your children, your friends. Even telling your dog
should be considered risky! Do not tell a person verbally, by
electronic mail or by any other means.

Remember: if someone has your password, they can commit criminal acts using
your account!

SERT staff have been alerted to several security breaches at constituent
sites which have been attributed (in total or in part) to the sharing of
passwords between husband and wife, parent and child, and between friends.

The DOs

DO use a MINIMUM (not maximum!) of 8 or more characters (system permitting).

DO use mixed case wherever possible. DO NOT choose only the first letter as
uppercase. (e.g. Mich37bo is not as good as MicH37Bo.)

DO include at least two digits or punctuation characters. DO NOT simply replace
“o” and “O” with “0”, and “I”, “l” or “L” with 1. (e.g. fl0pp1mp is
not as good as fL0$p*Mp.)

DO change passwords frequently, and DO NOT reuse old passwords. Password
cracking algorithms have been around for quite a while now. By using
computationally intensive processes, a password can be broken in time.

Applying the techniques outlined above make the length of time required to
break a password prohibitively long. However, the time required to break a
password drops significantly as each letter is guessed, or other
information is known about a password. Passwords should be changed
regularly, so that even if a password is finally guessed, it will be long
out of date. A password should never be reused.

General techniques for generating safe passwords include:

– using two or three short words that are unrelated;
– always including some non-alphabetic, non-numeric (i.e. punctuation)
characters;
– deliberately misspelling;
– taking the first letter from each word of a phrase (a passphrase).

Note that different operating systems have different rules for the
characters that one is allowed to use in a password. Some operating systems
will allow any printable characters, whereas others only allow numeric and
alphabetic (i.e. non-punctuation) characters.

After reading all of that, you may ask “well, what is a good password? What
can I use?”. One technique would be to use a two or three word phrase, and
replace the 1st character of the 1st word with a -1, the 2nd
character of the 2nd word with a
-2, etc, and uppercase every second
character except punctuation. e.g. !Yc@rSm$lLs (my car smells).

Another alternative might be to use the first letter from each word in a
line from a song, have every third letter in upper case, and replace (aeiou)
with ({}:”?). For example, ‘Tie A Yellow Ribbon Round That Old Oak Tree’
would convert into ‘t{YrrT””T’.

(Rationale:
‘Tie A Yellow Ribbon Round That Old Oak Tree’ => ‘tayrrtoot’
Convert every third letter to upper case => ‘taYrrTooT’
Replace lower case vowels => ‘t{YrrT””T’)

Note that these examples should NOT be used as they are now published
widely!

You should be aware of what characters your system will accept in a
password, the length required for a password, and what time period is
allowed before the password will have to be changed again. You also need to
be aware of the commands used to change passwords.

What System Managers Can Do
—————————

Consider using the following techniques.

– Use Crack, a password cracking tool to audit existing passwords. You supply
a dictionary, and a list of massaging rules. Crack then tests the
encrypted password against the dictionary and rules list to see which
passwords it can guess. This is only available for UNIX systems.

– Consider also the use of password shadowing, which places the encrypted
passwords in a non-world-readable file, not /etc/passwd (which is
world-readable). Again, this is only applicable for UNIX systems.

– If your system has a facility to enforce rules on minimum password
content (e.g. “must include at least 1 upper case and at least 1
numeric”), then use this facility. For UNIX systems which don’t
have this facility, npasswd or passwd+ are good alternatives.

– If your system has a facility to (a) enforce password ageing, and (b) keep
a history file of passwords and disallow previous passwords, then
use this facility also.

– Keep passwords for system accounts distributed amongst the smallest group
of people possible. Change these passwords more frequently than
passwords for non-privileged accounts.

– Take care with the use of facilities that are available for logins which
bypass the use of passwords. For instance, on VMS systems, don’t
allow proxy logins for privileged accounts such as “SYSTEM”. On UNIX
machines, remove any .rhosts files (or /etc/hosts.equiv) with “+”
signs in them.

Login programs (such as /bin/login on UNIX systems) are constructed to
behave in a certain way. One method used by crackers to obtain passwords is
to execute a program (a trojan horse) masquerading as the login program.
The trojan horse will accept your username and password, log it into a
secret file, and then inform you that the combination entered was
incorrect, before finally calling the real login program. The user,
thinking that this was merely a typographical error, will proceed as normal
unaware that his or her password has been logged for later use. This can be
avoided in some cases by typing a few times before entering your
username/password combination.

Finally, system managers should be aware that X display managers (such as
xdm) may bypass several login and system facilities such as message of
the day, password ageing etcetera. Depending upon the sensitivity of your
site, this may present some problems which will need resolution using more
lateral methods.

If you believe that your system has been compromised, contact SERT or your
representative in FIRST (Forum of Incident Response and Security Teams).

Internet Email: sert@sert.edu.au
Facsimile: (07) 365 4477
Telephone: (07) 365 4417
SERT personnel answer during business hours (AEST).

Security Emergency Response Team
Prentice Centre
The University Of Queensland
Qld 4072
AUSTRALIA.

Appendix 3

Wrapper Example

The following material is an example of a wrapper that
could conceivably used for protecting the FAL object, as
outlined in Section 4.1, Wrappers.

$ SET NOON
$ SET NOCONTROL_Y
$ SaveVerify = F$VERIFY(0)
$ SET NOVERIFY
$!
================================================================
$!
$! Example Wrapper
$!
$! *** NOTE: This file is UNTESTED! ***
$!
$! Author: Rob McMillan, 1992
$!
$! Example wrapper for the FAL object. This command file should
be
$! specified as the file to execute for the FAL object in the NCP
$! database. This file is for example purposes only!
$!
$! Create allow and deny lists in AllowFile and DenyFile. The
$! format of each file is “HOST::USERNAME.”. Note the full stop.
$!
$! eg
$! NODE1::USER1.
$!
$! To have blanket values, use an asterisk *. For instance, to
$! have a blanket denial, but allow all people from NODE2::, and
$! allow NODE1::USER1, have the following configuration:
$!
$! DenyFile:
$! *::*.
$!
$! AllowFile:
$! NODE2::*.
$! NODE1::USER1.
$!
$! In the absence of enough information in the configuration
$! files, or a clash of information (eg denying and allowing
$! *::*), the default action is to deny a connection.
$!
$!================================================================
$!
$! — What object is this wrapper for?
$!
$ Executable = “SYS$SYSTEM:FAL.EXE” ! Object executable to use
$!
$! — Constants
$!
$ WAllowed == %x10000001
$ WDenied == %x10000002
$ WUnknown == %x10000003
$!
$! — Get connection details
$!
$ LocalNodeName = F$GETSYI(“NODENAME”) + “::”
$ LocalTime = F$TIME()
$ LocalUser = F$GETJPI(“”,”USERNAME”)
$ LocalUser = F$EXTRACT(0,F$LOCATE(” “,LocalUser),LocalUser)
$ RemoteNodeName = F$TRNLNM(“SYS$REM_NODE”)
$ RemoteUser = F$TRNLNM(“SYS$REM_ID”)
$ WrapperLogInfo = –
“at ”LocalTime’ from ”RemoteNodeName’::”RemoteUser’ as ”LocalUser'”
$!
$! — Check wrapper configuration
$!
$! At this point, we can use any of the following to check
$! whether we’ll allow the connection:
$!
$! – LocalNode
$! – LocalTime
$! – LocalUser
$! – RemoteNodeName
$! – RemoteUser
$!
$ ConnectionOkay = WUnknown
$ CheckFALRules ‘LocalNodeName’ ‘LocalTime’ ‘LocalUser’ –
‘RemoteNodeName’ ‘RemoteUser’
$ ConnectionOkay = $Status
$ IF (RemoteNodeName .EQS. LocalNodeName)
$ THEN
$ ConnectionOkay = WAllowed ! Failsafe
$ ENDIF
$!
$! — Log the event and take action
$!
$ IF (ConnectionOkay .NE. WAllowed)
$ THEN
$ WRITE SYS$OUTPUT “Network connect request failed ”WrapperLogInfo'”
$ WriteFALLog “Network connect request failed ”WrapperLogInfo'”
$ LOGOUT
$ ELSE
$ WRITE SYS$OUTPUT “Network connect request succeeded ”WrapperLogInfo'”
$ WriteFALLog “Network connect request succeeded ”WrapperLogInfo'”
$ RUN ‘Executable’
$ ENDIF
$!
$! — Go home now
$!
$ SaveVerify = F$VERIFY(SaveVerify)
$ EXIT ‘ConnectionOkay’

For interactive connections, the section in which
connection details are evaluated would be more
complicated. Different mechanisms would be required for
finding out these details based upon the type of
connection (eg local, DECnet, LAT, telnet). These are
mentioned in Section 4.1, Wrappers. These command files
should be world executable, but only readable and
writeable by system privileged users.

The two executables, CheckFALRules and WriteFALLog,
should be similarly protected (eg installed, protected
images). WriteFALLog is a very simple program which
writes the supplied parameters to the log file for this
object. CheckFALRules could look something like the
following example.

/*
* CheckFALRules.C
*
* Author: Rob McMillan, 1992
*
* Use current connection details to compare with local rules and
* return a value describing whether to allow the connection or
* not (Allow).
*
* The returned value (Allow) can return one of two values:
* WAllowed: allow the connection
* WDenied: refuse the connection
*
* This wrapper configuration tests only upon the basis of
* RemoteNodeName and RemoteUser. However, any of the details
* supplied below can be used, based upon paranoia levels. To
* do this, the following must be modified:
*
* – The CHECK_EXPLICIT_RULE subroutine
* – The calls in this subroutine to CHECK_EXPLICIT_RULE
* – The header comments at the top of this wrapper
* – The allow and deny files.
*
*/

#include
#include
#include
#include

#include “CheckFALRules.H”

typedef unsigned int BOOLEAN;
#define FALSE 0
#define TRUE 1

/* — Prototypes */
int CheckExplicitRule( char *, char *);
int ExitHandler(int, char *);
char * Salloc(unsigned int);
char * SnarfArgument(char *);

int
main (argc, argv)
int argc;
char * argv[];
{
char * localNodeName;
char * localTime;
char * localUser;
char * remoteNodeName;
char * remoteUser;
int status = WUnknown;

/* Get and display parameters */

localNodeName= SnarfArgument(argv[1]);
localTime = SnarfArgument(argv[2]);
localUser = SnarfArgument(argv[3]);
remoteNodeName = SnarfArgument(argv[4]);
remoteUser = SnarfArgument(argv[5]);
if ((localNodeName == (char *)0) ||
(localTime == (char *)0) ||
(localUser == (char *)0) ||
(remoteNodeName == (char *)0) ||
(remoteUser == (char *)0)
) {
fprintf( stderr, “Error snarfing check parameters!\n”);
exit( ExitHandler( WDefault, “Error snarfing check
parameters!”));
}

/* Now evaluate whether to allow the connection */

/* — We will only test based on source node and user.
* We can check other details if required at a later stage.
*
* Note that the order in which these rules are checked is
* important. Below, we check in the order of the most
* specific rule to the most general. Once a connection
* is found to be explicitly allowed or denied
* no further rules are checked.
*/

status = CheckExplicitRule( remoteNodeName, remoteUser);
if (status != WUnknown)
exit( ExitHandler( status, “On node::user combination”));

status = CheckExplicitRule( remoteNodeName, “*”);
if (status != WUnknown)
exit( ExitHandler( status, “On node::* combination”));

status = CheckExplicitRule( “*”, “*”);
if (status != WUnknown)
exit( ExitHandler( status, “On *::* combination”));

/* No applicable rules were found, or there were a clash of
* rules, so use the default.
*/
fprintf(stderr, “Warning! Unable to evaluate connection status!\n”);
exit ( ExitHandler( WDefault, “Default action taken”));
} /* end main */

/*
* CheckExplicitRule
*
* Use the remoteNodeName and remoteUser to return a value
* describing whether the proposed connection is explicitly allowed
* or denied. The returned value can be one of three values:
*
* WAllowed: explicitly allow the connection
* WDenied: explicitly deny the connection
* WUnknown: couldn’t evaluate on supplied information
*
* Allowed configurations are set out in ALLOW_FILE.
* Disallowed configurations are set out in DENY_FILE.
*
* If the record is found in both files, or the record can’t be
* found in either file, return WUnknown. Otherwise, return
* the result explicitly described by the files.
*
*/
int
CheckExplicitRule( remoteNodeName, remoteUser)
char * remoteNodeName;
char * remoteUser;
{
char inbuf[132]; /* Should be heaps */
char * searchKey;
BOOLEAN allow = WUnknown;
BOOLEAN foundAllow = FALSE;
BOOLEAN foundDeny = FALSE;
FILE * fp;

if ((searchKey = Salloc(strlen(remoteNodeName) + 3 +
strlen(remoteUser))) == (char *)0)
return( WUnknown);
searchKey = strcpy(searchKey, remoteNodeName);
searchKey = strcat(searchKey, “::”);
searchKey = strcat(searchKey, remoteUser);

/* See if there is a matching record in the allow file */
if ((fp = fopen( ALLOW_FILE, “r”)) == (FILE *)NULL) {
fprintf(stderr, “Error! Cannot open wrapper AllowFile! \n”);
return( WUnknown);
}
else {
/* Search file for matching record */
while ((foundAllow == FALSE) && (fgets(inbuf, 132, fp) != (char *)NULL))
if (strncmp(searchKey, inbuf, strlen(searchKey)) == 0)
foundAllow = TRUE;
fclose(fp);
}

/* Now search deny file as well */
if ((fp = fopen( DENY_FILE, “r”)) == (FILE *)NULL) {
fprintf(stderr, “Error! Cannot open wrapper DenyFile! \n”);
return( WUnknown);
}
else {
/* Search file for matching record */
while ((foundDeny == FALSE) && (fgets(inbuf, 132, fp) != (char *)NULL))
if (strncmp(searchKey, inbuf, strlen(searchKey)) == 0)
foundDeny = TRUE;
fclose(fp);
}

/* If we get a strict decision, then return the result. If we
* get two FALSEs or two TRUEs, then there is no decision.
*/
if ((foundAllow == TRUE) && (foundDeny == FALSE))
allow = WAllowed;
if ((foundAllow == FALSE) && (foundDeny == TRUE))
allow = WDenied;

return( allow);

} /* end CheckExplicitRule */

/*
* ExitHandler
*
* Carry out any cleaning up required whilst exiting.
*
*/
int
ExitHandler( exitCode, diagnostic)
int exitCode;
char * diagnostic;
{

#ifdef DEBUG
switch (exitCode) {
case WAllowed:
fprintf( stdout, “\nConnection allowed: “);
fprintf( stdout, “%s.\n”, diagnostic);
break;
case WDenied:
fprintf( stdout, “\nConnection denied: “);
fprintf( stdout, “%s.\n”, diagnostic);
break;
case WUnknown:
fprintf( stdout, “\nCan’t figure out to allow connection or not: “);
fprintf( stdout, “%s.\n”, diagnostic);
break;
default:
fprintf( stdout, “\nError. Unknown exit code: “);
fprintf( stdout, “%s.\n”, diagnostic);
break;
}
#endif

return( exitCode);
} /* end ExitHandler */

/*
* Salloc
*
* Safe malloc
*
* See P321 “C Programming in a UNIX Environment”
* by Judy Kay and Bob Kummerfeld,
* Addison-Wesley, 1989.
*
*/
char *
Salloc(size)
unsigned int size;
{
char * result;
if ((result = malloc(size)) == (char *)0)
fprintf(stderr, “Cannot malloc %d bytes.\n”, size);
return result;
} /* end Salloc */

/*
* SnarfArgument
*
* Make a copy of arg string.
*
*/
char *
SnarfArgument( arg)
char * arg;
{
char * result;

if ((result = Salloc(strlen(arg)+1)) != (char *)0)
result = strcpy(result, arg);
return( result);
} /* end SnarfArgument */

The header file for this program would contain the following:

/*
* CheckFALRules.H
*
* Author: Rob McMillan, 1992
*
* See comments in CheckFALRules.C.
*
* THE CONTENTS OF THIS FILE MUST MATCH THOSE IN THE WRAPPER COMMAND FILE!
*
*/

/* — Define file paths */
#define DEBUG
#ifdef DEBUG
#define ALLOW_FILE “{Allow File name here}”
#define DENY_FILE “{Deny File name here}”
#else
#define ALLOW_FILE “local$wrap:{Allow File name here}”
#define DENY_FILE “local$wrap:{Deny File name here}”
#endif

/* — Define exit values */
#define WAllowed 0x10000001
#define WDenied 0x10000002
#define WUnknown 0x10000003
#define WDefault WDenied