diff src/group.c @ 250:93d5d8b098da noffle

[svn] *** empty log message ***
author mirkol
date Wed, 05 Jun 2002 23:03:44 +0100
parents 0340b9c17edc
children 94b7962a0fbe
line wrap: on
line diff
--- a/src/group.c	Tue May 14 15:25:45 2002 +0100
+++ b/src/group.c	Wed Jun 05 23:03:44 2002 +0100
@@ -7,7 +7,7 @@
   loadGrp() and saveGrp(). This is done transparently. Access to the groups
   database is done by group name, by the functions defined in group.h.        
 
-  $Id: group.c 381 2002-05-14 14:25:45Z mirkol $
+  $Id: group.c 382 2002-06-05 22:03:44Z mirkol $
 */
 
 #if HAVE_CONFIG_H
@@ -20,11 +20,15 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include "configfile.h"
+#include "wildmat.h"
 #include "group.h"
 #include "log.h"
 #include "util.h"
 #include "portable.h"
 
+/* max length of a group name: */
+#define MAX_GROUPNAME 78
+
 /* currently only used within grp */
 typedef struct
 {
@@ -63,6 +67,30 @@
     return gdbm_strerror( gdbm_errno );
 }
 
+/* forbidden hierarchies */
+struct ForbiddenGroupName
+{
+    const char *pattern;
+    Bool match;
+} forbiddenGroupNames[] =
+{
+/*    { "*[^-+_.0-9a-zA-Z]*", TRUE}, */      /* allow only traditional group names */
+    { "*.*", FALSE },                   /* Single component */
+    { "control.*", TRUE },              /* control.* groups */
+    { "to.*", TRUE },                   /* to.* groups */
+    { "*.all", TRUE },                  /* 'all' as a component */
+    { "*.all.*", TRUE },
+    { "all.*", TRUE },
+    { "*.ctl", TRUE },                  /* 'ctl' as a component */
+    { "*.ctl.*", TRUE },
+    { "ctl.*", TRUE },
+    { "example.*", TRUE },              /* example.* groups */
+    { "*,*", TRUE },                    /* newsgroups separator */
+/*    { "_*", TRUE }, */                      /* reserved for future use, but accept nevertheless */
+    { "+*", TRUE },                     /* reserved */
+    { "-*", TRUE }
+};
+
 Bool
 Grp_open( void )
 {
@@ -412,58 +440,51 @@
     return ( cursor.dptr != NULL );
 }
 
+/* Group names' sanity checks. Groups with forbidden names
+   can't be safely deleted or created. */
 Bool
-Grp_isValidGroupName( const char *name)
+Grp_isForbiddenName( const char *name)
 {
-    const char *pname, *ppat;
-    const char *illegalchars = "\t\n\r,/:\\";  /* Are there any other dangerous characters? */
-
-    /* Find directory prefixes to prevent exploits. */
-    switch ( name[0] )
-    {
-        case '.':   /* prevent noffle -C ../fetchlist */
-        case '+':  
-        case '-':       /* reserved for internal use of implementations 
-                         * rf. draft-ietf-usefor-article-06.txt, ch 5.5.1 */
-            return FALSE; /* group name invalid */
-            break;
-        default:
-            break;
-    }
-
+    const char *illegalchars = "\t\n\v\r /:\\";
+/*  "\t\n\v\r " whitespace
+    "/:\\" directory prefix (Unix, MacOS, Freedos filesystems) */
     /* Find illegal characters. */
     if ( strpbrk( name, illegalchars ) )
-        return FALSE;
+        return TRUE;
+    /* Find '.' dot directory prefix to prevent exploits. */
+    if ( name[0] == '.')  /* prevent noffle -C ../fetchlist */
+        return TRUE; /* group name invalid */
+    return FALSE;
+}
 
-    /* Find "all", "all.*", "*.all" or "*.all.*"  */
-    pname = name;
-    while ( ( ppat = strstr( pname, "all" ) ) != NULL )
-    {
-        if ( ( ppat == name || *(ppat - 1) == '.'  )
-             && ( *(ppat+4) == '\0' || *(ppat+4) == '.' ) )
-            return FALSE;
-        else
-            pname += 3;
-    }
+/*
+   Forbidden or restricted group names or hierarchies. Please refer to
+   draft-ietf-usefor-article-06, chapter 5.5.1. Groups with invalid
+   names can't be created, but can still be deleted.
+ */
+Bool
+Grp_isValidName( const char *name)
+{
+    size_t i;
     
-   /* Find "ctl", "ctl.*", "*.ctl" or "*.ctl.*"  */
-    pname = name;
-    while ( ( ppat = strstr( pname, "ctl" ) ) != NULL )
+    for ( i = 0;
+          i < sizeof( forbiddenGroupNames ) /
+              sizeof( struct ForbiddenGroupName );
+          ++i )
     {
-        if ( ( ppat == name || *(ppat - 1) == '.'  )
-             && ( *(ppat+4) == '\0' || *(ppat+4) == '.' ) )
+        /* Negate result of Wld_match to ensure it is 1 or 0. */
+        if ( forbiddenGroupNames[i].match !=
+             ( ! Wld_match( name, forbiddenGroupNames[i].pattern ) ) )
             return FALSE;
-        else
-            pname += 3;
     }
-    /* Find some special groups and hierarchies. */
-    if ( !( strcmp( name, "poster" ) && strcmp( name, "junk" )
-       && strcmp( name, "control" ) && strcmp( name, "to" )
-       && strncmp( name, "control.", 8 ) && strncmp( name, "to.", 3 )
-       && strncmp( name, "example.", 8 ) ) )
-            return FALSE;
-
-
-    /* Group name is hopefully valid. */   
+    /* Groups with lengthy names like
+       alt.the.lame.troll.should.be.posting.again.in.just.a.few.more.weeks.from.what.he.said
+       or
+       microsoft.public.windows.inetexplorer.ie55.programming.components.codedownload
+       are most likely bogus groups that have been mistakenly created.
+    */
+    if ( strlen( name ) > MAX_GROUPNAME )
+        return FALSE;
+    /* no match? then assume the group is valid. */
     return TRUE;
 }