Solaris Trusted Extensions Developer's Guide

Chapter 3 Label Code Examples

This chapter contains several code examples that show how to use the label APIs that are described in Chapter 2, Labels and Clearances.

This chapter covers the following topics:

Obtaining a Process Label

This code example shows how to obtain and print the sensitivity label of the zone in which this program is run.

#include <tsol/label.h>

main()
{
    m_label_t* pl;
    char *plabel = NULL;
    int retval;

    /* allocate an m_label_t for the process sensitivity label */
    pl = m_label_alloc(MAC_LABEL);
    /* get the process sensitivity label */
    if ((retval = getplabel(pl)) != 0) {
        perror("getplabel(pl) failed");
        exit(1);
    }

    /* Translate the process sensitivity label to text and print */
    if ((retval = label_to_str(pl, &plabel, M_LABEL, LONG_NAMES)) != 0) {
        perror("label_to_str(M_LABEL, LONG_NAMES) failed");
        exit(1);
    }
    printf("Process label = %s\n", plabel);

    /* free allocated memory */
    m_label_free(pl);
    free(plabel);
    }

The printf() statement prints the sensitivity label. The sensitivity label is inherited from the zone in which the program is run. The following shows the text output of this example program:


Process label = ADMIN_LOW

The text output depends on the specifications in the label_encodings file.

Obtaining a File Label

You can obtain a file's sensitivity label and perform operations on that label.

This code example uses the getlabel() routine to obtain the file's label. The fgetlabel() routine can be used in the same way, but it operates on a file descriptor.

#include <tsol/label.h>

main()
{
    m_label_t* docLabel;
    const char* path = "/zone/restricted/documents/designdoc.odt";
    int retval;
    char* label_string;

    /* allocate label and get the file label specified by path */
    docLabel = m_label_alloc(MAC_LABEL);
    retval = getlabel(path, docLabel);

    /* translate the file's label to a string and print the string */
    retval = label_to_str(docLabel, &label_string, M_LABEL, LONG_NAMES);
    printf("The file's label = %s\n", label_string);
    
    /* free allocated memory */
    m_label_free(docLabel);
    free(label_string);
    }

When you run this program, the output might look similar to this:


The file's label = CONFIDENTIAL : INTERNAL USE ONLY

Setting a File Sensitivity Label

When you change the sensitivity label of a file, the file is moved to a new zone that matches the file's new label.

In this code example, the process is running at the CONFIDENTIAL label. The user who is running the process has a TOP SECRET clearance. The TOP SECRET label dominates the CONFIDENTIAL label. The process upgrades the sensitivity label to TOP SECRET. The user needs the Upgrade File Label RBAC authorization to successfully perform the upgrade.

The following program is called upgrade-afile.

#include <tsol/label.h>

main()
{
   int retval, error;
   m_label_t *fsenslabel;
   char *string = “TOP SECRET”;
   *string1 = “TOP SECRET”;

   /* Create new sensitivity label value */
   if ((retval = str_to_label(string, &fsenslabel, MAC_LABEL, L_DEFAULT, &err)) != 0) {
        perror("str_to_label(MAC_LABEL, L_DEFAULT) failed");
        exit(1);
    }

   /* Set file label to new value */
   if ((retval = setflabel(“/export/home/zelda/afile”, &fsenslabel)) != 0) {
        perror("setflabel(“/export/home/zelda/afile”) failed");
        exit(1);
    }

   m_label_free(fsenslabel);
}

The result of running this program depends on the process's label, relative to the label of the file that was passed to the process.

Before and after you run this program, you use the getlabel command to verify the file's label. As the following shows, before the program runs, the label for afile is CONFIDENTIAL. After the program runs, the label for afile is TOP SECRET.


% pwd
/export/home/zelda
% getlabel afile
afile: CONFIDENTIAL
% update-afile
% getlabel afile
afile: TOP SECRET

If you run the getlabel command from a window labeled CONFIDENTIAL after you reclassified the file, it is no longer visible. If you run the getlabel command in a window labeled TOP SECRET, you can see the reclassified file.

Determining the Relationship Between Two Labels

If your application accesses data at different sensitivity labels, perform checks in your code to ensure that the process label has the correct relationship to the data label before you permit an access operation to occur. You check the sensitivity label of the object that is being accessed to determine whether access is permitted by the system.

The following code example shows how to test two sensitivity labels for equality, dominance, and strict dominance. The program checks whether a file's label is dominated by or is equal to the process's label.

#include <stdio.h>
#include <stdlib.h>

#include <tsol/label.h>

