--On 14 August 2006 14:06:06 -0400 Barry Warsaw <[EMAIL PROTECTED]> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Aug 14, 2006, at 9:49 AM, Ian Eiloart wrote:

One thing that would make integration easier, would be a script
bin/may_post (or something), which takes a list name (ideally
qualified
with domain) and sender address, and returns true if the sender
address is
allowed to post, and false otherwise.

Why don't you code something up and submit it here? :)

- -Barry

I started to write that I've no python coding experience. Well, about 3 lines because php can't do "utf-something or other". Then I thought, well it's about time I got some.

I had hacked up a shell script using the existing Mailman scripts, but that was far too inefficient. Instead I've hacked up the attached. It started life as list_config, but hopefully I've not left much trace of that. The second issue below ***MUST*** be resolved before using this script with an MTA.

The attached script takes these arguments:
-o --outputfile FILE_PATH can be used to specify logging of denies. use '-' to log to stdout
-v --verbose causes logging of all results, allows as well as denies.
-h --help prints help
-s --sender EMAIL_ADDRESS is required

The script applies these tests, printing 'allow' or 'deny' to std out on the first match.
allow list owners
allow list moderators
allow members of accept_these_nonmembers
deny members of reject_these_nonmembers
if generic_nonmember_action is 'reject':
   allow members to post
   deny non-members
allow by default

These issues are outstanding:
----------------------------
On allow, I say "return 1" on deny I say "return 0". I'm not sure whether that's correct. Actually, I think I want the script to succeed every time, so it can't be.

I've not figured out how to do a pattern match so accept_these_nonmembers and reject_these_nonmembers are only tested for exact string matches. This *****needs to be fixed***** for accept_these_nonmembers, otherwise some won't be permitted to post.

It'd be nice to log to syslog, but the MTA could take care of that.

It might be nice to say 'hold' or 'discard' where appropriate. It's often sensible to reject rather than discard a message, for example.

The list's nonmember_rejection_notice isn't used here. It could be returned instead of 'deny' for the MTA to construct a rejection string with.

I've hard-coded '2' as the 'reject' key to generic_nonmember_action, which is sinful.
--
Ian Eiloart
IT Services, University of Sussex
#! /local/bin/python
#
# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

"""Find out whether list will reject a message from sender.

Usage: check_sender.py [options] -s sender listname

Options:

    --outputfile filename
    -o filename
        optionally log denys to list file.

    --sender sender
    -s sender
        check whether the sender is allowed to post to the list.

    --verbose
    -v
        log allows as well as denys.

    --help
    -h
        Print this help message and exit.

The option -s is required.

"""

import sys
import re
import time
import getopt
from types import TupleType

import paths
from Mailman import mm_cfg
from Mailman import MailList
from Mailman import Utils
from Mailman import Errors
from Mailman.i18n import _

NL = '\n'



def usage(code, msg=''):
    if code:
        fd = sys.stderr
    else:
        fd = sys.stdout
    print >> fd, _(__doc__)
    if msg:
        print >> fd, msg
    sys.exit(code)



def do_check(listname, sender, outfile, verbose):
    closep = 0
    try:
        if outfile == '-':
            outfp = sys.stdout
        else:
            outfp = open(outfile, 'a')
            closep = 1
        # Open the specified list unlocked, since we're only reading it.
        try:
            mlist = MailList.MailList(listname, lock=0)
        except Errors.MMListError:
            usage(1, _('No such list: %(listname)s'))
        # get all the list config info.  all this stuff is accessible via
the
        # web interface
        when = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())

        # always allow the owner to post
        if sender in mlist.owner :
            if verbose:
                print >> outfp, _('''%(when)s %(listname)s owner %(sender)s
allowed''')
            print >> sys.stdout, 'allow'
            return 1
        # always allow moderators to post
        if sender in mlist.moderator :
            if verbose:
                print >> outfp, _('''%(when)s %(listname)s moderator
%(sender)s allowed''')
            print >> sys.stdout, 'allow'
            return 1
        # always allow accept_these_nonmembers to post
        if sender in mlist.accept_these_nonmembers :
            if verbose:
                print >> outfp, _('''%(when)s %(listname)s
accept_these_nonmembers %(sender)s allowed''')
            print >> sys.stdout, 'allow'
            return 1
        # deny reject_these_nonmembers
        if sender in mlist.reject_these_nonmembers :
            print >> outfp, _('''%(when)s %(listname)s
reject_these_nonmembers %(sender)s allowed''')
            print >> sys.stdout, 'deny'
            return 0
        # 2 is the key for 'reject', but there's probably a global we
should use
        if  mlist.generic_nonmember_action == 2:
            # regular members
            rmembers = mlist.getRegularMemberKeys()
            # digest members
            dmembers = mlist.getDigestMemberKeys()
            allmembers = rmembers + dmembers
            # should lowercase sender
            if sender.lower() in allmembers:
                if verbose:
                    print >> outfp, _('''%(when)s %(listname)s member
%(sender)s allowed''')
                print >> sys.stdout, 'allow'
                return 1
            else:
                print >> outfp, _('''%(when)s %(listname)s member
%(sender)s denied''')
                print >> sys.stdout, 'deny'
                return 0
        print >> outfp, _('''%(when)s %(listname)s unknow %(sender)s
allowed by default''')
        print >> sys.stdout, 'allow'
        return 1
    finally:
        if closep:
            outfp.close()






def main():
    try:
        opts, args = getopt.getopt(
            sys.argv[1:], 's:o:vh',
            ['list=', 'sender=', 'verbose', 'help'])
    except getopt.error, msg:
        usage(1, msg)

    # defaults
    infile = None
    outfile = None
    list = None
    sender = None
    verbose = 0
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage(0)
        elif opt in ('-l', '--list'):
            list = arg
        elif opt in ('-s', '--sender'):
            sender = arg
        elif opt in ('-o', '--outputfile'):
            outfile = arg
        elif opt in ('-v', '--verbose'):
            verbose = 1

    # sanity check
    if sender is None:
        usage(1, _('--sender is required'))

    # get the list name
    if len(args) <> 1:
        usage(1, _('List name is required'))
    listname = args[0].lower().strip()

    do_check(listname, sender, outfile, verbose)



if __name__ == '__main__':
    main()
_______________________________________________
Mailman-Developers mailing list
Mailman-Developers@python.org
http://mail.python.org/mailman/listinfo/mailman-developers
Mailman FAQ: http://www.python.org/cgi-bin/faqw-mm.py
Searchable Archives: 
http://www.mail-archive.com/mailman-developers%40python.org/
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-developers/archive%40jab.org

Security Policy: 
http://www.python.org/cgi-bin/faqw-mm.py?req=show&file=faq01.027.htp

Reply via email to