Ignore:
Timestamp:
08/06/06 12:51:22 (13 years ago)
Author:
spascoe
Message:

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.

Location:
TI05-delivery/trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/trunk/src/bbftp-server-3.2.0/includes/ndg.h

    r1139 r1141  
    3535char *ndg_getusername(char *logmessage); 
    3636 
     37int ndg_authz_control(int msgcode, int transferoption, char *path, char *logmessage); 
     38int ndg_authz_retr(char *path, char *logmessage); 
     39int ndg_authz_store(char *path, char *logmessage); 
     40 
     41 
    3742#endif // NDG_PYTHON_EMBED 
  • TI05-delivery/trunk/src/python_ext/bbftpd.c

    r1139 r1141  
    1111 
    1212#include <Python.h> 
     13#include <ndg.h> 
    1314 
    1415extern char **environ; 
     
    2728 * Static variables. 
    2829 */ 
    29 static PyObject *authContext = NULL; 
    30 static PyObject *authzContext = NULL; 
     30static PyObject *authHandler = NULL; 
     31static PyObject *authzHandler = NULL; 
     32 
     33static void ndg_pyerr_to_logmessage(char *logmessage, char *prefix); 
    3134 
    3235/*--------------------------------------------------------------------------------------------------- 
     
    3740 
    3841/** 
     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 */ 
     52static 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/** 
    3975 * Make a callback bbftpd->python to handle authentication. 
    4076 * 
     
    4581int ndg_auth(char *logmessage) { 
    4682 
    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"); 
    66101    return -1; 
    67102  } 
     
    71106 
    72107/** 
    73  * retrieve the username from authzContext. 
     108 * retrieve the username from authzHandler. 
    74109 * 
    75110 * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE 
     
    81116  PyObject *str_obj; 
    82117 
    83   if (authzContext == NULL) { 
    84     sprintf(logmessage, "bbftpd_private_auth_getusername: no authzContext set"); 
    85     return NULL; 
    86   } 
    87  
    88   if ((str_obj = PyObject_GetAttrString(authzContext, "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"); 
    90125    return NULL; 
    91126  } 
    92127 
    93128  if ((username = PyString_AsString(str_obj)) == NULL) { 
     129    ndg_pyerr_to_logmessage(logmessage, "ndg_getusername"); 
    94130    Py_DECREF(str_obj); 
    95     sprintf(logmessage, "bbftpd_private_auth_getusername: authzContext.username not a string"); 
    96131    return NULL; 
    97132  } 
     
    101136 
    102137 
    103        
     138/** 
     139 * Make a callback to do authorisation of a control command. 
     140 * 
     141 * @see bbftpd_private_authz_control() 
     142 */ 
     143int 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 */ 
     173int 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 */ 
     204int 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      
    104231/*------------------------------------------------------------------------------------------------- 
    105232 * Functions exported to python 
     
    116243  } 
    117244 
    118   if (authContext == NULL) { 
     245  if (authHandler == NULL) { 
    119246    PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpd callback"); 
    120247    return NULL; 
     
    139266  } 
    140267 
    141   if (authContext == NULL) { 
     268  if (authHandler == NULL) { 
    142269    PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpd callback"); 
    143270    return NULL; 
     
    167294  PyObject *daemon_args, *item; 
    168295 
    169   if (!PyArg_ParseTuple(args, "OO", &authContext, &daemon_args)) { 
    170     return NULL; 
    171   } 
    172   Py_INCREF(authContext); 
     296  if (!PyArg_ParseTuple(args, "OO", &authHandler, &daemon_args)) { 
     297    return NULL; 
     298  } 
     299  Py_INCREF(authHandler); 
    173300  Py_INCREF(daemon_args); 
    174301 
     
    190317  for (i=0; i<argc; i++) { 
    191318    if ((item = PySequence_GetItem(daemon_args, i)) == NULL) { 
    192       Py_DECREF(authContext); 
     319      Py_DECREF(authHandler); 
    193320      Py_DECREF(daemon_args); 
    194321      return NULL; 
     
    197324      free(argv); 
    198325      Py_DECREF(item); 
    199       Py_DECREF(authContext); 
     326      Py_DECREF(authHandler); 
    200327      Py_DECREF(daemon_args); 
    201328      return NULL; 
     
    213340 
    214341  free(argv); 
    215   Py_DECREF(authContext); authContext = NULL; 
     342  Py_DECREF(authHandler); authHandler = NULL; 
    216343  Py_DECREF(daemon_args); 
    217344 
Note: See TracChangeset for help on using the changeset viewer.