Segfault prevention due to NULL printing
authorNeutron Soutmun <neo.neutron@gmail.com>
Thu, 21 Aug 2008 05:25:09 +0000 (12:25 +0700)
committerNeutron Soutmun <neo.neutron@gmail.com>
Sun, 2 Nov 2008 19:43:11 +0000 (02:43 +0700)
2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>

* src/rahunasd.{h,c}, src/rh-xmlrpc-server.c:
  - Prevent the segfault due to the log printing username and session_id
    pointing to NULL.
  - Implement the ipset Flush set command.
* src/rh-ipset.{h,c}: Add code to support ipset Flush set command.
* + rahunas.in: Add init script example.

ChangeLog
rahunas.in [new file with mode: 0755]
src/rahunasd.c
src/rahunasd.h
src/rh-ipset.c
src/rh-ipset.h
src/rh-xmlrpc-server.c

index d4d7cb7..f612168 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>
 
+       * src/rahunasd.{h,c}, src/rh-xmlrpc-server.c:
+         - Prevent the segfault due to the log printing username and session_id 
+           pointing to NULL.
+         - Implement the ipset Flush set command.
+       * src/rh-ipset.{h,c}: Add code to support ipset Flush set command.
+       * + rahunas.in: Add init script example.
+
+2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>
+
        * src/rahunasd.c: Remove the including to ipset-control.h which not exist now.
 
 2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>
diff --git a/rahunas.in b/rahunas.in
new file mode 100755 (executable)
index 0000000..c1b3bd5
--- /dev/null
@@ -0,0 +1,68 @@
+#! /bin/sh
+
+### BEGIN INIT INFO
+# Provides:          rahunas
+# Required-Start:    $syslog
+# Required-Stop:     $syslog
+# Should-Start:      $local_fs $network
+# Should-Stop:       $local_fs $network
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Handles the rahunas daemon
+# Description:       Starts, stops the rahunas daemon. 
+### END INIT INFO
+
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/local/bin/rahunasd
+NAME=rahunasd
+DESC="rahunasd: Network Access Server"
+
+RUN_DAEMON=yes
+
+# This value is overriden in /etc/default/frox if it exists
+#RUN_DAEMON=no
+#
+#test -f $DAEMON || exit 0
+#
+#set -e
+#
+## Get configuration
+#if [ -r /etc/default/frox ]; then
+#        . /etc/default/frox
+#fi
+
+case "$1" in
+  start)
+       echo -n "Starting $DESC: "
+       if [ "$RUN_DAEMON" = "yes" ]; then
+               start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
+               --exec $DAEMON
+               echo done
+       else
+               echo disabled 
+       fi
+       ;;
+  stop)
+       echo -n "Stopping $DESC: "
+       start-stop-daemon --stop --oknodo --quiet --pidfile /var/run/$NAME.pid \
+               --exec $DAEMON
+       echo done 
+       ;;
+  restart|force-reload)
+       echo -n "Restarting $DESC: "
+       start-stop-daemon --stop --oknodo --quiet --pidfile \
+               /var/run/$NAME.pid --exec $DAEMON
+       sleep 1
+       start-stop-daemon --start --quiet --pidfile \
+               /var/run/$NAME.pid --exec $DAEMON
+       echo "$NAME."
+       ;;
+  *)
+       N=/etc/init.d/$NAME
+       echo "Usage: $N {start|stop|restart|force-reload}" >&2
+       exit 1
+       ;;
+esac
+
+exit 0
index d1c15e2..8838d92 100644 (file)
@@ -43,6 +43,9 @@ struct set *rahunas_set = NULL;
 struct set **set_list = NULL;
 ip_set_id_t max_sets = 0;
 
+const char *dummy = '\0';
+pid_t pid, sid;
+
 uint32_t iptoid(struct rahunas_map *map, const char *ip) {
   uint32_t ret;
   struct in_addr req_ip;
@@ -102,18 +105,20 @@ void rh_free(void **data)
 
 void rh_free_member (struct rahunas_member *member)
 {
-  if (member->username)
+  if (member->username && member->username != dummy)
     free(member->username);
 
-  if (member->session_id)
+  if (member->session_id && member->session_id != dummy)
     free(member->session_id);
   
   memset(member, 0, sizeof(struct rahunas_member));
+  member->username = dummy;
+  member->session_id = dummy;
 }
 
 int rh_openlog(const char *filename)
 {
-  return open(filename, O_WRONLY | O_APPEND);
+  return open(filename, O_WRONLY | O_APPEND | O_CREAT);
 }
 
 int rh_closelog(int fd)
@@ -170,17 +175,24 @@ int logmsg(int priority, const char *msg, ...)
        rh_free(&np);
 }
 
-void rh_shutdown(int sig)
+void rh_sighandler(int sig)
 {
-  ipset_flush();
-  finish();
-  rh_closelog(DEFAULT_LOG);
+  switch (sig) {
+    case SIGINT:
+    case SIGTERM:
+    case SIGKILL:
+      ipset_flush();
+      finish();
+      rh_closelog(DEFAULT_LOG);
+      exit(EXIT_SUCCESS);
+      break;
+  }
 }
 
 int ipset_flush()
 {
   logmsg(RH_LOG_NORMAL, "Flushing IPSET...");
-  /* TODO: Flush the ipset */
+  set_flush(SET_NAME);
 }
 
 int finish()
