From 991eeea9f8f13717fc1c57870d0b0f5fca2fd716 Mon Sep 17 00:00:00 2001 From: example Date: Sat, 30 Jul 2022 12:09:38 +0200 Subject: [PATCH] verify_mode ueber config setzbar, ssl context in funktion ausgelagert --- source/server/apistatusd.conf | 4 ++- source/server/apistatusd.py | 52 ++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/source/server/apistatusd.conf b/source/server/apistatusd.conf index 177f44a..601204d 100644 --- a/source/server/apistatusd.conf +++ b/source/server/apistatusd.conf @@ -19,13 +19,15 @@ key = ./certs/statusd-key.pem [client] cert = ./certs/statusclient-pub.pem +# possible values: true, false, may +required = true [api] api = ./api template = ./api_template [mastodon] -send = true +send = false host = localhost token = aaaaa-bbbbb-ccccc-ddddd-eeeee diff --git a/source/server/apistatusd.py b/source/server/apistatusd.py index 4fe1eda..f8e3355 100755 --- a/source/server/apistatusd.py +++ b/source/server/apistatusd.py @@ -50,6 +50,36 @@ def print_config(config): else: logging.debug(' {}: {}'.format(i, config[section][i])) +def create_ssl_context(config): + ''' + Creates the ssl context. + return: context object or None + ''' + context = None + requirement = None + required = config['client']['required'].lower() + if required == 'false': + requirement = ssl.CERT_NONE + elif required == 'may': + requirement = ssl.CERT_OPTIONAL + else: requirement = ssl.CERT_REQUIRED + try: + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.verify_mode = requirement + context.load_cert_chain(certfile=config['server']['cert'], + keyfile=config['server']['key']) + context.load_verify_locations(cafile=config['client']['cert']) + # ensure, compression is disabled (disabled by default anyway at the moment) + context.options |= ssl.OP_NO_COMPRESSION + context.options = ssl.PROTOCOL_TLS_SERVER + context.options = ssl.OP_CIPHER_SERVER_PREFERENCE + logging.debug('SSL context created') + except Exception as e: + logging.error('Failed to create SSL context') + logging.error('Error: {}'.format(e)) + return None + return context + def print_ciphers(cipherlist): ''' Prints the list of allowed ciphers. @@ -283,7 +313,8 @@ def main(): 'key': './certs/server.key' }, 'client': { - 'cert': './certs/client.crt' + 'cert': './certs/client.crt', + 'required': 'true' }, 'api': { 'api': './api', @@ -320,16 +351,11 @@ def main(): logging.error('Cert check failed\nExit') sys.exit(1) - context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - context.verify_mode = ssl.CERT_OPTIONAL - context.load_cert_chain(certfile=config['server']['cert'], - keyfile=config['server']['key']) - context.load_verify_locations(cafile=config['client']['cert']) - context.options = ssl.OP_CIPHER_SERVER_PREFERENCE - # ensure, compression is disabled (disabled by default anyway at the moment) - context.options |= ssl.OP_NO_COMPRESSION - logging.debug('SSL context created') - print_context(context) + # ssl context erstellen + context = create_ssl_context(config) + if context is not None: + print_context(context) + else: sys.exit(2) try: # tcp socket öffnen => MySocket @@ -347,7 +373,7 @@ def main(): except Exception as e: logging.error('Unable to bind and listen') logging.error('{}'.format(e)) - sys.exit(1) + sys.exit(3) # endlos auf verbindungen warten => ClientSocket while True: ClientSocket, ClientAddress = MySocket.accept() @@ -384,7 +410,7 @@ def main(): Connection.close() except KeyboardInterrupt: logging.info('Keyboard interrupt received') - sys.exit(1) + sys.exit(255) except Exception as e: logging.error('{}'.format(e)) finally: