From e3c0aa9ea26bc20d9609db66df00029740f18bfe Mon Sep 17 00:00:00 2001 From: Giga Murphy Date: Thu, 24 Jul 2025 00:18:27 +0000 Subject: [PATCH] T7635: OpenConnect Certificate Authentication --- data/templates/ocserv/ocserv_config.j2 | 9 ++++++++ interface-definitions/vpn_openconnect.xml.in | 24 ++++++++++++++++++++ src/conf_mode/vpn_openconnect.py | 15 +++++++++--- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/data/templates/ocserv/ocserv_config.j2 b/data/templates/ocserv/ocserv_config.j2 index 81f7770314..2679378a03 100644 --- a/data/templates/ocserv/ocserv_config.j2 +++ b/data/templates/ocserv/ocserv_config.j2 @@ -30,6 +30,15 @@ auth = "plain[otp=/run/ocserv/users.oath]" {% else %} auth = "plain[/run/ocserv/ocpasswd]" {% endif %} +{% elif "certificate" in authentication.mode %} +auth = "certificate" +{% if authentication.mode.certificate == "cn" %} +cert-user-oid = 2.5.4.3 +{% elif authentication.mode.certificate == "uid" %} +cert-user-oid = 0.9.2342.19200300.100.1.1 +{% else %} +cert-user-oid = {{ authentication.mode.certificate }} +{% endif %} {% else %} auth = "plain[/run/ocserv/ocpasswd]" {% endif %} diff --git a/interface-definitions/vpn_openconnect.xml.in b/interface-definitions/vpn_openconnect.xml.in index a2f040b2fa..7f905e5395 100644 --- a/interface-definitions/vpn_openconnect.xml.in +++ b/interface-definitions/vpn_openconnect.xml.in @@ -69,6 +69,30 @@ + + + Use certificate based authentication + + cn + OID 2.5.4.3 - Common Name + + + uid + OID 0.9.2342.19200300.100.1.1 - UID + + + x.x.xx.xxx + Custom OID in dotted decimal format + + + (^\d{1,5}(?:\.\d{1,5})*$|cn|uid) + + Invalid OID selection. Must be cn, uid, or a valid OID format. + + cn uid x.x.xx.xxx + + + diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py index 78cdaa1796..c3faee4142 100755 --- a/src/conf_mode/vpn_openconnect.py +++ b/src/conf_mode/vpn_openconnect.py @@ -104,11 +104,17 @@ def verify(ocserv): if 'authentication' in ocserv: if 'mode' in ocserv['authentication']: if ( - 'local' in ocserv['authentication']['mode'] - and 'radius' in ocserv['authentication']['mode'] + ('local' in ocserv['authentication']['mode'] + and 'radius' in ocserv['authentication']['mode']) + or + ('local' in ocserv['authentication']['mode'] + and 'certificate' in ocserv['authentication']['mode']) + or + ('radius' in ocserv['authentication']['mode'] + and 'certificate' in ocserv['authentication']['mode']) ): raise ConfigError( - 'OpenConnect authentication modes are mutually-exclusive, remove either local or radius from your configuration' + 'OpenConnect authentication modes are mutually-exclusive. Only one of local, radius, or certificate.' ) if 'radius' in ocserv['authentication']['mode']: if 'server' not in ocserv['authentication']['radius']: @@ -202,6 +208,9 @@ def verify(ocserv): raise ConfigError('SSL certificate missing on OpenConnect config!') verify_pki_certificate(ocserv, ocserv['ssl']['certificate']) + if 'ca_certificate' not in ocserv['ssl'] and 'certificiate' in ocserv['authentication']['mode']: + raise ConfigError('CA certificate must be provided in certificate authentication mode!') + if 'ca_certificate' in ocserv['ssl']: for ca_cert in ocserv['ssl']['ca_certificate']: verify_pki_ca_certificate(ocserv, ca_cert)