Changeset 1259 for TI05-delivery


Ignore:
Timestamp:
29/06/06 16:40:28 (13 years ago)
Author:
spascoe
Message:

Client-side authentication handling is implemented but currently broken.
I'm still working out what's wrong.

Location:
TI05-delivery/trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • TI05-delivery/trunk/setup.py

    r1242 r1259  
    4343    ] 
    4444 
    45 server_sources = ['%s/bbftpd/%s' % (bbftpd_home, x) for x in bbftpd_src] + ['./src/python_ext/bbftpd.c'] 
     45server_sources = ['%s/bbftpd/%s' % (bbftpd_home, x) for x in bbftpd_src] + ['./src/python_ext/bbftpd.c', 
     46                                                                            './src/python_ext/util.c', 
     47                                                                            ] 
    4648 
    4749bbftpc_src = [  
     
    7375    'setsignals.c', 
    7476    'bbftp_private.c', 
    75     'bbftp_private_user.c' 
     77    'bbftp_private_user.c', 
     78    'ndg_client.c' 
    7679    ] 
    7780 
  • TI05-delivery/trunk/src/bbftp-client-3.2.0/bbftpc/bbftp_private_user.c

    r1100 r1259  
    3131#include <bbftp_private_user.h> 
    3232#include <client.h> 
     33 
     34#ifdef NDG_PRIVATE_AUTH 
     35int ndg_client_auth(char *logmessage); 
     36#endif // NDG_PRIVATE_AUTH 
     37 
    3338 
    3439/* 
     
    133138  int len; 
    134139 
     140#ifdef NDG_PYTHON_EMBED 
     141  return ndg_client_auth(logmessage); 
     142#else 
     143 
    135144  /* Send version verification message.  */ 
    136145  if (ndg_message_send(NDG_HANDSHAKE, strlen(NDG_HANDSHAKE) + 1, logmessage) == -1) { 
     
    159168 
    160169  return  0 ; 
     170#endif // NDG_PRIVATE_AUTH 
    161171} 
    162172 
  • TI05-delivery/trunk/src/bbftp-server-3.2.0/includes/ndg.h

    r1195 r1259  
    1212#include <bbftpd.h> 
    1313#include <netinet/in.h> 
    14 #include <structures.h> 
    1514 
    1615/* The logmessage size limit is hard coded into the bbFTP source.  I define a macro here to avoid 
  • TI05-delivery/trunk/src/python_ext/bbftpc.c

    r1248 r1259  
    1212#include <Python.h> 
    1313#include <stdio.h> 
     14#include <ndg_client.h> 
    1415 
    1516#include "util.h" 
     17 
     18#define STATE_NOTCONNECTED 0 
     19#define STATE_CONNECTED 1 
     20#define STATE_AUTH 2 
     21 
    1622 
    1723extern char **environ; 
     
    2127int treatcommand(char *cmd); 
    2228 
     29 
     30/** 
     31 * Global variables. 
     32 */ 
     33PyObject *authClientHandler = NULL; 
     34static int state = STATE_NOTCONNECTED; 
     35 
     36 
     37/** 
     38 * Make a callback bbftpc->python to handle authentication. 
     39 * 
     40 * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE 
     41 *     for storing an error message when returning -1. 
     42 * @return 0 on success, -1 on failure 
     43 */ 
     44int ndg_client_auth(char *logmessage) { 
     45  PyObject *ret_obj; 
     46  int mybool; 
     47 
     48  state = STATE_AUTH; 
     49  ret_obj = PyObject_CallMethod(authClientHandler, "authenticate", ""); 
     50  state = STATE_CONNECTED; 
     51 
     52  /** @todo exceptions of type delivery.server.AuthenticationFailure should be logged as 
     53   *      failure rather than error. 
     54   */ 
     55  if (ret_obj == NULL) { 
     56    ndg_pyerr_to_logmessage(logmessage, "ndg_client_auth"); 
     57    return -1; 
     58  } 
     59 
     60  Py_INCREF(ret_obj); 
     61  mybool = PyObject_IsTrue(ret_obj); 
     62  Py_DECREF(ret_obj); 
     63 
     64  /* Authentication is considered failed if the return value isn't True.  */ 
     65  if (!mybool) { 
     66    sprintf(logmessage, "ndg_client_auth: python authentication failed"); 
     67    return -1; 
     68  } 
     69 
     70  return 0; 
     71} 
     72 
     73 
     74 
     75/** 
     76 * Functions exported to python 
     77 */ 
    2378 
    2479/** 
     
    3186  PyObject *client_args, *item; 
    3287 
    33   if (!PyArg_ParseTuple(args, "O", &client_args)) { 
    34     return NULL; 
    35   } 
     88  if (state != STATE_NOTCONNECTED) { 
     89    PyErr_SetString(PyExc_RuntimeError, "Connection already in use.  Call bbftpc.close() first."); 
     90    return NULL; 
     91  } 
     92 
     93  if (!PyArg_ParseTuple(args, "OO", &authClientHandler, &client_args)) { 
     94    return NULL; 
     95  } 
     96  Py_INCREF(authClientHandler); 
    3697  Py_INCREF(client_args); 
     98 
     99  state = STATE_CONNECTED; 
    37100 
    38101  /* 
     
    88151static PyObject *bbftpc_close(PyObject *self, PyObject *args) { 
    89152 
    90    
    91  
    92153  // Check there are no arguments 
    93   if (!PyArg_ParseTuple(args, "", NULL)) { 
    94     return NULL; 
    95   } 
    96  
    97   bbftpc_final(); 
     154  if (!PyArg_ParseTuple(args, "")) { 
     155    return NULL; 
     156  } 
     157 
     158  if (state == STATE_AUTH) { 
     159    PyErr_SetString(PyExc_RuntimeError, "Cannot close connection during authentication"); 
     160    return NULL; 
     161  } 
     162 
     163  if (state == STATE_CONNECTED) { 
     164    bbftpc_final(); 
     165    state = STATE_NOTCONNECTED; 
     166    authClientHandler = NULL; 
     167  } 
    98168 
    99169  Py_RETURN_NONE; 
    100170} 
     171 
     172/** 
     173 * Execute a bbftpc command. 
     174 */ 
    101175 
    102176static PyObject *bbftpc_docommand(PyObject *self, PyObject *args) { 
     
    108182  } 
    109183 
     184  if (state == STATE_AUTH) { 
     185    PyErr_SetString(PyExc_RuntimeError, "Cannot do command during authentication"); 
     186    return NULL; 
     187  } 
     188 
     189  if (state == STATE_NOTCONNECTED) { 
     190    PyErr_SetString(PyExc_RuntimeError, "No Connection."); 
     191    return NULL; 
     192  } 
     193 
    110194  if ((ret = Py_BuildValue("i", treatcommand(cmd))) == NULL) { 
    111195    return NULL; 
    112196  } 
    113197 
     198  return ret; 
     199} 
     200 
     201static PyObject *bbftpc_isConnected(PyObject *self, PyObject *args) { 
     202   
     203  if (!PyArg_ParseTuple(args, "")) { 
     204    return NULL; 
     205  } 
     206 
     207  if (state == STATE_NOTCONNECTED) { 
     208    Py_RETURN_FALSE; 
     209  } 
     210  else { 
     211    Py_RETURN_TRUE; 
     212  } 
     213} 
     214 
     215/** 
     216 * Send a message to the server during authentication. 
     217 */ 
     218static PyObject *bbftpc_send(PyObject *self, PyObject *args) { 
     219  char *buffer, logmessage[1024]; 
     220  int len; 
     221 
     222  if (!PyArg_ParseTuple(args, "s#", &buffer, &len)) { 
     223    return NULL; 
     224  } 
     225 
     226  if (state != STATE_AUTH) { 
     227    PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpc callback"); 
     228    return NULL; 
     229  } 
     230 
     231  if (ndg_client_message_send(buffer, len+1, logmessage) == -1) { 
     232    PyErr_SetString(PyExc_IOError, logmessage); 
     233    return NULL; 
     234  } 
     235 
     236  Py_RETURN_NONE; 
     237} 
     238 
     239/** 
     240 * Receive a message from the server during authentication. 
     241 * 
     242 * @return the message as a string. 
     243 */ 
     244static PyObject *bbftpc_recv(PyObject *self, PyObject *args) { 
     245  char *buffer, logmessage[1024]; 
     246  int len; 
     247  PyObject *ret; 
     248 
     249  if (!PyArg_ParseTuple(args, "")) { 
     250    return NULL; 
     251  } 
     252 
     253  if (state != STATE_AUTH) { 
     254    PyErr_SetString(PyExc_RuntimeError, "Must be called within a bbftpc callback"); 
     255    return NULL; 
     256  } 
     257 
     258  if (ndg_client_message_recv(&buffer, &len, logmessage) == -1) { 
     259    PyErr_SetString(PyExc_IOError, logmessage); 
     260    free(buffer); 
     261    return NULL; 
     262  } 
     263 
     264  ret = Py_BuildValue("s#", buffer, len); 
     265  free(buffer); 
    114266  return ret; 
    115267} 
     
    134286    "@param cmd: The command string." 
    135287  }, 
     288  { 
     289    "isConnected", bbftpc_isConnected, METH_VARARGS, 
     290    "Predicate returning whether the client is connected." 
     291  }, 
     292  { 
     293    "send", bbftpc_send, METH_VARARGS, 
     294    "Send an authentication message." 
     295  }, 
     296  { 
     297    "recv", bbftpc_recv, METH_VARARGS, 
     298    "Receive an authentication message." 
     299  }, 
    136300  {NULL, NULL, 0, NULL} 
    137301}; 
  • TI05-delivery/trunk/src/python_ext/bbftpd.c

    r1195 r1259  
    1313#include <Python.h> 
    1414#include <ndg.h> 
    15  
     15#include "util.h" 
     16#include <structures.h> 
    1617 
    1718extern char **environ; 
     
    3334static PyObject *authzHandler = NULL; 
    3435 
    35 static void ndg_pyerr_to_logmessage(char *logmessage, char *prefix); 
    36  
    3736/*--------------------------------------------------------------------------------------------------- 
    3837 * The following functions interact with bbftpd_private_user.  They are placed here to separate 
     
    4140 */ 
    4241 
    43 /** 
    44  * Copy the python exception message to a bbftp logmessage. 
    45  * 
    46  * If the python error indicator is set it will be cleared. 
    47  * If the python error indicator is not set the empty string will be copied to \a logmessage. 
    48  * The exception message is truncated if it exceeds \c NDG_MAX_LOGMESSAGE. 
    49  * 
    50  * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE 
    51  *     for storing an error message when returning -1. 
    52  * @param prefix a string to be prefixed to the logmessage. 
    53  */ 
    54 static void ndg_pyerr_to_logmessage(char *logmessage, char *prefix) { 
    55   PyObject *ptype, *pvalue, *ptraceback, *obj; 
    56   char *exname, *exvalue; 
    57  
    58   PyErr_Fetch(&ptype, &pvalue, &ptraceback); 
    59    
    60   if ((obj = PyObject_GetAttrString(ptype, "__name__")) == NULL) goto error; 
    61   exname = PyString_AsString(obj); Py_DECREF(obj); 
    62   if (exname == NULL) goto error; 
    63  
    64   if ((obj = PyObject_Str(pvalue)) == NULL) goto error; 
    65   exvalue = PyString_AsString(obj); Py_DECREF(obj); 
    66   if (exvalue == NULL) goto error; 
    67  
    68   snprintf(logmessage, NDG_MAX_LOGMESSAGE, "%s: %s: %s", prefix, exname, exvalue); 
    69   return; 
    70    
    71  error: 
    72   sprintf("ndg_pyerr_to_logmessage: internal python error", logmessage); 
    73   return; 
    74 } 
    7542 
    7643/** 
  • TI05-delivery/trunk/src/python_ext/util.c

    r1188 r1259  
    7575 
    7676 
     77/** 
     78 * Copy the python exception message to a bbftp logmessage. 
     79 * 
     80 * If the python error indicator is set it will be cleared. 
     81 * If the python error indicator is not set the empty string will be copied to \a logmessage. 
     82 * The exception message is truncated if it exceeds \c NDG_MAX_LOGMESSAGE. 
     83 * 
     84 * @param logmessage a pointer to a buffer of length \c NDG_MAX_LOGMESSAGE 
     85 *     for storing an error message when returning -1. 
     86 * @param prefix a string to be prefixed to the logmessage. 
     87 */ 
     88void ndg_pyerr_to_logmessage(char *logmessage, char *prefix) { 
     89  PyObject *ptype, *pvalue, *ptraceback, *obj; 
     90  char *exname, *exvalue; 
     91 
     92  PyErr_Fetch(&ptype, &pvalue, &ptraceback); 
     93   
     94  if ((obj = PyObject_GetAttrString(ptype, "__name__")) == NULL) goto error; 
     95  exname = PyString_AsString(obj); Py_DECREF(obj); 
     96  if (exname == NULL) goto error; 
     97 
     98  if ((obj = PyObject_Str(pvalue)) == NULL) goto error; 
     99  exvalue = PyString_AsString(obj); Py_DECREF(obj); 
     100  if (exvalue == NULL) goto error; 
     101 
     102  snprintf(logmessage, NDG_MAX_LOGMESSAGE, "%s: %s: %s", prefix, exname, exvalue); 
     103  return; 
     104   
     105 error: 
     106  sprintf("ndg_pyerr_to_logmessage: internal python error", logmessage); 
     107  return; 
     108} 
  • TI05-delivery/trunk/src/python_ext/util.h

    r1188 r1259  
    99 * 
    1010 */ 
     11 
     12#include <Python.h> 
     13 
     14#define NDG_MAX_LOGMESSAGE 1024 
    1115 
    1216#define TRUE 1 
     
    2428int ndg_argv_add(struct ndg_argv *argv_s, char *arg); 
    2529 
     30void ndg_pyerr_to_logmessage(char *logmessage, char *prefix); 
     31 
  • TI05-delivery/trunk/test/runclient.py

    r1248 r1259  
    66""" 
    77 
    8 import os, sys 
     8import os, sys, time 
    99from glob import glob 
    1010 
    1111HOME = os.path.abspath(os.getenv('NDG_DELIVERY_HOME', os.curdir)) 
    1212BUILDDIR = glob('%s/build/lib.*' % HOME)[0] 
     13VERSION = open('%s/VERSION' % HOME).read() 
     14NDG_MESSAGE_LEN = 256 
     15 
     16NDG_HANDSHAKE = "NDG-Delivery-server %s" % VERSION 
     17 
     18 
    1319sys.path.append(BUILDDIR) 
    1420 
    1521import delivery.bbftpc as BC 
     22 
     23 
     24class AuthClientHandler(object): 
     25    def __init__(self, privatestr=""): 
     26        self.privatestr = privatestr 
     27 
     28    def authenticate(self): 
     29        print >>sys.stderr, "Waiting 20s for gdb connect: pid=%d" % os.getpid(), 
     30        time.sleep(20) 
     31        print >>sys.stderr, "continueing" 
     32 
     33        BC.send(NDG_HANDSHAKE) 
     34        resp = BC.recv() 
     35 
     36        BC.send(self.privatestr) 
     37 
     38        return True 
     39 
    1640 
    1741# Extract the command (-e) since bbftpc doesn't use it any more 
     
    2852    args = args[:ei] + args[ei+2:] 
    2953 
    30 BC.connect(args) 
     54try: 
     55    i = args.index('-P') 
     56except ValueError: 
     57    privatestr = "" 
     58    pass 
     59else: 
     60    privatestr = args[i+1] 
     61    args = args[:i] + args[i+2:] 
     62 
     63ach = AuthClientHandler(privatestr) 
     64 
     65BC.connect(ach, args) 
    3166for cmd in cmds: 
    3267    BC.docommand(cmd) 
Note: See TracChangeset for help on using the changeset viewer.