@@ -190,6 +202,9 @@ int finish()
        int i;
   int end;
 
+  if (pid != 0) // Do not permit child to call this
+    kill(pid, SIGKILL);
+
   if (map) {
     if (map->members) {
       members = map->members;
@@ -199,8 +214,7 @@ int finish()
     }  
 
          for (i=0; i < end; i++) {
-                         rh_free(&(members[i].username));
-                         rh_free(&(members[i].session_id));
+                         rh_free_member(&members[i]);
                }
 
                rh_free(&(map->members));
@@ -437,6 +451,20 @@ size_t expired_check(void *data)
 
         if (res == 0) {
                            send_xmlrpc_stopacct(map, i);
+
+          if (!members[i].username)
+            members[i].username = dummy;
+
+          if (!members[i].session_id)
+            members[i].session_id = dummy;
+
+          logmsg(RH_LOG_NORMAL, "Session Idle-Timeout, User: %s, IP: %s, "
+                                "Session ID: %s, MAC: %s",
+                                members[i].username, 
+                                idtoip(map, i), 
+                                members[i].session_id,
+                                mac_tostring(members[i].mac_address)); 
+
           rh_free_member(&members[i]);
         }
       } 
@@ -534,15 +562,11 @@ watch_child(char *argv[])
        int status;
 
        int nullfd;
-
-  pid_t pid, sid;
+  int pidfd;
 
        if (*(argv[0]) == '(')
          return;
 
-  signal(SIGINT, rh_shutdown);
-  signal(SIGTERM, rh_shutdown);
-  signal(SIGKILL, rh_shutdown);
 
   pid = fork();        
        if (pid < 0) {
@@ -550,14 +574,18 @@ watch_child(char *argv[])
                exit(EXIT_FAILURE);
        } else if (pid > 0) {
          /* parent */
+    pidfd = open(DEFAULT_PID, O_WRONLY | O_TRUNC | O_CREAT);
+    if (pidfd) {
+      dup2(pidfd, STDOUT_FILENO);
+      fprintf(stdout, "%d\n", pid);
+      close(pidfd);
+    }
          exit(EXIT_SUCCESS);
        }
 
   /* Change the file mode mask */
   umask(0);
 
-
-
        if ((sid = setsid()) < 0)
          syslog(LOG_ALERT, "setsid failed");
 
@@ -570,6 +598,12 @@ watch_child(char *argv[])
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
 
