1##  $Id: nnrpd_access.py 10282 2018-05-14 12:42:14Z iulius $
2##
3##  This is a sample access module for the Python nnrpd hook.
4##
5##  See the INN Python Filtering and Authentication Hooks documentation
6##  for more information.
7##  The python_access: parameter in readers.conf is used to load this script.
8##
9##  An instance of ACCESS class is passed to nnrpd via the set_auth_hook()
10##  function imported from nnrpd.  The following methods of that class
11##  are known to nnrpd:
12##
13##  __init__()                  - Use this method to initialize your
14##                                general variables or open a common
15##                                database connection.  May be omitted.
16##  access_init()               - Init function specific to access
17##                                control.  May be omitted.
18##  access(attributes)          - Called when a python_access
19##                                statement is reached in the
20##                                processing of readers.conf.  Returns
21##                                a dictionary of values representing
22##                                statements to be included in an
23##                                access group.
24##  access_close()              - Called on nnrpd termination.  Save
25##                                your state variables or close a
26##                                database connection.  May be omitted.
27##
28##  If there is a problem with return codes from any of these methods,
29##  then nnrpd will die and syslog the exact reason.
30##
31##  There are also a few Python functions defined in nnrpd:
32##
33##  set_auth_hook()             - Called by nnrpd as this module is loaded.
34##                              It is used to pass a reference to an
35##                              instance of authentication class to nnrpd.
36##  syslog()                    - An equivalent replacement for regular syslog.
37##                              One consideration for using it is to
38##                              uniform nnrpd logging.
39
40##  Sample access class.  It defines all access methods known to nnrpd.
41class ACCESS:
42    """Provide access callbacks to nnrpd."""
43
44    def __init__(self):
45        """This is a good place to initialize variables or open a
46           database connection."""
47        syslog('notice', 'nnrpd access class instance created')
48
49    def access_init(self):
50        """Called when this script is initialized."""
51        pass
52
53    def access(self, attributes):
54        """Called when python_access: is encountered in readers.conf."""
55
56        # Just for debugging purposes (in Python 3.x syntax).
57        # syslog('notice', 'n_a access() invoked: hostname %s, ipaddress %s, port %lu, interface %s, intipaddr %s, intport %lu, user %s' % ( \
58        #        attributes['hostname'].tobytes(), \
59        #        attributes['ipaddress'].tobytes(), \
60        #        attributes['port'], \
61        #        attributes['interface'].tobytes(), \
62        #        attributes['intipaddr'].tobytes(), \
63        #        attributes['intport'], \
64        #        (attributes['user'].tobytes() if attributes['user'] else "-")))
65
66        # Allow newsreading from specific host only.
67        # Python 2.x syntax:
68        #  if '127.0.0.1' == str(attributes['ipaddress']):
69        # Python 3.x syntax:
70        #  if b'127.0.0.1' == attributes['ipaddress'].tobytes():
71        #    syslog('notice', 'authentication access by IP address succeeded')
72        #    return {'read':'*', 'post':'*'}
73
74        syslog('notice', 'authentication access by IP address failed')
75        return {'read':'!*', 'post':'!*'}
76
77    def access_close(self):
78        """Called on nnrpd termination."""
79        pass
80
81
82##  The rest is used to hook up the access module on nnrpd.  It is unlikely
83##  you will ever need to modify this.
84
85##  Import functions exposed by nnrpd.  This import must succeed, or nothing
86##  will work!
87from nnrpd import *
88
89##  Create a class instance.
90myaccess = ACCESS()
91
92##  ...and try to hook up on nnrpd.  This would make auth object methods visible
93##  to nnrpd.
94import sys
95try:
96    set_auth_hook(myaccess)
97    syslog('notice', "access module successfully hooked into nnrpd")
98except Exception: # Syntax valid in both Python 2.x and 3.x.
99    e = sys.exc_info()[1]
100    syslog('error', "Cannot obtain nnrpd hook for access method: %s" % e.args[0])
101