summaryrefslogtreecommitdiffstats
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
parentindentation fix, 3nd try.. (diff)
downloadpyload-7579e0750c7bd81c916012e2842c8a96ad8fa414.tar.xz
secure xmlrpc
-rw-r--r--module/file_list.py2
-rw-r--r--module/remote/SecureXMLRPCServer.py103
-rw-r--r--module/remote/SocketServer.py84
-rw-r--r--module/thread_list.py2
-rwxr-xr-xpyLoadCore.py4
5 files changed, 107 insertions, 88 deletions
diff --git a/module/file_list.py b/module/file_list.py
index c55ce5bc6..1701b801b 100644
--- a/module/file_list.py
+++ b/module/file_list.py
@@ -113,7 +113,7 @@ class File_List(object):
output = open('links.pkl', 'wb')
cPickle.dump(self.data, output, -1)
- self.inform_client()
+ #self.inform_client()
self.lock.release()
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)
diff --git a/module/thread_list.py b/module/thread_list.py
index d4f2dac97..da13afba6 100644
--- a/module/thread_list.py
+++ b/module/thread_list.py
@@ -60,7 +60,7 @@ class Thread_List(object):
def get_job(self):
"""return job if suitable, otherwise send thread idle"""
- if not self.parent.is_dltime() or self.pause or self.reconnecting or not self.list.files: #conditions when threads dont download
+ if not self.parent.is_time_download() or self.pause or self.reconnecting or not self.list.files: #conditions when threads dont download
return None
self.init_reconnect()
diff --git a/pyLoadCore.py b/pyLoadCore.py
index 51a95169e..920278fe0 100755
--- a/pyLoadCore.py
+++ b/pyLoadCore.py
@@ -49,7 +49,7 @@ except ImportError:
from module.file_list import File_List
from module.thread_list import Thread_List
#from module.web.WebServer import WebServer
-from SimpleXMLRPCServer import SimpleXMLRPCServer as Server
+from module.remote.SecureXMLRPCServer import SecureXMLRPCServer
from module.network.Request import Request
import thread
@@ -253,7 +253,7 @@ class Core(object):
def init_server(self):
try:
- self.server = Server(("", 1337), allow_none=True)
+ self.server = SecureXMLRPCServer(("", 1337), "ssl.crt", "ssl.key", {"testuser":"testpw"})
self.server.register_function(self.status_downloads)
self.server.register_function(self.status_server)
self.server.register_function(self.kill)