Ethereal-dev: [Ethereal-dev] global version of "disabled_protos"

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

Date Prev · Date Next · Thread Prev · Thread Next
From: Tadaaki Nagao <nagao@xxxxxxxxx>
Date: Thu, 01 Jan 2004 17:17:01 +0900 (JST)
Hello,

I made a patch to add a global version of "disabled_protos", which
might be particularly useful in such situations as:

  - If a new vulnerability is found in a dissector, you can simply
    disable it with the global (system-wide) "disabled_protos" file,
    thus implementing a workaround for all users on your system.

  - When the user id running tethereal doesn't have its home directory
    (user "www", "nobody" or whatever), the only way to disable some
    dissectors is to have a global "disabled_protos" file.

Included in this email is the patch against CVS HEAD as of 7am, Jan 1
2004 GMT.

Though there are some design choices in implementing this, I chose the
following in this patch:

  - The global "disabled_protos" file is placed in the same directory
    as "ethereal.conf".  On my FreeBSD box, it is
    /usr/X11R6/share/ethereal/disabled_protos.

  - Globally disabled protocols cannot be re-enabled with user's
    settings (~/.ethereal/disabled_protos), and they don't appear in
    the "Enabled Protocols" dialog just like the dissectors you can't
    disable.

Enjoy!

Thanks,
Tadaaki Nagao <nagao@xxxxxxxxx>
System Design and Development Division, Internet Initiative Japan Inc.
Index: disabled_protos.c
===================================================================
RCS file: /cvsroot/ethereal/disabled_protos.c,v
retrieving revision 1.3
diff -u -r1.3 disabled_protos.c
--- disabled_protos.c	16 Nov 2003 23:17:15 -0000	1.3
+++ disabled_protos.c	1 Jan 2004 08:11:13 -0000
@@ -42,11 +42,13 @@
 
 #include "disabled_protos.h"
 
-#define PROTOCOLS_FILE_NAME	"disabled_protos"
+#define GLOBAL_PROTOCOLS_FILE_NAME	"disabled_protos"
+#define PROTOCOLS_FILE_NAME		"disabled_protos"
 
 /*
  * List of disabled protocols
  */
+static GList *global_disabled_protos = NULL;
 static GList *disabled_protos = NULL;
 
 #define INIT_BUF_SIZE	128
@@ -61,60 +63,88 @@
  * or "*read_errno_return" is set to the error if a read failed.
  */
 
+static int read_disabled_protos_list_file(const char *ff_path, FILE *ff,
+					  GList **flp);
+
 void
