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)