Пример обмена конфиденциальными данными через сокет#
Пример проверки работы, если server запущен на данном компьютере: telnet 127.0.0.1 9001 В случае успеха, будет выдана строка “client parsec label: ”
// gcc -Wall -lparsec-base -lparsec-mac server.c -o server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/prctl.h>
/* for pdp_set_EQU_fd */
/* #include <parsec/pdp.h> */
#include <parsec/mac.h>
#include <parsec/parsec_mac.h>
#include <parsec/parsec_integration.h>
#define PORT 9001
#define MAX_QUEUE_LEN 16
#define ANSWER_TO_CLIENT "client parsec label: "
#define REPORT_AND_EXIT(output_number) \
do \
{ \
fprintf(stderr, "%s, %s, %d: ", __FILE__, __FUNCTION__, __LINE__); \
perror(NULL); \
exit(output_number); \
} while(0)
#define REPORT() \
do \
{ \
fprintf(stderr, "%s, %s, %d: ", __FILE__, __FUNCTION__, __LINE__); \
perror(NULL); \
} while(0)
/*
* TCP socket,
* descriptor and sockaddr
*/
struct TCP_socket
{
int sd;
struct sockaddr_in addr;
unsigned addr_size;
};
/************children process************/
void children_process(int csd)
{
/*get mac level*/
parsec_mac_label_t mac_label;
if(parsec_fstatmac(csd, &mac_label))
REPORT_AND_EXIT(7);
/*answer client*/
char answer[strlen(ANSWER_TO_CLIENT) + 2*sizeof(char)];
sprintf(answer, ANSWER_TO_CLIENT "%d\n", mac_label.mac.lev);
if((send(csd, answer, sizeof(answer), 0) != sizeof(answer)))
REPORT_AND_EXIT(8);
}
/****************************************/
/**************main process**************/
struct TCP_socket create_listen_socket()
{
/*create listen socket and its sockaddr*/
struct TCP_socket ls;
ls.sd = socket(AF_INET, SOCK_STREAM, 0);
if((ls.sd == -1))
REPORT_AND_EXIT(3);
ls.addr.sin_family = AF_INET;
ls.addr.sin_port = htons(PORT);
ls.addr.sin_addr.s_addr = htonl(INADDR_ANY);
ls.addr_size = sizeof(ls.addr);
/*set port reuse*/
int optval = 1;
if((setsockopt(ls.sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1))
REPORT_AND_EXIT(4);
/*bind socket with its params*/
if((bind(ls.sd, (struct sockaddr *)&ls.addr, ls.addr_size) == -1))
REPORT_AND_EXIT(5);
/*make socket listen*/
if((listen(ls.sd, MAX_QUEUE_LEN) == -1))
REPORT_AND_EXIT(6);
return ls;
}
void set_caps()
{
parsec_caps_t pcaps = {0, 0, 0};
pcaps.cap_permitted |= CAP_TO_MASK(PARSEC_CAP_SETMAC);
pcaps.cap_permitted |= CAP_TO_MASK(PARSEC_CAP_PRIV_SOCK);
pcaps.cap_effective |= CAP_TO_MASK(PARSEC_CAP_SETMAC);
pcaps.cap_effective |= CAP_TO_MASK(PARSEC_CAP_PRIV_SOCK);
pcaps.cap_inheritable |= CAP_TO_MASK(PARSEC_CAP_PRIV_SOCK);
pcaps.cap_inheritable |= CAP_TO_MASK(PARSEC_CAP_SETMAC);
if(prctl(PR_SET_KEEPCAPS, 1))
REPORT_AND_EXIT(1);
/*set privilege*/
if(parsec_cur_caps_set(NULL, &pcaps) < 0)
REPORT_AND_EXIT(2);
}
int main(void)
{
set_caps();
struct TCP_socket ls = create_listen_socket();
/* alternative set_caps */
/* pdp_set_EQU_fd(ls.sd); */
/*main loop*/
for(;;)
{
int csd = accept(ls.sd, (struct sockaddr *)&ls.addr, (socklen_t *)&ls.addr_size);
if((csd == -1))
{
REPORT();
continue;
}
/*create service process */
int pid = fork();
if((pid == -1))
REPORT();
if((pid == 0))
{
/*service process*/
close(ls.sd);
children_process(csd);
exit(0);
}
/*main process*/
close(csd);
/*check children*/
do
{
pid = wait3(NULL, WNOHANG, NULL);
} while((pid > 0));
}
return 0;
}
/****************************************/