Commit 9e03ff88 authored by Ales Mrazek's avatar Ales Mrazek

Merge branch 'networktocode-ssl' into ssl

parents 5534fc65 23119cb1
......@@ -36,6 +36,7 @@ class JcConfig:
"SERVER_SSL_CERT": "server.crt",
"SERVER_SSL_PRIVKEY": "server.key",
"DISABLE_SSL": False,
"CA_CERT": "ca.pem",
"DBG_DISABLE_CERTS": False
}
......
......@@ -48,6 +48,14 @@ ERRTAG_INVVALUE = "invalid-value"
ERRTAG_EXISTS = "data-exists"
def get_username(client_cert: SSLCertT, headers: OrderedDict) -> str:
if config.CFG.http["DISABLE_SSL"]:
return headers.get("x-ssl-client-cn")
else:
return CertHelpers.get_field(client_cert, "emailAddress")
class HttpRequestError(Exception):
pass
......@@ -351,7 +359,7 @@ class HttpHandlersImpl:
return http_resp
def get_api_running(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] api_get_running: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_running_data):]
......@@ -359,7 +367,7 @@ class HttpHandlersImpl:
return http_resp
def get_api_staging(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] api_get_staging: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_data):]
......@@ -367,7 +375,7 @@ class HttpHandlersImpl:
return http_resp
def get_api_op(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] get_op: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_ops):].rstrip("/")
......@@ -416,7 +424,7 @@ class HttpHandlersImpl:
def get_file(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
# Ordinary file on filesystem
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
url_path = headers[":path"].split("?")[0]
url_path_safe = "".join(filter(lambda c: c.isalpha() or c in "/-_.", url_path)).replace("..", "").strip("/")
file_path = os.path.join(config.CFG.http["DOC_ROOT"], url_path_safe)
......@@ -596,7 +604,7 @@ class HttpHandlersImpl:
return http_resp
def post_api(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] api_post: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_data):]
......@@ -677,7 +685,7 @@ class HttpHandlersImpl:
return http_resp
def put_api(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] api_put: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_data):]
......@@ -745,7 +753,7 @@ class HttpHandlersImpl:
return http_resp
def delete_api(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] api_delete: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_data):]
......@@ -753,7 +761,7 @@ class HttpHandlersImpl:
return http_resp
def post_api_op_call(self, headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
username = get_username(client_cert, headers)
info("[{}] invoke_op: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(config.CFG.api_root_ops):]
......
......@@ -57,17 +57,21 @@ class H2Protocol(asyncio.Protocol):
self.transport = transport
self.client_cert = transport.get_extra_info("peercert")
ssl_context = transport.get_extra_info("ssl_object")
if ssl.HAS_ALPN:
agreed_protocol = ssl_context.selected_alpn_protocol()
else:
agreed_protocol = ssl_context.selected_npn_protocol()
if agreed_protocol is None:
error("Connection error, client does not support HTTP/2")
self.transport.close()
else:
if config.CFG.http["DISABLE_SSL"]:
self.conn.initiate_connection()
else:
ssl_context = transport.get_extra_info("ssl_object")
if ssl.HAS_ALPN:
agreed_protocol = ssl_context.selected_alpn_protocol()
else:
agreed_protocol = ssl_context.selected_npn_protocol()
if agreed_protocol is None:
error("Connection error, client does not support HTTP/2")
self.transport.close()
else:
self.conn.initiate_connection()
def data_received(self, data: bytes):
events = self.conn.receive_data(data)
......@@ -272,21 +276,24 @@ class H2Protocol(asyncio.Protocol):
class RestServer:
def __init__(self):
# HTTP server init
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.options |= (ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION)
ssl_context.load_cert_chain(certfile=config.CFG.http["SERVER_SSL_CERT"], keyfile=config.CFG.http["SERVER_SSL_PRIVKEY"])
if ssl.HAS_ALPN:
ssl_context.set_alpn_protocols(["h2"])
# HTTP server init
if config.CFG.http["DISABLE_SSL"]:
ssl_context = None
else:
info("Python not compiled with ALPN support, using NPN instead.")
ssl_context.set_npn_protocols(["h2"])
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.options |= (ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION)
ssl_context.load_cert_chain(certfile=config.CFG.http["SERVER_SSL_CERT"], keyfile=config.CFG.http["SERVER_SSL_PRIVKEY"])
if ssl.HAS_ALPN:
ssl_context.set_alpn_protocols(["h2"])
else:
info("Python not compiled with ALPN support, using NPN instead.")
ssl_context.set_npn_protocols(["h2"])
if not config.CFG.http["DBG_DISABLE_CERTS"]:
ssl_context.verify_mode = ssl.CERT_REQUIRED
if not config.CFG.http["DBG_DISABLE_CERTS"]:
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_verify_locations(cafile=config.CFG.http["CA_CERT"])
ssl_context.load_verify_locations(cafile=config.CFG.http["CA_CERT"])
self.loop = asyncio.get_event_loop()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment