From b9591222f5d280dd1e656e307973179d2107a1f0 Mon Sep 17 00:00:00 2001 From: lolodomo Date: Sun, 30 Oct 2022 13:04:09 +0100 Subject: [PATCH] [hue] Check HTTPS connection (download of PEM certificate) (#13617) * [hue] Check HTTPS connection (download of PEM certificate) Fix #13586 Signed-off-by: Laurent Garnier --- .../HueTlsTrustManagerProvider.java | 23 ++++++++++--- .../internal/handler/HueBridgeHandler.java | 33 ++++++++++++++----- .../main/resources/OH-INF/i18n/hue.properties | 1 + 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/connection/HueTlsTrustManagerProvider.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/connection/HueTlsTrustManagerProvider.java index 5fa2820ed..414de92f4 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/connection/HueTlsTrustManagerProvider.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/connection/HueTlsTrustManagerProvider.java @@ -44,6 +44,8 @@ public class HueTlsTrustManagerProvider implements TlsTrustManagerProvider { private final Logger logger = LoggerFactory.getLogger(HueTlsTrustManagerProvider.class); + private @Nullable PEMTrustManager trustManager; + public HueTlsTrustManagerProvider(String hostname, boolean useSelfSignedCertificate) { this.hostname = hostname; this.useSelfSignedCertificate = useSelfSignedCertificate; @@ -56,20 +58,33 @@ public class HueTlsTrustManagerProvider implements TlsTrustManagerProvider { @Override public X509ExtendedTrustManager getTrustManager() { + PEMTrustManager localTrustManager = getPEMTrustManager(); + if (localTrustManager == null) { + logger.error("Cannot get the PEM certificate - returning a TrustAllTrustManager"); + } + return localTrustManager != null ? localTrustManager : TrustAllTrustManager.getInstance(); + } + + public @Nullable PEMTrustManager getPEMTrustManager() { + PEMTrustManager localTrustManager = trustManager; + if (localTrustManager != null) { + return localTrustManager; + } try { if (useSelfSignedCertificate) { logger.trace("Use self-signed certificate downloaded from Hue Bridge."); // use self-signed certificate downloaded from Hue Bridge - return PEMTrustManager.getInstanceFromServer("https://" + getHostName()); + localTrustManager = PEMTrustManager.getInstanceFromServer("https://" + getHostName()); } else { logger.trace("Use Signify private CA Certificate for Hue Bridges from resources."); // use Signify private CA Certificate for Hue Bridges from resources - return getInstanceFromResource(PEM_FILENAME); + localTrustManager = getInstanceFromResource(PEM_FILENAME); } + this.trustManager = localTrustManager; } catch (CertificateException | MalformedURLException e) { - logger.error("An unexpected exception occurred - returning a TrustAllTrustManager: {}", e.getMessage(), e); + logger.debug("An unexpected exception occurred: {}", e.getMessage(), e); } - return TrustAllTrustManager.getInstance(); + return localTrustManager; } /** diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java index 1afcef518..22686f89c 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java @@ -706,20 +706,35 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl "@text/offline.conf-error-no-ip-address"); } else { if (hueBridge == null) { - if (HueBridgeConfig.HTTPS.equals(hueBridgeConfig.protocol)) { - // register trustmanager service - HueTlsTrustManagerProvider tlsTrustManagerProvider = new HueTlsTrustManagerProvider( - ip + ":" + hueBridgeConfig.getPort(), hueBridgeConfig.useSelfSignedCertificate); - serviceRegistration = FrameworkUtil.getBundle(getClass()).getBundleContext() - .registerService(TlsTrustManagerProvider.class.getName(), tlsTrustManagerProvider, null); - } - hueBridge = new HueBridge(httpClient, ip, hueBridgeConfig.getPort(), hueBridgeConfig.protocol, scheduler); updateStatus(ThingStatus.UNKNOWN); + + if (HueBridgeConfig.HTTPS.equals(hueBridgeConfig.protocol)) { + scheduler.submit(() -> { + // register trustmanager service + HueTlsTrustManagerProvider tlsTrustManagerProvider = new HueTlsTrustManagerProvider( + ip + ":" + hueBridgeConfig.getPort(), hueBridgeConfig.useSelfSignedCertificate); + + // Check before registering that the PEM certificate can be downloaded + if (tlsTrustManagerProvider.getPEMTrustManager() == null) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "@text/offline.conf-error-https-connection"); + return; + } + + serviceRegistration = FrameworkUtil.getBundle(getClass()).getBundleContext().registerService( + TlsTrustManagerProvider.class.getName(), tlsTrustManagerProvider, null); + + onUpdate(); + }); + } else { + onUpdate(); + } + } else { + onUpdate(); } - onUpdate(); } } diff --git a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue.properties b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue.properties index 2b2af1df1..9f376076c 100644 --- a/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue.properties +++ b/bundles/org.openhab.binding.hue/src/main/resources/OH-INF/i18n/hue.properties @@ -148,6 +148,7 @@ config-status.error.missing-ip-address-configuration = No IP address for the Hue # thing status descriptions offline.communication-error = An unexpected exception occurred during execution. +offline.conf-error-https-connection = HTTPS secure connection failed. Please check your configuration settings (network address, protocol, port, type of certificate) and change protocol to http when using a V1 bridge. offline.conf-error-invalid-ssl-certificate = Invalid certificate for secured connection. You might want to enable the "Use Self-Signed Certificate" configuration. offline.conf-error-no-ip-address = Cannot connect to Hue Bridge. IP address not available in configuration. offline.conf-error-no-username = Cannot connect to Hue Bridge. User name for authentication not available in configuration.