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