summaryrefslogtreecommitdiffstats
path: root/module/remote
diff options
context:
space:
mode:
Diffstat (limited to 'module/remote')
-rw-r--r--module/remote/ClientHandler.py24
-rw-r--r--module/remote/ClientSocket.py63
-rw-r--r--module/remote/RequestHandler.py64
-rw-r--r--module/remote/RequestObject.py18
-rw-r--r--module/remote/SecureXMLRPCServer.py130
-rw-r--r--module/remote/SocketServer.py84
6 files changed, 130 insertions, 253 deletions
diff --git a/module/remote/ClientHandler.py b/module/remote/ClientHandler.py
deleted file mode 100644
index 9653db9ae..000000000
--- a/module/remote/ClientHandler.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-authored by: RaNaN
-
-this module handels the incoming requests
-
-"""
-import hashlib
-
-from Crypto.Cipher import Blowfish
-from RequestHandler import RequestHandler
-
-class ClientHandler(RequestHandler):
- def __init__(self, client, pw):
- self.client = client
- key = hashlib.sha256(pw)
- self.bf = Blowfish.new(key.hexdigest(), Blowfish.MODE_ECB)
-
- def proceed(self, data):
- obj = self.decrypt(data)
-
- self.client.data_arrived(obj) \ No newline at end of file
diff --git a/module/remote/ClientSocket.py b/module/remote/ClientSocket.py
deleted file mode 100644
index 0e6a5ed53..000000000
--- a/module/remote/ClientSocket.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-authored by: RaNaN
-
-socket for connecting to the core's server
-
-"""
-import asynchat
-import asyncore
-import socket
-import threading
-
-from ClientHandler import ClientHandler
-from RequestObject import RequestObject
-
-class SocketThread(threading.Thread):
- def __init__(self, adress, port, pw, client):
- threading.Thread.__init__(self)
- self.setDaemon(True)
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.connect((adress, port))
- self.socket = ClientSocket(sock, pw, client)
- self.start()
-
- def run(self):
- asyncore.loop()
- print "loop closed"
-
- def push_exec(self, function, args=[]):
- obj = RequestObject()
- obj.command = "exec"
- obj.function = function
- obj.args = args
- self.push(obj)
-
- def push(self, obj):
- self.socket.push_obj(obj)
-
-
-class ClientSocket(asynchat.async_chat):
- def __init__(self, sock, pw, client):
- asynchat.async_chat.__init__(self, sock)
- self.data = ""
- self.handler = ClientHandler(client, pw)
- self.set_terminator("\n")
- #self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
-
- def handle_close(self):
- print "Disconnected from", self.getpeername()
- self.close()
-
- def collect_incoming_data(self, data):
- self.data += data
-
- def found_terminator(self):
- self.handler.proceed(self.data)
- self.data = ""
-
- def push_obj(self, obj):
- string = self.handler.encrypt(obj)
- self.push(string) \ No newline at end of file
diff --git a/module/remote/RequestHandler.py b/module/remote/RequestHandler.py
deleted file mode 100644
index a879d2297..000000000
--- a/module/remote/RequestHandler.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-authored by: RaNaN
-
-this module handels the incoming requests
-
-"""
-
-import base64
-import hashlib
-import random
-import string
-
-import cPickle
-from Crypto.Cipher import Blowfish
-from RequestObject import RequestObject
-
-
-class RequestHandler:
- def __init__(self, core):
- self.core = core
- key = hashlib.sha256(core.config['remote']['password'])
- self.bf = Blowfish.new(key.hexdigest(), Blowfish.MODE_ECB)
-
- def proceed(self, data):
- obj = self.decrypt(data)
-
- if obj.command == "exec":
- func = getattr(self.core, obj.function)
- obj.data = func( * obj.args)
- else:
- obj.data = "error happend"
-
- return self.encrypt(obj)
-
-
- def decrypt(self, dec_str):
- try:
- dec_str = base64.standard_b64decode(dec_str)
- dec_str = self.bf.decrypt(dec_str)
-
- dec_str = dec_str[:-(int(dec_str[-1], 16) + 1)]
- obj = cPickle.loads(dec_str)
- except:
- obj = RequestObject()
-
- return obj
-
- def encrypt(self, obj):
- enc_str = cPickle.dumps(obj, 1)
- padding = len(enc_str) % 16
- padding = 16 - padding
-
- p_str = ""
- for i in range(padding - 1):
- p_str += random.choice(string.letters + string.digits + string.punctuation)
- p_str += hex(len(p_str)).replace("0x", "")
- enc_str += p_str
-
- enc_str = self.bf.encrypt(enc_str)
- enc_str = base64.standard_b64encode(enc_str)
- return enc_str + "\n"
diff --git a/module/remote/RequestObject.py b/module/remote/RequestObject.py
deleted file mode 100644
index 54ea837a6..000000000
--- a/module/remote/RequestObject.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-authored by: RaNaN
-
-represents the object for interaction
-
-"""
-class RequestObject(object):
- def __init__(self):
- self.version = 0
- self.sender = "ip"
- self.status = {}
- self.command = None
- self.function = ""
- self.args = []
- self.data = None
diff --git a/module/remote/SecureXMLRPCServer.py b/module/remote/SecureXMLRPCServer.py
new file mode 100644
index 000000000..7a60f6c90
--- /dev/null
+++ b/module/remote/SecureXMLRPCServer.py
@@ -0,0 +1,130 @@
+# 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
+import SocketServer
+import socket
+import base64
+
+
+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)
+
+class SecureSocketServer(SocketServer.TCPServer, SocketServer.ThreadingMixIn):
+ def __init__(self, addr, cert, key, requestHandler, verify_cert_func=None):
+ SSL = __import__("OpenSSL", globals(), locals(), "SSL", -1).SSL
+ 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)
+
+#######################################
+########### Request Handler ###########
+#######################################
+
+class AuthXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+ def __init__(self, request, client_address, server):
+ self.authMap = server.getAuthenticationMap()
+ SimpleXMLRPCRequestHandler.__init__(self, request, client_address, server)
+
+ 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 SecureXMLRPCRequestHandler(AuthXMLRPCRequestHandler):
+ 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
+
+#####################################
+########### XMLRPC Server ###########
+#####################################
+
+class AuthXMLRPCServer(SimpleXMLRPCServer):
+ def __init__(self, address, authenticationMap = None, handler=AuthXMLRPCRequestHandler):
+ SimpleXMLRPCServer.__init__(self, address, requestHandler=handler)
+ self.logRequests = False
+ self._send_traceback_header = False
+ self.encoding = "utf-8"
+ self.allow_none = True
+ self.authenticationMap = authenticationMap
+
+ def getAuthenticationMap(self):
+ return self.authenticationMap
+
+class SecureXMLRPCServer(AuthXMLRPCServer, SecureSocketServer):
+ def __init__(self, address, cert, key, authenticationMap = None, handler=SecureXMLRPCRequestHandler, verify_cert_func=None):
+ self.logRequests = False
+ self._send_traceback_header = False
+ self.encoding = "utf-8"
+ self.allow_none = True
+ 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
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)