SHARE
TWEET

Untitled

a guest Feb 7th, 2013 95 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  *  rigid syslog
  3.  *  Permit syslog() calls only with allowed facility and severity.
  4.  *
  5.  *  Environment variable examples:
  6.  *
  7.  *    Permit whitelisted program identifier names:
  8.  *    trailing star examined as wildcard.
  9.  *
  10.  *      RGDLOG_PROGNAME=myprog1,myprog2,myprog*
  11.  *
  12.  *    Deny blacklisted program identifier names:
  13.  *    blacklist is prior than whitelist,
  14.  *    unset to use only whitelist.
  15.  *
  16.  *      RGDLOG_PROGNAME_NO=cron,sshd,exim*
  17.  *
  18.  *    Coma-separated list of allowed facilities and severities:
  19.  *    see <syslog.h> for meaning of values.
  20.  *
  21.  *      RGDLOG_FACILITY=1,17,18,19
  22.  *      RGDLOG_SEVERITY=3,4,5
  23. */
  24.  
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <dlfcn.h>
  28. #include <string.h>
  29. #include <sys/socket.h>
  30. #include <limits.h>
  31. #include <errno.h>
  32. // gcc -O0 -ldl -shared rgdlog.c -o rgdlog.so
  33.  
  34.  
  35. int session_facility = 0;
  36. char *rgdlog_progname;
  37. char *rgdlog_progname_no;
  38. char *rgdlog_facility;
  39. char *rgdlog_severity;
  40.  
  41.  
  42. __attribute__ ((constructor)) void f() {
  43. /*
  44.         if(getenv("RGDLOG_FACILITY")==NULL || getenv("RGDLOG_SEVERITY")==NULL) {
  45.                 fprintf(stderr, "In order to apply rigidlog, set and export RGDLOG_FACILITY and RGDLOG_SEVERITY environments.\n");
  46.                 exit(1);
  47.         }
  48. */
  49.         // Save initial environment
  50.         rgdlog_progname = getenv("RGDLOG_PROGNAME");
  51.         rgdlog_progname_no = getenv("RGDLOG_PROGNAME_NO");
  52.         rgdlog_facility = getenv("RGDLOG_FACILITY");
  53.         rgdlog_severity = getenv("RGDLOG_SEVERITY");
  54. }
  55.  
  56. void openlog(const char *ident, int option, int facility)
  57. {
  58.         static void (*real_openlog)(const char *ident, int option, int facility) = NULL;
  59.  
  60.         if (real_openlog == NULL) {
  61.                 void *handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
  62.                 if (handle == NULL) {
  63.                         fprintf(stderr, "dlopen: %s\n", dlerror());
  64.                         exit(1);
  65.                 }
  66.                 real_openlog = dlsym(handle, "openlog");
  67.                 if (real_openlog == NULL) {
  68.                         fprintf(stderr, "dlsym: %s\n", dlerror());
  69.                         exit(1);
  70.                 }
  71.         }
  72.  
  73.         char *s, *s2;
  74.         char permit = 1;
  75.         session_facility = facility >> 3;
  76.  
  77.         //fprintf(stderr, "openlog(\"%s\", %d, %d)\n", ident, option, facility);
  78.  
  79.         if(rgdlog_progname != NULL) {
  80.                 permit = 0;
  81.                 s = strtok(rgdlog_progname, ",");
  82.                 while(s != NULL) {
  83.                         if(strcmp(s, ident) == 0) {
  84.                                 permit = 1;
  85.                                 break;
  86.                         }
  87.                         else if(s[strlen(s)-1]=='*') {
  88.                                 s2 = strdup(ident);
  89.                                 s[strlen(s)-1] = s2[strlen(s)-1] = 0;
  90.                                 if(strcmp(s, s2) == 0) {
  91.                                         permit = 1;
  92.                                         break;
  93.                                 }
  94.                         }
  95.                         s = strtok(NULL, ",");
  96.                 }
  97.         }
  98.         if(rgdlog_progname_no != NULL) {
  99.                 s = strtok(rgdlog_progname_no, ",");
  100.                 while(s != NULL) {
  101.                         if(strcmp(s, ident) == 0) {
  102.                                 permit = 0;
  103.                                 break;
  104.                         }
  105.                         else if(s[strlen(s)-1]=='*') {
  106.                                 s2 = strdup(ident);
  107.                                 s[strlen(s)-1] = s2[strlen(s)-1] = 0;
  108.                                 if(strcmp(s, s2) == 0) {
  109.                                         permit = 0;
  110.                                         break;
  111.                                 }
  112.                         }
  113.                         s = strtok(NULL, ",");
  114.                 }
  115.         }
  116.         if(!permit) {
  117.                 fprintf(stderr, "rgdlog: syslog program name \"%s\" prohibited.\n", ident);
  118.                 return;
  119.         }
  120.        
  121.         real_openlog(ident, option, facility);
  122. }
  123.  
  124. //void syslog(int priority, const char *format, ...)
  125. void syslog(int priority, const char *format, const char *hellip)
  126. {
  127.         static void (*real_syslog)(int priority, const char *format, ...) = NULL;
  128.  
  129.         if (real_syslog == NULL) {
  130.                 void *handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
  131.                 if (handle == NULL) {
  132.                         fprintf(stderr, "dlsys: %s\n", dlerror());
  133.                         exit(1);
  134.                 }
  135.                 real_syslog = dlsym(handle, "syslog");
  136.                 if (real_syslog == NULL) {
  137.                         fprintf(stderr, "dlsym: %s\n", dlerror());
  138.                         exit(1);
  139.                 }
  140.         }
  141.  
  142.         int facility, severity;
  143.         char *s;
  144.         char permit;
  145.  
  146.         facility = priority >> 3;
  147.         if(facility == 0) facility = session_facility;
  148.         severity = priority & 7;
  149.  
  150.         //fprintf(stderr, "syslog(%d /* facility=%d, severity=%d */, \"%s\", \"%s\")\n", priority, facility, severity, format, hellip);
  151.  
  152.         if(rgdlog_facility != NULL) {
  153.                 permit = 0;
  154.                 s = strtok(rgdlog_facility, ",");
  155.                 while(s != NULL) {
  156.                         if(atoi(s) == facility) {
  157.                                 permit = 1;
  158.                                 break;
  159.                         }
  160.                         s = strtok(NULL, ",");
  161.                 }
  162.                 if(!permit) {
  163.                         fprintf(stderr, "rgdlog: syslog facility %d prohibited.\n", facility);
  164.                         return;
  165.                 }
  166.         }
  167.        
  168.         if(rgdlog_severity != NULL) {
  169.                 permit = 0;
  170.                 s = strtok(rgdlog_severity, ",");
  171.                 while(s != NULL) {
  172.                         if(atoi(s) == severity) {
  173.                                 permit = 1;
  174.                                 break;
  175.                         }
  176.                         s = strtok(NULL, ",");
  177.                 }
  178.                 if(!permit) {
  179.                         fprintf(stderr, "rgdlog: syslog severity %d prohibited.\n", severity);
  180.                         return;
  181.                 }
  182.         }
  183.        
  184.         /* permit syslog() */
  185.         real_syslog(priority, format, hellip);
  186. }
  187.  
  188. int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
  189. {
  190.         static int (*real_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen) = NULL;
  191.  
  192.         if (real_connect == NULL) {
  193.                 void *handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
  194.                 if (handle == NULL) {
  195.                         fprintf(stderr, "dlsys: %s\n", dlerror());
  196.                         exit(1);
  197.                 }
  198.                 real_connect = dlsym(handle, "connect");
  199.                 if (real_connect == NULL) {
  200.                         fprintf(stderr, "dlsym: %s\n", dlerror());
  201.                         exit(1);
  202.                 }
  203.         }
  204.        
  205.         char path[PATH_MAX];
  206.        
  207.         realpath(addr->sa_data, path);
  208.         if(addr->sa_family == AF_FILE && strcmp(path, "/dev/log")==0) {
  209.                 fprintf(stderr, "rgdlog: bare syslog connection attempt prevented.\n");
  210.                 errno = EACCES;
  211.                 return -1;
  212.         }
  213.         return real_connect(sockfd, addr, addrlen);
  214. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top