diff options
| author | 2009-11-22 15:04:30 +0100 | |
|---|---|---|
| committer | 2009-11-22 15:04:30 +0100 | |
| commit | 7579e0750c7bd81c916012e2842c8a96ad8fa414 (patch) | |
| tree | 2c0f0b8b561182596b2fb38786efcc27ea635872 /module/remote | |
| parent | indentation fix, 3nd try.. (diff) | |
| download | pyload-7579e0750c7bd81c916012e2842c8a96ad8fa414.tar.xz | |
secure xmlrpc
Diffstat (limited to 'module/remote')
| -rw-r--r-- | module/remote/SecureXMLRPCServer.py | 103 | ||||
| -rw-r--r-- | module/remote/SocketServer.py | 84 | 
2 files changed, 103 insertions, 84 deletions
| diff --git a/module/remote/SecureXMLRPCServer.py b/module/remote/SecureXMLRPCServer.py new file mode 100644 index 000000000..fb666b4ab --- /dev/null +++ b/module/remote/SecureXMLRPCServer.py @@ -0,0 +1,103 @@ +# Source: http://sources.gentoo.org/viewcvs.py/gimli/server/SecureXMLRPCServer.py?view=markup +#         which seems to be based on http://www.sabren.net/code/python/SecureXMLRPCServer.py +# +# Changes: +# 	2007-01-06 Christian Hoffmann <ch@hoffie.info> +# 		* Bugfix: replaced getattr by hasattr in the conditional +# 		  (lead to an error otherwise) +# 		* SecureXMLRPCServer: added self.instance = None, otherwise a "wrong" +# 		  exception is raised when calling unknown methods via xmlrpc +# 		* Added HTTP Basic authentication support +#  +# Modified for the Sceradon project +# +# This code is in the public domain +# and is provided AS-IS WITH NO WARRANTY WHATSOEVER. +# $Id: SecureXMLRPCServer.py 5 2007-01-06 17:54:13Z hoffie $ + +from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +from OpenSSL import SSL +import SocketServer +import socket +import base64 + +class SecureSocketServer(SocketServer.TCPServer, SocketServer.ThreadingMixIn): +	def __init__(self, addr, cert, key, requestHandler, verify_cert_func=None): +		SocketServer.TCPServer.__init__(self, addr, requestHandler) +		ctx = SSL.Context(SSL.SSLv23_METHOD) +		if not verify_cert_func and hasattr(self, 'verify_client_cert'): +			verify_cert_func = getattr(self, 'verify_client_cert') +		if verify_cert_func: +			ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cert_func) +		ctx.use_privatekey_file(key) +		ctx.use_certificate_file(cert) +		 +		tmpConnection = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) +		self.socket = SecureSocketConnection(tmpConnection) +		 +		self.server_bind() +		self.server_activate() + +	def finish_request(self, request, client_address): +		"""Finish one request by instantiating RequestHandlerClass.""" +		self.RequestHandlerClass(request, client_address, self) + + +class SecureXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): +	def __init__(self, request, client_address, server, client_digest=None): +		self.authMap = server.getAuthenticationMap() +		SimpleXMLRPCRequestHandler.__init__(self, request, client_address, server) +		self.client_digest = client_digest +	 +	def setup(self): +		self.connection = self.request +		self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) +		self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) +	 +	def do_POST(self): +		# authentication +		if self.authMap != None: # explicit None! +			if self.headers.has_key('authorization') and self.headers['authorization'].startswith('Basic '): +				authenticationString = base64.b64decode(self.headers['authorization'].split(' ')[1]) +				if authenticationString.find(':') != -1: +					username, password = authenticationString.split(':', 1) +					if self.authMap.has_key(username) and self.verifyPassword(username, password): +						return SimpleXMLRPCRequestHandler.do_POST(self) +			self.send_response(401) +			self.end_headers() +			return False +		return SimpleXMLRPCRequestHandler.do_POST(self) +	 +	def verifyPassword(self, username, givenPassword): +		return self.authMap[username] == givenPassword + + +class SecureXMLRPCServer(SecureSocketServer, SimpleXMLRPCServer): +	def __init__(self, address, cert, key, authenticationMap = None, handler=SecureXMLRPCRequestHandler, verify_cert_func=None): +		self.logRequests = False +		SecureSocketServer.__init__(self, address, cert, key, handler, verify_cert_func) +		# This comes from SimpleXMLRPCServer.__init__()->SimpleXMLRPCDispatcher.__init__() +		self.funcs = {} +		self.instance = None +		self.authenticationMap = authenticationMap +	 +	def getAuthenticationMap(self): +		return self.authenticationMap + + +class SecureSocketConnection: +	def __init__(self, connection): +		self.__dict__["connection"] = connection +	 +	def __getattr__(self, name): +		return getattr(self.__dict__["connection"], name) +	 +	def __setattr__(self, name, value): +		setattr(self.__dict__["connection"], name, value) +	 +	def shutdown(self, how=1): +		self.__dict__["connection"].shutdown() +	 +	def accept(self): +		connection, address = self.__dict__["connection"].accept() +		return (SecureSocketConnection(connection), address) diff --git a/module/remote/SocketServer.py b/module/remote/SocketServer.py deleted file mode 100644 index 2edd1d9f3..000000000 --- a/module/remote/SocketServer.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -authored by:  RaNaN - -This modul class handels all incoming and outgoing data between server and gui - -""" -import asynchat -import asyncore -import socket -import threading -import time - -from RequestHandler import RequestHandler - - -class ServerThread(threading.Thread): -    def __init__(self, pycore): -        threading.Thread.__init__(self) -        self.setDaemon(True) -        self.server = MainServerSocket(int(pycore.config['remote']['port']), pycore) - -    def run(self): -        asyncore.loop() -        print "loop closed" - -    def sockets(self): -        """returns all connected sockets in a list""" -        sockets = [] -        for value in asyncore.socket_map.values(): -            if SecondaryServerSocket == value.__class__: -                sockets.append(value) - -        return sockets - -    def push_all(self, obj): -        """push obj to all sockets""" -        for socket in self.sockets(): -            socket.push_obj(obj) - - -class MainServerSocket(asyncore.dispatcher): -    def __init__(self, port, pycore): -        asyncore.dispatcher.__init__(self) -        pycore.logger.info('initing Remote-Server') -        self.pycore = pycore -        try: -            self.create_socket(socket.AF_INET, socket.SOCK_STREAM) -            self.bind(('', port)) -            self.listen(5) -        except: -            raise Exception("Can't create socket") -    def handle_accept(self): -        newSocket, address = self.accept() -        self.pycore.logger.info("Connected from " + str(address)) -        SecondaryServerSocket(newSocket, self.pycore) -    def handle_close(self): -        print "going to close" -        self.close() - - -class SecondaryServerSocket(asynchat.async_chat): -    def __init__(self, socket, pycore): -        asynchat.async_chat.__init__(self, socket) -        self.pycore = pycore -        self.handler = RequestHandler(pycore) -        self.set_terminator('\n') -        self.data = "" -    def collect_incoming_data(self, data): -        self.data += data -    def found_terminator(self): -        time.sleep(0.2) # if response is received to fast client gets an error O_o ?!?!? -        rep = self.handler.proceed(self.data) -        self.push(rep) -        self.data = "" -        #having fun with the data -    def handle_close(self): -        self.pycore.logger.info("Disconnected from "+ str(self.getpeername())) -        self.close() -    def push_obj(self, obj): -        obj = self.handler.encrypt(obj) -        self.push(obj) | 
