Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ aa_library(3T) — DG/UX 5.4.2T

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

inittab(4)



aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


NAME
       aa_library - identify and authenticate the user

SYNOPSIS
       #include <aainterface.h>



       Environmental Functions

       int  aaineffect ()
       int  aamacineffect ()
       int  aatrustedprocess()


       Session Initiation

       int  aagetsessionkit (username, service, location, macalias,
                               password, sessionkitpp)
            char *                 username,
            char *                 service,
            char *                 location,
            char *                 macalias,
            char *                 password,
            aasessionkitt * *   sessionkitpp;

       int  aapasswordcheck (sessionkitpp, password)
            aasessionkitt * *   sessionkitpp;
            char *                 password;

       int  aapasswordoverride (sessionkitpp)
            aasessionkitt * *   sessionkitpp;


       Password Management

       int  aapasswordexpired (sessionkitp)
            aasessionkitt *  sessionkitp;

       int  aapasswordwarning (sessionkitp)
            aasessionkitt *  sessionkitp;

       int  aaotherpwexpired (sessionkitp)
            aasessionkitt *  sessionkitp;

       int  aaotherpwwarning (sessionkitp)
            aasessionkitt *  sessionkitp;

       char *  aatrunctodhms (interval)
            timet    interval;


       char *  aapasswordcritique (sessionkitp, newpassword)
            aasessionkitt *   sessionkitp;



