Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

nsec_map_library(3)



nsec_library(3)          DG/UX B2 Security R4.12MU02         nsec_library(3)


NAME
       nsec_library, dg_running_with_nsec, dg_nsec_get_peer_credentials,
       dg_nsec_free_peer_credentials, dg_nsec_get_object_attributes,
       dg_nsec_free_object_attributes, dg_nsec_get_null_attrs,
       dg_nsec_get_attrs, dg_nsec_set_attrs, dg_nsec_free_attrs,
       dg_nsec_get_attr, dg_nsec_set_attr, dg_nsec_get_err_msg - NSEC
       (network security) routines in libtrust

SYNOPSIS
       #include <dg_running_with.h>
       #include <dg_nsec.h>

       int     dg_running_with_nsec (void)

       int     dg_nsec_get_peer_credentials
                                 (int                  fd,
                                  struct sockaddr      *name,
                                  int                  name_len,
                                  dg_sec_cred_t        **sec_cred_ptr_ptr)

       int     dg_nsec_free_peer_credentials
                                 (dg_sec_cred_t        **sec_cred_ptr_ptr)

       int     dg_nsec_get_object_attributes
                                 (int                  fd,
                                  struct sockaddr      *name,
                                  int                  name_len,
                                  dg_object_attrs_type **obj_attrs_ptr_ptr)

       int     dg_nsec_free_object_attributes
                                 (dg_object_attrs_type **obj_attrs_ptr_ptr)

       int     dg_nsec_get_null_attrs (void           **attrs_handle_ptr)

       int     dg_nsec_get_attrs (int                  fd,
                                  int                  attrs_type,
                                  struct sockaddr      *name,
                                  int                  name_len,
                                  void                 **attrs_handle_ptr)

       int     dg_nsec_set_attrs (int                  fd,
                                  struct sockaddr      *name,
                                  int                  name_len,
                                  void                 *attrs_handle)

       int     dg_nsec_free_attrs(void                 **attrs_handle_ptr)

       int     dg_nsec_get_attr  (void                 *attrs_handle,
                                  unsigned int         kind_of_attr,
                                  void                 *attr_ptr,
                                  unsigned int         *attr_len_ptr)

       int     dg_nsec_set_attr  (unsigned int         kind_of_attr,
                                  void                 *attr_ptr,
                                  unsigned int         attr_len,
                                  void                 *attrs_handle)

       char   *dg_nsec_get_err_msg (void)

