Server example
This program acts as a server and uses the eread routine to receive messages that are sent to its port. After successfully receiving a message, this program outputs the security attributes of the message.
The following privileges are required in the program's innate privilege
set (without assigning FSF_EPS secflags):
- PV_LAB_LEF
- PV_MAC_CL
- PV_MAC_R_STR
#include <sys/mac.h>
#include <sys/socket.h>
#include <sys/priv.h>
#include <sys/secattr.h>
#include <sys/stropts.h>
#include <netinet/in.h>
#include <errno.h>
#include <stropts.h>
#include <unistd.h>
#include <stdio.h>
#include <mls/mls.h>
#define MAX_HR_LABEL_LEN 2048
#define SECURE 1
int
main(int argc, char *argv[])
{
pid_t childpid;
uint clilen;
int sockfd, newsockfd;
struct sockaddr_in cli_addr, serv_addr;
#ifdef SECURE
int l_init_result;
char label_str[MAX_HR_LABEL_LEN];
sec_labels_t seclab;
#endif /* SECURE */
if ( argc != 2 )
{
fprintf(stderr, "Usage:%s PORT\n", argv[0]);
exit(1);
}
#ifdef SECURE
priv_raise(PV_LAB_LEF, -1);
l_init_result = initlabeldb(NULL);
if (priv_remove(PV_LAB_LEF, -1) != 0)
{
fprintf(stderr, "Privilege Failure\n");
exit(1);
}
if (l_init_result != 0)
{
fprintf(stderr, "Could not read the Label Encodings Database\n");
exit(1);
}
#endif /* SECURE */
/* Open a TCP socket (an Internet stream socket). */
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
perror("tcpserver: ");
fprintf(stderr, "server: Cant open stream socket\n");
exit(1);
}
/*Bind our local address so that the client can send to us*/
memset((char *) &serv_addr;, '\0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
if ( bind(sockfd, (struct sockaddr *) & serv_addr,
sizeof(serv_addr)) < 0 )
{
perror("tcpserver: ");
fprintf(stderr, "server: Cant bind local address\n");
exit(0);
}
listen(sockfd, 5);
for (;;)
{
/*
* * Wait for a connection from a client process.
* */
fprintf(stdout, "Waiting for a connection from a client\n");
clilen = sizeof(cli_addr);
newsockfd = eaccept(sockfd, (struct sockaddr *) & cli_addr,
&clilen;, &seclab;);
if ( newsockfd < 0 )
{
perror("tcpserver: ");
fprintf(stderr, "server: accept error\n");
}
/* Print SL */
if ( slbtohr(label_str, &seclab.sl;, HR_SHORT) != 0 )
{
fprintf(stderr,"problem converting sl to string\n");
}
else
{
fprintf(stdout, "sl = %s.\n",label_str);
}
/* Print MIN CLEARANCE */
if ( slbtohr(label_str, &seclab.sl_cl_min;, HR_SHORT) != 0 )
{
fprintf(stderr,"problem converting min clearance to string\n");
}
else
{
fprintf(stdout, "sl_cl_min = %s.\n",label_str);
}
/* Print MAX CLEARANCE */
if ( slbtohr(label_str, &seclab.sl_cl_max;, HR_SHORT) != 0 )
{
fprintf(stderr,"problem converting max clearance to string\n");
}
else
{
fprintf(stdout, "sl_cl_max = %s.\n",label_str);
}
if ( (childpid = fork()) < 0 )
{
perror("tcpserver: ");
fprintf(stderr, "server: fork error\n");
exit(0);
}
else if ( childpid == 0 ) /* child process */
{
int i, j;
char buf[BUFSIZ];
#ifdef SECURE
sec_labels_t e_seclab;
#endif /* SECURE */
close(sockfd);
for (;;)
{
int ret, flag;
struct strbuf ctstr, dtstr;
char ctbuf[2048], dtbuf[2048];
ctstr.maxlen=2048;
ctstr.buf = ctbuf;
dtstr.maxlen=2048;
dtstr.buf = dtbuf;
#ifdef SECURE
fprintf(stdout, "Calling eread\n");
priv_raise(PV_MAC_CL,PV_MAC_R_STR,-1);
ret = eread(newsockfd, buf, sizeof(buf),&e_seclab;);
priv_lower(PV_MAC_CL,PV_MAC_R_STR,-1);
if ( ret < 1 )
{
if ( ret == -1 )
fprintf(stderr, "eread error\n");
else
fprintf(stderr, "eread no data\n");
close(newsockfd);
exit(ret);
}
fprintf(stdout, "\n%s", buf);
fprintf(stdout, "\n");
/* Print SL */
if ( slbtohr(label_str, &e_seclab.sl;, HR_SHORT) != 0 )
{
fprintf(stderr, "problem converting sl to string\n");
}
else
{
fprintf(stdout, "sl = %s.\n",label_str);
}
/* Print MIN CLEARANCE */
if ( slbtohr(label_str,&e_seclab.sl_cl_min;,HR_SHORT)!= 0)
{
fprintf(stderr,"problem converting min CL to string\n");
}
else
{
fprintf(stdout, "sl_cl_min = %s.\n",label_str);
}
/* Print MAX CLEARANCE */
if ( slbtohr(label_str,&e_seclab.sl_cl_max;,HR_SHORT) !=0)
{
fprintf(stderr,"problem converting max CL to string\n");
}
else
{
fprintf(stdout, "sl_cl_max = %s.\n",label_str);
}
fflush(stdout);
#else /* NOT SECURE */
fprintf(stdout, "Calling read\n");
if (read(newsockfd, buf, sizeof(buf)) < 1)
{
if (ret == -1)
fprintf(stderr, "read error\n");
else
fprintf(stderr, "read no data\n");
close(newsockfd);
exit(ret);
}
fprintf(stdout, "%s\n", buf);
fflush(stdout);
#endif /* NOT SECURE */
}
}
/* parent process */
close(newsockfd);
}
}