diff --git a/keylime/registrar_common.py b/keylime/registrar_common.py index fb37e5b..6b550d0 100644 --- a/keylime/registrar_common.py +++ b/keylime/registrar_common.py @@ -2,7 +2,9 @@ import base64 import http.server import ipaddress import os +import select import signal +import ssl import sys import threading from http.server import BaseHTTPRequestHandler, HTTPServer @@ -30,6 +32,24 @@ except SQLAlchemyError as err: class ProtectedHandler(BaseHTTPRequestHandler, SessionManager): + def handle(self) -> None: + """ Need to perform SSL handshake here, as do_handshake_on_connect=False for non-blocking SSL socket """ + while True: + try: + self.request.do_handshake() + break + except ssl.SSLWantReadError: + select.select([self.request], [], []) + except ssl.SSLWantWriteError: + select.select([], [self.request], []) + except ssl.SSLError as e: + logger.error("SSL connection error: %s", e) + return + except Exception as e: + logger.error("General communication failure: %s", e) + return + BaseHTTPRequestHandler.handle(self) + def do_HEAD(self): """HEAD not supported""" web_util.echo_json_response(self, 405, "HEAD not supported") @@ -490,7 +510,7 @@ def start(host, tlsport, port): protected_server = RegistrarServer((host, tlsport), ProtectedHandler) context = web_util.init_mtls("registrar", logger=logger) if context is not None: - protected_server.socket = context.wrap_socket(protected_server.socket, server_side=True) + protected_server.socket = context.wrap_socket(protected_server.socket, server_side=True, do_handshake_on_connect=False) thread_protected_server = threading.Thread(target=protected_server.serve_forever) # Set up the unprotected registrar server