From 08bfac1077ec9e5c38aaa01c93c82a939c964931 Mon Sep 17 00:00:00 2001
From: Hans Trompert <hans.trompert@surf.nl>
Date: Fri, 29 Oct 2021 12:55:18 +0200
Subject: [PATCH] base_url and non-TLS mode client authentication

- in a proxied setup base_url is not just the combination of host+port, in this
  case use base_url to specify your outside endpoint
- even in non-TLS mode enable client authentication when a key and certificate
  are specified
---
 datafiles/opennsa.conf |  3 +++
 opennsa/config.py      |  6 ++++++
 opennsa/setup.py       | 19 ++++++++++++++-----
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/datafiles/opennsa.conf b/datafiles/opennsa.conf
index 3d42e435..8e2669b9 100644
--- a/datafiles/opennsa.conf
+++ b/datafiles/opennsa.conf
@@ -16,6 +16,9 @@
 # host=example.org
 # port=9443
 
+## in a proxied setup specify base_url
+# base_url=https://opennsa.example.domain/
+
 ## security settings
 
 #tls=true # defaults to true
diff --git a/opennsa/config.py b/opennsa/config.py
index 5fc080ab..eeeaa89a 100644
--- a/opennsa/config.py
+++ b/opennsa/config.py
@@ -44,6 +44,7 @@ LOG_FILE = 'logfile'
 HOST = 'host'
 PORT = 'port'
 TLS = 'tls'
+BASE_URL = 'base_url'
 REST = 'rest'
 NRM_MAP_FILE = 'nrmmap'
 PEERS = 'peers'
@@ -309,6 +310,11 @@ class Config(object):
         vc[TLS] = cfg.getboolean(BLOCK_SERVICE, TLS, fallback=DEFAULT_TLS)
         vc[PORT] = cfg.getint(BLOCK_SERVICE, PORT, fallback=DEFAULT_TLS_PORT if vc[TLS] else DEFAULT_TCP_PORT)
 
+        try:
+            vc[BASE_URL] = cfg.get(BLOCK_SERVICE, BASE_URL)
+        except configparser.NoOptionError:
+            vc[BASE_URL] = None
+
         try:
             policies = cfg.get(BLOCK_SERVICE, POLICY).split(',')
             for policy in policies:
diff --git a/opennsa/setup.py b/opennsa/setup.py
index 198c34a6..f4cea162 100644
--- a/opennsa/setup.py
+++ b/opennsa/setup.py
@@ -108,9 +108,15 @@ def setupTLSContext(vc):
         if not os.path.isdir(vc[config.CERTIFICATE_DIR]):
             raise config.ConfigurationError(
                 'certdir value {} is not a directory'.format(vc[config.CERTIFICATE_DIR]))
-        from opennsa.opennsaTlsContext import opennsaTlsContext
-        ctx_factory = opennsaTlsContext(
-            vc[config.CERTIFICATE_DIR], vc[config.VERIFY_CERT])
+        if vc[config.KEY] and vc[config.CERTIFICATE]:
+            # enable client authentication even when not in TLS mode
+            from opennsa.opennsaTlsContext import opennsa2WayTlsContext
+            ctx_factory = opennsa2WayTlsContext(
+                vc[config.KEY], vc[config.CERTIFICATE], vc[config.CERTIFICATE_DIR], vc[config.VERIFY_CERT])
+        else:
+            from opennsa.opennsaTlsContext import opennsaTlsContext
+            ctx_factory = opennsaTlsContext(
+                vc[config.CERTIFICATE_DIR], vc[config.VERIFY_CERT])
     else:
         ctx_factory = None
 
@@ -168,8 +174,11 @@ class OpenNSAService(twistedservice.MultiService):
         nsa_name = domain_name + ':nsa'
 
         # base url
-        base_protocol = 'https://' if vc[config.TLS] else 'http://'
-        base_url = base_protocol + vc[config.HOST] + ':' + str(vc[config.PORT])
+        if vc[config.BASE_URL]:
+            base_url = vc[config.BASE_URL]
+        else:
+            base_protocol = 'https://' if vc[config.TLS] else 'http://'
+            base_url = base_protocol + vc[config.HOST] + ':' + str(vc[config.PORT])
 
         # nsi endpoint and agent
         provider_endpoint = base_url + '/NSI/services/CS2'  # hardcode for now
-- 
GitLab