+  signal(SIGCHLD, SIG_IGN);
+  signal(SIGHUP, rh_sighandler);
+  signal(SIGINT, rh_sighandler);
+  signal(SIGTERM, rh_sighandler);
+  signal(SIGKILL, rh_sighandler);
+
   while(1) {
 
          if ((pid = fork()) == 0) {
@@ -617,7 +651,7 @@ watch_child(char *argv[])
        if (WIFSIGNALED(status)) {
       switch (WTERMSIG(status)) {
                  case SIGKILL:
-                         exit(0);
+          rh_sighandler(SIGKILL);
                                break;
                        
                        case SIGINT:
@@ -646,14 +680,8 @@ int main(int argc, char **argv)
 
        GNetXmlRpcServer *server = NULL;
        GMainLoop* main_loop     = NULL;
-
-
-       watch_child(argv);
   
-  gnet_init();
-  main_loop = g_main_loop_new (NULL, FALSE);
-
-  sprintf(version, "Starting %s - Version %s", PROGRAM, VERSION);
+       watch_child(argv);
 
   /* Open log file */
        if ((fd_log = rh_openlog(DEFAULT_LOG)) == (-1)) {
@@ -663,6 +691,12 @@ int main(int argc, char **argv)
 
   dup2(fd_log, STDERR_FILENO);
 
+  gnet_init();
+  main_loop = g_main_loop_new (NULL, FALSE);
+
+  sprintf(version, "Starting %s - Version %s", PROGRAM, VERSION);
+
+  
        logmsg(RH_LOG_NORMAL, version);
   syslog(LOG_INFO, version);
 
index f5196ad..708d32b 100644 (file)
 
 /* Configuration */
 #define DEFAULT_LOG "/var/log/rahunas/rahunas.log"
+#define DEFAULT_PID "/var/run/rahunasd.pid"
 #define IDLE_THRESHOLD 600
-#define POLLING 120 
+#define POLLING 30 
 #define SET_NAME "rahunas_set"
 #define XMLSERVICE_HOST        "localhost"
 #define XMLSERVICE_PORT        8888
 #define XMLSERVICE_URL "/xmlrpc_service.php"
 
+enum RH_LOG {
+  RH_LOG_DEBUG,
+       RH_LOG_NORMAL,
+       RH_LOG_ERROR
+};
+
+#define RH_LOG_LEVEL RH_LOG_NORMAL
+
+#ifdef RH_DEBUG
+#define DP(format, args...) \
+  do {  \
+    fprintf(stderr, "%s - %s: %s (DBG): ", timemsg(), __FILE__, __FUNCTION__); \
+    fprintf(stderr, format "\n", ## args); \
+  } while (0)
+#else
+#define DP(format, args...)
+#endif
 
 struct rahunas_map {
   struct rahunas_member *members;
@@ -62,22 +80,4 @@ static char *timemsg()
   return tmsg; 
 }
 
-enum RH_LOG {
-  RH_LOG_DEBUG,
-       RH_LOG_NORMAL,
-       RH_LOG_ERROR
-};
-
-#define RH_LOG_LEVEL RH_LOG_NORMAL
-
-#ifdef RH_DEBUG
-#define DP(format, args...) \
-  do {  \
-    fprintf(stderr, "%s - %s: %s (DBG): ", timemsg(), __FILE__, __FUNCTION__); \
-    fprintf(stderr, format "\n", ## args); \
-  } while (0)
-#else
-#define DP(format, args...)
-#endif
-
 #endif // __RAHUNASD_H
index e698cdb..9832b81 100644 (file)
@@ -172,7 +172,7 @@ int set_adtip(struct set *rahunas_set, const char *adtip, const char *adtmac,
               unsigned op)
 {
   ip_set_ip_t ip;
-  unsigned char mac[ETH_ALEN];
+  unsigned char mac[ETH_ALEN] = {0,0,0,0,0,0};
   parse_ip(adtip, &ip);  
   parse_mac(adtmac, &mac);
 
@@ -236,6 +236,18 @@ int set_adtip_nb(struct set *rahunas_set, ip_set_ip_t *adtip,
   return res;
 }
 
+
+void set_flush(const char *name)
+{
+  struct ip_set_req_std req;
+
+  req.op = IP_SET_OP_FLUSH;
+  req.version = IP_SET_PROTOCOL_VERSION;
+  strcpy(req.name, name);
+
+  kernel_sendto(&req, sizeof(struct ip_set_req_std));
+}
+
 size_t load_set_list(const char name[IP_SET_MAXNAMELEN],
                            ip_set_id_t *idx,
                            unsigned op, unsigned cmd)
index 09525ed..327e4f9 100644 (file)
@@ -74,6 +74,8 @@ int set_adtip(struct set *rahunas_set, const char *adtip, const char *adtmac,
 int set_adtip_nb(struct set *rahunas_set, ip_set_ip_t *adtip, 
                      unsigned char adtmac[ETH_ALEN], unsigned op);
 
+void set_flush(const char *name);
+
 size_t load_set_list(const char name[IP_SET_MAXNAMELEN],
                            ip_set_id_t *idx,
                            unsigned op, unsigned cmd);
index 68ecb63..92b082b 100644 (file)
@@ -10,8 +10,8 @@
 #include "rh-xmlrpc-server.h"
 #include "rh-ipset.h"
 
-
 extern struct set *rahunas_set;
+extern const char* dummy;
 
 int do_startsession(GNetXmlRpcServer *server,
                     const gchar *command,
@@ -21,7 +21,7 @@ int do_startsession(GNetXmlRpcServer *server,
 {
   struct rahunas_map *map = (struct rahunas_map *)user_data;
        struct rahunas_member *members = NULL;
-  unsigned char ethernet[ETH_ALEN];
+  unsigned char ethernet[ETH_ALEN] = {0,0,0,0,0,0};
        gchar *ip = NULL;
        gchar *username = NULL;
        gchar *session_id = NULL;
@@ -76,18 +76,22 @@ int do_startsession(GNetXmlRpcServer *server,
                return 0;
        }
 
-
   res = set_adtip(rahunas_set, ip, mac_address, IP_SET_OP_ADD_IP);
   if (res == 0) {
     members[id].flags = 1;
-    if (!members[id].username)
+    if (members[id].username && members[id].username != dummy)
       free(members[id].username);
 
-    if (!members[id].session_id)
+    if (members[id].session_id && members[id].username != dummy)
       free(members[id].session_id);
 
     members[id].username   = strdup(username);
+    if (!members[id].username)
+      members[id].username = dummy;
+
     members[id].session_id = strdup(session_id);
+    if (!members[id].session_id)
+      members[id].session_id = dummy;
 
                time(&(members[id].session_start));
 
@@ -131,7 +135,7 @@ int do_stopsession(GNetXmlRpcServer *server,
        gchar *pEnd = NULL;
        uint32_t   id;
   int res = 0;
-  unsigned char ethernet[ETH_ALEN];
+  unsigned char ethernet[ETH_ALEN] = {0,0,0,0,0,0};
 
        if (!map)
          goto out;
@@ -174,6 +178,12 @@ int do_stopsession(GNetXmlRpcServer *server,
       res = set_adtip(rahunas_set, idtoip(map, id), mac_address,
                       IP_SET_OP_DEL_IP);
       if (res == 0) {
+        if (!members[id].username)
+          members[id].username = dummy;
+
+        if (!members[id].session_id)
+          members[id].session_id = dummy;
+
         logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
                               "Session ID: %s, MAC: %s",
                               members[id].username,