Changeset 1141 for TI05-delivery/trunk
- Timestamp:
- 08/06/06 12:51:22 (15 years ago)
- Location:
- TI05-delivery/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TI05-delivery/trunk/lib/python/delivery/server.py
r1133 r1141 7 7 import bbftpd 8 8 9 def start(authHandler ):9 def start(authHandler, args): 10 10 """Start the bbftp server. 11 11 12 12 The server performs a fork() during initialisation, the child process remains in 13 13 the server's main loop and the parent returns from this function. The server process 14 calls authHandler () on each connection to do authentication/authorisation.14 calls authHandler.authorise() on each connection to do authentication/authorisation. 15 15 16 16 @note: because the server process forks, authHandler will not see any changes to the python 17 17 interpreter following the call to start(). 18 18 19 @param authHandler: an instance of AuthHandler. 20 @param args: a list of command line arguments. 19 21 @return: the PID of the server process. 20 22 """ 21 23 22 bbftpd.run(authHandler)24 return bbftpd.run(authHandler, args) 23 25 24 26 … … 30 32 """ 31 33 32 def __call__(self):33 """Entry point called by the server to do authorisation.34 35 This function simply calls the authorise() method. See authorise() for details.36 """37 return self.authorise()38 39 34 def send(self, buffer): 40 35 """Send a message to the client. … … 70 65 class AuthzHandler(object): 71 66 """Abstract base class for implementing authorisation. 67 68 @ivar username the client's username 72 69 """ 73 70 … … 92 89 raise NotImplementedError 93 90 94 def authzS end(self, path):95 """Authorise a s endrequest.91 def authzStore(self, path): 92 """Authorise a store request. 96 93 97 94 @param path: the destination file. … … 99 96 """ 100 97 98 raise NotImplementedError 99 100 def _raiseNoUsername(self): 101 raise ValueError, "No username has been set" 102 username = property(_raiseNoUsername) 101 103 102 104 #-------------------------------------------------------------------------------------------------------------- 103 105 104 106 class BasicClientAuthHandler(AuthHandler): … … 124 126 return msg 125 127 128 129 130 class 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 -
TI05-delivery/trunk/src/bbftp-server-3.2.0/includes/ndg.h
r1139 r1141 35 35 char *ndg_getusername(char *logmessage); 36 36 37 int ndg_authz_control(int msgcode, int transferoption, char *path, char *logmessage); 38 int ndg_authz_retr(char *path, char *logmessage); 39 int ndg_authz_store(char *path, char *logmessage); 40 41 37 42 #endif // NDG_PYTHON_EMBED -
TI05-delivery/trunk/src/python_ext/bbftpd.c
r1139 r1141 11 11 12 12 #include <Python.h> 13 #include <ndg.h> 13 14 14 15 extern char **environ; … … 27 28 * Static variables. 28 29 */ 29 static PyObject *authContext = NULL; 30 static PyObject *authzContext = NULL; 30 static PyObject *authHandler = NULL; 31 static PyObject *authzHandler = NULL; 32 33 static void ndg_pyerr_to_logmessage(char *logmessage, char *prefix); 31 34 32 35 /*--------------------------------------------------------------------------------------------------- … … 37 40 38 41 /** 42 * Copy the python exception message to a bbftp logmessage. 43 * 44 * If the python error indicator is set it will be cleared. 45 * If the python error indicator is not set the empty string will be copied to \a logmessage. 46 * The exception message is truncated if it exceeds \c NDG_MAX_LOGMESSAGE. 47 * 48 * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE 49 * for storing an error message when returning -1. 50 * @param prefix a string to be prefixed to the logmessage. 51 */ 52 static void ndg_pyerr_to_logmessage(char *logmessage, char *prefix) { 53 PyObject *ptype, *pvalue, *ptraceback, *obj; 54 char *exname, *exvalue; 55 56 PyErr_Fetch(&ptype, &pvalue, &ptraceback); 57 58 if ((obj = PyObject_GetAttrString(ptype, "__name__")) == NULL) goto error; 59 exname = PyString_AsString(obj); Py_DECREF(obj); 60 if (exname == NULL) goto error; 61 62 if ((obj = PyObject_Str(pvalue)) == NULL) goto error; 63 exvalue = PyString_AsString(obj); Py_DECREF(obj); 64 if (exvalue == NULL) goto error; 65 66 snprintf(logmessage, NDG_MAX_LOGMESSAGE, "%s: %s: %s", prefix, exname, exvalue); 67 return; 68 69 error: 70 sprintf("ndg_pyerr_to_logmessage: internal python error", logmessage); 71 return; 72 } 73 74 /** 39 75 * Make a callback bbftpd->python to handle authentication. 40 76 * … … 45 81 int ndg_auth(char *logmessage) { 46 82 47 if (authzContext != NULL) { 48 sprintf(logmessage, "bbftpd_private_auth_callback: authzContext already present"); 49 return -1; 50 } 51 52 if (authContext == NULL) { 53 sprintf(logmessage, "bbftpd_private_auth_callback: no authContext set"); 54 return -1; 55 } 56 57 if ((authzContext = PyObject_CallObject(authContext, NULL)) == NULL) { 58 //!TODO: should probably read the exception object to fill logmessage. 59 sprintf(logmessage, "bbftpd_private_auth_callback: authContext.authorise() failed"); 60 return -1; 61 } 62 63 /* If authContext.authorise() returned None then authorisation failed. */ 64 if (authzContext == Py_None) { 65 sprintf(logmessage, "bbftpd_private_auth_callback: python authorisation failed"); 83 if (authzHandler != NULL) { 84 sprintf(logmessage, "ndg_auth: authzHandler already present"); 85 return -1; 86 } 87 88 if (authHandler == NULL) { 89 sprintf(logmessage, "ndg_auth: no authHandler set"); 90 return -1; 91 } 92 93 if ((authzHandler = PyObject_CallMethod(authHandler, "authorise", "")) == NULL) { 94 ndg_pyerr_to_logmessage(logmessage, "ndg_auth"); 95 return -1; 96 } 97 98 /* If authHandler.authorise() returned None then authorisation failed. */ 99 if (authzHandler == Py_None) { 100 sprintf(logmessage, "ndg_auth: python authorisation failed"); 66 101 return -1; 67 102 } … … 71 106 72 107 /** 73 * retrieve the username from authz Context.108 * retrieve the username from authzHandler. 74 109 * 75 110 * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE … … 81 116 PyObject *str_obj; 82 117 83 if (authz Context== NULL) {84 sprintf(logmessage, "bbftpd_private_auth_getusername: no authz Contextset");85 return NULL; 86 } 87 88 if ((str_obj = PyObject_GetAttrString(authz Context, "username")) == NULL) {89 sprintf(logmessage, "bbftpd_private_auth_getusername: authzContext.username lookup failed");118 if (authzHandler == NULL) { 119 sprintf(logmessage, "bbftpd_private_auth_getusername: no authzHandler set"); 120 return NULL; 121 } 122 123 if ((str_obj = PyObject_GetAttrString(authzHandler, "username")) == NULL) { 124 ndg_pyerr_to_logmessage(logmessage, "ndg_getusername"); 90 125 return NULL; 91 126 } 92 127 93 128 if ((username = PyString_AsString(str_obj)) == NULL) { 129 ndg_pyerr_to_logmessage(logmessage, "ndg_getusername"); 94 130 Py_DECREF(str_obj); 95 sprintf(logmessage, "bbftpd_private_auth_getusername: authzContext.username not a string");96 131 return NULL; 97 132 } … … 101 136 102 137 103 138 /** 139 * Make a callback to do authorisation of a control command. 140 * 141 * @see bbftpd_private_authz_control() 142 */ 143 int ndg_authz_control(int msgcode, int transferoption, char *path, char *logmessage) { 144 PyObject *ret_obj; 145 int ret; 146 147 if (authzHandler == NULL) { 148 sprintf(logmessage, "ndg_authz_control: no authzHandler set"); 149 return -1; 150 } 151 152 if ((ret_obj = PyObject_CallMethod(authzHandler, "authzControl", "iis", msgcode, transferoption, path)) == NULL) { 153 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_control"); 154 return -1; 155 } 156 157 if (!PyInt_Check(ret_obj)) { 158 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_control"); 159 Py_DECREF(ret_obj); 160 return -1; 161 } 162 163 ret = (int)PyInt_AsLong(ret_obj); 164 Py_DECREF(ret_obj); 165 return ret; 166 } 167 168 /** 169 * Make a callback to do authorisation of a retr command. 170 * 171 * @see bbftpd_private_authz_store() 172 */ 173 int ndg_authz_retr(char *path, char *logmessage) { 174 PyObject *ret_obj; 175 int ret; 176 177 if (authzHandler == NULL) { 178 sprintf(logmessage, "ndg_authz_retr: no authzHandler set"); 179 return -1; 180 } 181 182 if ((ret_obj = PyObject_CallMethod(authzHandler, "authzRetr", "s", path)) == NULL) { 183 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_retr"); 184 return -1; 185 } 186 187 if (!PyInt_Check(ret_obj)) { 188 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_retr"); 189 Py_DECREF(ret_obj); 190 return -1; 191 } 192 193 ret = (int)PyInt_AsLong(ret_obj); 194 Py_DECREF(ret_obj); 195 return ret; 196 } 197 198 199 /** 200 * Make a callback to do authorisation of a store command. 201 * 202 * @see bbftpd_private_authz_store() 203 */ 204 int ndg_authz_store(char *path, char *logmessage) { 205 PyObject *ret_obj; 206 int ret; 207 208 if (authzHandler == NULL) { 209 sprintf(logmessage, "ndg_authz_store: no authzHandler set"); 210 return -1; 211 } 212 213 if ((ret_obj = PyObject_CallMethod(authzHandler, "authzStore", "s", path)) == NULL) { 214 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_store"); 215 return -1; 216 } 217 218 if (!PyInt_Check(ret_obj)) { 219 ndg_pyerr_to_logmessage(logmessage, "ndg_authz_store"); 220 Py_DECREF(ret_obj); 221 return -1; 222 } 223 224 ret = (int)PyInt_AsLong(ret_obj); 225 Py_DECREF(ret_obj); 226 return ret; 227 } 228 229 230 104 231 /*------------------------------------------------------------------------------------------------- 105 232 * Functions exported to python … … 116 243 } 117 244 118 if (auth Context== NULL) {245 if (authHandler == NULL) { 119 246 PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpd callback"); 120 247 return NULL; … … 139 266 } 140 267 141 if (auth Context== NULL) {268 if (authHandler == NULL) { 142 269 PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpd callback"); 143 270 return NULL; … … 167 294 PyObject *daemon_args, *item; 168 295 169 if (!PyArg_ParseTuple(args, "OO", &auth Context, &daemon_args)) {170 return NULL; 171 } 172 Py_INCREF(auth Context);296 if (!PyArg_ParseTuple(args, "OO", &authHandler, &daemon_args)) { 297 return NULL; 298 } 299 Py_INCREF(authHandler); 173 300 Py_INCREF(daemon_args); 174 301 … … 190 317 for (i=0; i<argc; i++) { 191 318 if ((item = PySequence_GetItem(daemon_args, i)) == NULL) { 192 Py_DECREF(auth Context);319 Py_DECREF(authHandler); 193 320 Py_DECREF(daemon_args); 194 321 return NULL; … … 197 324 free(argv); 198 325 Py_DECREF(item); 199 Py_DECREF(auth Context);326 Py_DECREF(authHandler); 200 327 Py_DECREF(daemon_args); 201 328 return NULL; … … 213 340 214 341 free(argv); 215 Py_DECREF(auth Context); authContext= NULL;342 Py_DECREF(authHandler); authHandler = NULL; 216 343 Py_DECREF(daemon_args); 217 344 -
TI05-delivery/trunk/test/test_embedded.py
r1133 r1141 22 22 23 23 sys.path.append(BUILDDIR) 24 import delivery.bbftpd as bbftpd 25 26 class AuthzContext: 27 def __init__(self, version_msg, user): 28 self.version = version_msg 29 self.username = user 30 31 class AuthContext: 32 def __call__(self): 33 # Read the auth version message 34 msg = bbftpd.recv() 35 # Trim to first '\0' 36 x = msg.find('\0') 37 if x: 38 msg = msg[:x] 24 25 import delivery.server as server 26 27 28 class TestAuthHandler(server.BasicClientAuthHandler): 29 def authorise(self): 30 msg = self.recvCStr() 39 31 40 32 syslog.syslog(syslog.LOG_DEBUG, 'AuthContext received Auth message: %s' % msg) 41 33 42 # Send the response 43 msg = NDG_HANDSHAKE + '\0' * (NDG_MESSAGE_LEN - len(NDG_HANDSHAKE)) 44 bbftpd.send(msg) 45 46 # Get privatestr 47 privatestr = bbftpd.recv() 48 # Trim to first '\0' 49 x = privatestr.find('\0') 50 if x: 51 privatestr = privatestr[:x] 34 self.send(NDG_HANDSHAKE) 35 36 privatestr = self.recvCStr() 52 37 syslog.syslog(syslog.LOG_DEBUG, "AuthContext received privatestr: %s" % privatestr) 53 38 54 return AuthzContext(msg, "TestCaseUser") 55 56 57 class FailingAuthContext(AuthContext): 58 def __call__(self): 59 az = super(FailingAuthContext).authorise() 39 return TestAuthzHandler(msg, "TestCaseUser") 40 41 class TestAuthzHandler(server.LiberalAuthzHandler): 42 def __init__(self, version, username): 43 super(TestAuthzHandler, self).__init__(username) 44 self.version = version 45 46 47 class TestFailAuthHandler(server.AuthHandler): 48 def authorise(self): 60 49 return None 61 62 63 64 50 65 51 class BaseFixture(unittest.TestCase): … … 81 67 def _startServer(self, authContext=None): 82 68 if not authContext: 83 authContext = AuthContext()69 authContext = TestAuthHandler() 84 70 # Start the server and store it's PID 85 self.pid = bbftpd.run(authContext, ['-l', 'DEBUG'])71 self.pid = server.start(authContext, ['-l', 'DEBUG']) 86 72 87 73 def _stopServer(self): … … 217 203 # Check the client output 218 204 output = fh.read() 205 219 206 self.assertLines(['get.*nogzip'], output) 220 207 … … 258 245 syslog.syslog(syslog.LOG_DEBUG, 'Starting EmbeddedServerTestCase') 259 246 260 self._startServer(authContext= FailingAuthContext())247 self._startServer(authContext=TestFailAuthHandler()) 261 248 262 249 def test(self):
Note: See TracChangeset
for help on using the changeset viewer.