diff options
author | mkaay <mkaay@mkaay.de> | 2009-11-30 17:47:42 +0100 |
---|---|---|
committer | mkaay <mkaay@mkaay.de> | 2009-11-30 17:47:42 +0100 |
commit | f3c2e597ebb63094c43ec39acb67a23a1cc2c141 (patch) | |
tree | 07b4fbfe3f71045d765639e0fd08477efe8e65f1 | |
parent | Cleaned XMLRPC in Core (diff) | |
download | pyload-f3c2e597ebb63094c43ec39acb67a23a1cc2c141.tar.xz |
added xmlrpc auth without ssl
-rw-r--r-- | config | 2 | ||||
-rw-r--r-- | module/remote/SecureXMLRPCServer.py | 186 | ||||
-rwxr-xr-x | pyLoadCli.py | 8 | ||||
-rwxr-xr-x | pyLoadCore.py | 54 |
4 files changed, 140 insertions, 110 deletions
@@ -1,5 +1,5 @@ [remote] -port = 8080 +port = 7227 listenaddr = 0.0.0.0 username = admin password = pwhere diff --git a/module/remote/SecureXMLRPCServer.py b/module/remote/SecureXMLRPCServer.py index 158e44863..9dacd7b26 100644 --- a/module/remote/SecureXMLRPCServer.py +++ b/module/remote/SecureXMLRPCServer.py @@ -2,12 +2,12 @@ # 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 +# 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 # @@ -21,86 +21,110 @@ 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): - 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 __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) + 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(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 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 -class SecureXMLRPCServer(SecureSocketServer, SimpleXMLRPCServer): - 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 +##################################### +########### 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 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 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/pyLoadCli.py b/pyLoadCli.py index 2a03c8e59..2d38ab4ca 100755 --- a/pyLoadCli.py +++ b/pyLoadCli.py @@ -250,7 +250,11 @@ if __name__=='__main__': config = ConfigParser.SafeConfigParser() config.read('config') - server_url = "https://%s:%s@%s:%s/" % ( + ssl = "" + if config.get("ssl", "activated") == "True": + ssl = "s" + server_url = "http%s://%s:%s@%s:%s/" % ( + ssl, config.get("remote", "username"), config.get("remote", "password"), config.get("remote", "listenaddr"), @@ -260,7 +264,7 @@ if __name__=='__main__': if len(extraparams) == 1: server_url = sys.argv[1] else: - print "URL scheme: https://user:password@host:port/" + print "URL scheme: http[s]://user:password@host:port/" server_url = raw_input("URL: ") curses.wrapper(main) diff --git a/pyLoadCore.py b/pyLoadCore.py index add30126b..1f048c268 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -145,32 +145,54 @@ class Core(object): self.logger.info(_("Downloadtime: %s") % self.server_methods.is_time_download()) # debug only - self.server_methods.read_url_list(self.config['general']['link_file']) + self.read_url_list(self.config['general']['link_file']) while True: sleep(2) if self.do_kill: self.logger.info("pyLoad quits") exit() + + def read_url_list(self, url_list): + """read links from txt""" + txt = open(url_list, 'r') + new_links = 0 + links = txt.readlines() + for link in links: + if link != "\n": + self.file_list.collector.addLink(link) + new_links += 1 + + txt.close() + + self.file_list.save() + if new_links: + self.logger.info("Parsed link from %s: %i" % (url_list, new_links)) + + txt = open(url_list, 'w') + txt.write("") + txt.close() def init_server(self): try: server_addr = (self.config['remote']['listenaddr'], int(self.config['remote']['port'])) - usermap = { self.config['remote']['username']: self.config['remote']['password'] } + usermap = { self.config['remote']['username']: self.config['remote']['password']} + Server = __import__("module.remote.SecureXMLRPCServer", globals(), locals(), "SecureXMLRPCServer", -1) if self.config['ssl']['activated']: - Server = __import__("module.remote.SecureXMLRPCServer", globals(), locals(), "SecureXMLRPCServer", -1) self.server = Server.SecureXMLRPCServer(server_addr, self.config['ssl']['cert'], self.config['ssl']['key'], usermap) self.logger.info("Secure XMLRPC Server Started") else: - Server = __import__("SimpleXMLRPCServer") - self.server = Server.SimpleXMLRPCServer(server_addr) - self.logger.info("Normal XMLRPC Server Started") + self.server = Server.AuthXMLRPCServer(server_addr, usermap) + self.logger.info("Auth XMLRPC Server Started") self.server.register_instance(self.server_methods) thread.start_new_thread(self.server.serve_forever, ()) except Exception, e: self.logger.error("Failed starting socket server, CLI and GUI will not be available: %s" % str(e)) + if self.config['general']['debug_mode']: + import traceback + traceback.print_exc() def init_logger(self, level): @@ -375,26 +397,6 @@ class ServerMethods(): # for id in ids: # self.core.file_list.move(id, 1) # self.core.file_list.save() - - def read_url_list(self, url_list): - """read links from txt""" - txt = open(self.core.config['general']['link_file'], 'r') - new_links = 0 - links = txt.readlines() - for link in links: - if link != "\n": - self.core.file_list.collector.addLink(link) - new_links += 1 - - txt.close() - - self.core.file_list.save() - if new_links: - self.core.logger.info("Parsed link from %s: %i" % (self.core.config['general']['link_file'], new_links)) - - txt = open(self.core.config['general']['link_file'], 'w') - txt.write("") - txt.close() def is_time_download(self): start = self.core.config['downloadTime']['start'].split(":") |