From 86dd1b0ef4cfb2c4df5f3610a3092d1ac37d85f8 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Tue, 19 Jan 2010 17:49:32 +0100 Subject: [PATCH] Manage SSL (HTTPS) connections. --- TODO | 3 ++- radicale.py | 42 +++++++++++++++++++++++++++++------------- radicale/__init__.py | 21 +++++++++++++++++++-- radicale/config.py | 8 ++++---- 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/TODO b/TODO index 9a3564c..0e78068 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,8 @@ 0.2 === -* SSL connections and authentications +* [DONE] SSL connections +* Authentications * [DONE] Daemon mode * [DONE] User configuration diff --git a/radicale.py b/radicale.py index 1be60c5..ccc5e6e 100755 --- a/radicale.py +++ b/radicale.py @@ -36,32 +36,48 @@ import optparse import radicale +# Get command-line options parser = optparse.OptionParser() parser.add_option( "-d", "--daemon", action="store_true", default=radicale.config.getboolean("server", "daemon"), help="launch as daemon") parser.add_option( - "-n", "--name", - default=radicale.config.get("server", "name"), - help="set server name") + "-H", "--host", + default=radicale.config.get("server", "host"), + help="set server hostname") parser.add_option( - "-p", "--port", + "-p", "--port", type="int", default=radicale.config.getint("server", "port"), help="set server port") parser.add_option( - "-P", "--protocol", - default=radicale.config.get("server", "protocol"), - help="set server protocol") + "-s", "--ssl", action="store_true", + default=radicale.config.getboolean("server", "ssl"), + help="use SSL connection") +parser.add_option( + "-k", "--key", + default=radicale.config.get("server", "key"), + help="private key file ") +parser.add_option( + "-c", "--certificate", + default=radicale.config.get("server", "certificate"), + help="certificate file ") options, args = parser.parse_args() +# Update radicale configuration according to options +for option in parser.option_list: + key = option.dest + if key: + value = getattr(options, key) + radicale.config.set("server", key, value) + +# Fork if Radicale is launched as daemon if options.daemon: if os.fork(): sys.exit() sys.stdout = sys.stderr = open(os.devnull, "w") -if options.protocol == "http": - server = radicale.server.HTTPServer( - (options.name, options.port), radicale.CalendarHandler) - server.serve_forever() -else: - raise StandardError("%s: unsupported protocol" % options.protocol) + +# Launch calendar server +server_class = radicale.HTTPSServer if options.ssl else radicale.HTTPServer +server = server_class((options.host, options.port), radicale.CalendarHTTPHandler) +server.serve_forever() diff --git a/radicale/__init__.py b/radicale/__init__.py index b16cc94..5564b18 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -20,7 +20,7 @@ # TODO: Manage errors (see xmlutils) -import posixpath +import socket try: from http import client, server except ImportError: @@ -29,7 +29,24 @@ except ImportError: from radicale import config, support, xmlutils -class CalendarHandler(server.BaseHTTPRequestHandler): +HTTPServer = server.HTTPServer + +class HTTPSServer(HTTPServer): + def __init__(self, address, handler): + # Fails with Python 2.5, import if needed + import ssl + + super(HTTPSServer, self).__init__(address, handler) + self.socket = ssl.wrap_socket( + socket.socket(self.address_family, self.socket_type), + server_side=True, + certfile=config.get("server", "certificate"), + keyfile=config.get("server", "key"), + ssl_version=ssl.PROTOCOL_SSLv23) + self.server_bind() + self.server_activate() + +class CalendarHTTPHandler(server.BaseHTTPRequestHandler): """HTTP requests handler for calendars.""" def _parse_path(self): path = self.path.strip("/").split("/") diff --git a/radicale/config.py b/radicale/config.py index b2cb452..c038966 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -43,12 +43,12 @@ items = _config.items _initial = { "server": { - "protocol": "http", - "name": "", + "host": "", "port": "5232", "daemon": "False", - #"certificate": "/etc/apache2/ssl/server.crt", - #"privatekey": "/etc/apache2/ssl/server.key", + "ssl": "False", + "certificate": "/etc/apache2/ssl/server.crt", + "key": "/etc/apache2/ssl/server.key", #"log": "/var/www/radicale/server.log", }, "encoding": {