DESCRIPTION
       The NSEC (Network SECurity) library functions provide a mechanism for
       security-aware applications to get and set security attributes on
       network sessions.  A network session is a unique association of two
       network endpoints: a local and a remote endpoint.  The client
       endpoint is by default the first endpoint to transmit a packet (i.e.
       to issue the connect system call for TCP); the server endpoint of the
       session is the other endpoint.  However, if the endpoint which
       receives the first packet had the DG_CAP_NET_CLIENT capability
       asserted at the time it was created, then it is the client endpoint.

       Each network endpoint has at least two and possibly three sets of
       security attributes.

       Each endpoint always has a set of object security attributes.  Each
       network session is an object that is being accessed via the endpoint;
       the network session can then be compared to a file that two processes
       are sharing.  The object attributes can be retrieved by a call to
       dg_nsec_get_object_attributes() or dg_nsec_get_attrs().

       Each endpoint also always has an outgoing set of attributes that may
       be sent to the remote endpoint for the session.  By default, the
       outgoing attributes for the client endpoint are the credentials of
       the client process which created the local endpoint (at the time the
       local endpoint was created); similarly, the outgoing attributes for a
       server endpoint are the credentials of the server process except that
       the MAC label is equal to the MAC label from the incoming attributes.
       Therefore, packets traveling in either direction between two
       endpoints will have the same MAC label.  The outgoing attributes may
       be changed with a call to dg_nsec_set_attrs() by a process with
       appropriate privilege; see the ACCESS CONTROL section below for more
       information.  The current value of the outgoing attributes can be
       retrieved with a call to dg_nsec_get_attrs().  Note that the set of
       attributes that are actually transmitted across the network is
       typically a subset of the credentials; the set of attributes actually
       transmitted is dependent upon the type of the remote host.  For
       example, if the remote host is a generic (i.e. unlabeled) host, no
       attributes are transmitted.  (See dn6d.config.4m discussion of
       network attributes for more information.)

       Each endpoint may also have an incoming set of security attributes,
       or peer credentials.  These are the last attributes received from the
       remote endpoint and are the credentials (i.e. process attributes) of
       the peer process at the time the remote endpoint was created.  So for
       a server process, the incoming set of security attributes are the
       client's credentials.  If no packets have been received from the
       remote endpoint, there are no incoming attributes.  Note that for a
       TCP connection, packets are transmitted in both directions in order
       to establish the connection; therefore, an endpoint corresponding to
       an established TCP connection will always have an incoming set of
       security attributes.  The incoming attributes (or peer's credentials)
       can be retrieved with a call to dg_nsec_get_peer_credentials or
       dg_nsec_get_attrs().  These attributes can not be modified.  Note
       that Trusted IP assigns default values for the fields of the
       credentials which are not actually transmitted over the network; by
       default, the following attributes are transmitted from one B2 system
       to another: UID and GID (as found in the cred_t structure of the
       DG_SEC_CRED_T_ATTR attribute), MAC label, and authentication ID.
       (See dn6d.config.4m discussion of network attributes for more
       information.)


   dg_running_with_nsec
       This function returns true if the local system is configured with
       network security; otherwise, it returns false.


   dg_nsec_get_peer_credentials
       This function returns the peer's credentials; that is, the
       credentials of the process at the remote end of the session.  The
       session has a local endpoint corresponding to fd and a remote
       endpoint corresponding to name and name_len.  Upon return,
       sec_cred_ptr_ptr is set to point to the peer's credentials.  It is
       the responsibility of the caller to free the credentials by calling
       dg_sec_cred_free().  If no error occurs, the function returns 0;
       otherwise, it sets errno to indicate the error.

       Errors:

       ENOMEM  Unable to allocate space for the credentials.


   dg_nsec_free_peer_credentials
       This function frees the peer's credentials that are allocated by
       dg_nsec_get_peer_credentials().  If no error occurs, the function
       returns 0; otherwise, it sets errno to indicate the error.



   dg_nsec_get_object_attributes
       This function returns the session's object attributes.  A session can
       be viewed as a file through which processes pass information.  The
       session has a local endpoint corresponding to fd and a remote
       endpoint corresponding to name and name_len.  Upon return,
       obj_attrs_ptr_ptr is set to point to the session's object attributes.
       It is the responsibility of the caller to free the credentials by
       calling dg_nsec_free_object_attributes().  If no error occurs, the
       function returns 0; otherwise, it sets errno to indicate the error.

       Errors:

       ENOMEM  Unable to allocate space for the credentials.


   dg_nsec_free_object_attributes
       This function frees the object attributes that are allocated by
       dg_nsec_get_object_attributes().  If no error occurs, the function
       returns 0; otherwise, it sets errno to indicate the error.



   dg_nsec_get_null_attrs
       This function sets attrs_handle_ptr to point to a set of null
       attributes (which may be freed with a call to dg_nsec_free_attrs()),
       This function is typically used when you need to build a set of
       attributes from scratch.n If no error occurs, the function returns 0;
       otherwise, it sets errno to indicate the error.

       Errors:

       ENOMEM  Unable to allocate space for the set of null attributes.


   dg_nsec_get_attrs
       If attrs_type equals 0, the function sets attrs_handle_ptr to point
       to the current outgoing attributes for the session.  If name_len
       equals 0, the attributes that are used to create all future locally
       initiated sessions are retrieved; otherwise, the attributes that will
       be sent to a particular remote endpoint specified by name are
       retrieved.  Note that if name_len does not equal 0, a packet must
       have been previously sent to or received from the remote endpoint
       specified by name.

       If attrs_type equals 1, this function sets attrs_handle_ptr to point
       to the current incoming attributes for the session.  The session has
       a local endpoint corresponding to fd and a remote endpoint
       corresponding to name and name_len.  Therefore, to retrieve the
       current incoming attributes for the session, the name and name_len
       must denote a valid remote network endpoint.  If no error occurs, the
       function returns 0; otherwise, it sets errno to indicate the error.

       If attrs_type equals 2, this function sets attrs_handle_ptr to point
       to the current object attributes for the session.  The session has a
       local endpoint corresponding to fd and a remote endpoint
       corresponding to name and name_len.  Therefore, to retrieve the
       current object attributes for the session, the name and name_len must
       denote a valid remote network endpoint.  If no error occurs, the
       function returns 0; otherwise, it sets errno to indicate the error.

       The attributes pointed to by *attrs_handle_ptr upon return may be
       freed with a call to dg_nsec_free_attrs().

       Errors:

       ENOMEM     Unable to allocate space for the set of attributes.

       EDGNOATTR  No packets have been received for this session, where
                  attrs_type equals 1 or 2.

   dg_nsec_set_attrs
       This function sets the outgoing attributes for a session.  If
       name_len equals 0, set the attributes that are to be used as the
       outgoing attributes for all future locally initiated sessions;
       otherwise, set the outgoing attributes for the session between the
       local endpoint specified by fd and the remote endpoint specified by
       name and name_len.  If name_len does not equal 0 (i.e. a remote
       endpoint is specified), a packet must have previously been received
       from (or sent to) the remote endpoint.  The caller must have the
       appropriate privilege to perform this operation; see ACCESS CONTROL
       below for more information.

       If no error occurs, the function returns 0; otherwise, it sets errno
       to indicate the error.

       Errors:

       EACCES  The caller is not privileged to perform this operation.

       ENOMEM  Unable to allocate buffer space for the operation.

   dg_nsec_free_attrs
       This function frees the memory used to hold a set of attributes.  The
       attributes handle pointed to by attrs_handle_ptr is set to NULL upon
       return.  If no error occurs, the function returns 0; otherwise, it
       sets errno to indicate the error.

   dg_nsec_get_attr
       This function extracts an individual attribute (specified by
       kind_of_attr) from the set of attributes associated with
       attrs_handle.  If the attribute is found and no error occurs, the
       function returns a value greater than 0; if the attribute is not
       found but no error occurs, the function returns 0; if an error
       occurs, the function sets errno to indicate the error and returns a
       value less than 0.

       Upon entry to dg_nsec_get_attr(), *attr_len_ptr is set to the maximum
       length of the buffer pointed to by attr_ptr.  Upon return from
       dg_nsec_get_attr where the return value is greater than 0, the buffer
       contains the requested attribute and *attr_len_ptr is set to the
       length of the attribute.

       The valid values for kind_of_attr are listed below.  Associated with
       each value is the corresponding type of the attribute pointer which
       is returned in *attr_ptr, and whether this attribute is mandatory,
       optional, or never exists for incoming, outgoing, and object
       attributes.


              DG_SEC_MAC_ATTR
                     Type of attribute pointer returned is mac_label_t as
                     defined in sys/mac.h.  Mandatory in incoming and
                     outgoing attributes; optional in object attributes.
                     Note that an object must have a MAC label or a MAC
                     tuple, and may also have both.
              DG_SEC_CAP_ATTR
                     Type of attribute pointer returned is cap_t as defined
                     in sys/capability.h.  Mandatory in incoming and
                     outgoing attributes; optional in object attributes.
              DG_SEC_MAC_TUPLE_ATTR
                     Type of attribute pointer returned is mac_tuple_t as
                     defined in sys/mac.h.  Mandatory in incoming and
                     outgoing attributes; optional in object attributes.
                     Note that an object must have either a MAC label or a
                     MAC tuple, and may also have both.
              DG_SEC_REQUIRED_CAP_ATTR
                     Type of attribute pointer returned is cap_required_t as
                     defined in sys/capability.h.  Optional in incoming,
                     outgoing, and object attributes.
              DG_SEC_ACL_ATTR
                     Type of attribute pointer returned is acl_t as defined
                     in sys/acl.h.  Optional in incoming and outgoing
                     attributes; mandatory in object attributes.
              DG_SEC_CRED_T_ATTR
                     Type of attribute pointer returned is cred_t as defined
                     in sys/cred.h.  Note that this structure contains the
                     real and effective UID and GID.  Mandatory in incoming
                     and outgoing attributes; optional in object attributes.
              DG_SEC_AUTHINFO_ATTR
                     Type of attribute pointer returned is pointer to
                     dg_authinfo_t as defined in dg_authinfo.h.  Optional in
                     incoming and outgoing attributes; never exists in
                     object attributes.
              DG_SEC_INFO_LABEL_ATTR
                     Type of attribute pointer returned is mac_label_t from
                     sys/mac.h.  Optional in incoming and outgoing
                     attributes; this attribute will only exist if the
                     remote endpoint is on a system which needs to receive
                     this attribute, as is the case for a CMW (Compartmental
                     Mode Workstation).  This attribute never exists in
                     object attributes.
              DG_SEC_AUDIT_MASK_ATTR
                     Type of attribute pointer returned is aud_mask_t as
                     defined in sys/audit.h.  Mandatory in incoming and
                     outgoing attributes; never exists in object attributes.
              DG_SEC_AUTH_ID_ATTR
                     Type of attribute pointer returned is auth_id_t as
                     defined in sys/dg_tparms.h.  Mandatory in incoming and
                     outgoing attributes; never exists in object attributes.
              DG_SEC_PID_ATTR
                     Type of attribute pointer returned is pid_t as defined
                     in sys/types.h.  Optional in incoming attributes;
                     mandatory in outgoing attributes; never exists in
                     object attributes.


       Errors:

       ENOBUFS  The attribute was too large for the buffer of size
                *attr_len_ptr.

       EINVAL   Invalid value for kind_of_attr specified.

   dg_nsec_set_attr
       This function sets an individual attribute (specified by
       kind_of_attr) in the set of attributes associated with attrs_handle
       to the value pointed to by attr_ptr with length of attr_len.  The
       actual type of the structure pointed to by attr_ptr is dependent upon
       the value of kind_of_attr.  For a list of the valid values of
       kind_of_attr and the associated type of structure pointer for
       attr_ptr, see the description under dg_nsec_get_attr above.

       If no error occurs, the function returns 0; otherwise, it sets errno
       to indicate the error.

       Errors:

       EINVAL  Invalid value for kind_of_attr specified.

   dg_nsec_get_err_msg
       If any of the above functions fail, this function can then be used to
       retrieve a null terminated error message string denoting the reason
       for the failure.  Note, however, that the message string is stored in
       a single internal buffer and is overwritten by each successive
       failure.


ACCESS CONTROL
       To perform dg_nsec_set_attrs, a process must have appropriate
       privilege.

       For systems supporting the DG/UX Capability Option, appropriate
       privilege is defined as having one or more specific capabilities
       enabled in the effective capability set of the calling process.  See
       cap_defaults(5) for the default capability for this system call.  On
       systems without the DG/UX Capability Option, appropriate privilege
       means that the process has an effective UID of root. See the
       appropriate_privilege(5) man page for more information.


EXAMPLE
       /*
        * This is a sample program that uses the nsec_library(3).
        * When invoked it accepts tcp connections and then writes some
        * of the security attributes of the connection back as data on
        * the connection.
        *
        * This can be compiled and then executed as follows:
        *
        * Compile:
        * m88k:  cc -o <program> <program>.c -ltrust
        * ix86:  cc -o <program> <program>.c -lnsl -lsocket -ltrust
        *
        * Usage:
        *      <program> <port-number>
        *
        * To see the attributes:
        *      telnet hostname <port-number>
        */

       #include <malloc.h>
       #include <nsec.h>
       #include <dg_sec_subject.h>
       #include <netinet/in.h>
       #include <stdio.h>
       #include <sys/audit.h>
       #include <sys/capability.h>
       #include <sys/cred.h>
       #include <sys/dg_tparms.h>
       #include <sys/mac.h>
       #include <sys/socket.h>
       #include <sys/types.h>

       /*
        * This reads the attributes from the connection and
        * builds a readable string for the attributes in msg.
        */

       void
       get_client_attributes
           (
           int                 new_fd,
           struct sockaddr_in  *remote_addr_p,
           int                 remote_addr_len,
           char                *msg
           )
       {
           dg_sec_cred_t       *sec_cred_p;
           char                *mac_alias = NULL;
           int                 rtn;

           /*
            * Get attributes from network connection
            */
           rtn = dg_nsec_get_peer_credentials(
                                       new_fd,
                                       remote_addr_p,
                                       remote_addr_len,
                                       &sec_cred_p );
           if( rtn < 0 ) {
               sprintf( msg,
                        "Couldn't get credentials: %s0,
                        dg_nsec_get_err_msg() );
               return;
           }

           /*
            * Convert the MAC label to its alias.
            */
           rtn = mac_label_to_alias( sec_cred_p->label,
                                     M_ALIAS,
                                     &mac_alias );
           if( rtn < 0 ) {
               sprintf(msg,"mac_label_to_alias failed0);
               goto done;
           }
                                                    0,
           sprintf( msg, 0ID: %d, GID:%d, AUTHID: %d
                 "MAC: %s
                    mac_alias,
                    sec_cred_p->cred_ptr->cr_uid,
                    sec_cred_p->cred_ptr->cr_gid,
                    sec_cred_p->auid );

       done:
           /*
            * Free any storage lying around.
            */
           (void) dg_nsec_free_peer_credentials(&sec_cred_p);
           if( mac_alias != NULL ) {
               free(mac_alias);
           }

           return;

       }

       main(int argc, char * argv[])
       {
           int                 port_number;
           int                 listen_fd;
           int                 new_fd;
           int                 result;
           struct sockaddr_in  remote_address;
           int                 addr_len;
           char                reply_line[10000];

           if(argc != 2) {
               fprintf(stderr,"Usage %s <port_number>0,argv[0]);
               exit(1);
           }

           port_number = atoi(argv[1]);
           if( port_number == 0 ) {
               fprintf("Invalid port number %s0,argv[1]);
               exit(1);
           }

           /*
            * Create TCP endpoint and bind to appropriate port.
            */
           listen_fd = socket(AF_INET,SOCK_STREAM,0);
           if(listen_fd < 0) {
               perror("socket call failed");
               exit(1);
           }

           memset((char*)&remote_address,0,sizeof(remote_address));
           remote_address.sin_port = htons(port_number);
           remote_address.sin_family = AF_INET;
           result = bind(listen_fd,&remote_address,sizeof(remote_address));
           if(result < 0) {
               perror("bind failed");
               exit(1);
           }
           result = listen(listen_fd,5);
           if(result < 0) {
               perror("listen failed");
               exit(1);
           }

           printf("Listening on port %d0,port_number);

           /*
            * Loop waiting for connections.
            */
           for(;;) {

               /*
                * Accept new connection.
                */
               addr_len = sizeof(remote_address);
               new_fd = accept(listen_fd,&remote_address,&addr_len);
               if(new_fd < 0) {
                   perror("accept failed");
                   exit(1);
               }

               sprintf( reply_line,                              0,
                        "You are calling from addr=%8.8x, port=%d
                        remote_address.sin_addr,
                        remote_address.sin_port);

               result = write(new_fd,reply_line,strlen(reply_line));
               if(result < 0) {
                   fprintf(stderr,"write failed");
               }

               /*
                * Get attributes into text message.
                */
               if( dg_running_with_nsec() ) {
                   get_net_attributes( new_fd,
                                       &remote_address,
                                       addr_len,
                                       reply_line);
               } else {
                   sprintf( reply_line,                              0);
                            "No network security attributes available
               }

               result = write(new_fd,reply_line,strlen(reply_line));
               if( result < 0 ) {
                   fprintf(stderr,"write failed");
               }

               close(new_fd);

           } /* end for */

       } /* end main */


SEE ALSO
       nsec_map_library(3).


Licensed material--property of copyright holder(s)

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