-read_disabled_protos_list(char **pref_path_return, int *open_errno_return,
+read_disabled_protos_list(char **gpath_return, int *gopen_errno_return,
+			  int *gread_errno_return,
+			  char **path_return, int *open_errno_return,
                           int *read_errno_return)
 {
-  char       *ff_path, *ff_name;
+  int         err;
+  char       *gff_path, *ff_path;
   FILE       *ff;
-  GList      **flp;
-  GList      *fl_ent;
-  protocol_def *prot;
-  int         c;
-  char       *prot_name;
-  int         prot_name_len;
-  int         prot_name_index;
-  int         line = 1;
 
-  *pref_path_return = NULL;	/* assume no error */
+  /* Construct the pathname of the global disabled protocols file. */
+  gff_path = get_datafile_path(GLOBAL_PROTOCOLS_FILE_NAME);
 
-  ff_name = PROTOCOLS_FILE_NAME;
-  flp = &disabled_protos;
+  /* Read the global disabled protocols file, if it exists. */
+  *gpath_return = NULL;
+  if ((ff = fopen(gff_path, "r")) != NULL) {
+    /* We succeeded in opening it; read it. */
+    err = read_disabled_protos_list_file(gff_path, ff,
+					 &global_disabled_protos);
+    if (err != 0) {
+      /* We had an error reading the file; return the errno and the
+         pathname, so our caller can report the error. */
+      *gopen_errno_return = 0;
+      *gread_errno_return = err;
+      *gpath_return = gff_path;
+    } else
+      g_free(gff_path);
+    fclose(ff);
+  } else {
+    /* We failed to open it.  If we failed for some reason other than
+       "it doesn't exist", return the errno and the pathname, so our
+       caller can report the error. */
+    if (errno != ENOENT) {
+      *gopen_errno_return = errno;
+      *gread_errno_return = 0;
+      *gpath_return = gff_path;
+    }
+  }
+
+  /* Construct the pathname of the user's disabled protocols file. */
+  ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, FALSE);
 
-  /* To do: generalize this */
-  ff_path = get_persconffile_path(ff_name, FALSE);
-  if ((ff = fopen(ff_path, "r")) == NULL) {
-    /*
-     * Did that fail because we the file didn't exist?
-     */
+  /* Read the global disabled protocols file, if it exists. */
+  *path_return = NULL;
+  if ((ff = fopen(ff_path, "r")) != NULL) {
+    /* We succeeded in opening it; read it. */
+    err = read_disabled_protos_list_file(ff_path, ff, &disabled_protos);
+    if (err != 0) {
+      /* We had an error reading the file; return the errno and the
+         pathname, so our caller can report the error. */
+      *open_errno_return = 0;
+      *read_errno_return = err;
+      *path_return = ff_path;
+    } else
+      g_free(ff_path);
+    fclose(ff);
+  } else {
+    /* We failed to open it.  If we failed for some reason other than
+       "it doesn't exist", return the errno and the pathname, so our
+       caller can report the error. */
     if (errno != ENOENT) {
-      /*
-       * No.  Just give up.
-       */
-      *pref_path_return = ff_path;
       *open_errno_return = errno;
       *read_errno_return = 0;
-      return;
-    }
-
-    /*
-     * Yes.  See if there's a "protocols" file; if so, read it.
-     */
-    g_free(ff_path);
-    ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, FALSE);
-    if ((ff = fopen(ff_path, "r")) == NULL) {
-      /*
-       * Well, that didn't work, either.  Just give up.
-       * Return an error if the file existed but we couldn't open it.
-       */
-      if (errno != ENOENT) {
-	*pref_path_return = ff_path;
-	*open_errno_return = errno;
-	*read_errno_return = 0;
-      }
-      return;
+      *path_return = ff_path;
     }
   }
+}
+
+static int
+read_disabled_protos_list_file(const char *ff_path, FILE *ff,
+			       GList **flp)
+{
+  GList      *fl_ent;
+  protocol_def *prot;
+  int         c;
+  char       *prot_name;
+  int         prot_name_len;
+  int         prot_name_index;
+  int         line = 1;
 
   /* If we already have a list of protocols, discard it. */
   if (*flp != NULL) {
@@ -214,16 +244,11 @@
     prot->name   = g_strdup(prot_name);
     *flp = g_list_append(*flp, prot);
   }
-  g_free(ff_path);
-  fclose(ff);
   g_free(prot_name);
-  return;
+  return 0;
 
 error:
-  *pref_path_return = ff_path;
-  *open_errno_return = 0;
-  *read_errno_return = errno;
-  fclose(ff);
+  return errno;
 }
 
 /*
@@ -240,7 +265,7 @@
    * assume all protocols are enabled by default
    */
   if (disabled_protos == NULL)
-    return;	/* nothing to disable */
+    goto skip;
 
   fl_ent = g_list_first(disabled_protos);
 
