source: TI05-delivery/trunk/lib/python/delivery/server.py @ 1141

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/lib/python/delivery/server.py@1141
Revision 1141, 4.0 KB checked in by spascoe, 14 years ago (diff)

There are various changes here.

The server now calls python for authorisation. This is untested, although the test suite passes. More flesh on delivery.server and it's now used in the
test suite. The server now logs python exceptions to syslog from within C code.

Line 
1"""
2Interface to the BBftp server.
3
4@author Stephen Pascoe
5"""
6
7import bbftpd
8
9def start(authHandler, args):
10    """Start the bbftp server.
11
12    The server performs a fork() during initialisation, the child process remains in
13    the server's main loop and the parent returns from this function.  The server process
14    calls authHandler.authorise() on each connection to do authentication/authorisation.
15
16    @note: because the server process forks, authHandler will not see any changes to the python
17        interpreter following the call to start().
18
19    @param authHandler: an instance of AuthHandler.
20    @param args: a list of command line arguments.
21    @return: the PID of the server process.
22    """
23   
24    return bbftpd.run(authHandler, args)
25
26
27class AuthHandler(object):
28    """Abstract base class for implementing authentication.
29
30    Subclasses should implement the authorise() method to authenticate clients connecting to
31    the server.  An AuthHandler object is passed to start() when initialising the server.
32    """
33   
34    def send(self, buffer):
35        """Send a message to the client.
36
37        @param buffer a string containing the message to send.
38        """
39   
40        return bbftpd.send(buffer)
41
42    def recv(self):
43        """Receive a message from the client.
44
45        @return a string containing the message received.
46        """
47
48        return bbftpd.recv()
49
50    def authorise(self):
51        """Authenticate a connection.
52
53        This function should be overridden in subclasses to implement authentication using
54        the method calls self.send() and send.recv().
55
56        @note because the server process forks on each connection, calls to authorise() will
57            see the state of the python interpreter as it was when start() was called.
58
59        @return an AuthzHandler instance if authentication succeeds, else None.
60        """
61
62        raise NotImplementedError
63
64
65class AuthzHandler(object):
66    """Abstract base class for implementing authorisation.
67
68    @ivar username the client's username
69    """
70
71    def authzControl(self, msgcode, transferoption, path):
72        """Authorise a control command.
73
74        @param msgcode: the command type.
75        @param transferoption: extra options specified in the command.
76        @param path: the file or directory to which the command applies.
77        @return: 0 on success or -1 on failure.
78        """
79
80        raise NotImplementedError
81
82    def authzRetr(self, path):
83        """Authorise a retrieve request.
84
85        @param path: the file being retrieved.
86        @return: 0 on success or -1 on failure.
87        """
88
89        raise NotImplementedError
90
91    def authzStore(self, path):
92        """Authorise a store request.
93
94        @param path: the destination file.
95        @return: 0 on success or -1 on failure.
96        """
97
98        raise NotImplementedError
99   
100    def _raiseNoUsername(self):
101        raise ValueError, "No username has been set"
102    username = property(_raiseNoUsername)
103
104#--------------------------------------------------------------------------------------------------------------
105
106class BasicClientAuthHandler(AuthHandler):
107    """
108    When testing with the basic bbftp client some messages will be NULL terminated.  This class
109    makes communicating with such clients slightly easier.
110    """
111
112    def recvCStr(self):
113        """Receive a message from the client which may contain \\0 characters indicating message end.
114
115        The message is truncated to the first \\0 character.
116
117        @return a string containing the message received.
118        """
119
120        msg = self.recv()
121        # Trim to first '\0'
122        x = msg.find('\0')
123        if x:
124            msg = msg[:x]
125
126        return msg
127
128
129
130class LiberalAuthzHandler(AuthzHandler):
131    """Allow everything.
132    """
133
134    username = None
135
136    def __init__(self, username):
137        self.username = username
138
139    def authzControl(self, m, t, p):
140        return 0;
141
142    def authzRetr(self, p):
143        return 0;
144
145    def authzStore(self, p):
146        return 0;
147   
Note: See TracBrowser for help on using the repository browser.