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); 
        } 
}