Licensed material--property of copyright holder(s)                         1




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


            char *              newpassword;

       int  aapasswordchange (sessionkitp, newpassword)
            aasessionkitt *   sessionkitp;
            char *              newpassword;

       void  aanotepwchangefailed (sessionkitp)
            aasessionkitt *   sessionkitp;


       int  aamaccheckandlabel ( sessionkitp, targettype, target )
            aasessionkitt *     sessionkitp;
            int                    targettype;
            void *                 target;

       int  aasetfilemaclabel (sessionkitp, filename)
            aasessionkitt *   sessionkitp;
            char *              filename;

       int  aasetidandsecurity (sessionkitp)
            aasessionkitt *   sessionkitp;


       int  aaproxyidandsecurity (sessionkitp)
            aasessionkitt *   sessionkitp;


       Information Functions

       char * aausergecos (sessionkitp)
            aasessionkitt *   sessionkitp;

       uidt  aauseruid (sessionkitp)
            aasessionkitt *   sessionkitp;

       gidt  aausergid (sessionkitp)
            aasessionkitt *   sessionkitp;

       aasupgrpt *  aausersupplementarygroups (sessionkitp)
            aasessionkitt *   sessionkitp;


       char * aaservicerootdirectory (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaservicehomedirectory (sessionkitp)
            aasessionkitt *   sessionkitp;

       short aaservicepriority (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaserviceprogram (sessionkitp)
            aasessionkitt *   sessionkitp;




Licensed material--property of copyright holder(s)                         2




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       int  aaaccounteverused (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastusedwhat (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastusedwhere (sessionkitp)
            aasessionkitt *   sessionkitp;

       timet aaaccountlastusedwhen (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastusedmac (sessionkitp)
            aasessionkitt *   sessionkitp;

       int  aaaccounteverdenied (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastdeniedwhat (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastdeniedwhere (sessionkitp)
            aasessionkitt *   sessionkitp;

       timet aaaccountlastdeniedwhen (sessionkitp)
            aasessionkitt *   sessionkitp;

       char * aaaccountlastdeniedmac (sessionkitp)
            aasessionkitt *   sessionkitp;

DESCRIPTION
       The aalibrary group of functions is used by service initiators
       (e.g., login, ftp and xdm), and may be used by any program that
       requires users to identify and authenticate themselves, or in
       addition needs to establish a session on the behalf of a user.

       These functions reside in the library libtrust.a and in turn require
       functions in the library libdgc.a.

       These functions perform identification and authentication, and then
       set session process attributes, dynamically using different steps
       depending upon the current configuration of the system.  Thus, a
       single binary executable built using these functions will perform the
       appropriate steps on standard DG/UX, C2 Trusted DG/UX, and B1 Trusted
       DG/UX.

       Note that references to specific attributes may not apply to some
       systems, depending upon the features configured.  The following lists
       the only configurations supported:

          Standard DG/UX:    No additional features

          C2 Trusted DG/UX:  A&A, auditing, ACLs




Licensed material--property of copyright holder(s)                         3




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


          B1 Trusted DG/UX:  A&A, auditing, ACLs, MAC

       The A&A subsystem requires the following additional information for
       each user based upon the feature sets configured:

          A&A:       authorization to use each specific service
                     default password set
                     a password set may be assigned on a per-service basis
                     standard DG/UX process attributes specified in A&A
                     database

          Auditing:  default audit mask
                     an audit mask may be assigned on a per-service basis

          ACLs:      no A&A requirements

          MAC:       default default MAC label alias
                     a default MAC label alias may be assigned on a per-
                     service basis

       The following discussion is described in terms of a library interface
       and a protocol for using it that applies to both the Trusted and
       standard DG/UX system environments.  The login program is used merely
       as an example.

   User Name
       No change is necessary in the way each service, Trusted or standard,
       gets a username.

   Optional MAC Label
       On a Trusted DG/UX system on which MAC is configured, a user may
       want, or need, to specify the MAC label at which their session will
       run.  If so, it should be read in as ASCII text along with the user
       name and password.  Login requires this text (the "MAC alias") to
       have no white space, so other interfaces may require the same without
       loss of generality.

       If MAC is not configured, the service access program should either
       not ask for a MAC label (if that's what it otherwise does), or not
       try to interpret anything the user supplies as a MAC label.

       For example, if MAC is configured, login will accept a MAC label
       option with the user name, as follows:

          login: fred -l CONFIDENTIAL:ALL
          password:

       If MAC is not configured, attempting the same login will simply place
       the strings following the username into fred's environment in the
       usual way (cf. login(1)), as follows:

          L0=-l
          L1=CONFIDENTIAL:ALL




Licensed material--property of copyright holder(s)                         4




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       The following interface tells whether MAC is currently configured on
       the host system:

          int aamacineffect ( ) /*1=yes,0=no*/

       This and all the following declarations are delivered in the include
       file <aainterface.h>.

   Password
       Trusted DG/UX, unlike standard DG/UX, always requires a password for
       remote login and similar services.

       Standard DG/UX supports the existing less secure open system
       mechanisms.  For example, rlogin (among other commands) makes use of
       the /etc/hosts.equiv and .rhosts mechanism.  This allows a user to
       rlogin from a "trusted system" without having to re-enter the
       password.  Such a user is said to be pre-authenticated and login
       knows:

          a.    on a standard DG/UX system, not to ask for a password (i.e.,
                business as usual)

          b.    on a Trusted DG/UX system, to ask for a password anyway

       NOTE:  Do not confuse the NIS concept of a "trusted system" - one
              which  you trust to have preauthenticated a user - with a
              Trusted DG/UX system.  In Trusted DG/UX, there is no concept
              of trusting another system to authenticate a user.  The NIS
              mechanism is easily spoofed (fooled).

       So login and other services need to be able to find out whether the
       host system is Trusted.  More specifically, whether the Trusted
       Identification and Authentication subsystem is active.  The interface
       definitions follow:

          int aaineffect ( ) /* 1=yes, 0=no */

   Session Kit (aagetsessionkit()) and Password Checking
       (aapasswordcheck())
       So at some point, the service-access program has the username,
       possibly a MAC alias, and the user's cleartext password or knows the
       system is non-Trusted and the user is pre-authenticated.  The
       service-access program should also have an agreed-upon ASCII name for
       the service in question, and an id for the location, or access point,
       from which the service is being invoked.

       All authorization and authentication checks are then carried out in
       the two functions aa_get_session_kit() and aa_password_check().  The
       first one is sufficient if the user is pre-authenticated or has a
       null password.  Otherwise the service-access program should ask for a
       password, and have it checked by the second function.  The details
       are as follows:

       int     aagetsessionkit (username, service, location, macalias,



Licensed material--property of copyright holder(s)                         5




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


                                  password, sessionkitpp)
              char *              username;
              char *              service;
              char *              location;
              char *              macalias;
              char *              password;
              aasessionkitt * * sessionkitpp;

       If MAC is not in effect, or if the user has chosen not to specify the
       optional session MAC label, macalias should be NULL.

       If the host system is a standard DG/UX system and the user is pre-
       authenticated, password should be NULL.

       It is normally most convenient to declare an aasessionkitt
       *sessionkitp variable, and let sessionkitpp be &sessionkitp.
       sessionkitt is declared in <aainterface.h>.

       This function returns 0 (success) or -1 (failure).

       On success the user has been granted access, and the contents of
       sessionkitpp point to a malloc'd sessionkit for use by the
       functions below.  This sessionkit will be used for all further tests
       and requests for information.  Note that in this case the user will
       have been granted access without entering a password.

       Failure means the user should enter a (non-null) password, and the
       service-access program should check it by calling the
       aa_password_check() function.  In fact failure may have been because
       the user is denied access to the specified service, location, current
       time, and MAC label; and aapasswordcheck() will now fail no matter
       how good the password -- but the service-access program should not
       give this information to the user, and no provision to do so has been
       made in this interface.  So the next step is to ask for a password,
       and call the following:

       int  aapasswordcheck (sessionkitpp, password)
            aasessionkitt * *   sessionkitpp;
            char *                 password;

       The session kit parameter is again the address of a pointer to a
       sessionkitt, just as for aagetsessionkit(), because on failure
       aapasswordcheck() will deallocate this session kit, which is no
       longer useful, and set the value of the pointer to NULL.

       This function returns 0 (success) or -1 (failure).

       On success the user has been granted access, and the contents of
       sessionkitpp point to a malloc'd sessionkit for use by the
       functions below.  This sessionkit will be used for all further tests
       and requests for information.

       On failure the user has been denied access.  No reason is given.  The
       only appropriate message to the user is Login incorrect or the



Licensed material--property of copyright holder(s)                         6




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       equivalent for your particular service.  At this point the service-
       access interface may exit or retry -- i.e., ask for another user
       name, etc.

   Password Override (aapasswordoverride())
       Some services may need to assume a particular identity without a
       password.  One instance is anonymous ftp, which runs anonymous users
       as the user ftp.  In a case like this, the service-access program
       should call the following function instead of aapasswordcheck().

       int  aapasswordoverride (sessionkitpp)
            aasessionkitt * *   sessionkitpp;

       This function carries out the same functions as aapasswordcheck(),
       but without the password check.  In other words, if the service
       request has basically failed already, perhaps due to an unauthorized
       location, but aagetsessionkit() still expects the formality of a
       password before we announce the failure, then aapasswordoverride()
       will fail appropriately.  Otherwise it will succeed without the
       password.

       The remaining Trusted DG/UX steps are password management, chroot()
       (if applicable), and set id/security attributes.  After that, the
       service-access program may proceed with whatever else it normally
       does (except chroot()).

   Password Management
       When aagetsessionkit() succeeds, all security-related checks have
       passed (including authentication) and the user is entitled to
       service.  However, if the user's password has expired, Trusted DG/UX
       requires that it be changed before any further service is actually
       delivered.  So, immediately after aagetsessionkit(), call the
       following function:

       int  aapasswordexpired (sessionkitp)
            sessionkitt *    sessionkitp;

       This function returns 1 (yes) or 0 (no).

       If aapasswordexpired() returns 0 (no), continue.

       It will be possible for the Security Administrator to configure a
       service to NOT change an expired password -- just deny service.  When
       invoking ftp, for example, it might be inappropriate for the user to
       type in a new password from somewhere on the Internet.  If this is
       the case, aagetsessionkit() will return -1 (failure), because the
       user should, but cannot, change the password before receiving
       service.

       If aapasswordexpired() returned 1 (yes), it is required that the
       user change their password before receiving further service.  Ask
       them to do so.  There should be a way for them to refuse, which is
       discussed in a following paragraph.




Licensed material--property of copyright holder(s)                         7




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       When they supply a new password, call the following interface:

       char *  aapasswordcritique (sessionkitp, newpassword)
               sessionkitt *    sessionkitp;
               char *            newpassword;

       If the new password is not acceptable, this function returns a
       pointer to the text of a message explaining why not.  (Currently
       implemented checks:  length > 6, not circular shift of the username,
       at least two alpha and one numeric or special character, and differs
       from the old password in at least 3 positions.)  Print the message,
       ask for another password, and keep trying until one is acceptable,
       the user refuses, or you decide that they've tried long enough.  If a
       password is acceptable, call the following interface:

       int     aapasswordchange (sessionkitp, newpassword)
               sessionkitt *   sessionkitp;
               char *           newpassword;

       This function returns 0 (success), or -1 (failure).  Failure is fatal
       to the session -- i.e., the service-access program should exit or
       retry.

       If they refuse to supply a new password (e.g., login interprets ^D or
       <NL> -- the empty string -- as refusal), or your service access
       program decides they have failed too many times (e.g., 3 for login),
       call the following interface:

       void    aanotepwchangefailed (sessionkitp)
               sessionkitt *   sessionkitp;

       Then exit, or try for another session.  This call is needed to audit
       the fact that the user's expired password was not changed.  (The A&A
       subsystem does most auditing transparently to the caller, but in this
       case it has no way to know when you or the user are going to give up
       on the new password.)

   Change Root Command (chroot() )
       If the service-access program is going to chroot() before exec'ing
       the user's program, it should be done after Password Management and
       before setting id/security attributes.  The reason for this is that
       setting id/security attributes might make the user's new root
       directory inaccessible from where this service-access program is
       executing.  There may also be other considerations, such as the fact
       that any system file processing (e.g., /etc/wtmp) should also be done
       before chroot().

       If a root directory for this service is specified by the
       administrator, it's available by calling:

       char *  aaservicerootdirectory (sessionkitp)
               sessionkitt *   sessionkitp;

       Values of NULL  , "", and "/" indicate no special root directory.



Licensed material--property of copyright holder(s)                         8




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       Note that chroot() has irrevocably changed process state.  If
       anything fails beyond this point, the service-access program must
       exit.  It cannot retry from the new root.  It is also good practice
       for the service access program to chdir("/") at this point.

   Set Id/Security Attributes
       All interactive sessions created on a DG/UX session must be able to
       communicate with the user through the connecting device special file
       (tty).  A&A leaves the DAC on the connecting tty as set by the
       service initiator (this will change in a future release).  The MAC
       attributes of the connecting device are set as described in the
       following function.

       If MAC is configured, A&A sets the MAC label on the connecting tty.
       All tty devices are configured by the Trusted DG/UX system to be
       governed by a MAC range, and with DAC protection preventing non-
       privileged users from accessing the devices.  The MAC range serves
       several purposes.  First, it provides additional protection from
       users attempting to start a Trojan Horse program on the device (e.g.,
       a fake login program).  Second, it is used by the A&A functions to
       limit the range of sessions that may be initiated on that device.
       (There is no administrative support for setting these ranges to other
       than their default IMPLEMENTATION_LO/IMPLEMENTATION_HI.  However, a
       site may add a site-specific command to inittab(4) to set these
       ranges to any desired values.)  The A&A functions use
       dgmacaccess(2) to see if the proposed session MAC label will grant
       the user write access to the device.  If it will, the session MAC
       label is accepted.  If not, the session creation request will be
       rejected.

       Once the MAC label is accepted, A&A attempts to set the MAC label on
       the device.  However, if dgsetomac(1) were used to set the MAC
       label, then that device would not be able to revert to being governed
       by a MAC range when the session is terminated, because the MAC label
       would thereafter mask the MAC range.  Therefore, A&A uses
       dgsettmpomac(2) to set the MAC label.  This offers several
       advantages:

          ⊕    A temporary MAC label will be removed from the device when
               all open's on the device are closed.  Thus the device will
               again be governed by a MAC range when a session terminates.

          ⊕    If there are still processes that have the device open, the
               device will not be governed by a MAC range.  This will cause
               dgsettmpomac(2) to fail, and thus the A&A functions to fail.
               This prevents any prior session from leaving a Trojan Horse
               running on the device.  This even protects against the case
               where the prior session was running at the same MAC label as
               the proposed new session MAC label.  In this event the
               dgmacaccess(2) check will succeed, but the A&A function
               will still fail.  This is exactly what is desired.  (This is
               also very easily detected in the audit trail.)

       WARNING:  If there are any privileged processes started at boot time



Licensed material--property of copyright holder(s)                         9




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


                 (or at any time) that open the device to, say, log error
                 messages, this will prevent the A&A functions from starting
                 a session on that device.  This is especially common for
                 /dev/console.  B1 Trusted DG/UX has modified all DG
                 supplied daemons so that they open /dev/syscon if they are
                 required to leave the console open.  The best procedure is
                 to have daemons use the syslog service to log error
                 messages.  Future releases of Trusted DG/UX will do this.

       The MAC processing described above is performed by the following
       function.  (Note that this function will fail if MAC is not in
       effect.  Do not call this function without first ensuring that MAC is
       configured.)



       int     aasetfilemaclabel (sessionkitp, filename)
               sessionkitt *   sessionkitp;
               char *           filename;

       It returns 0 (success) or -1 (failure -- which is fatal to the
       session).

       It is up to the service-access program to figure out the appropriate
       filename parameter.  Login, for example, calls ttyname().  Note that
       for login on a hard-wired tty line, this filename is the same as the
       session's "location", but for remote login (rlogin) and similar
       services it is generally a pseudo-tty, and not the session's location
       (which is a network access point).

       NOTE:  MAC label changes require appropriate privilege, and must be
              accomplished before calling the next function,
              aasetidandsecurity().

       The following function then sets all process id and security
       attributes:

       int     aasetidandsecurity (sessionkitp)
               sessionkitt *   sessionkitp;

       If it returns -1, exit; there was an internal error.  If it returns 0
       (success), continue.  After this point the process is running with
       the user's id, groups, and security attributes.

       Some services may need to retain certain privileges while acting on
       behalf of the user.  For example, ftp needs to both assume the user's
       identity and retain the privilege of opening the data connection on a
       privileged port.  Services that need that capability should call the
       following function instead of aasetidandsecurity() above:

       int  aaproxyidandsecurity (sessionkitp)
            aasessionkitt *   sessionkitp;

       If it returns -1, exit -- there was an internal error.  If it returns



Licensed material--property of copyright holder(s)                        10




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       0 (success), continue.  After this point the process is running with
       the effective user id and the user's groups.

       After setting id/security attributes, the service-access program
       should carry out the rest of its usual functions, culminating with
       the exec() of the service program.  In order to do this, it will need
       some information normally obtained from the user's /etc/passwd entry
       (and possibly from the /etc/group file).  This information will also
       be tucked away in *sessionkitp, accessible by calling the following
       functions:

       Information about the user:

       char *  aausergecos (sessionkitp)
               sessionkitt *   sessionkitp;

       (The gecos information will NOT begin with the optional pri=xx,
       priority specification.)

       uidt   aauseruid (sessionkitp)
               sessionkitt *    sessionkitp;
       gidt   aausergid (sessionkitp)
               sessionkitt *   sessionkitp;
       aasupgrpt *   aausersupplementarygroups (sessionkitp)
               sessionkitt *   sessionkitp;

       (The aasupgrpt contains supplementary group id's in the form
       required by the setgroups(2) system call.  But the supplementary
       groups will already have been set by aasetidandsecurity().)

       Information about the service:

       char *  aaservicerootdirectory (sessionkitp)
               sessionkitt *   sessionkitp;
       char *  aaservicehomedirectory (sessionkitp)
               sessionkitt *   sessionkitp;
       char *  aaserviceprogram (sessionkitp)
               sessionkitt *   sessionkitp;
       short   aaservicepriority (sessionkitp)
               sessionkitt *   sessionkitp;

   Miscellaneous
       Trusted Process

       If the application you're writing needs to know if it is still a
       trusted process, directly derived from the system, i.e. its
       authentication identifier (authid) is zero, use:

       int     aatrustedprocess ()
       If the authid is 0, then this function returns 1, otherwise it
       returns 1.

       Umask




Licensed material--property of copyright holder(s)                        11




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       If the system is running Trusted (i.e., aaineffect() returns 1)
       the default umask should be 077, unless configured otherwise by
       the system administrator.

       Messages

       If the system is running Trusted, the service-access program should
       inform the user of the following:

          1.   Password(s) expired or about to expire

          2.   Last successful/unsuccessful service requests

       Password(s) expired or about to expire

       On Trusted DG/UX a user may have multiple passwords, each possibly in
       different stages of
       its
       life cycle.  Use the following
       interfaces to find out about these:

       int     aapasswordwarning (sessionkitp)
               sessionkitt *   sessionkitp;

       If the password with which the user was just granted service is not
       about to expire, this function returns 0.  If that password is about
       to expire, this function returns the number of seconds before it will
       do so.

       int     aaotherpwexpired (sessionkitp)
               sessionkitt *   sessionkitp;

       This function returns 1 if one or more of the user's other passwords
       has expired, 0 if not.

       int     aaotherpwwarning (sessionkitp)
               sessionkitt *   sessionkitp;

       If one or more of the user's other passwords is about to expire, this
       function returns the remaining lifetime in seconds of the one that is
       to expire soonest; otherwise (i.e., if none of the user's other
       passwords are about to expire) it returns 0.

       int     aatrunctodhms (interval)
               timet           interval;

       This function takes a timet in seconds, and returns a character
       string message expressing that time in days, hours, minutes, or
       seconds (the largest unit appropriate).  It's simply a convenience
       for printing out password expiration messages above.

       Last successful/unsuccessful service requests

       The following functions are provided for formulating messages about



Licensed material--property of copyright holder(s)                        12




aa_library(3T)             C2 Trusted DG/UX 5.4.2T            aa_library(3T)


       what this user's account last succeeded or failed in doing.  Login,
       for example, prints out messages of the following form:

       Last service:  <service> from <location>, <time>, <mac-alias>
       Last failure:  <service> from <location>, <time>, <mac-alias>

       int     aaaccounteverused (sessionkitp) /* 1=yes, 0=no */
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastusedwhat (sessionkitp)
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastusedwhere (sessionkitp)
               aasessionkitt *   sessionkitp;

       timet  aaaccountlastusedwhen (sessionkitp)
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastusedmac (sessionkitp)
               aasessionkitt *   sessionkitp;


       int     aaaccounteverdenied (sessionkitp) /* 1=yes, 0=no */
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastdeniedwhat (sessionkitp)
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastdeniedwhere (sessionkitp)
               aasessionkitt *   sessionkitp;

       timet  aaaccountlastdeniedwhen (sessionkitp)
               aasessionkitt *   sessionkitp;

       char *  aaaccountlastdeniedmac (sessionkitp)
               aasessionkitt *   sessionkitp;


SEE ALSO
       inittab(4), dgmacaccess(2), dgsetomac(2), f4dgsettmpomac(2),
       Trusted Facility Manual for the C2 Trusted DG/UX System,
       Security Features Programming Guide for the C2 Trusted DG/UX System.















Licensed material--property of copyright holder(s)                        13


Typewritten Software • bear@typewritten.org • Edmonds, WA 98026