# HG changeset patch # User mirkol # Date 1008689228 0 # Node ID 1ad2602f57dbf7f3835945ad0e065dcb79d901a8 # Parent c48d7e881a2192fde95d1e7fef6e0b2f2a31a489 [svn] see Changelog Dec 18 2001 diff -r c48d7e881a21 -r 1ad2602f57db src/client.c --- a/src/client.c Tue Dec 18 15:24:49 2001 +0000 +++ b/src/client.c Tue Dec 18 15:27:08 2001 +0000 @@ -1,7 +1,7 @@ /* client.c - $Id: client.c 342 2001-12-09 12:31:57Z bears $ + $Id: client.c 358 2001-12-18 15:27:08Z mirkol $ */ #if HAVE_CONFIG_H @@ -457,6 +457,11 @@ Log_err( "Unknown reply to LIST or NEWGROUPS: %s", line ); continue; } + if ( ! Grp_isValidGroupName( grp ) ) + { + Log_inf( "Group name %s invalid", grp ); + continue; + } if ( isForbiddenGroupName( grp ) ) { Log_inf( "Group %s forbidden", grp ); diff -r c48d7e881a21 -r 1ad2602f57db src/group.c --- a/src/group.c Tue Dec 18 15:24:49 2001 +0000 +++ b/src/group.c Tue Dec 18 15:27:08 2001 +0000 @@ -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 316 2001-10-31 11:44:53Z bears $ + $Id: group.c 358 2001-12-18 15:27:08Z mirkol $ */ #if HAVE_CONFIG_H @@ -411,3 +411,38 @@ *name = cursor.dptr; return ( cursor.dptr != NULL ); } + +Bool +Grp_isValidGroupName( const char *name) +{ + const char *pname, *ppat; + const char *illegalchars = "\t\n\r,"; /* Are there any other illegal characters? */ + + /* Find directory prefixes to prevent exploits. */ + switch ( name[0] ) + { + case '.': /* prevent noffle -C ../fetchlist */ + case '/': /* prevent noffle -C /etc/noffle.conf */ + case ':': + case '\\': + return FALSE; /* group name invalid */ + } + + /* Find illegal characters. */ + if ( strpbrk( name, illegalchars ) ) + return FALSE; + + /* Find "all", "all.*", "*.all" or "*.all.*" */ + pname = name; + while ( ppat = strstr( pname, "all" ) ) + { + if ( ( ppat == name || *(ppat - 1) == '.' ) + && ( *(ppat+4) == '\0' || *(ppat+4) == '.' ) ) + return FALSE; + else + pname += 3; + } + + /* Group name is hopefully valid. */ + return TRUE; +} diff -r c48d7e881a21 -r 1ad2602f57db src/group.h --- a/src/group.h Tue Dec 18 15:24:49 2001 +0000 +++ b/src/group.h Tue Dec 18 15:27:08 2001 +0000 @@ -3,7 +3,7 @@ Groups database - $Id: group.h 310 2001-10-20 13:23:46Z bears $ + $Id: group.h 358 2001-12-18 15:27:08Z mirkol $ */ #ifndef GRP_H @@ -117,7 +117,7 @@ void Grp_setLastPostTime( const char *name ); -/* Begin iterating trough the names of all groups. Store name of first +/* Begin iterating through the names of all groups. Store name of first group (or NULL if there aren't any) in name. Returns whether there are any groups. */ Bool @@ -129,4 +129,10 @@ Bool Grp_nextGrp( const char **name ); +/* Check group name for validity. Returns false if the group name is + invalid. It should be called before Grp_create() or before deleting an + overview file. This function doesn't call Grp_exists(), though. */ +Bool +Grp_isValidGroupName( const char *name ); + #endif diff -r c48d7e881a21 -r 1ad2602f57db src/noffle.c --- a/src/noffle.c Tue Dec 18 15:24:49 2001 +0000 +++ b/src/noffle.c Tue Dec 18 15:27:08 2001 +0000 @@ -10,7 +10,7 @@ received for some seconds (to allow multiple clients connect at the same time). - $Id: noffle.c 342 2001-12-09 12:31:57Z bears $ + $Id: noffle.c 358 2001-12-18 15:27:08Z mirkol $ */ #if HAVE_CONFIG_H @@ -323,7 +323,12 @@ name = Utl_stripWhiteSpace( grp ); if ( Grp_exists( name ) ) + { fprintf( stderr, "'%s' already exists.\n", name ); + return; + } + if ( ! Grp_isValidGroupName( name ) ) + fprintf( stderr, "'%s' invalid group name.\n", name ); else { Log_inf( "Creating new local group '%s'", name ); @@ -346,7 +351,17 @@ name = Utl_stripWhiteSpace( grp ); if ( ! Grp_exists( name ) ) + { fprintf( stderr, "'%s' does not exist.\n", name ); + return; + } + if ( ! Grp_isValidGroupName( name ) ) + { + fprintf( stderr, "'%s' invalid group name. Skipping deletion of overviews.\n", name ); + Log_inf( "Deleting invalid group '%s' without deleting overviews.", name ); + Grp_delete( name ); + printf( "Group '%s' deleted.\n", name ); + } else { int i;