summaryrefslogtreecommitdiffstats
path: root/module/remote
diff options
context:
space:
mode:
authorGravatar mkaay <mkaay@mkaay.de> 2009-11-22 15:04:30 +0100
committerGravatar mkaay <mkaay@mkaay.de> 2009-11-22 15:04:30 +0100
commit7579e0750c7bd81c916012e2842c8a96ad8fa414 (patch)
tree2c0f0b8b561182596b2fb38786efcc27ea635872 /module/remote
parentindentation fix, 3nd try.. (diff)
downloadpyload-7579e0750c7bd81c916012e2842c8a96ad8fa414.tar.xz
secure xmlrpc
Diffstat (limited to 'module/remote')
-rw-r--r--module/remote/SecureXMLRPCServer.py103
-rw-r--r--module/remote/SocketServer.py84
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)