+++ /dev/null
-"""RPC Server module."""\r
-\r
-import sys\r
-import socket\r
-import pickle\r
-from fnmatch import fnmatch\r
-from repr import repr\r
-\r
-\r
-# Default verbosity (0 = silent, 1 = print connections, 2 = print requests too)\r
-VERBOSE = 1\r
-\r
-\r
-class Server:\r
-\r
- """RPC Server class. Derive a class to implement a particular service."""\r
-\r
- def __init__(self, address, verbose = VERBOSE):\r
- if type(address) == type(0):\r
- address = ('', address)\r
- self._address = address\r
- self._verbose = verbose\r
- self._socket = None\r
- self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r
- self._socket.bind(address)\r
- self._socket.listen(1)\r
- self._listening = 1\r
-\r
- def _setverbose(self, verbose):\r
- self._verbose = verbose\r
-\r
- def __del__(self):\r
- self._close()\r
-\r
- def _close(self):\r
- self._listening = 0\r
- if self._socket:\r
- self._socket.close()\r
- self._socket = None\r
-\r
- def _serverloop(self):\r
- while self._listening:\r
- self._serve()\r
-\r
- def _serve(self):\r
- if self._verbose: print "Wait for connection ..."\r
- conn, address = self._socket.accept()\r
- if self._verbose: print "Accepted connection from %s" % repr(address)\r
- if not self._verify(conn, address):\r
- print "*** Connection from %s refused" % repr(address)\r
- conn.close()\r
- return\r
- rf = conn.makefile('r')\r
- wf = conn.makefile('w')\r
- ok = 1\r
- while ok:\r
- wf.flush()\r
- if self._verbose > 1: print "Wait for next request ..."\r
- ok = self._dorequest(rf, wf)\r
-\r
- _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*']\r
-\r
- def _verify(self, conn, address):\r
- host, port = address\r
- for pat in self._valid:\r
- if fnmatch(host, pat): return 1\r
- return 0\r
-\r
- def _dorequest(self, rf, wf):\r
- rp = pickle.Unpickler(rf)\r
- try:\r
- request = rp.load()\r
- except EOFError:\r
- return 0\r
- if self._verbose > 1: print "Got request: %s" % repr(request)\r
- try:\r
- methodname, args, id = request\r
- if '.' in methodname:\r
- reply = (None, self._special(methodname, args), id)\r
- elif methodname[0] == '_':\r
- raise NameError, "illegal method name %s" % repr(methodname)\r
- else:\r
- method = getattr(self, methodname)\r
- reply = (None, apply(method, args), id)\r
- except:\r
- reply = (sys.exc_type, sys.exc_value, id)\r
- if id < 0 and reply[:2] == (None, None):\r
- if self._verbose > 1: print "Suppress reply"\r
- return 1\r
- if self._verbose > 1: print "Send reply: %s" % repr(reply)\r
- wp = pickle.Pickler(wf)\r
- wp.dump(reply)\r
- return 1\r
-\r
- def _special(self, methodname, args):\r
- if methodname == '.methods':\r
- if not hasattr(self, '_methods'):\r
- self._methods = tuple(self._listmethods())\r
- return self._methods\r
- raise NameError, "unrecognized special method name %s" % repr(methodname)\r
-\r
- def _listmethods(self, cl=None):\r
- if not cl: cl = self.__class__\r
- names = cl.__dict__.keys()\r
- names = filter(lambda x: x[0] != '_', names)\r
- names.sort()\r
- for base in cl.__bases__:\r
- basenames = self._listmethods(base)\r
- basenames = filter(lambda x, names=names: x not in names, basenames)\r
- names[len(names):] = basenames\r
- return names\r
-\r
-\r
-from security import Security\r
-\r
-\r
-class SecureServer(Server, Security):\r
-\r
- def __init__(self, *args):\r
- apply(Server.__init__, (self,) + args)\r
- Security.__init__(self)\r
-\r
- def _verify(self, conn, address):\r
- import string\r
- challenge = self._generate_challenge()\r
- conn.send("%d\n" % challenge)\r
- response = ""\r
- while "\n" not in response and len(response) < 100:\r
- data = conn.recv(100)\r
- if not data:\r
- break\r
- response = response + data\r
- try:\r
- response = string.atol(string.strip(response))\r
- except string.atol_error:\r
- if self._verbose > 0:\r
- print "Invalid response syntax", repr(response)\r
- return 0\r
- if not self._compare_challenge_response(challenge, response):\r
- if self._verbose > 0:\r
- print "Invalid response value", repr(response)\r
- return 0\r
- if self._verbose > 1:\r
- print "Response matches challenge. Go ahead!"\r
- return 1\r