|
|||
1. Solaris Trusted Extensions APIs and Security Policy 4. Printing and the Label APIs 5. Interprocess Communications 8. Trusted Web Guard Prototype Administrative Web Guard Prototype 9. Experimental Java Bindings for the Solaris Trusted Extensions Label APIs |
Accessing Lower-Level Untrusted ServersSometimes a client needs to be able to access a server on an unlabeled system. An unlabeled system is a system that does not run the Trusted Extensions software. In such a case, you cannot use multilevel ports because they are restricted to privileged servers that run in the global zone or in labeled zones. For example, suppose your browser is running in the INTERNAL zone. You want to access a web server that runs on a single-level network that has been assigned the PUBLIC sensitivity label by means of the tnrhdb database. Such access is not permitted by default. However, you could write a privileged proxy server to forward the HTTP request to the PUBLIC web server. The proxy should use a special Trusted Extensions socket option called SO_MAC_EXEMPT. This socket option permits a request to be sent to an untrusted lower-level service, and permits the reply from that service to be returned to the requester. Note - The use of the SO_MAC_EXEMPT option represents an unprotected downgrade channel and should be used very carefully. The SO_MAC_EXEMPT option cannot be set unless the calling process has the PRIV_NET_MAC_AWARE privilege in its effective set. Such a process must enforce its own data filtering policy to prevent leaking higher-level data to the lower-level service. For example, the proxy should sanitize URLs to restrict words from being used as values. The following code excerpt demonstrates the use of SO_MAC_EXEMPT in a modified version of the wget command's connect_to_ip() routine in connect.c. The call to setsockopt() has been added to show how to set the SO_MAC_EXEMPT option. int connect_to_ip (const ip_address *ip, int port, const char *print) { struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; int sock; int on = 1; /* If PRINT is non-NULL, print the "Connecting to..." line, with PRINT being the host name we're connecting to. */ if (print) { const char *txt_addr = pretty_print_address (ip); if (print && 0 != strcmp (print, txt_addr)) logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "), escnonprint (print), txt_addr, port); else logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port); } /* Store the sockaddr info to SA. */ sockaddr_set_data (sa, ip, port); /* Create the socket of the family appropriate for the address. */ sock = socket (sa->sa_family, SOCK_STREAM, 0); if (sock < 0) goto err; if (setsockopt (sock, SOL_SOCKET, SO_MAC_EXEMPT, &on, sizeof (on)) == -1) { perror("setsockopt SO_MAC_EXEMPT"); } #if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) if (opt.ipv6_only) { /* In case of error, we will go on anyway... */ int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)); } #endif |
||
|