#
#
# This is a sample authentication and authorization module for python
# nnrpd hook
#
# For details, see the file doc/hook-python that came with INN.
#
#
# This file is loaded when one of the python_* readers.conf parameters
# is encountered. An instance of AUTH class is passed to nnrpd via
# set_auth_hook() function imported from nnrpd. The following methods
# of that class are known to nnrpd:
#
# __init__() - Use this method to initilalize your
# general variables or open a common
# database connection. May be omitted.
# access_init() - Init function specific to access
# control. May be omitted
# access(attributes) - Called when a python_access
# statement is reached in the
# processing of readers.conf. Returns
# a dictionary of values representing
# statements to be included in an
# access group.
# access_close() - Called on nnrpd termination. Save
# your state variables or close a
# database connection. May be omitted
# authen_init() - Init function specific to
# authentication. May be omitted
# authenticate(attributes) - Called when a python_auth statement
# is reached in the processing of
# readers.conf. Returns a response
# code, an error string and an
# optional string to appear in the
# logs as the username.
# authen_close() - Called on nnrpd termination. Save
# your state variables or close a database
# connection. May be omitted
# dynamic_init() - Init function specific to
# authentication. May be omitted
# dynamic(attributes) - Called whenever a reader requests either
# read or post access to a
# newsgroup. Returns None to grant
# access, or a non-empty string (which
# will be reported back to reader)
# otherwise.
# dynamic_close() - Called on nnrpd termination. Save
# your state variables or close a database
# connection. May be omitted
#
# If there is a problem with return codes from any of these methods then nnrpd
# will die and syslog the exact reason.
#
# There are also a few Python functions defined in nnrpd:
#
# set_auth_hook() - Called by nnrpd as this module is loaded.
# It is used to pass a reference to an
# instance of authentication class to nnrpd.
# syslog() - An equivalent replacement for regular syslog.
# One consideration for using it is to
# uniform nnrpd logging.
#
# Sample authentication and authorization class. It defines all methods known
# to nnrpd.
#
class AUTH:
"""Provide authentication and authorization callbacks to nnrpd."""
def __init__(self):
"""This is a good place to initialize variables or open a
database connection.
"""
# Create a list of NNTP codes to respond on connect
self.connectcodes = { 'READPOST':200,
'READ':201,
'AUTHNEEDED':480,
'PERMDENIED':502
}
# Create a list of NNTP codes to respond on authentication
self.authcodes = { 'ALLOWED':281,
'DENIED':502
}
syslog('notice', 'nnrpd authentication class instance created')
def authenticate(self, attributes):
"""Called when python_auth is encountered in readers.conf"""
# just for debugging purposes
syslog('notice', 'n_a authenticate() invoked: hostname %s, ipaddress %s, interface %s, user %s' % (\
attributes['hostname'], \
attributes['ipaddress'], \
attributes['interface'], \
attributes['user']))
# do username passworld authentication
if 'foo' == str(attributes['user']) \
and 'foo' == str(attributes['pass']):
syslog('notice', 'authentication by username succeeded')
return ( self.authcodes['ALLOWED'], 'No error', 'default_user')
else:
syslog('notice', 'authentication by username failed')
return ( self.authcodes['DENIED'], 'Access Denied!')
def access(self, attributes):
"""Called when python_access is encountered in readers.conf"""
# just for debugging purposes
syslog('notice', 'n_a access() invoked: hostname %s, ipaddress %s, interface %s, user %s' % (\
attributes['hostname'], \
attributes['ipaddress'], \
attributes['interface'], \
attributes['user']))
# allow newsreading from specific host only
if '127.0.0.1' == str(attributes['ipaddress']):
syslog('notice', 'authentication by IP address succeeded')
return {'read':'*','post':'*'}
else:
syslog('notice', 'authentication by IP address failed')
return {'read':'!*','post':'!*'}
def dynamic(self, attributes):
"""Called when python_dynamic was reached in the processing of
readers.conf and a reader requests either read or post
permission for particular newsgroup.
"""
# just for debugging purposes
syslog('notice', 'n_a dyanmic() invoked against type %s, hostname %s, ipaddress %s, interface %s, user %s' % (\
attributes['type'], \
attributes['hostname'], \
attributes['ipaddress'], \
attributes['interface'], \
attributes['user']))
# Allow reading of any newsgroup but not posting
if 'post' == str(attributes['type']):
syslog('notice', 'authorization for post access denied')
return "no posting for you"
elif 'read' == str(attributes['type']):
syslog('notice', 'authorization for read access granted')
return None
else:
syslog('notice', 'authorization type is not known: %s' % attributes['type'])
return "Internal error";
#
# The rest is used to hook up the auth module on nnrpd. It is unlikely
# you will ever need to modify this.
#
# Import functions exposed by nnrpd. This import must succeed, or nothing
# will work!
from nnrpd import *
# Create a class instance
myauth = AUTH()
# ...and try to hook up on nnrpd. This would make auth object methods visible
# to nnrpd.
try:
set_auth_hook(myauth)
syslog('notice', "authentication module successfully hooked into nnrpd")
except Exception, errmsg:
syslog('error', "Cannot obtain nnrpd hook for authentication method: %s" % errmsg[0])
syntax highlighted by Code2HTML, v. 0.9.1