@@ -248,10 +273,31 @@
     prot = (protocol_def *) fl_ent->data;
     i = proto_get_id_by_filter_name(prot->name);
     if (i == -1) {
-    	/* XXX - complain here? */
+      /* XXX - complain here? */
     } else {
-      if (proto_can_disable_protocol(i))
-        proto_set_decoding(i, FALSE);
+      if (proto_can_toggle_protocol(i))
+	proto_set_decoding(i, FALSE);
+    }
+
+    fl_ent = fl_ent->next;
+  }
+
+skip:
+  if (global_disabled_protos == NULL)
+    return;
+
+  fl_ent = g_list_first(global_disabled_protos);
+
+  while (fl_ent != NULL) {
+    prot = (protocol_def *) fl_ent->data;
+    i = proto_get_id_by_filter_name(prot->name);
+    if (i == -1) {
+      /* XXX - complain here? */
+    } else {
+      if (proto_can_toggle_protocol(i)) {
+	proto_set_decoding(i, FALSE);
+	proto_set_cant_toggle(i);
+      }
     }
 
     fl_ent = fl_ent->next;
@@ -299,7 +345,7 @@
   for (i = proto_get_first_protocol(&cookie); i != -1;
        i = proto_get_next_protocol(&cookie)) {
 
-    if (!proto_can_disable_protocol(i)) {
+    if (!proto_can_toggle_protocol(i)) {
       continue;
     }
 
Index: disabled_protos.h
===================================================================
RCS file: /cvsroot/ethereal/disabled_protos.h,v
retrieving revision 1.1
diff -u -r1.1 disabled_protos.h
--- disabled_protos.h	7 Aug 2003 00:41:26 -0000	1.1
+++ disabled_protos.h	1 Jan 2004 08:11:13 -0000
@@ -40,8 +40,10 @@
  * or "*read_errno_return" is set to the error if we got an error reading
  * the file.
  */
-void read_disabled_protos_list(char **pref_path_return, int *open_errno_return,
-                               int *read_errno_return);
+void read_disabled_protos_list(char **gpath_return, int *gopen_errno_return,
+			       int *gread_errno_return,
+			       char **path_return, int *open_errno_return,
+			       int *read_errno_return);
 
 /*
  * Disable protocols as per the stored configuration
Index: packet-data.c
===================================================================
RCS file: /cvsroot/ethereal/packet-data.c,v
retrieving revision 1.33
diff -u -r1.33 packet-data.c
--- packet-data.c	22 Apr 2003 13:47:37 -0000	1.33
+++ packet-data.c	1 Jan 2004 08:11:13 -0000
@@ -67,5 +67,5 @@
 	 * "Data" is used to dissect something whose normal dissector
 	 * is disabled, so it cannot itself be disabled.
 	 */
-	proto_set_cant_disable(proto_data);
+	proto_set_cant_toggle(proto_data);
 }
Index: packet-frame.c
===================================================================
RCS file: /cvsroot/ethereal/packet-frame.c,v
retrieving revision 1.42
diff -u -r1.42 packet-frame.c
--- packet-frame.c	6 Dec 2003 06:09:10 -0000	1.42
+++ packet-frame.c	1 Jan 2004 08:11:13 -0000
@@ -308,7 +308,7 @@
 
 	/* You can't disable dissection of "Frame", as that would be
 	   tantamount to not doing any dissection whatsoever. */
-	proto_set_cant_disable(proto_frame);
+	proto_set_cant_toggle(proto_frame);
 
 	proto_short = proto_register_protocol("Short Frame", "Short frame", "short");
 	proto_malformed = proto_register_protocol("Malformed Packet",
@@ -320,9 +320,9 @@
 	/* "Short Frame", "Malformed Packet", and "Unreassembled Fragmented
 	   Packet" aren't really protocols, they're error indications;
 	   disabling them makes no sense. */
-	proto_set_cant_disable(proto_short);
-	proto_set_cant_disable(proto_malformed);
-	proto_set_cant_disable(proto_unreassembled);
+	proto_set_cant_toggle(proto_short);
+	proto_set_cant_toggle(proto_malformed);
+	proto_set_cant_toggle(proto_unreassembled);
 
 	/* Our preferences */
 	frame_module = prefs_register_protocol(proto_frame, NULL);
Index: tethereal.c
===================================================================
RCS file: /cvsroot/ethereal/tethereal.c,v
retrieving revision 1.212
diff -u -r1.212 tethereal.c
--- tethereal.c	18 Dec 2003 02:46:45 -0000	1.212
+++ tethereal.c	1 Jan 2004 08:11:14 -0000
@@ -782,9 +782,10 @@
 #endif	/* _WIN32 */
 
   char                *gpf_path, *pf_path;
-  char                *dp_path;
+  char                *gdp_path, *dp_path;
   int                  gpf_open_errno, gpf_read_errno;
   int                  pf_open_errno, pf_read_errno;
+  int                  gdp_open_errno, gdp_read_errno;
   int                  dp_open_errno, dp_read_errno;
   int                  err;
 #ifdef HAVE_LIBPCAP
@@ -882,7 +883,21 @@
   g_resolv_flags = prefs->name_resolve;
 
   /* Read the disabled protocols file. */
-  read_disabled_protos_list(&dp_path, &dp_open_errno, &dp_read_errno);
+  read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+			    &dp_path, &dp_open_errno, &dp_read_errno);
+  if (gdp_path != NULL) {
+    if (gdp_open_errno != 0) {
+      fprintf(stderr,
+        "Could not open global disabled protocols file\n\"%s\": %s.\n",
+	gdp_path, strerror(gdp_open_errno));
+    }
+    if (gdp_read_errno != 0) {
+      fprintf(stderr,
+        "I/O error reading global disabled protocols file\n\"%s\": %s.\n",
+	gdp_path, strerror(gdp_read_errno));
+    }
+    g_free(gdp_path);
+  }
   if (dp_path != NULL) {
     if (dp_open_errno != 0) {
       fprintf(stderr,
@@ -1375,7 +1390,7 @@
   prefs_apply_all();
 
   /* disabled protocols as per configuration file */
-  if (dp_path == NULL) {
+  if (gdp_path == NULL && dp_path == NULL) {
     set_disabled_protos_list();
   }
 
Index: epan/proto.c
===================================================================
RCS file: /cvsroot/ethereal/epan/proto.c,v
retrieving revision 1.128
diff -u -r1.128 proto.c
--- epan/proto.c	24 Dec 2003 23:37:28 -0000	1.128
+++ epan/proto.c	1 Jan 2004 08:11:15 -0000
@@ -138,7 +138,7 @@
 	GList	*fields;	/* fields for this protocol */
 	GList	*last_field;	/* pointer to end of list of fields */
 	gboolean is_enabled;	/* TRUE if protocol is enabled */
-	gboolean can_disable;	/* TRUE if protocol can be disabled */
+	gboolean can_toggle;	/* TRUE if is_enabled can be changed */
 };
 
 /* List of all protocols */
@@ -2235,7 +2235,7 @@
 	protocol->filter_name = filter_name;
 	protocol->fields = NULL;
 	protocol->is_enabled = TRUE; /* protocol is enabled by default */
-	protocol->can_disable = TRUE;
+	protocol->can_toggle = TRUE;
 	protocols = g_list_insert_sorted(protocols, protocol,
 	    proto_compare_name);
 
@@ -2401,12 +2401,12 @@
 }
 
 gboolean
-proto_can_disable_protocol(int proto_id)
+proto_can_toggle_protocol(int proto_id)
 {
 	protocol_t *protocol;
 
 	protocol = find_protocol_by_id(proto_id);
-	return protocol->can_disable;
+	return protocol->can_toggle;
 }
 
 void
@@ -2415,17 +2415,17 @@
 	protocol_t *protocol;
 
 	protocol = find_protocol_by_id(proto_id);
-	g_assert(enabled || protocol->can_disable);
+	g_assert(protocol->can_toggle);
 	protocol->is_enabled = enabled;
 }
 
 void
-proto_set_cant_disable(int proto_id)
+proto_set_cant_toggle(int proto_id)
 {
 	protocol_t *protocol;
 
 	protocol = find_protocol_by_id(proto_id);
-	protocol->can_disable = FALSE;
+	protocol->can_toggle = FALSE;
 }
 
 /* for use with static arrays only, since we don't allocate our own copies
Index: epan/proto.h
===================================================================
RCS file: /cvsroot/ethereal/epan/proto.h,v
retrieving revision 1.54
diff -u -r1.54 proto.h
--- epan/proto.h	6 Dec 2003 06:09:13 -0000	1.54
+++ epan/proto.h	1 Jan 2004 08:11:15 -0000
@@ -558,7 +558,7 @@
 extern gboolean proto_is_protocol_enabled(protocol_t *protocol);
 
 /* Can item #n decoding be disabled? */
-extern gboolean proto_can_disable_protocol(int proto_id);
+extern gboolean proto_can_toggle_protocol(int proto_id);
 
 /* Routines to use to iterate over the protocols and their fields;
  * they return the item number of the protocol in question or the
@@ -589,8 +589,8 @@
 /* Enable / Disable protocol */
 extern void proto_set_decoding(int proto_id, gboolean enabled);
 
-/* Disable disabling of protocol */
-extern void proto_set_cant_disable(int proto_id);
+/* Disable disabling/enabling of protocol */
+extern void proto_set_cant_toggle(int proto_id);
 
 /* Get length of registered field according to field type.
  * 0 means undeterminable at registration time.
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.347
diff -u -r1.347 main.c
--- gtk/main.c	29 Dec 2003 20:05:59 -0000	1.347
+++ gtk/main.c	1 Jan 2004 08:11:16 -0000
@@ -1760,10 +1760,12 @@
   char                *rf_path;
   int                  rf_open_errno;
   char                *gpf_path, *pf_path;
-  char                *cf_path, *df_path, *dp_path;
+  char                *cf_path, *df_path;
+  char                *gdp_path, *dp_path;
   int                  gpf_open_errno, gpf_read_errno;
   int                  pf_open_errno, pf_read_errno;
   int                  cf_open_errno, df_open_errno;
+  int                  gdp_open_errno, gdp_read_errno;
   int                  dp_open_errno, dp_read_errno;
   int                  err;
 #ifdef HAVE_LIBPCAP
@@ -1968,7 +1970,8 @@
   read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
 
   /* Read the disabled protocols file. */
-  read_disabled_protos_list(&dp_path, &dp_open_errno, &dp_read_errno);
+  read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
+			    &dp_path, &dp_open_errno, &dp_read_errno);
 
   init_cap_file(&cfile);
 
@@ -2433,7 +2436,7 @@
   prefs_apply_all();
 
   /* disabled protocols as per configuration file */
-  if (dp_path == NULL) {
+  if (gdp_path == NULL && dp_path == NULL) {
     set_disabled_protos_list();
   }
 
@@ -2702,6 +2705,24 @@
       g_free(df_path);
   }
 
+  /* If the global disabled protocols file exists but we failed to open it,
+     or had an error reading it, pop up an alert box; we defer that until now,
+     so that the alert box is more likely to come up on top of the main
+     window. */
+  if (gdp_path != NULL) {
+    if (gdp_open_errno != 0) {
+      simple_dialog(ESD_TYPE_WARN, NULL,
+        "Could not open global disabled protocols file\n\"%s\": %s.",
+	gdp_path, strerror(gdp_open_errno));
+    }
+    if (gdp_read_errno != 0) {
+      simple_dialog(ESD_TYPE_WARN, NULL,
+        "I/O error reading global disabled protocols file\n\"%s\": %s.",
+	gdp_path, strerror(gdp_read_errno));
+    }
+    g_free(gdp_path);
+  }
+
   /* If the user's disabled protocols file exists but we failed to open it,
      or had an error reading it, pop up an alert box; we defer that until now,
      so that the alert box is more likely to come up on top of the main
Index: gtk/proto_dlg.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/proto_dlg.c,v
retrieving revision 1.27
diff -u -r1.27 proto_dlg.c
--- gtk/proto_dlg.c	16 Nov 2003 23:17:26 -0000	1.27
+++ gtk/proto_dlg.c	1 Jan 2004 08:11:16 -0000
@@ -567,7 +567,7 @@
 
   for (i = proto_get_first_protocol(&cookie); i != -1;
        i = proto_get_next_protocol(&cookie)) {
-      if (proto_can_disable_protocol(i)) {
+      if (proto_can_toggle_protocol(i)) {
         p = g_malloc(sizeof(protocol_data_t));
         protocol = find_protocol_by_id(i);
         p->name = proto_get_protocol_name(i);