[leafnode-list] Re: LIST filtering
Matthew Parry
mettw at mettw.homelinux.net
Thu Jul 27 00:57:37 CEST 2006
I've merged the two patches and adjusted the formatting to match
your indentation in the patch below.
I'll review your group access control and list filtering patches as time
permits. Are you licensing your code under GNU GPL v2 or a compatible
license? Or would you prefer to transfer copyright to me?
Whatever is easiest for you.
We may need to talk about the user interface rationale, because
something like "user-dependent newsgroups" (based on some
"authentication" not specified in detail yet, might be IP- or
user/password based or perhaps, much later, a client-side TLS
certificate) is already on the TODO list and would combine nicely with
this approach, but if I find the code acceptable, chances are I'll take
your suggestion (perhaps without #ifdef) now and refine the interface
later - after all, that's what alpha versions and snapshots are for.
With the group access control I used an env var as you say in the docs
that you didn't want to add server level access control, so this seemed
to be the only way to implement it. user/password based control would
have to be added separately to this I suppose.
With the LIST filtering, this doesn't really have any use other than as
a convenience since it doesn't actually stop anyone accessing the groups.
It's useful for me to get rid of all the foreign groups and I suppose
it could be used with group access control to make it clearer to users
which groups are accessible.
--
Matthew Parry
-
"There now, didn't I tell you to keep a good count? Well,
there's an end of the story. God knows there's no going on
with it now." - Sancho Panza.
--- leafnode-2.0.0.alpha20060711a/nntpd.c 2006-06-09 08:51:09.000000000 +1000
+++ nntpd.c 2006-07-27 08:55:07.557000760 +1000
@@ -82,6 +82,49 @@
static int authflag = 0; /* TRUE if authenticated */
static char *peeraddr = NULL; /* peer address, for X-NNTP-Posting header */
+/*
+ * Determine if the env var ACCESSIBLE_GROUPS is set and if so then
+ * whether the group passed as an argument is in it.
+ *
+ * ACCESSIBLE_GROUPS is a space seperated list of newsgroups to
+ * allow access to. Can use wildmat patterns.
+ *
+ * On GROUP, NEWNEWS, ARTICLE and POST, if ACCESSIBLE_GROUPS is set and
+ * non-empty and the group is not listed in ACCESSIBLE_GROUPS then the
+ * server sends a "484 Access to the newsgroup xxx is restricted" error.
+ *
+ * BUGS:
+ *
+ * No checks done on the format of ACCESSIBLE_GROUPS.
+ *
+ * Matthew Parry <mettw at yahoo.com.au>
+ */
+
+static int
+allow_access_to_group(char *name)
+{
+ static struct stringlisthead *allowed_groups = NULL;
+ static int allow_all_groups = FALSE;
+
+ if(allow_all_groups)
+ return TRUE;
+ else if(!allowed_groups){
+ char *leafnode_groups = getenv("ACCESSIBLE_GROUPS");
+
+ if(!leafnode_groups || strlen(leafnode_groups) == 0){
+ allow_all_groups = TRUE;
+ return TRUE;
+ } else
+ allowed_groups = cmdlinetolist(leafnode_groups);
+
+ }
+
+ if(matchlist(allowed_groups->head, name) == NULL)
+ return FALSE;
+ else
+ return TRUE;
+}
+
/*
* this function avoids the continuous calls to both ln_log and printf
* it also appends \r\n automagically
@@ -564,6 +607,11 @@
assert(what >= 0 && what <= 3);
+ if(!allow_access_to_group(group->name)){
+ nntpprintf("484 Access to the newsgroup %s is restricted",
+ group->name);
+ return;
+ }
f = fopenart(group, arg, artno);
if (!f) {
if (arg && *arg != '<' && !group)
@@ -689,6 +737,12 @@
rereadactive();
g = findgroup(arg, active, -1);
if (g) {
+ if(!allow_access_to_group(g->name)){
+ nntpprintf("484 Access to the newsgroup %s is restricted",
+ g->name);
+ return group;
+ }
+
opengroup(g);
if (is_pseudogroup(g->name))
@@ -797,6 +851,38 @@
/* LIST ACTIVE if what==0, else LIST NEWSGROUPS */
static void printlist(const struct newsgroup *ng, const int what) {
+
+ /* There are 35,000 groups in my groupinfo file and
+ * this makes it very hard to find usefull groups.
+ * This section will filter out any group
+ * that does not match one of the space seperated
+ * wildmat patterns in the env var LISTGROUPS.
+ *
+ * Matthew Parry <mettw at yahoo.com.au>
+ */
+
+ static struct stringlisthead *groups_to_filter = NULL;
+ static int filter_groups = TRUE;
+
+ if(filter_groups){
+
+ if(!groups_to_filter){
+ char *filter_patterns = getenv("LISTGROUPS");
+
+ if(!filter_patterns || strlen(filter_patterns) == 0){
+ filter_groups = FALSE;
+ printlist(ng, what); /* I don't like goto */
+ return;
+ }
+
+ groups_to_filter = cmdlinetolist(filter_patterns);
+
+ }
+
+ if(matchlist(groups_to_filter->head, ng->name) == NULL)
+ return;
+ }
+
if (what) {
printf("%s\t%s", ng->name, ng->desc ? ng->desc : "-x-");
if (ng->status == 'm' && (!ng->desc || !strstr(ng->desc, " (Moderated)")))
@@ -1015,6 +1101,12 @@
return;
}
+ if(!allow_access_to_group(l->head->string)){
+ nntpprintf("484 Access to the newsgroup %s is restricted",
+ l->head->string);
+ freelist(l);
+ return;
+ }
nntpprintf_as("230 List of new articles since %ld in newsgroup %s",
(long int)age, l->head->string);
s = mastr_new(LN_PATH_MAX);
@@ -1478,6 +1570,16 @@
/* apply filter for all newsgroups found in turn */
for (t = strtok(u, ", "); t; t = strtok(NULL, ", ")) {
struct filterlist *fi = selectfilter(t);
+
+ /* Check first if access to group is permitted */
+ if(!allow_access_to_group(t)) {
+ nntpprintf("484 Access to the newsgroup %s is restricted",
+ t);
+ log_unlink(inname, 0);
+ free(u);
+ goto cleanup;
+ }
+
if (killfilter(fi, l)) {
nntpprintf("441 Article rejected by filter.");
log_unlink(inname, 0);
More information about the leafnode-list
mailing list