main(int argc, char *argv[])
{
   m_label_t *plabel;
   m_label_t *flabel;

   plabel = m_label_alloc(MAC_LABEL);
   flabel = m_label_alloc(MAC_LABEL);

   if (getplabel(plabel) == -1) {
      perror("getplabel");
      exit(1);
   }
   if (getlabel(argv[1], flabel) == -1) {
      perror("getlabel");
      exit(1);
   }

   if (blequal(plabel, flabel)) {
      printf("Labels are equal\n");
   }
   if (bldominates(plabel, flabel)) {
      printf("Process label dominates file label\n");
   }
   if (blstrictdom(plabel, flabel)) {
      printf("Process label strictly dominates file label\n");
   }

   m_label_free(plabel);
   m_label_free(flabel);

   return (0);
}

The text output of this program depends on the process's label, relative to the label of the file that was passed to the process, as follows:

Obtaining the Color Names of Labels

This code example uses the label_to_str() function to obtain the color name of a label. The mappings between color names and labels are defined in the label_encodings file.

#include <stdlib.h>
#include <stdio.h>

#include <tsol/label.h>

int
main()
{
   m_label_t *plabel;
   char *label = NULL;
   char *color = NULL;

   plabel = m_label_alloc(MAC_LABEL);

   if (getplabel(plabel) == -1) {
      perror("getplabel");
      exit(1);
   }

   if (label_to_str(plabel, &color, M_COLOR, 0) != 0) {
      perror("label_to_string(M_COLOR)");
      exit(1);
   }
   if (label_to_str(plabel, &label, M_LABEL, DEF_NAMES) != 0) {
      perror("label_to_str(M_LABEL)");
      exit(1);
   }

   printf("The color for the \"%s\" label is \"%s\".\n, label, color);

   m_label_free(plabel);

   return (0);
}

If the label_encodings file maps the color blue to the label CONFIDENTIAL, the program prints the following:


The color for the "CONFIDENTIAL" label is "BLUE".

Obtaining Printer Banner Information

The label_encodings file defines several conversions that are useful for printing security information on printer output. Label conversions are printed at the top and at the bottom of pages. Other conversions, such as handling channels, can appear on the banner pages.

In the following code example, the label_to_str() routine converts a label to strings, such as the header and footer, a caveats section, and handling channels. This routine is used internally by the Trusted Extensions print system, as shown in Chapter 4, Printing and the Label APIs.

#include <stdlib.h>
#include <stdio.h>

#include <tsol/label.h>

int
main()
{
   m_label_t *plabel;
   char *header = NULL;
   char *label = NULL;
   char *caveats = NULL;
   char *channels = NULL;

   plabel = m_label_alloc(MAC_LABEL);
   if (getplabel(plabel) == -1) {
      perror("getplabel");
      exit(1);
   }
   if (label_to_str(plabel, &header, PRINTER_TOP_BOTTOM, DEF_NAMES) != 0) {
      perror("label_to_str: header");
      exit(1);
   }
   if (label_to_str(plabel, &label, PRINTER_LABEL, DEF_NAMES) != 0) {
      perror("label_to_str: label");
      exit(1);
   }
   if (label_to_str(plabel, &caveats, PRINTER_CAVEATS, DEF_NAMES) != 0) {
      perror("label_to_str: caveats");
      exit(1);
   }
   if (label_to_str(plabel, &channels, PRINTER_CHANNELS, DEF_NAMES) != 0) {
      perror("label_to_str: channels");
      exit(1);
   }

   printf("\t\t\t\"%s\"\n\n", header);
   printf("\t\tUnless manually reviewed and downgraded, this output\n");
   printf("\t\tmust be protected at the following label:\n\n");
   printf("\t\t\t\"%s\"\n", label);
   printf("\n\n\n");
   printf("\t\t\"%s\"\n", caveats);
   printf("\t\t\"%s\"\n", channels);
   printf("\n\n");
   printf("\t\t\t\"%s\"\n", header);

   m_label_free(plabel);

   return (0);
}

For a process label of TS SA SB, the text output might be the following:


			"TOP SECRET"

		Unless manually reviewed and downgraded, this output
		must be protected at the following label:

			"TOP SECRET A B SA SB"



		"(FULL SB NAME) (FULL SA NAME)"
		"HANDLE VIA (CH B)/(CH A) CHANNELS JOINTLY"


			"TOP SECRET"

For more information, see the label_encodings(4) man page, Compartmented Mode Workstation Labeling: Encodings Format, and Solaris Trusted Extensions Label Administration.