From 97d361c4963fe56bfdc53ffe110825dc08e525c6 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Mon, 12 Aug 2013 15:03:35 +0000 Subject: Add HTTPS support Add optional HTTPS support, including client certificate support. Configured using command line options. --- diff --git a/journal2webdav b/journal2webdav index 20f5404..9db5042 100755 --- a/journal2webdav +++ b/journal2webdav @@ -21,6 +21,7 @@ import gzip import logging import optparse import os +import ssl import sys import time import urllib @@ -620,9 +621,30 @@ def main(): help='only output warnings and errors') parser.add_option('-v', '--verbose', action='store_true', default=True, help='override a previous -q or --quiet option') + parser.add_option('--private-key', metavar='FILE', + help='private key file for TLS (enables TLS)') + parser.add_option('--certificate', metavar='FILE', + help='X.509 certificate file for TLS (required for TLS)') + parser.add_option('--tls-protocol', metavar='MODE', default='TLSv1', + choices=('SSLv23', 'TLSv1'), + help='TLS protocol to use (affects compatibility with' + ' clients) [choices: %choices, default: %default]') + parser.add_option('--ca-certificates', metavar='FILE', + help='X.509 CA certificates to verify client' + ' certificates against (required when requesting client' + ' certificates)') + parser.add_option('--client-certificate', metavar='MODE', default='none', + choices=('none', 'optional', 'required'), + help='whether to request and/or require a client' + ' certificate [choices: %choices, default: %default]') options, args = parser.parse_args() if args: parser.error('extra arguments passed') + if options.private_key and not options.certificate: + parser.error('Need server certificate in TLS mode') + if options.client_certificate != 'none' and not options.ca_certificates: + parser.error('Need CA certificates when requesting client' + ' certificates') root_query = eval(options.root_query) @@ -637,7 +659,10 @@ def main(): emulated_fs = fsemulation.FSEmulation(root_query) handler = RequestHandler - base_url = 'http://%s:%d' % (options.host, options.port) + if options.private_key: + base_url = 'https://%s:%d' % (options.host, options.port) + else: + base_url = 'http://%s:%d' % (options.host, options.port) handler.IFACE_CLASS = JournalHandler(emulated_fs, base_url, options.debug) handler.DO_AUTH = False handler.IFACE_CLASS.mimecheck = True # pylint: disable=W0201 @@ -647,8 +672,15 @@ def main(): noauth=True, chunked_http_response=True) runner = ThreadedHTTPServer((options.host, options.port), handler) - - log.info('Server running.') + if options.private_key: + cert_reqs = getattr(ssl, 'CERT_' + options.client_certificate.upper()) + ssl_version = getattr(ssl, 'PROTOCOL_' + options.tls_protocol) + runner.socket = ssl.wrap_socket( + runner.socket, server_side=True, certfile=options.certificate, + keyfile=options.private_key, ssl_version=ssl_version, + ca_certs=options.ca_certificates, cert_reqs=cert_reqs) + + log.info('Server running on %s', base_url) try: runner.serve_forever() except KeyboardInterrupt: -- cgit v0.9.1