Mercurial > noffle
comparison 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 |
comparison
equal
deleted
inserted
replaced
249:0340b9c17edc | 250:93d5d8b098da |
---|---|
5 the groups we know of. One database record is cached in the global struct | 5 the groups we know of. One database record is cached in the global struct |
6 grp. Group information is transfered between the grp and the database by | 6 grp. Group information is transfered between the grp and the database by |
7 loadGrp() and saveGrp(). This is done transparently. Access to the groups | 7 loadGrp() and saveGrp(). This is done transparently. Access to the groups |
8 database is done by group name, by the functions defined in group.h. | 8 database is done by group name, by the functions defined in group.h. |
9 | 9 |
10 $Id: group.c 381 2002-05-14 14:25:45Z mirkol $ | 10 $Id: group.c 382 2002-06-05 22:03:44Z mirkol $ |
11 */ | 11 */ |
12 | 12 |
13 #if HAVE_CONFIG_H | 13 #if HAVE_CONFIG_H |
14 #include <config.h> | 14 #include <config.h> |
15 #endif | 15 #endif |
18 #include <gdbm.h> | 18 #include <gdbm.h> |
19 #include <errno.h> | 19 #include <errno.h> |
20 #include <fcntl.h> | 20 #include <fcntl.h> |
21 #include <sys/stat.h> | 21 #include <sys/stat.h> |
22 #include "configfile.h" | 22 #include "configfile.h" |
23 #include "wildmat.h" | |
23 #include "group.h" | 24 #include "group.h" |
24 #include "log.h" | 25 #include "log.h" |
25 #include "util.h" | 26 #include "util.h" |
26 #include "portable.h" | 27 #include "portable.h" |
28 | |
29 /* max length of a group name: */ | |
30 #define MAX_GROUPNAME 78 | |
27 | 31 |
28 /* currently only used within grp */ | 32 /* currently only used within grp */ |
29 typedef struct | 33 typedef struct |
30 { | 34 { |
31 int first; /* number of first article within group */ | 35 int first; /* number of first article within group */ |
60 { | 64 { |
61 if ( errno != 0 ) | 65 if ( errno != 0 ) |
62 return strerror( errno ); | 66 return strerror( errno ); |
63 return gdbm_strerror( gdbm_errno ); | 67 return gdbm_strerror( gdbm_errno ); |
64 } | 68 } |
69 | |
70 /* forbidden hierarchies */ | |
71 struct ForbiddenGroupName | |
72 { | |
73 const char *pattern; | |
74 Bool match; | |
75 } forbiddenGroupNames[] = | |
76 { | |
77 /* { "*[^-+_.0-9a-zA-Z]*", TRUE}, */ /* allow only traditional group names */ | |
78 { "*.*", FALSE }, /* Single component */ | |
79 { "control.*", TRUE }, /* control.* groups */ | |
80 { "to.*", TRUE }, /* to.* groups */ | |
81 { "*.all", TRUE }, /* 'all' as a component */ | |
82 { "*.all.*", TRUE }, | |
83 { "all.*", TRUE }, | |
84 { "*.ctl", TRUE }, /* 'ctl' as a component */ | |
85 { "*.ctl.*", TRUE }, | |
86 { "ctl.*", TRUE }, | |
87 { "example.*", TRUE }, /* example.* groups */ | |
88 { "*,*", TRUE }, /* newsgroups separator */ | |
89 /* { "_*", TRUE }, */ /* reserved for future use, but accept nevertheless */ | |
90 { "+*", TRUE }, /* reserved */ | |
91 { "-*", TRUE } | |
92 }; | |
65 | 93 |
66 Bool | 94 Bool |
67 Grp_open( void ) | 95 Grp_open( void ) |
68 { | 96 { |
69 Str name; | 97 Str name; |
410 free( oldDptr ); | 438 free( oldDptr ); |
411 *name = cursor.dptr; | 439 *name = cursor.dptr; |
412 return ( cursor.dptr != NULL ); | 440 return ( cursor.dptr != NULL ); |
413 } | 441 } |
414 | 442 |
415 Bool | 443 /* Group names' sanity checks. Groups with forbidden names |
416 Grp_isValidGroupName( const char *name) | 444 can't be safely deleted or created. */ |
417 { | 445 Bool |
418 const char *pname, *ppat; | 446 Grp_isForbiddenName( const char *name) |
419 const char *illegalchars = "\t\n\r,/:\\"; /* Are there any other dangerous characters? */ | 447 { |
420 | 448 const char *illegalchars = "\t\n\v\r /:\\"; |
421 /* Find directory prefixes to prevent exploits. */ | 449 /* "\t\n\v\r " whitespace |
422 switch ( name[0] ) | 450 "/:\\" directory prefix (Unix, MacOS, Freedos filesystems) */ |
423 { | |
424 case '.': /* prevent noffle -C ../fetchlist */ | |
425 case '+': | |
426 case '-': /* reserved for internal use of implementations | |
427 * rf. draft-ietf-usefor-article-06.txt, ch 5.5.1 */ | |
428 return FALSE; /* group name invalid */ | |
429 break; | |
430 default: | |
431 break; | |
432 } | |
433 | |
434 /* Find illegal characters. */ | 451 /* Find illegal characters. */ |
435 if ( strpbrk( name, illegalchars ) ) | 452 if ( strpbrk( name, illegalchars ) ) |
453 return TRUE; | |
454 /* Find '.' dot directory prefix to prevent exploits. */ | |
455 if ( name[0] == '.') /* prevent noffle -C ../fetchlist */ | |
456 return TRUE; /* group name invalid */ | |
457 return FALSE; | |
458 } | |
459 | |
460 /* | |
461 Forbidden or restricted group names or hierarchies. Please refer to | |
462 draft-ietf-usefor-article-06, chapter 5.5.1. Groups with invalid | |
463 names can't be created, but can still be deleted. | |
464 */ | |
465 Bool | |
466 Grp_isValidName( const char *name) | |
467 { | |
468 size_t i; | |
469 | |
470 for ( i = 0; | |
471 i < sizeof( forbiddenGroupNames ) / | |
472 sizeof( struct ForbiddenGroupName ); | |
473 ++i ) | |
474 { | |
475 /* Negate result of Wld_match to ensure it is 1 or 0. */ | |
476 if ( forbiddenGroupNames[i].match != | |
477 ( ! Wld_match( name, forbiddenGroupNames[i].pattern ) ) ) | |
478 return FALSE; | |
479 } | |
480 /* Groups with lengthy names like | |
481 alt.the.lame.troll.should.be.posting.again.in.just.a.few.more.weeks.from.what.he.said | |
482 or | |
483 microsoft.public.windows.inetexplorer.ie55.programming.components.codedownload | |
484 are most likely bogus groups that have been mistakenly created. | |
485 */ | |
486 if ( strlen( name ) > MAX_GROUPNAME ) | |
436 return FALSE; | 487 return FALSE; |
437 | 488 /* no match? then assume the group is valid. */ |
438 /* Find "all", "all.*", "*.all" or "*.all.*" */ | |
439 pname = name; | |
440 while ( ( ppat = strstr( pname, "all" ) ) != NULL ) | |
441 { | |
442 if ( ( ppat == name || *(ppat - 1) == '.' ) | |
443 && ( *(ppat+4) == '\0' || *(ppat+4) == '.' ) ) | |
444 return FALSE; | |
445 else | |
446 pname += 3; | |
447 } | |
448 | |
449 /* Find "ctl", "ctl.*", "*.ctl" or "*.ctl.*" */ | |
450 pname = name; | |
451 while ( ( ppat = strstr( pname, "ctl" ) ) != NULL ) | |
452 { | |
453 if ( ( ppat == name || *(ppat - 1) == '.' ) | |
454 && ( *(ppat+4) == '\0' || *(ppat+4) == '.' ) ) | |
455 return FALSE; | |
456 else | |
457 pname += 3; | |
458 } | |
459 /* Find some special groups and hierarchies. */ | |
460 if ( !( strcmp( name, "poster" ) && strcmp( name, "junk" ) | |
461 && strcmp( name, "control" ) && strcmp( name, "to" ) | |
462 && strncmp( name, "control.", 8 ) && strncmp( name, "to.", 3 ) | |
463 && strncmp( name, "example.", 8 ) ) ) | |
464 return FALSE; | |
465 | |
466 | |
467 /* Group name is hopefully valid. */ | |
468 return TRUE; | 489 return TRUE; |
469 } | 490 } |