Advertisement
aaaaaa123456789

Flash policy daemon

Dec 2nd, 2013
128
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <errno.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <sys/socket.h>
  11. #include <sys/select.h>
  12. #include <netinet/ip.h>
  13. #include <arpa/inet.h>
  14.  
  15. int get_policy_data(const char *, void **);
  16. void generate_error(int, const char *, const char *);
  17. void process_reload_signal(int);
  18. int create_socket(unsigned short);
  19. void parse_requests(int, void *, int, const char *, const char *);
  20. int create_fdset(fd_set *, int *, unsigned, int);
  21. int * array_add(int *, unsigned, int);
  22. int * array_remove(int *, unsigned, int);
  23. void send_policy_info(int, void *, unsigned);
  24.  
  25. volatile sig_atomic_t reload_next;
  26.  
  27. int main (int argc, char ** argv) {
  28.   if (argc != 2) generate_error(1, *argv, argv[1]);
  29.   void * policydata;
  30.   int policylength = get_policy_data(argv[1], &policydata);
  31.   if (policylength < 0) generate_error(-policylength, *argv, argv[1]);
  32.   reload_next = 0;
  33.   int socketnumber = create_socket(843);
  34.   if (socketnumber < 0) generate_error(2, *argv, argv[1]);
  35.   if (signal(SIGHUP, &process_reload_signal) == SIG_ERR)
  36.     fprintf(stderr, "%s: could not install SIGHUP handler\n", *argv);
  37.   parse_requests(socketnumber, policydata, policylength, *argv, argv[1]);
  38.   close(socketnumber);
  39.   return 0;
  40. }
  41.  
  42. int get_policy_data (const char * filename, void ** data) {
  43.   int fd = open(filename, 0);
  44.   if (fd < 0)
  45.     switch (errno) {
  46.       case EACCES: return -3;
  47.       case ENOENT: case ENOTDIR: return -4;
  48.       default: return -5;
  49.     }
  50.   struct stat statdata;
  51.   if(fstat(fd, &statdata)) {
  52.     close(fd);
  53.     return -5;
  54.   }
  55.   int remainder = statdata.st_size;
  56.   int size = remainder;
  57.   *data = malloc(size + 1);
  58.   char * readp = *data;
  59.   int readsize;
  60.   while (remainder > 0) {
  61.     readsize = read(fd, readp, remainder);
  62.     if (readsize > 0) {
  63.       remainder -= readsize;
  64.       readp += readsize;
  65.       continue;
  66.     }
  67.     if (!readsize) {
  68.       size = readp - ((char *) (*data));
  69.       break;
  70.     }
  71.     if ((errno == EINTR) || (errno = EAGAIN)) continue;
  72.     close(fd);
  73.     if (errno == EISDIR) return -6;
  74.     return -5;
  75.   }
  76.   close(fd);
  77.   ((char *) (*data))[size] = 0;
  78.   return size + 1;
  79. }
  80.  
  81. void generate_error (int error, const char * programname, const char * filename) {
  82.   switch (error) {
  83.     case 1:
  84.       fprintf(stderr, "usage: %s policyfile\n", programname);
  85.       break;
  86.     case 2:
  87.       fprintf(stderr, "%s: could not create listening socket on port 843\n", programname);
  88.       break;
  89.     case 3:
  90.       fprintf(stderr, "%s: permission denied when accessing policy file %s\n", programname, filename);
  91.       break;
  92.     case 4:
  93.       fprintf(stderr, "%s: policy file %s does not exist\n", programname, filename);
  94.       break;
  95.     case 5:
  96.       fprintf(stderr, "%s: unknown error accessing policy file %s\n", programname, filename);
  97.       break;
  98.     case 6:
  99.       fprintf(stderr, "%s: policy file %s is actually a directory\n", programname, filename);
  100.       break;
  101.   }
  102.   exit(error);
  103. }
  104.  
  105. void process_reload_signal (int signalnumber) {
  106.   reload_next = 1;
  107. }
  108.  
  109. int create_socket (unsigned short port) {
  110.   int number = socket(AF_INET, SOCK_STREAM || SOCK_NONBLOCK, 0);
  111.   if (number < 0) return -1;
  112.   struct sockaddr_in sa;
  113.   sa.sin_family = AF_INET;
  114.   sa.sin_port = htons(port);
  115.   sa.sin_addr.s_addr = INADDR_ANY;
  116.   if (bind(number, (struct sockaddr *) &sa, sizeof sa)) {
  117.     close(number);
  118.     return -1;
  119.   }
  120.   if (listen(number, 128)) {
  121.     close(number);
  122.     return -1;
  123.   }
  124.   return number;
  125. }
  126.  
  127. void parse_requests (int socketnumber, void * policydata, int policylength, const char * programname, const char * filename) {
  128.   struct timeval tv = {.tv_sec = 5, .tv_usec = 0};
  129.   struct timeval tvs;
  130.   int cont = 1;
  131.   int result;
  132.   fd_set fdset;
  133.   int * clients = NULL;
  134.   unsigned clientcount = 0;
  135.   int * copy;
  136.   unsigned current, limit;
  137.   while (cont) {
  138.     result = create_fdset(&fdset, clients, clientcount, socketnumber);
  139.     tvs = tv;
  140.     result = select(result, &fdset, NULL, NULL, &tvs);
  141.     if (reload_next) {
  142.       void * newdata;
  143.       int status = get_policy_data(filename, &newdata);
  144.       if (status < 0)
  145.         fprintf(stderr, "%s: could not reload policy data from %s\n", programname, filename);
  146.       else {
  147.         free(policydata);
  148.         policydata = newdata;
  149.         policylength = status;
  150.       }
  151.       reload_next = 0;
  152.     }
  153.     if (result <= 0) continue;
  154.     copy = malloc(clientcount * sizeof(int));
  155.     memcpy(copy, clients, clientcount * sizeof(int));
  156.     limit = clientcount;
  157.     if (FD_ISSET(socketnumber, &fdset)) {
  158.       int newsocket = accept(socketnumber, NULL, NULL);
  159.       if (newsocket > 0) clients = array_add(clients, clientcount ++, newsocket);
  160.     }
  161.     for (current = 0; current < limit; current ++)
  162.       if (FD_ISSET(copy[current], &fdset)) {
  163.         char buffer[1024];
  164.         int reception = recv(copy[current], buffer, 1024, MSG_DONTWAIT);
  165.         if (!reception) {
  166.           close(copy[current]);
  167.           clients = array_remove(clients, clientcount --, copy[current]);
  168.         }
  169.         if (reception <= 0) continue;
  170.         unsigned short pos;
  171.         for (pos = 0; pos < reception; pos ++)
  172.           if (!buffer[pos])
  173.             send_policy_info(copy[current], policydata, policylength);
  174.       }
  175.     free(copy);
  176.   }
  177. }
  178.  
  179. int create_fdset (fd_set * fdset, int * fds, unsigned count, int listener) {
  180.   int * max = fds + count;
  181.   int * current;
  182.   int maxfd = listener + 1;
  183.   FD_ZERO(fdset);
  184.   FD_SET(listener, fdset);
  185.   for (current = fds; current < max; current ++) {
  186.     if (*current >= maxfd) maxfd = *current + 1;
  187.     FD_SET(*current, fdset);
  188.   }
  189.   return maxfd;
  190. }
  191.  
  192. int * array_add (int * array, unsigned length, int new) {
  193.   array = realloc(array, sizeof(int) * (length + 1));
  194.   array[length] = new;
  195.   return array;
  196. }
  197.  
  198. int * array_remove (int * array, unsigned length, int item) {
  199.   if (!length) {
  200.     free(array);
  201.     return NULL;
  202.   }
  203.   unsigned position;
  204.   for (position = 0; position < length; position ++)
  205.     if (array[position] == item) break;
  206.   if (position >= length) return array;
  207.   array[position] = array[-- length];
  208.   return realloc(array, sizeof(int) * length);
  209. }
  210.  
  211. void send_policy_info (int destsocket, void * data, unsigned length) {
  212.   char * pending = data;
  213.   unsigned size = length;
  214.   int status, retries = 0;
  215.   while (size) {
  216.     status = send(destsocket, pending, size, MSG_NOSIGNAL);
  217.     if (status >= 0) {
  218.       retries = 0;
  219.       size -= status;
  220.       pending += status;
  221.       continue;
  222.     }
  223.     if (errno == EPIPE) return;
  224.     retries ++;
  225.     if (retries >= 3) return;
  226.   }
  227. }
Advertisement
RAW Paste Data Copied
Advertisement