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

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

Updated python code to reflect the renaming of the delivery package to pybbftp.
Some C tidying to reduce compiler warnings.

Line 
1"""
2Start a bbftp server process and define python callbacks for authentication and authorisation.
3
4Interface to the BBftp server.
5
6@copyright Copyright (C) 2006 CCLRC & NERC
7@license This software may be distributed under the terms of the Q Public Licence, version 1.0 or later.
8
9@author Stephen Pascoe
10"""
11
12#!NOTE: Importing bbftpd and bbftpc together is dangerous and will cause stange errors.
13#       However if the module is being scanned by epydoc allow the import (This is a hack!)
14import sys
15if sys.modules.has_key('pybbftp.bbftpc') and not sys.modules.has_key('epydoc'):
16    raise ImportError, "pybbftp.bbftpc extension already loaded.  You cannot use both client and server extensions together"
17
18import bbftpd
19
20class TROPT:
21    """Static class containing constants used by bbftp in the transferoption parameter.
22
23    TROPT.X always corresponds to TROPT_X as defined in bbftpd/structures.h.
24    Options that aren't likely to be used for the delivery service are not
25    included (e.g. TROPT_RFIO).
26
27    @cvar TMP always use temporary name.
28    @cvar ACC keep access and modification time.
29    @cvar MODE keep mode.
30    @cvar DIR create all dirs in path.
31    """
32    TMP = bbftpd.TROPT_TMP
33    ACC = bbftpd.TROPT_ACC
34    MODE = bbftpd.TROPT_MODE
35    DIR = bbftpd.TROPT_DIR
36
37class MSG:
38    """Static class containing message codes used by bbftp.
39
40    MSG.X corresponds to MSG_X or MSG_X_V2 as defined in bbftpd/structures.h.
41    Message codes not returned by the auth/authz interface are not included.
42
43    @cvar CHDIR a chdir request.
44    @cvar LIST a ls/dir request.
45    @cvar MKDIR a mkdir request.
46    @cvar RM a rm request.
47    @cvar STAT a stat request.
48    @cvar DF a statfs request.
49    """
50    CHDIR = bbftpd.MSG_CHDIR_V2
51    LIST = bbftpd.MSG_LIST_V2
52    MKDIR = bbftpd.MSG_MKDIR_V2
53    RM = bbftpd.MSG_RM
54    STAT = bbftpd.MSG_STAT
55    DF = bbftpd.MSG_DF
56   
57
58#--------------------------------------------------------------------------------------------------------------
59
60def start(authHandler, args):
61    """Start the bbftp server.
62
63    The server performs a fork() during initialisation, the child process remains in
64    the server's main loop and the parent returns from this function.  The server process
65    calls authHandler.authorise() on each connection to do authentication/authorisation.
66
67    @note because the server process forks, authHandler will not see any changes to the python
68        interpreter following the call to start().
69
70    @param authHandler an instance of AuthHandler.
71    @param args a list of command line arguments.
72    @return the PID of the server process.
73    """
74   
75    return bbftpd.run(authHandler, args)
76
77
78class AuthenticationFailure(Exception):
79    """Signals authentication failed.
80    """
81    pass
82
83class AuthorisationFailure(Exception):
84    """Signals authorisation failed.
85    """
86    pass
87
88
89
90class AuthHandler(object):
91    """Abstract base class for implementing authentication.
92
93    Subclasses should implement the authorise() method to authenticate clients connecting to
94    the server.  An AuthHandler object is passed to start() when initialising the server.
95    """
96   
97    def send(self, buffer):
98        """Send a message to the client during authentication
99
100        This method must only be used from within self.authenticate() which has been called
101        from the bbftp server process started by start().
102
103        @param buffer a string containing the message to send.
104        """
105   
106        return bbftpd.send(buffer)
107
108    def recv(self):
109        """Receive a message from the client during authentication
110
111        This method must only be used from within self.authenticate() which has been called
112        from the bbftp server process started by start().
113
114        @return a string containing the message received.
115        """
116
117        return bbftpd.recv()
118
119    def authenticate(self):
120        """Authenticate a connection.
121
122        This function should be overridden in subclasses to implement authentication using
123        the method calls self.send() and send.recv().  It is called by the bbftp server process
124        created using the start() function.
125
126        @note because the server process forks on each connection, calls to authorise() will
127            see the state of the python interpreter as it was when start() was called.
128
129        @return an AuthzHandler instance if authentication succeeds.  Any false value is considered
130            an authorisation failure.
131        @raise AuthorisationFailure the preferred way of signaling authorisation failure to
132            the bbftp server process.
133        """
134
135        raise NotImplementedError
136
137
138class AuthzHandler(object):
139    """Abstract base class for implementing authorisation.
140
141    @ivar username: the client's username.  This attribute must be set before an instance of AuthzHandler
142        is returned to the bbftp server process by AuthHandler.authenticate().
143       
144    """
145
146    def authzControl(self, msgcode, transferoption, path):
147        """Authorise a control command.
148
149        @param msgcode the command type.
150        @param transferoption extra options specified in the command.
151        @param path the file or directory to which the command applies.
152        @return bool for success or failure.
153        """
154
155        raise NotImplementedError
156
157    def authzRetr(self, path):
158        """Authorise a retrieve request.
159
160        @param path the file being retrieved.
161        @return bool for success or failure.
162        """
163
164        raise NotImplementedError
165
166    def authzStore(self, path):
167        """Authorise a store request.
168
169        @param path the destination file.
170        @return bool for success or failure.
171        """
172
173        raise NotImplementedError
174   
175
176#--------------------------------------------------------------------------------------------------------------
177
178
179class LiberalAuthzHandler(AuthzHandler):
180    """Allow everything.
181    """
182
183    def __init__(self, username):
184        self.username = username
185
186    def authzControl(self, m, t, p):
187        return True;
188
189    def authzRetr(self, p):
190        return True;
191
192    def authzStore(self, p):
193        return True;
194   
Note: See TracBrowser for help on using the repository browser.